1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2020 The Khronos Group 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 vktSynchronizationNoneStageTests.cpp
21 * \brief Tests for VK_PIPELINE_STAGE_NONE{_2}_KHR that iterate over each writable layout
22 and over each readable layout. Data to tested image is writen using method
23 appropriate for the writable layout and read via readable layout appropriate method.
24 Betwean read and write operation there are bariers that use none stage.
25 Implemented tests are also testing generalized layouts (VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,
26 VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR) and access flags (MEMORY_ACCESS_READ|WRITE_BIT) to
27 test contextual synchronization introduced with VK_KHR_synchronization2 extension.
28 *//*--------------------------------------------------------------------*/
29
30 #include "vktSynchronizationNoneStageTests.hpp"
31 #include "vktSynchronizationOperation.hpp"
32 #include "vktSynchronizationUtil.hpp"
33 #include "vktTestCase.hpp"
34
35 #include "vkBuilderUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41
42 #include "tcuImageCompare.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "tcuTestLog.hpp"
45 #include "tcuStringTemplate.hpp"
46
47 #include "deUniquePtr.hpp"
48
49 #include <vector>
50
51 namespace vkt
52 {
53 namespace synchronization
54 {
55
56 using namespace vk;
57 using namespace de;
58 using namespace tcu;
59
60 namespace
61 {
62
63 static const deUint32 IMAGE_ASPECT_DEPTH_STENCIL = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
64 static const deUint32 IMAGE_ASPECT_ALL = 0u;
65
66 struct TestParams
67 {
68 SynchronizationType type;
69 bool useGenericAccessFlags;
70 VkImageLayout writeLayout;
71 VkImageAspectFlags writeAspect;
72 VkImageLayout readLayout;
73 VkImageAspectFlags readAspect;
74 };
75
76 // Helper class representing image
77 class ImageWrapper
78 {
79 public:
80
81 ImageWrapper () = default;
82 void create (Context& context, SimpleAllocator& alloc, VkFormat format, VkExtent3D extent, VkImageUsageFlags usage);
83
84 public:
85 Move<VkImage> handle;
86 MovePtr<Allocation> memory;
87 };
88
create(Context & context,SimpleAllocator & alloc,VkFormat format,VkExtent3D extent,VkImageUsageFlags usage)89 void ImageWrapper::create(Context& context, SimpleAllocator& alloc, VkFormat format, VkExtent3D extent, VkImageUsageFlags usage)
90 {
91 const DeviceInterface& vk = context.getDeviceInterface();
92 const VkDevice& device = context.getDevice();
93 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
94 const VkImageCreateInfo imageParams
95 {
96 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
97 DE_NULL, // pNext
98 0u, // flags
99 VK_IMAGE_TYPE_2D, // imageType
100 format, // format
101 extent, // extent
102 1u, // mipLevels
103 1u, // arraySize
104 VK_SAMPLE_COUNT_1_BIT, // samples
105 VK_IMAGE_TILING_OPTIMAL, // tiling
106 usage, // usage
107 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
108 1u, // queueFamilyIndexCount
109 &queueFamilyIndex, // pQueueFamilyIndices
110 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
111 };
112
113 handle = createImage(vk, device, &imageParams);
114 memory = alloc.allocate(getImageMemoryRequirements(vk, device, *handle), MemoryRequirement::Any);
115
116 vk.bindImageMemory(device, *handle, memory->getMemory(), memory->getOffset());
117 }
118
119 // Helper class representing buffer
120 class BufferWrapper
121 {
122 public:
123
124 BufferWrapper () = default;
125 void create (Context& context, SimpleAllocator& alloc, VkDeviceSize size, VkBufferUsageFlags usage);
126
127 public:
128 Move<VkBuffer> handle;
129 MovePtr<Allocation> memory;
130 };
131
create(Context & context,SimpleAllocator & alloc,VkDeviceSize size,VkBufferUsageFlags usage)132 void BufferWrapper::create(Context& context, SimpleAllocator& alloc, VkDeviceSize size, VkBufferUsageFlags usage)
133 {
134 const DeviceInterface& vk = context.getDeviceInterface();
135 const VkDevice& device = context.getDevice();
136 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(size, usage);
137
138 handle = createBuffer(vk, device, &bufferCreateInfo);
139 memory = alloc.allocate(getBufferMemoryRequirements(vk, device, *handle), MemoryRequirement::HostVisible);
140
141 VK_CHECK(vk.bindBufferMemory(device, *handle, memory->getMemory(), memory->getOffset()));
142 }
143
144 class NoneStageTestInstance : public vkt::TestInstance
145 {
146 public:
147 NoneStageTestInstance (Context& context,
148 const TestParams& testParams);
149 virtual ~NoneStageTestInstance (void) = default;
150
151 tcu::TestStatus iterate (void) override;
152
153 protected:
154
155 VkAccessFlags2KHR getAccessFlag (VkAccessFlags2KHR access);
156 VkBufferImageCopy buildCopyRegion (VkExtent3D extent,
157 VkImageAspectFlags aspect);
158 void buildVertexBuffer (void);
159 Move<VkRenderPass> buildBasicRenderPass (VkFormat outputFormat,
160 VkImageLayout outputLayout,
161 VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE);
162 Move<VkRenderPass> buildComplexRenderPass (VkFormat intermediateFormat,
163 VkImageLayout intermediateLayout,
164 VkImageAspectFlags intermediateAspect,
165 VkFormat outputFormat,
166 VkImageLayout outputLayout);
167 Move<VkImageView> buildImageView (VkImage image,
168 VkFormat format,
169 const VkImageSubresourceRange& subresourceRange);
170 Move<VkFramebuffer> buildFramebuffer (VkRenderPass renderPass,
171 const VkImageView* outView1,
172 const VkImageView* outView2 = DE_NULL);
173 Move<VkSampler> buildSampler (void);
174 Move<VkDescriptorSetLayout> buildDescriptorSetLayout (VkDescriptorType descriptorType);
175 Move<VkDescriptorPool> buildDescriptorPool (VkDescriptorType descriptorType);
176 Move<VkDescriptorSet> buildDescriptorSet (VkDescriptorPool descriptorPool,
177 VkDescriptorSetLayout descriptorSetLayout,
178 VkDescriptorType descriptorType,
179 VkImageView inputView,
180 VkImageLayout inputLayout,
181 const VkSampler* sampler = DE_NULL);
182 Move<VkPipeline> buildPipeline (deUint32 subpass,
183 VkImageAspectFlags resultAspect,
184 VkPipelineLayout pipelineLayout,
185 VkShaderModule vertShaderModule,
186 VkShaderModule fragShaderModule,
187 VkRenderPass renderPass);
188 bool verifyResult (const PixelBufferAccess& reference,
189 const PixelBufferAccess& result);
190
191 private:
192
193 const TestParams m_testParams;
194
195 VkFormat m_referenceImageFormat;
196 VkFormat m_transitionImageFormat;
197 VkFormat m_readImageFormat;
198 VkImageSubresourceRange m_referenceSubresourceRange;
199 VkImageSubresourceRange m_transitionSubresourceRange;
200 VkImageSubresourceRange m_readSubresourceRange;
201 VkImageAspectFlags m_transitionImageAspect;
202
203 VkExtent3D m_imageExtent;
204 VkImageLayout m_writeRenderPassOutputLayout;
205
206 // flag indicating that graphics pipeline is constructed to write data to tested image
207 bool m_usePipelineToWrite;
208
209 // flag indicating that graphics pipeline is constructed to read data from tested image
210 bool m_usePipelineToRead;
211
212 // flag indicating that write pipeline should be constructed in a special way to fill stencil buffer
213 bool m_useStencilDuringWrite;
214
215 // flag indicating that read pipeline should be constructed in a special way to use input attachment as a data source
216 bool m_useInputAttachmentToRead;
217
218 VkPipelineStageFlags2KHR m_srcStageToNoneStageMask;
219 VkAccessFlags2KHR m_srcAccessToNoneAccessMask;
220 VkPipelineStageFlags2KHR m_dstStageFromNoneStageMask;
221 VkAccessFlags2KHR m_dstAccessFromNoneAccessMask;
222
223 SimpleAllocator m_alloc;
224
225 ImageWrapper m_referenceImage;
226 VkImageUsageFlags m_referenceImageUsage;
227
228 // objects/variables initialized only when needed
229 ImageWrapper m_imageToWrite;
230 VkImageUsageFlags m_imageToWriteUsage;
231
232 ImageWrapper m_imageToRead;
233
234 BufferWrapper m_vertexBuffer;
235 std::vector<Move<VkImageView> > m_attachmentViews;
236
237 std::string m_writeFragShaderName;
238 Move<VkShaderModule> m_writeVertShaderModule;
239 Move<VkShaderModule> m_writeFragShaderModule;
240 Move<VkRenderPass> m_writeRenderPass;
241 Move<VkSampler> m_writeSampler;
242 Move<VkDescriptorSetLayout> m_writeDescriptorSetLayout;
243 Move<VkDescriptorPool> m_writeDescriptorPool;
244 Move<VkDescriptorSet> m_writeDescriptorSet;
245 Move<VkPipelineLayout> m_writePipelineLayout;
246 Move<VkPipeline> m_writePipeline;
247 Move<VkFramebuffer> m_writeFramebuffer;
248
249 std::string m_readFragShaderName;
250 Move<VkShaderModule> m_readVertShaderModule;
251 Move<VkShaderModule> m_readFragShaderModule;
252 Move<VkShaderModule> m_readFragShaderModule2;
253 Move<VkRenderPass> m_readRenderPass;
254 Move<VkSampler> m_readSampler;
255 Move<VkDescriptorSetLayout> m_readDescriptorSetLayout;
256 Move<VkDescriptorPool> m_readDescriptorPool;
257 Move<VkDescriptorSet> m_readDescriptorSet;
258 Move<VkPipelineLayout> m_readPipelineLayout;
259 Move<VkPipeline> m_readPipeline;
260 Move<VkFramebuffer> m_readFramebuffer;
261 };
262
NoneStageTestInstance(Context & context,const TestParams & testParams)263 NoneStageTestInstance::NoneStageTestInstance(Context& context, const TestParams& testParams)
264 : vkt::TestInstance(context)
265 , m_testParams (testParams)
266 , m_imageExtent { 32, 32, 1 }
267 , m_alloc (m_context.getDeviceInterface(),
268 m_context.getDevice(),
269 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()))
270 {
271 // note: for clarity whole configuration of whats going on in iterate method was moved here
272
273 const auto writeLayout = m_testParams.writeLayout;
274 const auto writeAspect = m_testParams.writeAspect;
275 const auto readLayout = m_testParams.readLayout;
276 const auto readAspect = m_testParams.readAspect;
277
278 // When testing depth stencil combined images, the stencil aspect is only tested when depth aspect is in ATTACHMENT_OPTIMAL layout.
279 // - it is invalid to read depth using sampler or input attachment in such layout
280 const auto readStencilFromCombinedDepthStencil = (readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL);
281
282 // select format that will be used for test
283 if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
284 {
285 m_transitionImageFormat = VK_FORMAT_D32_SFLOAT;
286 m_transitionImageAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
287 m_writeRenderPassOutputLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
288 }
289 else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
290 {
291 m_transitionImageFormat = VK_FORMAT_S8_UINT;
292 m_transitionImageAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
293 m_writeRenderPassOutputLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
294 }
295 else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
296 {
297 m_transitionImageFormat = VK_FORMAT_D24_UNORM_S8_UINT;
298 m_writeRenderPassOutputLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
299
300 if (readStencilFromCombinedDepthStencil)
301 {
302 m_transitionImageAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
303 }
304 else
305 {
306 // note: in test we focus only on depth aspect; no need to check both in those cases
307 m_transitionImageAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
308 }
309 }
310 else
311 {
312 m_transitionImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
313 m_transitionImageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
314 m_writeRenderPassOutputLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
315 }
316
317 m_referenceSubresourceRange = { m_transitionImageAspect, 0u, 1u, 0u, 1u };
318 m_transitionSubresourceRange = { m_transitionImageAspect, 0u, 1u, 0u, 1u };
319 m_readSubresourceRange = { m_transitionImageAspect, 0u, 1u, 0u, 1u };
320 m_referenceImageFormat = m_transitionImageFormat;
321 m_readImageFormat = m_transitionImageFormat;
322 m_referenceImageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
323 m_imageToWriteUsage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
324
325 // pipeline is not created for transfer and general layouts (general layouts in tests follow same path as transfer layouts)
326 m_usePipelineToWrite = (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
327 m_usePipelineToRead = (readLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout != VK_IMAGE_LAYOUT_GENERAL);
328 m_useStencilDuringWrite = false;
329
330 m_srcStageToNoneStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
331 m_srcAccessToNoneAccessMask = getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR);
332 m_dstStageFromNoneStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
333 m_dstAccessFromNoneAccessMask = getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR);
334
335 // when graphics pipelines are not created only image with gradient is used for test
336 if (!m_usePipelineToWrite && !m_usePipelineToRead)
337 {
338 m_referenceImageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
339 return;
340 }
341
342 if (m_usePipelineToWrite)
343 {
344 // depth/stencil layouts need diferent configuration
345 if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
346 {
347 if ((writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT) && !readStencilFromCombinedDepthStencil)
348 {
349 m_referenceImageFormat = VK_FORMAT_R32_SFLOAT;
350 m_referenceImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
351 m_referenceSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
352 m_writeFragShaderName = "frag-color-to-depth";
353 }
354 else
355 {
356 m_referenceImageUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
357 m_useStencilDuringWrite = true;
358 m_writeFragShaderName = "frag-color-to-stencil";
359 }
360
361 m_srcStageToNoneStageMask = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR;
362 m_srcAccessToNoneAccessMask = getAccessFlag(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR);
363 m_imageToWriteUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
364 }
365 else
366 {
367 m_referenceImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
368 m_srcStageToNoneStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR;
369 m_srcAccessToNoneAccessMask = getAccessFlag(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR);
370 m_writeFragShaderName = "frag-color";
371 m_imageToWriteUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
372 }
373 }
374
375 if (m_usePipelineToRead)
376 {
377 m_dstStageFromNoneStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR;
378 m_dstAccessFromNoneAccessMask = getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR);
379
380 m_readSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
381 if (((readAspect | writeAspect) & VK_IMAGE_ASPECT_DEPTH_BIT) && !readStencilFromCombinedDepthStencil)
382 m_readImageFormat = VK_FORMAT_R32_SFLOAT;
383 else if ((readAspect | writeAspect) & VK_IMAGE_ASPECT_STENCIL_BIT)
384 m_readImageFormat = VK_FORMAT_R8_UINT;
385
386 // for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
387 if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
388 {
389 m_useInputAttachmentToRead = true;
390 m_readFragShaderName = "frag-depth-or-stencil-to-color";
391 m_imageToWriteUsage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
392 m_dstAccessFromNoneAccessMask = getAccessFlag(VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR);
393
394 if (!m_usePipelineToWrite)
395 m_referenceImageUsage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
396 }
397 else // use image sampler for color and depth_stencil layouts
398 {
399 m_useInputAttachmentToRead = false;
400 m_readFragShaderName = "frag-color";
401 m_referenceImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
402 m_imageToWriteUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
403
404 // for depth_stencil layouts we need to have depth_stencil_attachment usage
405 if (!m_usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
406 m_referenceImageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
407
408 // when we read stencil as color we need to use usampler2D
409 if ((readAspect | writeAspect) == VK_IMAGE_ASPECT_STENCIL_BIT || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL && readStencilFromCombinedDepthStencil))
410 m_readFragShaderName = "frag-stencil-to-color";
411 }
412 }
413 }
414
getAccessFlag(VkAccessFlags2KHR access)415 VkAccessFlags2KHR NoneStageTestInstance::getAccessFlag(VkAccessFlags2KHR access)
416 {
417 if (m_testParams.useGenericAccessFlags)
418 {
419 switch (access)
420 {
421 case VK_ACCESS_2_HOST_READ_BIT_KHR:
422 case VK_ACCESS_2_TRANSFER_READ_BIT_KHR:
423 case VK_ACCESS_2_SHADER_READ_BIT_KHR:
424 case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
425 return VK_ACCESS_2_MEMORY_READ_BIT_KHR;
426
427 case VK_ACCESS_2_HOST_WRITE_BIT_KHR:
428 case VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR:
429 case VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR:
430 case VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR:
431 return VK_ACCESS_2_MEMORY_WRITE_BIT_KHR;
432
433 default:
434 TCU_THROW(TestError, "Unhandled access flag");
435 }
436 }
437 return access;
438 }
439
buildCopyRegion(VkExtent3D extent,VkImageAspectFlags aspect)440 VkBufferImageCopy NoneStageTestInstance::buildCopyRegion(VkExtent3D extent, VkImageAspectFlags aspect)
441 {
442 return
443 {
444 0u, // VkDeviceSize bufferOffset
445 extent.width, // deUint32 bufferRowLength
446 extent.height, // deUint32 bufferImageHeight
447 { aspect, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource
448 { 0, 0, 0 }, // VkOffset3D imageOffset
449 extent // VkExtent3D imageExtent
450 };
451 }
452
buildVertexBuffer()453 void NoneStageTestInstance::buildVertexBuffer()
454 {
455 const DeviceInterface& vk = m_context.getDeviceInterface();
456 const VkDevice& device = m_context.getDevice();
457
458 std::vector<float> vertices
459 {
460 1.0f, 1.0f, 0.0f, 1.0f,
461 -1.0f, 1.0f, 0.0f, 1.0f,
462 1.0f, -1.0f, 0.0f, 1.0f,
463 -1.0f, -1.0f, 0.0f, 1.0f,
464 };
465 m_vertexBuffer.create(m_context, m_alloc, sizeof(float) * vertices.size(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
466
467 deMemcpy(m_vertexBuffer.memory->getHostPtr(), vertices.data(), vertices.size() * sizeof(float));
468 flushAlloc(vk, device, *m_vertexBuffer.memory);
469 }
470
buildBasicRenderPass(VkFormat outputFormat,VkImageLayout outputLayout,VkAttachmentLoadOp loadOp)471 Move<VkRenderPass> NoneStageTestInstance::buildBasicRenderPass(VkFormat outputFormat, VkImageLayout outputLayout, VkAttachmentLoadOp loadOp)
472 {
473 // output color/depth attachment
474 VkAttachmentDescription2 attachmentDescription
475 {
476 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType
477 DE_NULL, // const void* pNext
478 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
479 outputFormat, // VkFormat format
480 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
481 loadOp, // VkAttachmentLoadOp loadOp
482 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
483 loadOp, // VkAttachmentLoadOp stencilLoadOp
484 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
485 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
486 outputLayout // VkImageLayout finalLayout
487 };
488
489 VkImageAspectFlags imageAspect = getImageAspectFlags(mapVkFormat(outputFormat));
490 VkAttachmentReference2 attachmentRef
491 {
492 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, outputLayout, imageAspect
493 };
494
495 VkAttachmentReference2* pColorAttachment = DE_NULL;
496 VkAttachmentReference2* pDepthStencilAttachment = DE_NULL;
497 if (imageAspect == VK_IMAGE_ASPECT_COLOR_BIT)
498 pColorAttachment = &attachmentRef;
499 else
500 pDepthStencilAttachment = &attachmentRef;
501
502 VkSubpassDescription2 subpassDescription
503 {
504 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
505 DE_NULL,
506 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
507 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
508 0u, // deUint32 viewMask
509 0u, // deUint32 inputAttachmentCount
510 DE_NULL, // const VkAttachmentReference2* pInputAttachments
511 !!pColorAttachment, // deUint32 colorAttachmentCount
512 pColorAttachment, // const VkAttachmentReference2* pColorAttachments
513 DE_NULL, // const VkAttachmentReference2* pResolveAttachments
514 pDepthStencilAttachment, // const VkAttachmentReference2* pDepthStencilAttachment
515 0u, // deUint32 preserveAttachmentCount
516 DE_NULL // const deUint32* pPreserveAttachments
517 };
518
519 const VkRenderPassCreateInfo2 renderPassInfo
520 {
521 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
522 DE_NULL, // const void* pNext
523 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
524 1u, // deUint32 attachmentCount
525 &attachmentDescription, // const VkAttachmentDescription* pAttachments
526 1u, // deUint32 subpassCount
527 &subpassDescription, // const VkSubpassDescription* pSubpasses
528 0u, // deUint32 dependencyCount
529 DE_NULL, // const VkSubpassDependency* pDependencies
530 0u, // deUint32 correlatedViewMaskCount
531 DE_NULL // const deUint32* pCorrelatedViewMasks
532 };
533
534 return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
535 }
536
buildComplexRenderPass(VkFormat intermediateFormat,VkImageLayout intermediateLayout,VkImageAspectFlags intermediateAspect,VkFormat outputFormat,VkImageLayout outputLayout)537 Move<VkRenderPass> NoneStageTestInstance::buildComplexRenderPass(VkFormat intermediateFormat, VkImageLayout intermediateLayout, VkImageAspectFlags intermediateAspect,
538 VkFormat outputFormat, VkImageLayout outputLayout)
539 {
540 std::vector<VkAttachmentDescription2> attachmentDescriptions
541 {
542 // depth/stencil attachment (when used in read pipeline it loads data filed in write pipeline)
543 {
544 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType
545 DE_NULL, // const void* pNext
546 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
547 intermediateFormat, // VkFormat format
548 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
549 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
550 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
551 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
552 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
553 intermediateLayout, // VkImageLayout initialLayout
554 intermediateLayout // VkImageLayout finalLayout
555 },
556 // color attachment
557 {
558 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType
559 DE_NULL, // const void* pNext
560 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
561 outputFormat, // VkFormat format
562 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
563 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp
564 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
565 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
566 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
567 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
568 outputLayout // VkImageLayout finalLayout
569 }
570 };
571
572 VkImageAspectFlags outputAspect = getImageAspectFlags(mapVkFormat(outputFormat));
573 std::vector<VkAttachmentReference2> attachmentRefs
574 {
575 { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, intermediateLayout, intermediateAspect },
576 { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 1u, outputLayout, outputAspect }
577 };
578
579 VkAttachmentReference2* pDepthStencilAttachment = &attachmentRefs[0];
580 VkAttachmentReference2* pColorAttachment = &attachmentRefs[1];
581
582 std::vector<VkSubpassDescription2> subpassDescriptions
583 {
584 {
585 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
586 DE_NULL,
587 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
588 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
589 0u, // deUint32 viewMask
590 1u, // deUint32 inputAttachmentCount
591 pDepthStencilAttachment, // const VkAttachmentReference2* pInputAttachments
592 1u, // deUint32 colorAttachmentCount
593 pColorAttachment, // const VkAttachmentReference2* pColorAttachments
594 DE_NULL, // const VkAttachmentReference2* pResolveAttachments
595 DE_NULL, // const VkAttachmentReference2* pDepthStencilAttachment
596 0u, // deUint32 preserveAttachmentCount
597 DE_NULL // deUint32* pPreserveAttachments
598 }
599 };
600
601 const VkRenderPassCreateInfo2 renderPassInfo
602 {
603 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
604 DE_NULL, // const void* pNext
605 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
606 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount
607 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
608 (deUint32)subpassDescriptions.size(), // deUint32 subpassCount
609 subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses
610 0u, // deUint32 dependencyCount
611 DE_NULL, // const VkSubpassDependency* pDependencies
612 0u, // deUint32 correlatedViewMaskCount
613 DE_NULL // const deUint32* pCorrelatedViewMasks
614 };
615
616 return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
617 }
618
buildImageView(VkImage image,VkFormat format,const VkImageSubresourceRange & subresourceRange)619 Move<VkImageView> NoneStageTestInstance::buildImageView(VkImage image, VkFormat format, const VkImageSubresourceRange& subresourceRange)
620 {
621 const DeviceInterface& vk = m_context.getDeviceInterface();
622 const VkDevice& device = m_context.getDevice();
623
624 const VkImageViewCreateInfo imageViewParams
625 {
626 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
627 DE_NULL, // const void* pNext
628 0u, // VkImageViewCreateFlags flags
629 image, // VkImage image
630 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
631 format, // VkFormat format
632 makeComponentMappingRGBA(), // VkComponentMapping components
633 subresourceRange, // VkImageSubresourceRange subresourceRange
634 };
635
636 return createImageView(vk, device, &imageViewParams);
637 }
638
buildFramebuffer(VkRenderPass renderPass,const VkImageView * outView1,const VkImageView * outView2)639 Move<VkFramebuffer> NoneStageTestInstance::buildFramebuffer(VkRenderPass renderPass, const VkImageView* outView1, const VkImageView* outView2)
640 {
641 const DeviceInterface& vk = m_context.getDeviceInterface();
642 const VkDevice& device = m_context.getDevice();
643
644 std::vector<VkImageView> imageViews = { *outView1 };
645 if (outView2)
646 imageViews.push_back(*outView2);
647
648 const VkFramebufferCreateInfo framebufferParams
649 {
650 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
651 DE_NULL, // const void* pNext
652 0u, // VkFramebufferCreateFlags flags
653 renderPass, // VkRenderPass renderPass
654 (deUint32)imageViews.size(), // deUint32 attachmentCount
655 imageViews.data(), // const VkImageView* pAttachments
656 m_imageExtent.width, // deUint32 width
657 m_imageExtent.height, // deUint32 height
658 1u, // deUint32 layers
659 };
660 return createFramebuffer(vk, device, &framebufferParams);
661 }
662
buildSampler()663 Move<VkSampler> NoneStageTestInstance::buildSampler()
664 {
665 const DeviceInterface& vk = m_context.getDeviceInterface();
666 const VkDevice& device = m_context.getDevice();
667
668 const VkSamplerCreateInfo samplerInfo
669 {
670 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
671 DE_NULL, // const void* pNext
672 0u, // VkSamplerCreateFlags flags
673 VK_FILTER_NEAREST, // VkFilter magFilter
674 VK_FILTER_NEAREST, // VkFilter minFilter
675 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode
676 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
677 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
678 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
679 0.0f, // float mipLodBias
680 VK_FALSE, // VkBool32 anisotropyEnable
681 1.0f, // float maxAnisotropy
682 DE_FALSE, // VkBool32 compareEnable
683 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
684 0.0f, // float minLod
685 0.0f, // float maxLod
686 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
687 VK_FALSE, // VkBool32 unnormalizedCoords
688 };
689 return createSampler(vk, device, &samplerInfo);
690 }
691
buildDescriptorSetLayout(VkDescriptorType descriptorType)692 Move<VkDescriptorSetLayout> NoneStageTestInstance::buildDescriptorSetLayout(VkDescriptorType descriptorType)
693 {
694 const DeviceInterface& vk = m_context.getDeviceInterface();
695 const VkDevice& device = m_context.getDevice();
696
697 return
698 DescriptorSetLayoutBuilder()
699 .addSingleSamplerBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL)
700 .build(vk, device);
701 }
702
buildDescriptorPool(VkDescriptorType descriptorType)703 Move<VkDescriptorPool> NoneStageTestInstance::buildDescriptorPool(VkDescriptorType descriptorType)
704 {
705 const DeviceInterface& vk = m_context.getDeviceInterface();
706 const VkDevice& device = m_context.getDevice();
707
708 return
709 DescriptorPoolBuilder()
710 .addType(descriptorType, 1u)
711 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
712 }
713
buildDescriptorSet(VkDescriptorPool descriptorPool,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorType descriptorType,VkImageView inputView,VkImageLayout inputLayout,const VkSampler * sampler)714 Move<VkDescriptorSet> NoneStageTestInstance::buildDescriptorSet(VkDescriptorPool descriptorPool,
715 VkDescriptorSetLayout descriptorSetLayout,
716 VkDescriptorType descriptorType,
717 VkImageView inputView,
718 VkImageLayout inputLayout,
719 const VkSampler* sampler)
720 {
721 const DeviceInterface& vk = m_context.getDeviceInterface();
722 const VkDevice& device = m_context.getDevice();
723
724 const VkDescriptorImageInfo inputImageInfo = makeDescriptorImageInfo(sampler ? *sampler : 0u, inputView, inputLayout);
725 Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout);
726
727 DescriptorSetUpdateBuilder()
728 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &inputImageInfo)
729 .update(vk, device);
730
731 return descriptorSet;
732 }
733
buildPipeline(deUint32 subpass,VkImageAspectFlags resultAspect,VkPipelineLayout pipelineLayout,VkShaderModule vertShaderModule,VkShaderModule fragShaderModule,VkRenderPass renderPass)734 Move<VkPipeline> NoneStageTestInstance::buildPipeline(deUint32 subpass,
735 VkImageAspectFlags resultAspect,
736 VkPipelineLayout pipelineLayout,
737 VkShaderModule vertShaderModule,
738 VkShaderModule fragShaderModule,
739 VkRenderPass renderPass)
740 {
741 const DeviceInterface& vk = m_context.getDeviceInterface();
742 const VkDevice& device = m_context.getDevice();
743 const std::vector<VkViewport> viewports { makeViewport(m_imageExtent) };
744 const std::vector<VkRect2D> scissors { makeRect2D(m_imageExtent) };
745 const bool useDepth = resultAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
746 const bool useStencil = resultAspect & VK_IMAGE_ASPECT_STENCIL_BIT;
747
748 const VkStencilOpState stencilOpState = makeStencilOpState(
749 VK_STENCIL_OP_REPLACE, // stencil fail
750 VK_STENCIL_OP_REPLACE, // depth & stencil pass
751 VK_STENCIL_OP_REPLACE, // depth only fail
752 VK_COMPARE_OP_ALWAYS, // compare op
753 1u, // compare mask
754 1u, // write mask
755 1u); // reference
756
757 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo
758 {
759 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
760 DE_NULL, // const void* pNext
761 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags
762 useDepth, // VkBool32 depthTestEnable
763 useDepth, // VkBool32 depthWriteEnable
764 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
765 VK_FALSE, // VkBool32 depthBoundsTestEnable
766 useStencil, // VkBool32 stencilTestEnable
767 stencilOpState, // VkStencilOpState front
768 stencilOpState, // VkStencilOpState back
769 0.0f, // float minDepthBounds
770 1.0f, // float maxDepthBounds
771 };
772
773 return makeGraphicsPipeline(
774 vk, // DeviceInterface& vk
775 device, // VkDevice device
776 pipelineLayout, // VkPipelineLayout pipelineLayout
777 vertShaderModule, // VkShaderModule vertexShaderModule
778 DE_NULL, // VkShaderModule tessellationControlModule
779 DE_NULL, // VkShaderModule tessellationEvalModule
780 DE_NULL, // VkShaderModule geometryShaderModule
781 fragShaderModule, // VkShaderModule fragmentShaderModule
782 renderPass, // VkRenderPass renderPass
783 viewports, // std::vector<VkViewport>& viewports
784 scissors, // std::vector<VkRect2D>& scissors
785 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology
786 subpass, // deUint32 subpass
787 0u, // deUint32 patchControlPoints
788 DE_NULL, // VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
789 DE_NULL, // VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
790 DE_NULL, // VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
791 &depthStencilStateCreateInfo); // VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
792 }
793
iterate(void)794 tcu::TestStatus NoneStageTestInstance::iterate(void)
795 {
796 const DeviceInterface& vk = m_context.getDeviceInterface();
797 const VkDevice& device = m_context.getDevice();
798 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
799 VkQueue queue = m_context.getUniversalQueue();
800 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
801 Move<VkCommandBuffer> cmdBuffer = makeCommandBuffer(vk, device, *cmdPool);
802 const VkDeviceSize vertexBufferOffset = 0;
803 ImageWrapper* transitionImagePtr = &m_referenceImage;
804 ImageWrapper* imageToVerifyPtr = &m_referenceImage;
805 const deUint32 imageSizeInBytes = m_imageExtent.width * m_imageExtent.height * 4;
806 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_testParams.type, vk, false);
807 const VkRect2D renderArea = makeRect2D(0, 0, m_imageExtent.width, m_imageExtent.height);
808 const VkBufferImageCopy transitionCopyRegion = buildCopyRegion(m_imageExtent, m_transitionImageAspect);
809 const VkBufferImageCopy colorCopyRegion = buildCopyRegion(m_imageExtent, VK_IMAGE_ASPECT_COLOR_BIT);
810
811 // create image that will have gradient (without data atm)
812 m_referenceImage.create(m_context, m_alloc, m_referenceImageFormat, m_imageExtent, m_referenceImageUsage);
813
814 // create buffer used for gradient data source
815 BufferWrapper srcBuffer;
816 srcBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
817
818 // generate gradient
819 std::vector<deUint32> referenceData (m_imageExtent.width * m_imageExtent.height);
820 tcu::TextureFormat referenceFormat (mapVkFormat(m_referenceImageFormat));
821 if (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
822 {
823 // when testing stencil aspect of depth stencil combined image, prepare reference date only with stencil,
824 // as the copy operation (used when m_usePipelineToWrite == false) sources just one aspect
825
826 // this format is used for tcu operations only - does not need to be supported by the Vulkan implementation
827 referenceFormat = mapVkFormat(VK_FORMAT_S8_UINT);
828 }
829 PixelBufferAccess referencePBA (referenceFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, referenceData.data());
830 fillWithComponentGradients(referencePBA, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
831 deMemcpy(srcBuffer.memory->getHostPtr(), referenceData.data(), static_cast<size_t>(imageSizeInBytes));
832 flushAlloc(vk, device, *srcBuffer.memory);
833
834 // create buffer for result transfer
835 BufferWrapper dstBuffer;
836 tcu::TextureFormat resultFormat (mapVkFormat(m_readImageFormat));
837 dstBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
838
839 if (m_usePipelineToWrite || m_usePipelineToRead)
840 {
841 buildVertexBuffer();
842
843 // create image view for reference image (its always at index 0)
844 m_attachmentViews.push_back(buildImageView(*m_referenceImage.handle, m_referenceImageFormat, m_referenceSubresourceRange));
845
846 // create graphics pipeline used to write image data
847 if (m_usePipelineToWrite)
848 {
849 // create image that will be used as attachment to write to
850 m_imageToWrite.create(m_context, m_alloc, m_transitionImageFormat, m_imageExtent, m_imageToWriteUsage);
851 m_attachmentViews.push_back(buildImageView(*m_imageToWrite.handle, m_transitionImageFormat, m_transitionSubresourceRange));
852
853 m_writeVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
854 m_writeFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_writeFragShaderName), 0);
855
856 if (m_useStencilDuringWrite)
857 {
858 // this is used only for cases where writable layout is VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL
859 // in this case generated gradient is only used for verification
860 m_writeRenderPass = buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout, VK_ATTACHMENT_LOAD_OP_CLEAR);
861 m_writePipelineLayout = makePipelineLayout(vk, device, DE_NULL);
862 m_writePipeline = buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
863 *m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
864 m_writeFramebuffer = buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
865 }
866 else
867 {
868 m_writeRenderPass = buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout);
869 m_writeSampler = buildSampler();
870 m_writeDescriptorSetLayout = buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
871 m_writeDescriptorPool = buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
872 m_writeDescriptorSet = buildDescriptorSet(*m_writeDescriptorPool, *m_writeDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
873 *m_attachmentViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, &m_writeSampler.get());
874 m_writePipelineLayout = makePipelineLayout(vk, device, *m_writeDescriptorSetLayout);
875 m_writePipeline = buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
876 *m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
877 m_writeFramebuffer = buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
878 }
879
880 transitionImagePtr = &m_imageToWrite;
881 imageToVerifyPtr = &m_imageToWrite;
882 }
883
884 // create graphics pipeline used to read image data
885 if (m_usePipelineToRead)
886 {
887 m_imageToRead.create(m_context, m_alloc, m_readImageFormat, m_imageExtent, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
888 m_attachmentViews.push_back(buildImageView(*m_imageToRead.handle, m_readImageFormat, m_readSubresourceRange));
889 imageToVerifyPtr = &m_imageToRead;
890
891 m_readVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
892 m_readFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_readFragShaderName), 0);
893
894 if (m_useInputAttachmentToRead)
895 {
896 m_readDescriptorSetLayout = buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
897 m_readDescriptorPool = buildDescriptorPool(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
898 m_readDescriptorSet = buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
899 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout);
900 m_readRenderPass = buildComplexRenderPass(m_transitionImageFormat, m_testParams.readLayout, m_transitionImageAspect,
901 m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
902 m_readFramebuffer = buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite].get(),
903 &m_attachmentViews[m_usePipelineToWrite+1].get());
904 m_readPipelineLayout = makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
905 m_readPipeline = buildPipeline(0u, VK_IMAGE_ASPECT_COLOR_BIT, *m_readPipelineLayout,
906 *m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
907 }
908 else
909 {
910 m_readSampler = buildSampler();
911 m_readDescriptorSetLayout = buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
912 m_readDescriptorPool = buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
913 m_readDescriptorSet = buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
914 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout, &m_readSampler.get());
915 m_readRenderPass = buildBasicRenderPass(m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
916 m_readFramebuffer = buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite + 1].get());
917 m_readPipelineLayout = makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
918 m_readPipeline = buildPipeline(0u, m_transitionImageAspect, *m_readPipelineLayout,
919 *m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
920 }
921 }
922 }
923
924 beginCommandBuffer(vk, *cmdBuffer);
925
926 // write data from buffer with gradient to image (for stencil_attachment cases we dont need to do that)
927 if (!m_useStencilDuringWrite)
928 {
929 // wait for reference data to be in buffer
930 const VkBufferMemoryBarrier2KHR preBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
931 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
932 getAccessFlag(VK_ACCESS_2_HOST_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
933 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
934 getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
935 *srcBuffer.handle, // VkBuffer buffer
936 0u, // VkDeviceSize offset
937 imageSizeInBytes // VkDeviceSize size
938 );
939
940 VkImageLayout copyBufferToImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
941 if(m_testParams.writeLayout == VK_IMAGE_LAYOUT_GENERAL)
942 copyBufferToImageLayout = VK_IMAGE_LAYOUT_GENERAL;
943
944 // change image layout so that we can copy to it data from buffer
945 const VkImageMemoryBarrier2KHR preImageMemoryBarrier2 = makeImageMemoryBarrier2(
946 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
947 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
948 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
949 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
950 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
951 copyBufferToImageLayout, // VkImageLayout newLayout
952 *m_referenceImage.handle, // VkImage image
953 m_referenceSubresourceRange // VkImageSubresourceRange subresourceRange
954 );
955 VkDependencyInfoKHR buffDependencyInfo = makeCommonDependencyInfo(DE_NULL, &preBufferMemoryBarrier2, &preImageMemoryBarrier2);
956 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &buffDependencyInfo);
957
958 const VkBufferImageCopy* copyRegion = m_usePipelineToWrite ? &colorCopyRegion : &transitionCopyRegion;
959 vk.cmdCopyBufferToImage(*cmdBuffer, *srcBuffer.handle, *m_referenceImage.handle, copyBufferToImageLayout, 1u, copyRegion);
960 }
961
962 if (m_usePipelineToWrite)
963 {
964 // wait till data is transfered to image (in all cases except when stencil_attachment is tested)
965 if (!m_useStencilDuringWrite)
966 {
967 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
968 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
969 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
970 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
971 getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
972 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
973 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout
974 *m_referenceImage.handle, // VkImage image
975 m_referenceSubresourceRange // VkImageSubresourceRange subresourceRange
976 );
977 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
978 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
979 }
980
981 beginRenderPass(vk, *cmdBuffer, *m_writeRenderPass, *m_writeFramebuffer, renderArea, tcu::Vec4(0.0f ,0.0f, 0.0f, 1.0f));
982
983 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipeline);
984 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
985 if (m_useStencilDuringWrite)
986 {
987 // when writing to stencil buffer draw single triangle (to simulate gradient over 1bit)
988 vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);
989 }
990 else
991 {
992 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipelineLayout, 0, 1, &m_writeDescriptorSet.get(), 0, DE_NULL);
993 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
994 }
995
996 endRenderPass(vk, *cmdBuffer);
997 }
998
999 // use none stage to wait till data is transfered to image
1000 {
1001 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1002 m_srcStageToNoneStageMask, // VkPipelineStageFlags2KHR srcStageMask
1003 m_srcAccessToNoneAccessMask, // VkAccessFlags2KHR srcAccessMask
1004 VK_PIPELINE_STAGE_2_NONE_KHR, // VkPipelineStageFlags2KHR dstStageMask
1005 VK_ACCESS_2_NONE_KHR, // VkAccessFlags2KHR dstAccessMask
1006 m_testParams.writeLayout, // VkImageLayout oldLayout
1007 m_testParams.writeLayout, // VkImageLayout newLayout
1008 *transitionImagePtr->handle, // VkImage image
1009 m_transitionSubresourceRange // VkImageSubresourceRange subresourceRange
1010 );
1011 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1012 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1013 }
1014
1015 // use all commands stage to change image layout
1016 {
1017 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1018 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
1019 VK_ACCESS_2_NONE_KHR, // VkAccessFlags2KHR srcAccessMask
1020 m_dstStageFromNoneStageMask, // VkPipelineStageFlags2KHR dstStageMask
1021 m_dstAccessFromNoneAccessMask, // VkAccessFlags2KHR dstAccessMask
1022 m_testParams.writeLayout, // VkImageLayout oldLayout
1023 m_testParams.readLayout, // VkImageLayout newLayout
1024 *transitionImagePtr->handle, // VkImage image
1025 m_transitionSubresourceRange // VkImageSubresourceRange subresourceRange
1026 );
1027 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1028 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1029 }
1030
1031 VkImageLayout copyImageToBufferLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1032 if (m_testParams.readLayout == VK_IMAGE_LAYOUT_GENERAL)
1033 copyImageToBufferLayout = VK_IMAGE_LAYOUT_GENERAL;
1034
1035 if (m_usePipelineToRead)
1036 {
1037 beginRenderPass(vk, *cmdBuffer, *m_readRenderPass, *m_readFramebuffer, renderArea);
1038
1039 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipeline);
1040 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipelineLayout, 0, 1, &m_readDescriptorSet.get(), 0, DE_NULL);
1041 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
1042 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
1043
1044 endRenderPass(vk, *cmdBuffer);
1045
1046 // wait till data is transfered to image
1047 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1048 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
1049 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
1050 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
1051 getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
1052 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
1053 copyImageToBufferLayout, // VkImageLayout newLayout
1054 *imageToVerifyPtr->handle, // VkImage image
1055 m_readSubresourceRange // VkImageSubresourceRange subresourceRange
1056 );
1057 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1058 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1059 }
1060
1061 // read back image
1062 {
1063 const VkBufferImageCopy* copyRegion = m_usePipelineToRead ? &colorCopyRegion : &transitionCopyRegion;
1064 vk.cmdCopyImageToBuffer(*cmdBuffer, *imageToVerifyPtr->handle, copyImageToBufferLayout, *dstBuffer.handle, 1u, copyRegion);
1065
1066 const VkBufferMemoryBarrier2KHR postBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
1067 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
1068 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
1069 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
1070 getAccessFlag(VK_ACCESS_2_HOST_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
1071 *dstBuffer.handle, // VkBuffer buffer
1072 0u, // VkDeviceSize offset
1073 imageSizeInBytes // VkDeviceSize size
1074 );
1075 VkDependencyInfoKHR bufDependencyInfo = makeCommonDependencyInfo(DE_NULL, &postBufferMemoryBarrier2);
1076 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &bufDependencyInfo);
1077 }
1078
1079 endCommandBuffer(vk, *cmdBuffer);
1080
1081 Move<VkFence> fence = createFence(vk, device);
1082 VkCommandBufferSubmitInfoKHR cmdBuffersInfo = makeCommonCommandBufferSubmitInfo(*cmdBuffer);
1083 synchronizationWrapper->addSubmitInfo(0u, DE_NULL, 1u, &cmdBuffersInfo, 0u, DE_NULL);
1084 VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
1085 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), VK_TRUE, ~0ull));
1086
1087 // read image data
1088 invalidateAlloc(vk, device, *dstBuffer.memory);
1089 PixelBufferAccess resultPBA(resultFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, dstBuffer.memory->getHostPtr());
1090
1091 // if result/reference is depth-stencil format then focus only on tested component
1092 if (isCombinedDepthStencilType(referenceFormat.type))
1093 referencePBA = getEffectiveDepthStencilAccess(referencePBA, (m_referenceSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1094 if (isCombinedDepthStencilType(resultFormat.type))
1095 resultPBA = getEffectiveDepthStencilAccess(resultPBA, (m_readSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1096
1097 if (verifyResult(referencePBA, resultPBA))
1098 return TestStatus::pass("Pass");
1099 return TestStatus::fail("Fail");
1100 }
1101
verifyResult(const PixelBufferAccess & reference,const PixelBufferAccess & result)1102 bool NoneStageTestInstance::verifyResult(const PixelBufferAccess& reference, const PixelBufferAccess& result)
1103 {
1104 TestLog& log = m_context.getTestContext().getLog();
1105
1106 const auto forceStencil = (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL);
1107
1108 if (isIntFormat(m_referenceImageFormat) || isUintFormat(m_referenceImageFormat) || forceStencil)
1109 {
1110 // special case for stencil (1bit gradient - top-left of image is 0, bottom-right is 1)
1111
1112 bool isResultCorrect = true;
1113 TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8),
1114 m_imageExtent.width, m_imageExtent.height, 1);
1115 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
1116
1117 for (deUint32 y = 0; y < m_imageExtent.height; y++)
1118 for (deUint32 x = 0; x < m_imageExtent.width; x++)
1119 {
1120 // skip textels on diagonal (gradient lights texels on diagonal and stencil operation in test does not)
1121 if ((x + y) == (m_imageExtent.width - 1))
1122 {
1123 errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, 0);
1124 continue;
1125 }
1126
1127 IVec4 refPix = reference.getPixelInt(x, y, 0);
1128 IVec4 cmpPix = result.getPixelInt(x, y, 0);
1129 bool isOk = (refPix[0] == cmpPix[0]);
1130 errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, 0);
1131 isResultCorrect &= isOk;
1132 }
1133
1134 Vec4 pixelBias(0.0f);
1135 Vec4 pixelScale(1.0f);
1136 if (isResultCorrect)
1137 {
1138 log << TestLog::ImageSet("Image comparison", "")
1139 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1140 << TestLog::EndImageSet;
1141 return true;
1142 }
1143
1144 log << TestLog::ImageSet("Image comparison", "")
1145 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1146 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
1147 << TestLog::Image("ErrorMask", "Error mask", errorMask)
1148 << TestLog::EndImageSet;
1149 return false;
1150 }
1151
1152 return floatThresholdCompare(log, "Image comparison", "", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1153 }
1154
1155 class NoneStageTestCase : public vkt::TestCase
1156 {
1157 public:
1158 NoneStageTestCase (tcu::TestContext& testContext,
1159 const std::string& name,
1160 const TestParams& testParams);
1161 ~NoneStageTestCase (void) = default;
1162
1163 void initPrograms (SourceCollections& sourceCollections) const override;
1164 TestInstance* createInstance (Context& context) const override;
1165 void checkSupport (Context& context) const override;
1166
1167 private:
1168 const TestParams m_testParams;
1169 };
1170
NoneStageTestCase(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)1171 NoneStageTestCase::NoneStageTestCase(tcu::TestContext& testContext, const std::string& name, const TestParams& testParams)
1172 : vkt::TestCase (testContext, name, "")
1173 , m_testParams (testParams)
1174 {
1175 }
1176
initPrograms(SourceCollections & sourceCollections) const1177 void NoneStageTestCase::initPrograms(SourceCollections& sourceCollections) const
1178 {
1179 const auto writeLayout = m_testParams.writeLayout;
1180 const auto writeAspect = m_testParams.writeAspect;
1181 const auto readLayout = m_testParams.readLayout;
1182 const auto readAspect = m_testParams.readAspect;
1183
1184 // for tests that use only transfer and general layouts we don't create pipeline
1185 if (((writeLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) || (readLayout == VK_IMAGE_LAYOUT_GENERAL)) &&
1186 ((writeLayout == VK_IMAGE_LAYOUT_GENERAL) || (readLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)))
1187 return;
1188
1189 sourceCollections.glslSources.add("vert") << glu::VertexSource(
1190 "#version 450\n"
1191 "layout(location = 0) in vec4 inPosition;\n"
1192 "layout(location = 0) out vec2 outUV;\n"
1193 "void main(void)\n"
1194 "{\n"
1195 " outUV = vec2(inPosition.x * 0.5 + 0.5, inPosition.y * 0.5 + 0.5);\n"
1196 " gl_Position = inPosition;\n"
1197 "}\n"
1198 );
1199
1200 sourceCollections.glslSources.add("frag-color") << glu::FragmentSource(
1201 "#version 450\n"
1202 "layout(binding = 0) uniform sampler2D u_sampler;\n"
1203 "layout(location = 0) in vec2 inUV;\n"
1204 "layout(location = 0) out vec4 fragColor;\n"
1205 "void main(void)\n"
1206 "{\n"
1207 " fragColor = texture(u_sampler, inUV);\n"
1208 "}\n"
1209 );
1210
1211 if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1212 {
1213 sourceCollections.glslSources.add("frag-color-to-depth") << glu::FragmentSource(
1214 "#version 450\n"
1215 "layout(binding = 0) uniform sampler2D u_sampler;\n"
1216 "layout(location = 0) in vec2 inUV;\n"
1217 "void main(void)\n"
1218 "{\n"
1219 " gl_FragDepth = texture(u_sampler, inUV).r;\n"
1220 "}\n"
1221 );
1222 }
1223
1224 if (writeAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
1225 {
1226 sourceCollections.glslSources.add("frag-color-to-stencil") << glu::FragmentSource(
1227 "#version 450\n"
1228 "void main(void)\n"
1229 "{\n"
1230 "}\n"
1231 );
1232 }
1233 if ((readLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) &&
1234 (readLayout != VK_IMAGE_LAYOUT_GENERAL) &&
1235 ((readAspect | writeAspect) == VK_IMAGE_ASPECT_STENCIL_BIT || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL && m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)))
1236 {
1237 // use usampler2D and uvec4 for color
1238 sourceCollections.glslSources.add("frag-stencil-to-color") << glu::FragmentSource(
1239 "#version 450\n"
1240 "layout(binding = 0) uniform usampler2D u_sampler;\n"
1241 "layout(location = 0) in vec2 inUV;\n"
1242 "layout(location = 0) out uvec4 fragColor;\n"
1243 "void main(void)\n"
1244 "{\n"
1245 " fragColor = texture(u_sampler, inUV);\n"
1246 "}\n"
1247 );
1248 }
1249
1250 if (readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1251 {
1252 // for stencil only cases we need to use usubpassInput (for depth and depth_stencil we need to use subpassInput)
1253 const bool readDepth = readAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
1254 const std::map<std::string, std::string> specializations
1255 {
1256 { "SUBPASS_INPUT", (readDepth ? "subpassInput" : "usubpassInput") },
1257 { "VALUE_TYPE", (readDepth ? "float" : "uint") }
1258 };
1259
1260 std::string source =
1261 "#version 450\n"
1262 "layout (input_attachment_index = 0, binding = 0) uniform ${SUBPASS_INPUT} depthOrStencilInput;\n"
1263 "layout(location = 0) in vec2 inUV;\n"
1264 "layout(location = 0) out ${VALUE_TYPE} fragColor;\n"
1265 "void main (void)\n"
1266 "{\n"
1267 " fragColor = subpassLoad(depthOrStencilInput).x;\n"
1268 "}\n";
1269 sourceCollections.glslSources.add("frag-depth-or-stencil-to-color")
1270 << glu::FragmentSource(tcu::StringTemplate(source).specialize(specializations));
1271 }
1272 }
1273
createInstance(Context & context) const1274 TestInstance* NoneStageTestCase::createInstance(Context& context) const
1275 {
1276 return new NoneStageTestInstance(context, m_testParams);
1277 }
1278
checkSupport(Context & context) const1279 void NoneStageTestCase::checkSupport(Context& context) const
1280 {
1281 context.requireDeviceFunctionality("VK_KHR_synchronization2");
1282
1283 const auto writeAspect = m_testParams.writeAspect;
1284 const auto readAspect = m_testParams.readAspect;
1285
1286 // check whether implementation supports separate depth/stencil layouts
1287 if (((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) && (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT)) ||
1288 ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) && (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT)))
1289 {
1290 if(!context.getSeparateDepthStencilLayoutsFeatures().separateDepthStencilLayouts)
1291 TCU_THROW(NotSupportedError, "Implementation does not support separateDepthStencilLayouts");
1292 }
1293
1294 const auto writeLayout = m_testParams.writeLayout;
1295 const auto readLayout = m_testParams.readLayout;
1296 bool usePipelineToWrite = (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
1297 bool usePipelineToRead = (readLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout != VK_IMAGE_LAYOUT_GENERAL);
1298
1299 if (!usePipelineToWrite && !usePipelineToRead)
1300 return;
1301
1302 VkFormat transitionImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
1303 if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
1304 transitionImageFormat = VK_FORMAT_D32_SFLOAT;
1305 else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
1306 transitionImageFormat = VK_FORMAT_S8_UINT;
1307 else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
1308 transitionImageFormat = VK_FORMAT_D24_UNORM_S8_UINT;
1309
1310 struct FormatToCheck
1311 {
1312 VkFormat format;
1313 VkImageUsageFlags usage;
1314 };
1315 std::vector<FormatToCheck> formatsToCheck
1316 {
1317 // reference image
1318 { transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_DST_BIT },
1319
1320 // image to write
1321 { transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_SRC_BIT }
1322 };
1323
1324 // note: conditions here are analogic to conditions in test case constructor
1325 // everything not needed was cout out leaving only logic related to
1326 // m_referenceImage and m_imageToWrite
1327 if (usePipelineToWrite)
1328 {
1329 if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1330 {
1331 if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1332 {
1333 formatsToCheck[0].format = VK_FORMAT_R32_SFLOAT;
1334 formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1335 }
1336 else
1337 formatsToCheck[0].usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1338
1339 formatsToCheck[1].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1340 }
1341 else
1342 {
1343 formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1344 formatsToCheck[1].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1345 }
1346 }
1347
1348 if (usePipelineToRead)
1349 {
1350 // for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
1351 if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
1352 {
1353 formatsToCheck[1].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1354
1355 if (!usePipelineToWrite)
1356 formatsToCheck[0].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1357 }
1358 else // use image sampler for color and depth_stencil layouts
1359 {
1360 formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1361
1362 // for depth_stencil layouts we need to have depth_stencil_attachment usage
1363 if (!usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
1364 formatsToCheck[0].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1365 }
1366 }
1367
1368 // it simplifies logic to pop image to write then to add conditions everywhere above
1369 if (!usePipelineToWrite)
1370 formatsToCheck.pop_back();
1371
1372 for (const auto& formatData : formatsToCheck)
1373 {
1374 VkImageFormatProperties properties;
1375 const vk::InstanceInterface& vki = context.getInstanceInterface();
1376 if (vki.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
1377 formatData.format,
1378 VK_IMAGE_TYPE_2D,
1379 VK_IMAGE_TILING_OPTIMAL,
1380 formatData.usage,
1381 0,
1382 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
1383 {
1384 std::string error = std::string("Format (") +
1385 vk::getFormatName(formatData.format) + ") doesn't support required capabilities.";
1386 TCU_THROW(NotSupportedError, error.c_str());
1387 }
1388 }
1389 }
1390
1391 } // anonymous
1392
createNoneStageTests(tcu::TestContext & testCtx)1393 tcu::TestCaseGroup* createNoneStageTests(tcu::TestContext& testCtx)
1394 {
1395 de::MovePtr<tcu::TestCaseGroup> noneStageTests(new tcu::TestCaseGroup(testCtx, "none_stage", ""));
1396
1397 struct LayoutData
1398 {
1399 VkImageLayout token;
1400 VkImageAspectFlags aspect;
1401 std::string name;
1402 };
1403
1404 const std::vector<LayoutData> writableLayoutsData
1405 {
1406 { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, IMAGE_ASPECT_ALL, "transfer_dst" },
1407 { VK_IMAGE_LAYOUT_GENERAL, IMAGE_ASPECT_ALL, "general" },
1408 { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, "color_attachment" },
1409 { VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_stencil_attachment" },
1410 { VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT, "depth_attachment" },
1411 { VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_STENCIL_BIT, "stencil_attachment" },
1412 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_ASPECT_COLOR_BIT, "generic_color_attachment" },
1413 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_ASPECT_DEPTH_BIT, "generic_depth_attachment" },
1414 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_ASPECT_STENCIL_BIT, "generic_stencil_attachment" },
1415 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, IMAGE_ASPECT_DEPTH_STENCIL, "generic_depth_stencil_attachment" },
1416 };
1417 const std::vector<LayoutData> readableLayoutsData
1418 {
1419 { VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, IMAGE_ASPECT_ALL, "transfer_src" },
1420 { VK_IMAGE_LAYOUT_GENERAL, IMAGE_ASPECT_ALL, "general" },
1421 { VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, IMAGE_ASPECT_ALL, "shader_read" },
1422 { VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_stencil_read" },
1423 { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_read_stencil_attachment" },
1424 { VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_attachment_stencil_read" },
1425 { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT, "depth_read" },
1426 { VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_STENCIL_BIT, "stencil_read" },
1427 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, IMAGE_ASPECT_ALL, "generic_color_read" },
1428 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_ASPECT_DEPTH_BIT, "generic_depth_read" },
1429 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_ASPECT_STENCIL_BIT, "generic_stencil_read" },
1430 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, IMAGE_ASPECT_DEPTH_STENCIL, "generic_depth_stencil_read" },
1431 };
1432
1433 struct SynchronizationData
1434 {
1435 SynchronizationType type;
1436 std::string casePrefix;
1437 bool useGenericAccessFlags;
1438 };
1439 std::vector<SynchronizationData> synchronizationData
1440 {
1441 { SynchronizationType::SYNCHRONIZATION2, "", true },
1442 { SynchronizationType::SYNCHRONIZATION2, "old_access_", false },
1443
1444 // using legacy synchronization structures with NONE_STAGE
1445 { SynchronizationType::LEGACY, "legacy_", false }
1446 };
1447
1448 for (const auto& syncData : synchronizationData)
1449 {
1450 for (const auto& writeData : writableLayoutsData)
1451 {
1452 for (const auto& readData : readableLayoutsData)
1453 {
1454 if (readData.aspect && writeData.aspect &&
1455 (readData.aspect != writeData.aspect))
1456 continue;
1457
1458 const std::string name = syncData.casePrefix + writeData.name + "_to_" + readData.name;
1459 noneStageTests->addChild(new NoneStageTestCase(testCtx, name, {
1460 syncData.type,
1461 syncData.useGenericAccessFlags,
1462 writeData.token,
1463 writeData.aspect,
1464 readData.token,
1465 readData.aspect
1466 }));
1467 }
1468 }
1469 }
1470
1471 return noneStageTests.release();
1472 }
1473
1474 } // synchronization
1475 } // vkt
1476