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 if (m_useInputAttachmentToRead && (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL || m_testParams.readLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL))
413 m_referenceImageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
414 }
415 }
416
getAccessFlag(VkAccessFlags2KHR access)417 VkAccessFlags2KHR NoneStageTestInstance::getAccessFlag(VkAccessFlags2KHR access)
418 {
419 if (m_testParams.useGenericAccessFlags)
420 {
421 switch (access)
422 {
423 case VK_ACCESS_2_HOST_READ_BIT_KHR:
424 case VK_ACCESS_2_TRANSFER_READ_BIT_KHR:
425 case VK_ACCESS_2_SHADER_READ_BIT_KHR:
426 case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
427 return VK_ACCESS_2_MEMORY_READ_BIT_KHR;
428
429 case VK_ACCESS_2_HOST_WRITE_BIT_KHR:
430 case VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR:
431 case VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR:
432 case VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR:
433 return VK_ACCESS_2_MEMORY_WRITE_BIT_KHR;
434
435 default:
436 TCU_THROW(TestError, "Unhandled access flag");
437 }
438 }
439 return access;
440 }
441
buildCopyRegion(VkExtent3D extent,VkImageAspectFlags aspect)442 VkBufferImageCopy NoneStageTestInstance::buildCopyRegion(VkExtent3D extent, VkImageAspectFlags aspect)
443 {
444 return
445 {
446 0u, // VkDeviceSize bufferOffset
447 extent.width, // deUint32 bufferRowLength
448 extent.height, // deUint32 bufferImageHeight
449 { aspect, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource
450 { 0, 0, 0 }, // VkOffset3D imageOffset
451 extent // VkExtent3D imageExtent
452 };
453 }
454
buildVertexBuffer()455 void NoneStageTestInstance::buildVertexBuffer()
456 {
457 const DeviceInterface& vk = m_context.getDeviceInterface();
458 const VkDevice& device = m_context.getDevice();
459
460 std::vector<float> vertices
461 {
462 1.0f, 1.0f, 0.0f, 1.0f,
463 -1.0f, 1.0f, 0.0f, 1.0f,
464 1.0f, -1.0f, 0.0f, 1.0f,
465 -1.0f, -1.0f, 0.0f, 1.0f,
466 };
467 m_vertexBuffer.create(m_context, m_alloc, sizeof(float) * vertices.size(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
468
469 deMemcpy(m_vertexBuffer.memory->getHostPtr(), vertices.data(), vertices.size() * sizeof(float));
470 flushAlloc(vk, device, *m_vertexBuffer.memory);
471 }
472
buildBasicRenderPass(VkFormat outputFormat,VkImageLayout outputLayout,VkAttachmentLoadOp loadOp)473 Move<VkRenderPass> NoneStageTestInstance::buildBasicRenderPass(VkFormat outputFormat, VkImageLayout outputLayout, VkAttachmentLoadOp loadOp)
474 {
475 // output color/depth attachment
476 VkAttachmentDescription2 attachmentDescription
477 {
478 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType
479 DE_NULL, // const void* pNext
480 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
481 outputFormat, // VkFormat format
482 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
483 loadOp, // VkAttachmentLoadOp loadOp
484 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
485 loadOp, // VkAttachmentLoadOp stencilLoadOp
486 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
487 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
488 outputLayout // VkImageLayout finalLayout
489 };
490
491 VkImageAspectFlags imageAspect = getImageAspectFlags(mapVkFormat(outputFormat));
492 VkAttachmentReference2 attachmentRef
493 {
494 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, outputLayout, imageAspect
495 };
496
497 VkAttachmentReference2* pColorAttachment = DE_NULL;
498 VkAttachmentReference2* pDepthStencilAttachment = DE_NULL;
499 if (imageAspect == VK_IMAGE_ASPECT_COLOR_BIT)
500 pColorAttachment = &attachmentRef;
501 else
502 pDepthStencilAttachment = &attachmentRef;
503
504 VkSubpassDescription2 subpassDescription
505 {
506 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
507 DE_NULL,
508 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
509 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
510 0u, // deUint32 viewMask
511 0u, // deUint32 inputAttachmentCount
512 DE_NULL, // const VkAttachmentReference2* pInputAttachments
513 !!pColorAttachment, // deUint32 colorAttachmentCount
514 pColorAttachment, // const VkAttachmentReference2* pColorAttachments
515 DE_NULL, // const VkAttachmentReference2* pResolveAttachments
516 pDepthStencilAttachment, // const VkAttachmentReference2* pDepthStencilAttachment
517 0u, // deUint32 preserveAttachmentCount
518 DE_NULL // const deUint32* pPreserveAttachments
519 };
520
521 const VkRenderPassCreateInfo2 renderPassInfo
522 {
523 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
524 DE_NULL, // const void* pNext
525 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
526 1u, // deUint32 attachmentCount
527 &attachmentDescription, // const VkAttachmentDescription* pAttachments
528 1u, // deUint32 subpassCount
529 &subpassDescription, // const VkSubpassDescription* pSubpasses
530 0u, // deUint32 dependencyCount
531 DE_NULL, // const VkSubpassDependency* pDependencies
532 0u, // deUint32 correlatedViewMaskCount
533 DE_NULL // const deUint32* pCorrelatedViewMasks
534 };
535
536 return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
537 }
538
buildComplexRenderPass(VkFormat intermediateFormat,VkImageLayout intermediateLayout,VkImageAspectFlags intermediateAspect,VkFormat outputFormat,VkImageLayout outputLayout)539 Move<VkRenderPass> NoneStageTestInstance::buildComplexRenderPass(VkFormat intermediateFormat, VkImageLayout intermediateLayout, VkImageAspectFlags intermediateAspect,
540 VkFormat outputFormat, VkImageLayout outputLayout)
541 {
542 std::vector<VkAttachmentDescription2> attachmentDescriptions
543 {
544 // depth/stencil attachment (when used in read pipeline it loads data filed in write pipeline)
545 {
546 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType
547 DE_NULL, // const void* pNext
548 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
549 intermediateFormat, // VkFormat format
550 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
551 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
552 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
553 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
554 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
555 intermediateLayout, // VkImageLayout initialLayout
556 intermediateLayout // VkImageLayout finalLayout
557 },
558 // color attachment
559 {
560 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType
561 DE_NULL, // const void* pNext
562 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
563 outputFormat, // VkFormat format
564 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
565 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp
566 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
567 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
568 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
569 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
570 outputLayout // VkImageLayout finalLayout
571 }
572 };
573
574 VkImageAspectFlags outputAspect = getImageAspectFlags(mapVkFormat(outputFormat));
575 std::vector<VkAttachmentReference2> attachmentRefs
576 {
577 { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, intermediateLayout, intermediateAspect },
578 { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 1u, outputLayout, outputAspect }
579 };
580
581 VkAttachmentReference2* pDepthStencilAttachment = &attachmentRefs[0];
582 VkAttachmentReference2* pColorAttachment = &attachmentRefs[1];
583
584 std::vector<VkSubpassDescription2> subpassDescriptions
585 {
586 {
587 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
588 DE_NULL,
589 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
590 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
591 0u, // deUint32 viewMask
592 1u, // deUint32 inputAttachmentCount
593 pDepthStencilAttachment, // const VkAttachmentReference2* pInputAttachments
594 1u, // deUint32 colorAttachmentCount
595 pColorAttachment, // const VkAttachmentReference2* pColorAttachments
596 DE_NULL, // const VkAttachmentReference2* pResolveAttachments
597 DE_NULL, // const VkAttachmentReference2* pDepthStencilAttachment
598 0u, // deUint32 preserveAttachmentCount
599 DE_NULL // deUint32* pPreserveAttachments
600 }
601 };
602
603 const VkRenderPassCreateInfo2 renderPassInfo
604 {
605 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
606 DE_NULL, // const void* pNext
607 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
608 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount
609 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
610 (deUint32)subpassDescriptions.size(), // deUint32 subpassCount
611 subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses
612 0u, // deUint32 dependencyCount
613 DE_NULL, // const VkSubpassDependency* pDependencies
614 0u, // deUint32 correlatedViewMaskCount
615 DE_NULL // const deUint32* pCorrelatedViewMasks
616 };
617
618 return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
619 }
620
buildImageView(VkImage image,VkFormat format,const VkImageSubresourceRange & subresourceRange)621 Move<VkImageView> NoneStageTestInstance::buildImageView(VkImage image, VkFormat format, const VkImageSubresourceRange& subresourceRange)
622 {
623 const DeviceInterface& vk = m_context.getDeviceInterface();
624 const VkDevice& device = m_context.getDevice();
625
626 const VkImageViewCreateInfo imageViewParams
627 {
628 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
629 DE_NULL, // const void* pNext
630 0u, // VkImageViewCreateFlags flags
631 image, // VkImage image
632 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
633 format, // VkFormat format
634 makeComponentMappingRGBA(), // VkComponentMapping components
635 subresourceRange, // VkImageSubresourceRange subresourceRange
636 };
637
638 return createImageView(vk, device, &imageViewParams);
639 }
640
buildFramebuffer(VkRenderPass renderPass,const VkImageView * outView1,const VkImageView * outView2)641 Move<VkFramebuffer> NoneStageTestInstance::buildFramebuffer(VkRenderPass renderPass, const VkImageView* outView1, const VkImageView* outView2)
642 {
643 const DeviceInterface& vk = m_context.getDeviceInterface();
644 const VkDevice& device = m_context.getDevice();
645
646 std::vector<VkImageView> imageViews = { *outView1 };
647 if (outView2)
648 imageViews.push_back(*outView2);
649
650 const VkFramebufferCreateInfo framebufferParams
651 {
652 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
653 DE_NULL, // const void* pNext
654 0u, // VkFramebufferCreateFlags flags
655 renderPass, // VkRenderPass renderPass
656 (deUint32)imageViews.size(), // deUint32 attachmentCount
657 imageViews.data(), // const VkImageView* pAttachments
658 m_imageExtent.width, // deUint32 width
659 m_imageExtent.height, // deUint32 height
660 1u, // deUint32 layers
661 };
662 return createFramebuffer(vk, device, &framebufferParams);
663 }
664
buildSampler()665 Move<VkSampler> NoneStageTestInstance::buildSampler()
666 {
667 const DeviceInterface& vk = m_context.getDeviceInterface();
668 const VkDevice& device = m_context.getDevice();
669
670 const VkSamplerCreateInfo samplerInfo
671 {
672 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
673 DE_NULL, // const void* pNext
674 0u, // VkSamplerCreateFlags flags
675 VK_FILTER_NEAREST, // VkFilter magFilter
676 VK_FILTER_NEAREST, // VkFilter minFilter
677 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode
678 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU
679 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV
680 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
681 0.0f, // float mipLodBias
682 VK_FALSE, // VkBool32 anisotropyEnable
683 1.0f, // float maxAnisotropy
684 DE_FALSE, // VkBool32 compareEnable
685 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
686 0.0f, // float minLod
687 0.0f, // float maxLod
688 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
689 VK_FALSE, // VkBool32 unnormalizedCoords
690 };
691 return createSampler(vk, device, &samplerInfo);
692 }
693
buildDescriptorSetLayout(VkDescriptorType descriptorType)694 Move<VkDescriptorSetLayout> NoneStageTestInstance::buildDescriptorSetLayout(VkDescriptorType descriptorType)
695 {
696 const DeviceInterface& vk = m_context.getDeviceInterface();
697 const VkDevice& device = m_context.getDevice();
698
699 return
700 DescriptorSetLayoutBuilder()
701 .addSingleSamplerBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL)
702 .build(vk, device);
703 }
704
buildDescriptorPool(VkDescriptorType descriptorType)705 Move<VkDescriptorPool> NoneStageTestInstance::buildDescriptorPool(VkDescriptorType descriptorType)
706 {
707 const DeviceInterface& vk = m_context.getDeviceInterface();
708 const VkDevice& device = m_context.getDevice();
709
710 return
711 DescriptorPoolBuilder()
712 .addType(descriptorType, 1u)
713 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
714 }
715
buildDescriptorSet(VkDescriptorPool descriptorPool,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorType descriptorType,VkImageView inputView,VkImageLayout inputLayout,const VkSampler * sampler)716 Move<VkDescriptorSet> NoneStageTestInstance::buildDescriptorSet(VkDescriptorPool descriptorPool,
717 VkDescriptorSetLayout descriptorSetLayout,
718 VkDescriptorType descriptorType,
719 VkImageView inputView,
720 VkImageLayout inputLayout,
721 const VkSampler* sampler)
722 {
723 const DeviceInterface& vk = m_context.getDeviceInterface();
724 const VkDevice& device = m_context.getDevice();
725
726 const VkDescriptorImageInfo inputImageInfo = makeDescriptorImageInfo(sampler ? *sampler : 0u, inputView, inputLayout);
727 Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout);
728
729 DescriptorSetUpdateBuilder()
730 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &inputImageInfo)
731 .update(vk, device);
732
733 return descriptorSet;
734 }
735
buildPipeline(deUint32 subpass,VkImageAspectFlags resultAspect,VkPipelineLayout pipelineLayout,VkShaderModule vertShaderModule,VkShaderModule fragShaderModule,VkRenderPass renderPass)736 Move<VkPipeline> NoneStageTestInstance::buildPipeline(deUint32 subpass,
737 VkImageAspectFlags resultAspect,
738 VkPipelineLayout pipelineLayout,
739 VkShaderModule vertShaderModule,
740 VkShaderModule fragShaderModule,
741 VkRenderPass renderPass)
742 {
743 const DeviceInterface& vk = m_context.getDeviceInterface();
744 const VkDevice& device = m_context.getDevice();
745 const std::vector<VkViewport> viewports { makeViewport(m_imageExtent) };
746 const std::vector<VkRect2D> scissors { makeRect2D(m_imageExtent) };
747 const bool useDepth = resultAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
748 const bool useStencil = resultAspect & VK_IMAGE_ASPECT_STENCIL_BIT;
749
750 const VkStencilOpState stencilOpState = makeStencilOpState(
751 VK_STENCIL_OP_REPLACE, // stencil fail
752 VK_STENCIL_OP_REPLACE, // depth & stencil pass
753 VK_STENCIL_OP_REPLACE, // depth only fail
754 VK_COMPARE_OP_ALWAYS, // compare op
755 1u, // compare mask
756 1u, // write mask
757 1u); // reference
758
759 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo
760 {
761 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
762 DE_NULL, // const void* pNext
763 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags
764 useDepth, // VkBool32 depthTestEnable
765 useDepth, // VkBool32 depthWriteEnable
766 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
767 VK_FALSE, // VkBool32 depthBoundsTestEnable
768 useStencil, // VkBool32 stencilTestEnable
769 stencilOpState, // VkStencilOpState front
770 stencilOpState, // VkStencilOpState back
771 0.0f, // float minDepthBounds
772 1.0f, // float maxDepthBounds
773 };
774
775 return makeGraphicsPipeline(
776 vk, // DeviceInterface& vk
777 device, // VkDevice device
778 pipelineLayout, // VkPipelineLayout pipelineLayout
779 vertShaderModule, // VkShaderModule vertexShaderModule
780 DE_NULL, // VkShaderModule tessellationControlModule
781 DE_NULL, // VkShaderModule tessellationEvalModule
782 DE_NULL, // VkShaderModule geometryShaderModule
783 fragShaderModule, // VkShaderModule fragmentShaderModule
784 renderPass, // VkRenderPass renderPass
785 viewports, // std::vector<VkViewport>& viewports
786 scissors, // std::vector<VkRect2D>& scissors
787 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology
788 subpass, // deUint32 subpass
789 0u, // deUint32 patchControlPoints
790 DE_NULL, // VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
791 DE_NULL, // VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
792 DE_NULL, // VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
793 &depthStencilStateCreateInfo); // VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
794 }
795
iterate(void)796 tcu::TestStatus NoneStageTestInstance::iterate(void)
797 {
798 const DeviceInterface& vk = m_context.getDeviceInterface();
799 const VkDevice& device = m_context.getDevice();
800 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
801 VkQueue queue = m_context.getUniversalQueue();
802 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
803 Move<VkCommandBuffer> cmdBuffer = makeCommandBuffer(vk, device, *cmdPool);
804 const VkDeviceSize vertexBufferOffset = 0;
805 ImageWrapper* transitionImagePtr = &m_referenceImage;
806 ImageWrapper* imageToVerifyPtr = &m_referenceImage;
807 const deUint32 imageSizeInBytes = m_imageExtent.width * m_imageExtent.height * 4;
808 SynchronizationWrapperPtr synchronizationWrapper = getSynchronizationWrapper(m_testParams.type, vk, false);
809 const VkRect2D renderArea = makeRect2D(0, 0, m_imageExtent.width, m_imageExtent.height);
810 const VkBufferImageCopy transitionCopyRegion = buildCopyRegion(m_imageExtent, m_transitionImageAspect);
811 const VkBufferImageCopy colorCopyRegion = buildCopyRegion(m_imageExtent, VK_IMAGE_ASPECT_COLOR_BIT);
812
813 // create image that will have gradient (without data atm)
814 m_referenceImage.create(m_context, m_alloc, m_referenceImageFormat, m_imageExtent, m_referenceImageUsage);
815
816 // create buffer used for gradient data source
817 BufferWrapper srcBuffer;
818 srcBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
819
820 // generate gradient
821 std::vector<deUint32> referenceData (m_imageExtent.width * m_imageExtent.height);
822 tcu::TextureFormat referenceFormat (mapVkFormat(m_referenceImageFormat));
823 if (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
824 {
825 // when testing stencil aspect of depth stencil combined image, prepare reference date only with stencil,
826 // as the copy operation (used when m_usePipelineToWrite == false) sources just one aspect
827
828 // this format is used for tcu operations only - does not need to be supported by the Vulkan implementation
829 referenceFormat = mapVkFormat(VK_FORMAT_S8_UINT);
830 }
831 PixelBufferAccess referencePBA (referenceFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, referenceData.data());
832 fillWithComponentGradients(referencePBA, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
833 deMemcpy(srcBuffer.memory->getHostPtr(), referenceData.data(), static_cast<size_t>(imageSizeInBytes));
834 flushAlloc(vk, device, *srcBuffer.memory);
835
836 // create buffer for result transfer
837 BufferWrapper dstBuffer;
838 tcu::TextureFormat resultFormat (mapVkFormat(m_readImageFormat));
839 dstBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
840
841 if (m_usePipelineToWrite || m_usePipelineToRead)
842 {
843 buildVertexBuffer();
844
845 // create image view for reference image (its always at index 0)
846 m_attachmentViews.push_back(buildImageView(*m_referenceImage.handle, m_referenceImageFormat, m_referenceSubresourceRange));
847
848 // create graphics pipeline used to write image data
849 if (m_usePipelineToWrite)
850 {
851 // create image that will be used as attachment to write to
852 m_imageToWrite.create(m_context, m_alloc, m_transitionImageFormat, m_imageExtent, m_imageToWriteUsage);
853 m_attachmentViews.push_back(buildImageView(*m_imageToWrite.handle, m_transitionImageFormat, m_transitionSubresourceRange));
854
855 m_writeVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
856 m_writeFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_writeFragShaderName), 0);
857
858 if (m_useStencilDuringWrite)
859 {
860 // this is used only for cases where writable layout is VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL
861 // in this case generated gradient is only used for verification
862 m_writeRenderPass = buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout, VK_ATTACHMENT_LOAD_OP_CLEAR);
863 m_writePipelineLayout = makePipelineLayout(vk, device, DE_NULL);
864 m_writePipeline = buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
865 *m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
866 m_writeFramebuffer = buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
867 }
868 else
869 {
870 m_writeRenderPass = buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout);
871 m_writeSampler = buildSampler();
872 m_writeDescriptorSetLayout = buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
873 m_writeDescriptorPool = buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
874 m_writeDescriptorSet = buildDescriptorSet(*m_writeDescriptorPool, *m_writeDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
875 *m_attachmentViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, &m_writeSampler.get());
876 m_writePipelineLayout = makePipelineLayout(vk, device, *m_writeDescriptorSetLayout);
877 m_writePipeline = buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
878 *m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
879 m_writeFramebuffer = buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
880 }
881
882 transitionImagePtr = &m_imageToWrite;
883 imageToVerifyPtr = &m_imageToWrite;
884 }
885
886 // create graphics pipeline used to read image data
887 if (m_usePipelineToRead)
888 {
889 m_imageToRead.create(m_context, m_alloc, m_readImageFormat, m_imageExtent, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
890 m_attachmentViews.push_back(buildImageView(*m_imageToRead.handle, m_readImageFormat, m_readSubresourceRange));
891 imageToVerifyPtr = &m_imageToRead;
892
893 m_readVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
894 m_readFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_readFragShaderName), 0);
895
896 if (m_useInputAttachmentToRead)
897 {
898 m_readDescriptorSetLayout = buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
899 m_readDescriptorPool = buildDescriptorPool(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
900 m_readDescriptorSet = buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
901 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout);
902 m_readRenderPass = buildComplexRenderPass(m_transitionImageFormat, m_testParams.readLayout, m_transitionImageAspect,
903 m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
904 m_readFramebuffer = buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite].get(),
905 &m_attachmentViews[m_usePipelineToWrite+1].get());
906 m_readPipelineLayout = makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
907 m_readPipeline = buildPipeline(0u, VK_IMAGE_ASPECT_COLOR_BIT, *m_readPipelineLayout,
908 *m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
909 }
910 else
911 {
912 m_readSampler = buildSampler();
913 m_readDescriptorSetLayout = buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
914 m_readDescriptorPool = buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
915 m_readDescriptorSet = buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
916 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout, &m_readSampler.get());
917 m_readRenderPass = buildBasicRenderPass(m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
918 m_readFramebuffer = buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite + 1].get());
919 m_readPipelineLayout = makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
920 m_readPipeline = buildPipeline(0u, m_transitionImageAspect, *m_readPipelineLayout,
921 *m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
922 }
923 }
924 }
925
926 beginCommandBuffer(vk, *cmdBuffer);
927
928 // write data from buffer with gradient to image (for stencil_attachment cases we dont need to do that)
929 if (!m_useStencilDuringWrite)
930 {
931 // wait for reference data to be in buffer
932 const VkBufferMemoryBarrier2KHR preBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
933 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
934 getAccessFlag(VK_ACCESS_2_HOST_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
935 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
936 getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
937 *srcBuffer.handle, // VkBuffer buffer
938 0u, // VkDeviceSize offset
939 imageSizeInBytes // VkDeviceSize size
940 );
941
942 VkImageLayout copyBufferToImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
943 if(m_testParams.writeLayout == VK_IMAGE_LAYOUT_GENERAL)
944 copyBufferToImageLayout = VK_IMAGE_LAYOUT_GENERAL;
945
946 // change image layout so that we can copy to it data from buffer
947 const VkImageMemoryBarrier2KHR preImageMemoryBarrier2 = makeImageMemoryBarrier2(
948 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
949 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
950 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
951 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
952 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
953 copyBufferToImageLayout, // VkImageLayout newLayout
954 *m_referenceImage.handle, // VkImage image
955 m_referenceSubresourceRange // VkImageSubresourceRange subresourceRange
956 );
957 VkDependencyInfoKHR buffDependencyInfo = makeCommonDependencyInfo(DE_NULL, &preBufferMemoryBarrier2, &preImageMemoryBarrier2);
958 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &buffDependencyInfo);
959
960 const VkBufferImageCopy* copyRegion = m_usePipelineToWrite ? &colorCopyRegion : &transitionCopyRegion;
961 vk.cmdCopyBufferToImage(*cmdBuffer, *srcBuffer.handle, *m_referenceImage.handle, copyBufferToImageLayout, 1u, copyRegion);
962 }
963
964 if (m_usePipelineToWrite)
965 {
966 // wait till data is transfered to image (in all cases except when stencil_attachment is tested)
967 if (!m_useStencilDuringWrite)
968 {
969 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
970 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
971 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
972 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
973 getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
974 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
975 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout
976 *m_referenceImage.handle, // VkImage image
977 m_referenceSubresourceRange // VkImageSubresourceRange subresourceRange
978 );
979 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
980 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
981 }
982
983 beginRenderPass(vk, *cmdBuffer, *m_writeRenderPass, *m_writeFramebuffer, renderArea, tcu::Vec4(0.0f ,0.0f, 0.0f, 1.0f));
984
985 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipeline);
986 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
987 if (m_useStencilDuringWrite)
988 {
989 // when writing to stencil buffer draw single triangle (to simulate gradient over 1bit)
990 vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);
991 }
992 else
993 {
994 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipelineLayout, 0, 1, &m_writeDescriptorSet.get(), 0, DE_NULL);
995 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
996 }
997
998 endRenderPass(vk, *cmdBuffer);
999 }
1000
1001 // use none stage to wait till data is transfered to image
1002 {
1003 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1004 m_srcStageToNoneStageMask, // VkPipelineStageFlags2KHR srcStageMask
1005 m_srcAccessToNoneAccessMask, // VkAccessFlags2KHR srcAccessMask
1006 VK_PIPELINE_STAGE_2_NONE_KHR, // VkPipelineStageFlags2KHR dstStageMask
1007 VK_ACCESS_2_NONE_KHR, // VkAccessFlags2KHR dstAccessMask
1008 m_testParams.writeLayout, // VkImageLayout oldLayout
1009 m_testParams.writeLayout, // VkImageLayout newLayout
1010 *transitionImagePtr->handle, // VkImage image
1011 m_transitionSubresourceRange // VkImageSubresourceRange subresourceRange
1012 );
1013 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1014 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1015 }
1016
1017 // use all commands stage to change image layout
1018 {
1019 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1020 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
1021 VK_ACCESS_2_NONE_KHR, // VkAccessFlags2KHR srcAccessMask
1022 m_dstStageFromNoneStageMask, // VkPipelineStageFlags2KHR dstStageMask
1023 m_dstAccessFromNoneAccessMask, // VkAccessFlags2KHR dstAccessMask
1024 m_testParams.writeLayout, // VkImageLayout oldLayout
1025 m_testParams.readLayout, // VkImageLayout newLayout
1026 *transitionImagePtr->handle, // VkImage image
1027 m_transitionSubresourceRange // VkImageSubresourceRange subresourceRange
1028 );
1029 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1030 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1031 }
1032
1033 VkImageLayout copyImageToBufferLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1034 if (m_testParams.readLayout == VK_IMAGE_LAYOUT_GENERAL)
1035 copyImageToBufferLayout = VK_IMAGE_LAYOUT_GENERAL;
1036
1037 if (m_usePipelineToRead)
1038 {
1039 beginRenderPass(vk, *cmdBuffer, *m_readRenderPass, *m_readFramebuffer, renderArea);
1040
1041 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipeline);
1042 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipelineLayout, 0, 1, &m_readDescriptorSet.get(), 0, DE_NULL);
1043 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
1044 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
1045
1046 endRenderPass(vk, *cmdBuffer);
1047
1048 // wait till data is transfered to image
1049 const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1050 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
1051 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // VkAccessFlags2KHR srcAccessMask
1052 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
1053 getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
1054 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
1055 copyImageToBufferLayout, // VkImageLayout newLayout
1056 *imageToVerifyPtr->handle, // VkImage image
1057 m_readSubresourceRange // VkImageSubresourceRange subresourceRange
1058 );
1059 VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1060 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1061 }
1062
1063 // read back image
1064 {
1065 const VkBufferImageCopy* copyRegion = m_usePipelineToRead ? &colorCopyRegion : &transitionCopyRegion;
1066 vk.cmdCopyImageToBuffer(*cmdBuffer, *imageToVerifyPtr->handle, copyImageToBufferLayout, *dstBuffer.handle, 1u, copyRegion);
1067
1068 const VkBufferMemoryBarrier2KHR postBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
1069 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR, // VkPipelineStageFlags2KHR srcStageMask
1070 getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR), // VkAccessFlags2KHR srcAccessMask
1071 VK_PIPELINE_STAGE_2_HOST_BIT_KHR, // VkPipelineStageFlags2KHR dstStageMask
1072 getAccessFlag(VK_ACCESS_2_HOST_READ_BIT_KHR), // VkAccessFlags2KHR dstAccessMask
1073 *dstBuffer.handle, // VkBuffer buffer
1074 0u, // VkDeviceSize offset
1075 imageSizeInBytes // VkDeviceSize size
1076 );
1077 VkDependencyInfoKHR bufDependencyInfo = makeCommonDependencyInfo(DE_NULL, &postBufferMemoryBarrier2);
1078 synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &bufDependencyInfo);
1079 }
1080
1081 endCommandBuffer(vk, *cmdBuffer);
1082
1083 Move<VkFence> fence = createFence(vk, device);
1084 VkCommandBufferSubmitInfoKHR cmdBuffersInfo = makeCommonCommandBufferSubmitInfo(*cmdBuffer);
1085 synchronizationWrapper->addSubmitInfo(0u, DE_NULL, 1u, &cmdBuffersInfo, 0u, DE_NULL);
1086 VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
1087 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), VK_TRUE, ~0ull));
1088
1089 // read image data
1090 invalidateAlloc(vk, device, *dstBuffer.memory);
1091 PixelBufferAccess resultPBA(resultFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, dstBuffer.memory->getHostPtr());
1092
1093 // if result/reference is depth-stencil format then focus only on tested component
1094 if (isCombinedDepthStencilType(referenceFormat.type))
1095 referencePBA = getEffectiveDepthStencilAccess(referencePBA, (m_referenceSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1096 if (isCombinedDepthStencilType(resultFormat.type))
1097 resultPBA = getEffectiveDepthStencilAccess(resultPBA, (m_readSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1098
1099 if (verifyResult(referencePBA, resultPBA))
1100 return TestStatus::pass("Pass");
1101 return TestStatus::fail("Fail");
1102 }
1103
verifyResult(const PixelBufferAccess & reference,const PixelBufferAccess & result)1104 bool NoneStageTestInstance::verifyResult(const PixelBufferAccess& reference, const PixelBufferAccess& result)
1105 {
1106 TestLog& log = m_context.getTestContext().getLog();
1107
1108 const auto forceStencil = (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL);
1109
1110 if (isIntFormat(m_referenceImageFormat) || isUintFormat(m_referenceImageFormat) || forceStencil)
1111 {
1112 // special case for stencil (1bit gradient - top-left of image is 0, bottom-right is 1)
1113
1114 bool isResultCorrect = true;
1115 TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8),
1116 m_imageExtent.width, m_imageExtent.height, 1);
1117 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
1118
1119 for (deUint32 y = 0; y < m_imageExtent.height; y++)
1120 for (deUint32 x = 0; x < m_imageExtent.width; x++)
1121 {
1122 // skip textels on diagonal (gradient lights texels on diagonal and stencil operation in test does not)
1123 if ((x + y) == (m_imageExtent.width - 1))
1124 {
1125 errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, 0);
1126 continue;
1127 }
1128
1129 IVec4 refPix = reference.getPixelInt(x, y, 0);
1130 IVec4 cmpPix = result.getPixelInt(x, y, 0);
1131 bool isOk = (refPix[0] == cmpPix[0]);
1132 errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, 0);
1133 isResultCorrect &= isOk;
1134 }
1135
1136 Vec4 pixelBias(0.0f);
1137 Vec4 pixelScale(1.0f);
1138 if (isResultCorrect)
1139 {
1140 log << TestLog::ImageSet("Image comparison", "")
1141 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1142 << TestLog::EndImageSet;
1143 return true;
1144 }
1145
1146 log << TestLog::ImageSet("Image comparison", "")
1147 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1148 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
1149 << TestLog::Image("ErrorMask", "Error mask", errorMask)
1150 << TestLog::EndImageSet;
1151 return false;
1152 }
1153
1154 return floatThresholdCompare(log, "Image comparison", "", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1155 }
1156
1157 class NoneStageTestCase : public vkt::TestCase
1158 {
1159 public:
1160 NoneStageTestCase (tcu::TestContext& testContext,
1161 const std::string& name,
1162 const TestParams& testParams);
1163 ~NoneStageTestCase (void) = default;
1164
1165 void initPrograms (SourceCollections& sourceCollections) const override;
1166 TestInstance* createInstance (Context& context) const override;
1167 void checkSupport (Context& context) const override;
1168
1169 private:
1170 const TestParams m_testParams;
1171 };
1172
NoneStageTestCase(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)1173 NoneStageTestCase::NoneStageTestCase(tcu::TestContext& testContext, const std::string& name, const TestParams& testParams)
1174 : vkt::TestCase (testContext, name)
1175 , m_testParams (testParams)
1176 {
1177 }
1178
initPrograms(SourceCollections & sourceCollections) const1179 void NoneStageTestCase::initPrograms(SourceCollections& sourceCollections) const
1180 {
1181 const auto writeLayout = m_testParams.writeLayout;
1182 const auto writeAspect = m_testParams.writeAspect;
1183 const auto readLayout = m_testParams.readLayout;
1184 const auto readAspect = m_testParams.readAspect;
1185
1186 // for tests that use only transfer and general layouts we don't create pipeline
1187 if (((writeLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) || (readLayout == VK_IMAGE_LAYOUT_GENERAL)) &&
1188 ((writeLayout == VK_IMAGE_LAYOUT_GENERAL) || (readLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)))
1189 return;
1190
1191 sourceCollections.glslSources.add("vert") << glu::VertexSource(
1192 "#version 450\n"
1193 "layout(location = 0) in vec4 inPosition;\n"
1194 "layout(location = 0) out vec2 outUV;\n"
1195 "void main(void)\n"
1196 "{\n"
1197 " outUV = vec2(inPosition.x * 0.5 + 0.5, inPosition.y * 0.5 + 0.5);\n"
1198 " gl_Position = inPosition;\n"
1199 "}\n"
1200 );
1201
1202 sourceCollections.glslSources.add("frag-color") << glu::FragmentSource(
1203 "#version 450\n"
1204 "layout(binding = 0) uniform sampler2D u_sampler;\n"
1205 "layout(location = 0) in vec2 inUV;\n"
1206 "layout(location = 0) out vec4 fragColor;\n"
1207 "void main(void)\n"
1208 "{\n"
1209 " fragColor = texture(u_sampler, inUV);\n"
1210 "}\n"
1211 );
1212
1213 if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1214 {
1215 sourceCollections.glslSources.add("frag-color-to-depth") << glu::FragmentSource(
1216 "#version 450\n"
1217 "layout(binding = 0) uniform sampler2D u_sampler;\n"
1218 "layout(location = 0) in vec2 inUV;\n"
1219 "void main(void)\n"
1220 "{\n"
1221 " gl_FragDepth = texture(u_sampler, inUV).r;\n"
1222 "}\n"
1223 );
1224 }
1225
1226 if (writeAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
1227 {
1228 sourceCollections.glslSources.add("frag-color-to-stencil") << glu::FragmentSource(
1229 "#version 450\n"
1230 "void main(void)\n"
1231 "{\n"
1232 "}\n"
1233 );
1234 }
1235 if ((readLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) &&
1236 (readLayout != VK_IMAGE_LAYOUT_GENERAL) &&
1237 ((readAspect | writeAspect) == VK_IMAGE_ASPECT_STENCIL_BIT || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL && m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)))
1238 {
1239 // use usampler2D and uvec4 for color
1240 sourceCollections.glslSources.add("frag-stencil-to-color") << glu::FragmentSource(
1241 "#version 450\n"
1242 "layout(binding = 0) uniform usampler2D u_sampler;\n"
1243 "layout(location = 0) in vec2 inUV;\n"
1244 "layout(location = 0) out uvec4 fragColor;\n"
1245 "void main(void)\n"
1246 "{\n"
1247 " fragColor = texture(u_sampler, inUV);\n"
1248 "}\n"
1249 );
1250 }
1251
1252 if (readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1253 {
1254 // for stencil only cases we need to use usubpassInput (for depth and depth_stencil we need to use subpassInput)
1255 const bool readDepth = readAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
1256 const std::map<std::string, std::string> specializations
1257 {
1258 { "SUBPASS_INPUT", (readDepth ? "subpassInput" : "usubpassInput") },
1259 { "VALUE_TYPE", (readDepth ? "float" : "uint") }
1260 };
1261
1262 std::string source =
1263 "#version 450\n"
1264 "layout (input_attachment_index = 0, binding = 0) uniform ${SUBPASS_INPUT} depthOrStencilInput;\n"
1265 "layout(location = 0) in vec2 inUV;\n"
1266 "layout(location = 0) out ${VALUE_TYPE} fragColor;\n"
1267 "void main (void)\n"
1268 "{\n"
1269 " fragColor = subpassLoad(depthOrStencilInput).x;\n"
1270 "}\n";
1271 sourceCollections.glslSources.add("frag-depth-or-stencil-to-color")
1272 << glu::FragmentSource(tcu::StringTemplate(source).specialize(specializations));
1273 }
1274 }
1275
createInstance(Context & context) const1276 TestInstance* NoneStageTestCase::createInstance(Context& context) const
1277 {
1278 return new NoneStageTestInstance(context, m_testParams);
1279 }
1280
checkSupport(Context & context) const1281 void NoneStageTestCase::checkSupport(Context& context) const
1282 {
1283 context.requireDeviceFunctionality("VK_KHR_synchronization2");
1284
1285 const auto writeAspect = m_testParams.writeAspect;
1286 const auto readAspect = m_testParams.readAspect;
1287
1288 // check whether implementation supports separate depth/stencil layouts
1289 if (((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) && (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT)) ||
1290 ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) && (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT)))
1291 {
1292 if(!context.getSeparateDepthStencilLayoutsFeatures().separateDepthStencilLayouts)
1293 TCU_THROW(NotSupportedError, "Implementation does not support separateDepthStencilLayouts");
1294 }
1295
1296 const auto writeLayout = m_testParams.writeLayout;
1297 const auto readLayout = m_testParams.readLayout;
1298 bool usePipelineToWrite = (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
1299 bool usePipelineToRead = (readLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout != VK_IMAGE_LAYOUT_GENERAL);
1300
1301 if (!usePipelineToWrite && !usePipelineToRead)
1302 return;
1303
1304 VkFormat transitionImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
1305 if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
1306 transitionImageFormat = VK_FORMAT_D32_SFLOAT;
1307 else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
1308 transitionImageFormat = VK_FORMAT_S8_UINT;
1309 else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
1310 transitionImageFormat = VK_FORMAT_D24_UNORM_S8_UINT;
1311
1312 struct FormatToCheck
1313 {
1314 VkFormat format;
1315 VkImageUsageFlags usage;
1316 };
1317 std::vector<FormatToCheck> formatsToCheck
1318 {
1319 // reference image
1320 { transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_DST_BIT },
1321
1322 // image to write
1323 { transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_SRC_BIT }
1324 };
1325
1326 // note: conditions here are analogic to conditions in test case constructor
1327 // everything not needed was cout out leaving only logic related to
1328 // m_referenceImage and m_imageToWrite
1329 if (usePipelineToWrite)
1330 {
1331 if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1332 {
1333 if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1334 {
1335 formatsToCheck[0].format = VK_FORMAT_R32_SFLOAT;
1336 formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1337 }
1338 else
1339 formatsToCheck[0].usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1340
1341 formatsToCheck[1].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1342 }
1343 else
1344 {
1345 formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1346 formatsToCheck[1].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1347 }
1348 }
1349
1350 if (usePipelineToRead)
1351 {
1352 // for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
1353 if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
1354 {
1355 formatsToCheck[1].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1356
1357 if (!usePipelineToWrite)
1358 formatsToCheck[0].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1359 }
1360 else // use image sampler for color and depth_stencil layouts
1361 {
1362 formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1363
1364 // for depth_stencil layouts we need to have depth_stencil_attachment usage
1365 if (!usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
1366 formatsToCheck[0].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1367 }
1368 if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
1369 if ((m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL || m_testParams.readLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL))
1370 formatsToCheck[0].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1371 }
1372
1373 // it simplifies logic to pop image to write then to add conditions everywhere above
1374 if (!usePipelineToWrite)
1375 formatsToCheck.pop_back();
1376
1377 for (const auto& formatData : formatsToCheck)
1378 {
1379 VkImageFormatProperties properties;
1380 const vk::InstanceInterface& vki = context.getInstanceInterface();
1381 if (vki.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
1382 formatData.format,
1383 VK_IMAGE_TYPE_2D,
1384 VK_IMAGE_TILING_OPTIMAL,
1385 formatData.usage,
1386 0,
1387 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
1388 {
1389 std::string error = std::string("Format (") +
1390 vk::getFormatName(formatData.format) + ") doesn't support required capabilities.";
1391 TCU_THROW(NotSupportedError, error.c_str());
1392 }
1393 }
1394 }
1395
1396 } // anonymous
1397
createNoneStageTests(tcu::TestContext & testCtx)1398 tcu::TestCaseGroup* createNoneStageTests(tcu::TestContext& testCtx)
1399 {
1400 de::MovePtr<tcu::TestCaseGroup> noneStageTests(new tcu::TestCaseGroup(testCtx, "none_stage"));
1401
1402 struct LayoutData
1403 {
1404 VkImageLayout token;
1405 VkImageAspectFlags aspect;
1406 std::string name;
1407 };
1408
1409 const std::vector<LayoutData> writableLayoutsData
1410 {
1411 { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, IMAGE_ASPECT_ALL, "transfer_dst" },
1412 { VK_IMAGE_LAYOUT_GENERAL, IMAGE_ASPECT_ALL, "general" },
1413 { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, "color_attachment" },
1414 { VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_stencil_attachment" },
1415 { VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT, "depth_attachment" },
1416 { VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_STENCIL_BIT, "stencil_attachment" },
1417 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_ASPECT_COLOR_BIT, "generic_color_attachment" },
1418 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_ASPECT_DEPTH_BIT, "generic_depth_attachment" },
1419 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_ASPECT_STENCIL_BIT, "generic_stencil_attachment" },
1420 { VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, IMAGE_ASPECT_DEPTH_STENCIL, "generic_depth_stencil_attachment" },
1421 };
1422 const std::vector<LayoutData> readableLayoutsData
1423 {
1424 { VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, IMAGE_ASPECT_ALL, "transfer_src" },
1425 { VK_IMAGE_LAYOUT_GENERAL, IMAGE_ASPECT_ALL, "general" },
1426 { VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, IMAGE_ASPECT_ALL, "shader_read" },
1427 { VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_stencil_read" },
1428 { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_read_stencil_attachment" },
1429 { VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, IMAGE_ASPECT_DEPTH_STENCIL, "depth_attachment_stencil_read" },
1430 { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT, "depth_read" },
1431 { VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_STENCIL_BIT, "stencil_read" },
1432 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, IMAGE_ASPECT_ALL, "generic_color_read" },
1433 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_ASPECT_DEPTH_BIT, "generic_depth_read" },
1434 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_ASPECT_STENCIL_BIT, "generic_stencil_read" },
1435 { VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, IMAGE_ASPECT_DEPTH_STENCIL, "generic_depth_stencil_read" },
1436 };
1437
1438 struct SynchronizationData
1439 {
1440 SynchronizationType type;
1441 std::string casePrefix;
1442 bool useGenericAccessFlags;
1443 };
1444 std::vector<SynchronizationData> synchronizationData
1445 {
1446 { SynchronizationType::SYNCHRONIZATION2, "", true },
1447 { SynchronizationType::SYNCHRONIZATION2, "old_access_", false },
1448
1449 // using legacy synchronization structures with NONE_STAGE
1450 { SynchronizationType::LEGACY, "legacy_", false }
1451 };
1452
1453 for (const auto& syncData : synchronizationData)
1454 {
1455 for (const auto& writeData : writableLayoutsData)
1456 {
1457 for (const auto& readData : readableLayoutsData)
1458 {
1459 if (readData.aspect && writeData.aspect &&
1460 (readData.aspect != writeData.aspect))
1461 continue;
1462
1463 const std::string name = syncData.casePrefix + writeData.name + "_to_" + readData.name;
1464 noneStageTests->addChild(new NoneStageTestCase(testCtx, name, {
1465 syncData.type,
1466 syncData.useGenericAccessFlags,
1467 writeData.token,
1468 writeData.aspect,
1469 readData.token,
1470 readData.aspect
1471 }));
1472 }
1473 }
1474 }
1475
1476 return noneStageTests.release();
1477 }
1478
1479 } // synchronization
1480 } // vkt
1481