1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 * Copyright (c) 2019 Valve Corporation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Tests vkCmdClearAttachments with unused attachments.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkObjUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include <sstream>
35 #include <functional>
36 #include <vector>
37 #include <string>
38 #include <memory>
39
40 namespace vkt
41 {
42 namespace renderpass
43 {
44
45 namespace
46 {
47
48 struct Vertex
49 {
50 tcu::Vec4 position;
51 tcu::Vec4 color;
52 };
53
54 template<typename T>
sizeInBytes(const std::vector<T> & vec)55 inline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
56 {
57 return vec.size() * sizeof(vec[0]);
58 }
59
genVertices(void)60 std::vector<Vertex> genVertices (void)
61 {
62 std::vector<Vertex> vectorData;
63 const tcu::Vec4 red = {1.0f, 0.0f, 0.0f, 1.0f};
64 const tcu::Vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
65 const tcu::Vec4 blue = {0.0f, 0.0f, 1.0f, 1.0f};
66 const tcu::Vec4 yellow = {1.0f, 1.0f, 0.0f, 1.0f};
67
68 vectorData.push_back({tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f) , red});
69 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , red});
70 vectorData.push_back({tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f) , red});
71 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , red});
72
73 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , green});
74 vectorData.push_back({tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f) , green});
75 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , green});
76 vectorData.push_back({tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f) , green});
77
78 vectorData.push_back({tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f) , blue});
79 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , blue});
80 vectorData.push_back({tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f) , blue});
81 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , blue});
82
83 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , yellow});
84 vectorData.push_back({tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f) , yellow});
85 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , yellow});
86 vectorData.push_back({tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f) , yellow});
87
88 return vectorData;
89 }
90
91 class MultipleSubpassesMultipleCommandBuffersTestInstance : public TestInstance
92 {
93 public:
94 MultipleSubpassesMultipleCommandBuffersTestInstance (Context& context);
~MultipleSubpassesMultipleCommandBuffersTestInstance(void)95 virtual ~MultipleSubpassesMultipleCommandBuffersTestInstance (void) {}
96 virtual tcu::TestStatus iterate (void);
97 void createCommandBuffer (const DeviceInterface& vk,
98 VkDevice vkDevice);
99 private:
100 static constexpr deUint32 kImageWidth = 32;
101 static constexpr deUint32 kImageHeight = 32;
102 const tcu::UVec2 m_renderSize = { kImageWidth, kImageHeight };
103
104 VkClearValue m_initialColor;
105 VkClearValue m_clearColor;
106
107 Move<VkImage> m_colorImageA;
108 de::MovePtr<Allocation> m_colorImageAllocA;
109 Move<VkImageView> m_colorAttachmentViewA;
110
111 Move<VkImage> m_colorImageB;
112 de::MovePtr<Allocation> m_colorImageAllocB;
113 Move<VkImageView> m_colorAttachmentViewB;
114
115 Move<VkRenderPass> m_renderPass;
116 Move<VkFramebuffer> m_framebufferA;
117 Move<VkFramebuffer> m_framebufferB;
118 Move<VkShaderModule> m_vertexShaderModule;
119 Move<VkShaderModule> m_fragmentShaderModule;
120 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
121 Move<VkPipelineLayout> m_pipelineLayout;
122 Move<VkPipeline> m_graphicsPipeline0;
123 Move<VkPipeline> m_graphicsPipeline1;
124 Move<VkPipeline> m_graphicsPipeline2;
125 Move<VkCommandPool> m_cmdPool;
126 Move<VkCommandBuffer> m_cmdBufferA;
127 Move<VkCommandBuffer> m_cmdBufferB;
128
129 Move<VkBuffer> m_vertexBuffer;
130 de::MovePtr<Allocation> m_vertexBufferAlloc;
131 };
132
133 class MultipleSubpassesMultipleCommandBuffersTest : public vkt::TestCase
134 {
135 public:
MultipleSubpassesMultipleCommandBuffersTest(tcu::TestContext & testContext,const std::string & name)136 MultipleSubpassesMultipleCommandBuffersTest (tcu::TestContext& testContext,
137 const std::string& name)
138 : vkt::TestCase(testContext, name)
139 {}
~MultipleSubpassesMultipleCommandBuffersTest(void)140 virtual ~MultipleSubpassesMultipleCommandBuffersTest (void) {}
141 virtual void initPrograms (SourceCollections& sourceCollections) const;
142 virtual TestInstance* createInstance (Context& context) const;
143 };
144
createInstance(Context & context) const145 TestInstance* MultipleSubpassesMultipleCommandBuffersTest::createInstance (Context& context) const
146 {
147 return new MultipleSubpassesMultipleCommandBuffersTestInstance(context);
148 }
149
initPrograms(SourceCollections & sourceCollections) const150 void MultipleSubpassesMultipleCommandBuffersTest::initPrograms (SourceCollections& sourceCollections) const
151 {
152 // Vertex shader.
153 sourceCollections.glslSources.add("vert_shader") << glu::VertexSource(
154 "#version 450\n"
155 "layout(location = 0) in vec4 position;\n"
156 "layout(location = 1) in vec4 color;\n"
157 "layout(location = 0) out vec4 vtxColor;\n"
158 "void main (void)\n"
159 "{\n"
160 "\tgl_Position = position;\n"
161 "\tvtxColor = color;\n"
162 "}\n");
163
164 // Fragment shader.
165 std::ostringstream fragmentSource;
166
167 fragmentSource << "#version 450\n"
168 << "layout(location = 0) in vec4 vtxColor;\n"
169 << "layout(location = 0) out vec4 fragColor;\n"
170 << "void main (void)\n"
171 << "{\n"
172 << "\tfragColor = vtxColor;\n"
173 << "}\n";
174
175 sourceCollections.glslSources.add("frag_shader") << glu::FragmentSource(fragmentSource.str());
176 }
177
178 // Create a render pass for this use case.
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice)179 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk, VkDevice vkDevice)
180 {
181 // Create attachment descriptions.
182 const VkAttachmentDescription attachmentDescription =
183 {
184 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
185 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
186 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
187 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
188 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
189 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
190 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
191 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout
192 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
193 };
194
195 // Mark attachments as used or not depending on the test parameters.
196 const VkAttachmentReference attachmentReference
197 {
198 0u, // deUint32 attachment
199 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout
200 };
201
202 // Create subpass description with the previous color attachment references.
203 std::vector<vk::VkSubpassDescription> subpassDescriptions;
204 {
205 const vk::VkSubpassDescription subpassDescription =
206 {
207 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
208 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
209 0u, // deUint32 inputAttachmentCount
210 DE_NULL, // const VkAttachmentReference* pInputAttachments
211 1u, // deUint32 colorAttachmentCount
212 &attachmentReference, // const VkAttachmentReference* pColorAttachments
213 DE_NULL, // const VkAttachmentReference* pResolveAttachments
214 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
215 0u, // deUint32 preserveAttachmentCount
216 DE_NULL // const deUint32* pPreserveAttachments
217 };
218 subpassDescriptions.emplace_back(subpassDescription);
219 subpassDescriptions.emplace_back(subpassDescription);
220 subpassDescriptions.emplace_back(subpassDescription);
221 }
222
223 std::vector<vk::VkSubpassDependency> subpassDependencies;
224 {
225 vk::VkSubpassDependency subpassDependency =
226 {
227 0u, // deUint32 srcSubpass
228 1u, // deUint32 dstSubpass
229 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
230 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
231 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
232 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
233 0u // VkDependencyFlags dependencyFlags
234 };
235 subpassDependencies.emplace_back(subpassDependency);
236 subpassDependency.srcSubpass = 1u;
237 subpassDependency.dstSubpass = 2u;
238 subpassDependencies.emplace_back(subpassDependency);
239 }
240
241
242 const vk::VkRenderPassCreateInfo renderPassInfo =
243 {
244 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
245 DE_NULL, // const void* pNext
246 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
247 1u, // deUint32 attachmentCount
248 &attachmentDescription, // const VkAttachmentDescription* pAttachments
249 static_cast<deUint32>(subpassDescriptions.size()), // deUint32 subpassCount
250 subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses
251 static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount
252 subpassDependencies.data(), // const VkSubpassDependency* pDependencies
253 };
254
255 return createRenderPass(vk, vkDevice, &renderPassInfo);
256 }
257
MultipleSubpassesMultipleCommandBuffersTestInstance(Context & context)258 MultipleSubpassesMultipleCommandBuffersTestInstance::MultipleSubpassesMultipleCommandBuffersTestInstance(Context& context)
259 : vkt::TestInstance(context)
260 {
261 // Initial color for all images.
262 m_initialColor.color.float32[0] = 0.0f;
263 m_initialColor.color.float32[1] = 0.0f;
264 m_initialColor.color.float32[2] = 0.0f;
265 m_initialColor.color.float32[3] = 1.0f;
266
267 // Clear color for used attachments.
268 m_clearColor.color.float32[0] = 1.0f;
269 m_clearColor.color.float32[1] = 1.0f;
270 m_clearColor.color.float32[2] = 1.0f;
271 m_clearColor.color.float32[3] = 1.0f;
272
273 const DeviceInterface& vk = m_context.getDeviceInterface();
274 const VkDevice vkDevice = m_context.getDevice();
275 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
276 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
277 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
278
279 // Create color images.
280 {
281 const VkImageCreateInfo colorImageParams =
282 {
283 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
284 DE_NULL, // const void* pNext;
285 0u, // VkImageCreateFlags flags;
286 VK_IMAGE_TYPE_2D, // VkImageType imageType;
287 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
288 { kImageWidth, kImageHeight, 1u }, // VkExtent3D extent;
289 1u, // deUint32 mipLevels;
290 1u, // deUint32 arrayLayers;
291 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
292 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
293 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
294 | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
295 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
296 1u, // deUint32 queueFamilyIndexCount;
297 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
298 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
299 };
300 // Create, allocate and bind image memory.
301 m_colorImageA = createImage(vk, vkDevice, &colorImageParams);
302 m_colorImageAllocA = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImageA), MemoryRequirement::Any);
303 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImageA, m_colorImageAllocA->getMemory(), m_colorImageAllocA->getOffset()));
304
305 m_colorImageB = createImage(vk, vkDevice, &colorImageParams);
306 m_colorImageAllocB = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImageB), MemoryRequirement::Any);
307 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImageB, m_colorImageAllocB->getMemory(), m_colorImageAllocB->getOffset()));
308
309 // Create image view.
310 {
311 const VkImageViewCreateInfo colorAttachmentViewParamsA =
312 {
313 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
314 DE_NULL, // const void* pNext;
315 0u, // VkImageViewCreateFlags flags;
316 *m_colorImageA, // VkImage image;
317 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
318 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
319 componentMapping, // VkChannelMapping channels;
320 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
321 };
322 m_colorAttachmentViewA = createImageView(vk, vkDevice, &colorAttachmentViewParamsA);
323
324 const VkImageViewCreateInfo colorAttachmentViewParamsB =
325 {
326 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
327 DE_NULL, // const void* pNext;
328 0u, // VkImageViewCreateFlags flags;
329 *m_colorImageB, // VkImage image;
330 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
331 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
332 componentMapping, // VkChannelMapping channels;
333 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
334 };
335 m_colorAttachmentViewB = createImageView(vk, vkDevice, &colorAttachmentViewParamsB);
336 }
337
338 // Clear image and leave it prepared to be used as a color attachment.
339 {
340 const VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
341 Move<VkCommandPool> cmdPool;
342 Move<VkCommandBuffer> cmdBuffer;
343 std::vector<VkImageMemoryBarrier> preImageBarriers;
344 std::vector<VkImageMemoryBarrier> postImageBarriers;
345
346 // Create command pool and buffer
347 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
348 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
349
350 // From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
351 const VkImageMemoryBarrier preImageBarrierA =
352 {
353 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
354 DE_NULL, // const void* pNext;
355 0u, // VkAccessFlags srcAccessMask;
356 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
357 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
358 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
359 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
360 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
361 *m_colorImageA, // VkImage image;
362 { // VkImageSubresourceRange subresourceRange;
363 aspectMask, // VkImageAspect aspect;
364 0u, // deUint32 baseMipLevel;
365 1u, // deUint32 mipLevels;
366 0u, // deUint32 baseArraySlice;
367 1u // deUint32 arraySize;
368 }
369 };
370
371 preImageBarriers.emplace_back(preImageBarrierA);
372
373 // From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
374 const VkImageMemoryBarrier postImageBarrierA =
375 {
376 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
377 DE_NULL, // const void* pNext;
378 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
379 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
380 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
381 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
382 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
383 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
384 *m_colorImageA, // VkImage image;
385 { // VkImageSubresourceRange subresourceRange;
386 aspectMask, // VkImageAspect aspect;
387 0u, // deUint32 baseMipLevel;
388 1u, // deUint32 mipLevels;
389 0u, // deUint32 baseArraySlice;
390 1u // deUint32 arraySize;
391 }
392 };
393
394 postImageBarriers.emplace_back(postImageBarrierA);
395
396 // From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
397 const VkImageMemoryBarrier preImageBarrierB =
398 {
399 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
400 DE_NULL, // const void* pNext;
401 0u, // VkAccessFlags srcAccessMask;
402 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
403 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
404 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
405 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
406 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
407 *m_colorImageB, // VkImage image;
408 { // VkImageSubresourceRange subresourceRange;
409 aspectMask, // VkImageAspect aspect;
410 0u, // deUint32 baseMipLevel;
411 1u, // deUint32 mipLevels;
412 0u, // deUint32 baseArraySlice;
413 1u // deUint32 arraySize;
414 }
415 };
416
417 preImageBarriers.emplace_back(preImageBarrierB);
418
419 // From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
420 const VkImageMemoryBarrier postImageBarrierB =
421 {
422 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
423 DE_NULL, // const void* pNext;
424 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
425 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
426 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
427 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
428 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
429 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
430 *m_colorImageB, // VkImage image;
431 { // VkImageSubresourceRange subresourceRange;
432 aspectMask, // VkImageAspect aspect;
433 0u, // deUint32 baseMipLevel;
434 1u, // deUint32 mipLevels;
435 0u, // deUint32 baseArraySlice;
436 1u // deUint32 arraySize;
437 }
438 };
439
440 postImageBarriers.emplace_back(postImageBarrierB);
441
442 const VkImageSubresourceRange clearRange =
443 {
444 aspectMask, // VkImageAspectFlags aspectMask;
445 0u, // deUint32 baseMipLevel;
446 1u, // deUint32 levelCount;
447 0u, // deUint32 baseArrayLayer;
448 1u // deUint32 layerCount;
449 };
450
451 // Clear image and transfer layout.
452 beginCommandBuffer(vk, *cmdBuffer);
453 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, static_cast<deUint32>(preImageBarriers.size()), preImageBarriers.data());
454 vk.cmdClearColorImage(*cmdBuffer, *m_colorImageA, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
455 vk.cmdClearColorImage(*cmdBuffer, *m_colorImageB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
456 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, static_cast<deUint32>(postImageBarriers.size()), postImageBarriers.data());
457 endCommandBuffer(vk, *cmdBuffer);
458
459 submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
460 }
461 }
462
463 // Create render pass.
464 m_renderPass = createRenderPass(vk, vkDevice);
465
466 // Create framebuffer
467 {
468 const VkImageView attachmentBindInfosA[1] =
469 {
470 *m_colorAttachmentViewA,
471 };
472 const VkFramebufferCreateInfo framebufferParamsA =
473 {
474 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
475 DE_NULL, // const void* pNext;
476 0u, // VkFramebufferCreateFlags flags;
477 *m_renderPass, // VkRenderPass renderPass;
478 1u, // deUint32 attachmentCount;
479 attachmentBindInfosA, // const VkImageView* pAttachments;
480 kImageWidth, // deUint32 width;
481 kImageHeight, // deUint32 height;
482 1u // deUint32 layers;
483 };
484
485 m_framebufferA = createFramebuffer(vk, vkDevice, &framebufferParamsA);
486
487 const VkImageView attachmentBindInfosB[1] =
488 {
489 *m_colorAttachmentViewB,
490 };
491 const VkFramebufferCreateInfo framebufferParamsB =
492 {
493 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
494 DE_NULL, // const void* pNext;
495 0u, // VkFramebufferCreateFlags flags;
496 *m_renderPass, // VkRenderPass renderPass;
497 1u, // deUint32 attachmentCount;
498 attachmentBindInfosB, // const VkImageView* pAttachments;
499 kImageWidth, // deUint32 width;
500 kImageHeight, // deUint32 height;
501 1u // deUint32 layers;
502 };
503
504 m_framebufferB = createFramebuffer(vk, vkDevice, &framebufferParamsB);
505 }
506
507 // Create pipeline layout.
508 {
509 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams =
510 {
511 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
512 DE_NULL, // const void* pNext
513 0u, // VkDescriptorSetLayoutCreateFlags flags
514 0u, // deUint32 bindingCount
515 DE_NULL // const VkDescriptorSetLayoutBinding* pBindings
516 };
517 m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
518
519 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
520 {
521 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
522 DE_NULL, // const void* pNext;
523 0u, // VkPipelineLayoutCreateFlags flags;
524 1u, // deUint32 setLayoutCount;
525 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
526 0u, // deUint32 pushConstantRangeCount;
527 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
528 };
529
530 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
531 }
532
533 // Create Vertex buffer
534 {
535 const std::vector<Vertex> vertexValues = genVertices();
536 const VkDeviceSize vertexBufferSize = sizeInBytes(vertexValues);
537
538 const vk::VkBufferCreateInfo bufferCreateInfo =
539 {
540 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
541 DE_NULL, // const void* pNext
542 0u, // VkBufferCreateFlags flags
543 vertexBufferSize, // VkDeviceSize size
544 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
545 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
546 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
547 1u, // deUint32 queueFamilyIndexCount
548 &queueFamilyIndex // const deUint32* pQueueFamilyIndices
549 };
550
551 m_vertexBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
552 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
553 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
554 // Load vertices into vertex buffer
555 deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertexValues.data(), static_cast<size_t>(vertexBufferSize));
556 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
557 }
558
559 // Vertex buffer description
560 const vk::VkVertexInputBindingDescription bindingDescription =
561 {
562 0u, // deUint32 binding
563 sizeof(Vertex), // deUint32 stride
564 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate
565 };
566
567 std::vector<vk::VkVertexInputAttributeDescription> attributeDescriptions;
568 {
569 vk::VkVertexInputAttributeDescription attributeDescriptionVertex =
570 {
571 0u, // deUint32 location
572 0u, // deUint32 binding
573 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
574 offsetof(Vertex, position) // deUint32 offset
575 };
576
577 vk::VkVertexInputAttributeDescription attributeDescriptionColor =
578 {
579 1u, // deUint32 location
580 0u, // deUint32 binding
581 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
582 offsetof(Vertex, color) // deUint32 offset
583 };
584 attributeDescriptions.emplace_back(attributeDescriptionVertex);
585 attributeDescriptions.emplace_back(attributeDescriptionColor);
586 }
587
588 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
589 {
590 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
591 DE_NULL, // const void* pNext
592 0u, // VkPipelineVertexInputStateCreateFlags flags
593 1u, // deUint32 vertexBindingDescriptionCount
594 &bindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
595 static_cast<deUint32>(attributeDescriptions.size()), // deUint32 vertexAttributeDescriptionCount
596 attributeDescriptions.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
597 };
598
599 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert_shader"), 0);
600 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag_shader"), 0);
601
602 // Create pipeline.
603 {
604 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
605 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
606
607 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
608 {
609 VK_FALSE, // VkBool32 blendEnable
610 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor
611 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor
612 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
613 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
614 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
615 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
616 VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask
617 | VK_COLOR_COMPONENT_G_BIT
618 | VK_COLOR_COMPONENT_B_BIT
619 | VK_COLOR_COMPONENT_A_BIT
620 };
621
622 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo =
623 {
624 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
625 DE_NULL, // const void* pNext
626 0u, // VkPipelineColorBlendStateCreateFlags flags
627 VK_FALSE, // VkBool32 logicOpEnable
628 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
629 1u, // deUint32 attachmentCount
630 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
631 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]
632 };
633
634 m_graphicsPipeline0 = makeGraphicsPipeline(vk, // const DeviceInterface& vk
635 vkDevice, // const VkDevice device
636 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
637 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
638 DE_NULL, // const VkShaderModule tessellationControlModule
639 DE_NULL, // const VkShaderModule tessellationEvalModule
640 DE_NULL, // const VkShaderModule geometryShaderModule
641 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
642 *m_renderPass, // const VkRenderPass renderPass
643 viewports, // const std::vector<VkViewport>& viewports
644 scissors, // const std::vector<VkRect2D>& scissors
645 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
646 0u, // const deUint32 subpass
647 0u, // const deUint32 patchControlPoints
648 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
649 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
650 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
651 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
652 &colorBlendStateCreateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
653
654 m_graphicsPipeline1 = makeGraphicsPipeline(vk, // const DeviceInterface& vk
655 vkDevice, // const VkDevice device
656 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
657 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
658 DE_NULL, // const VkShaderModule tessellationControlModule
659 DE_NULL, // const VkShaderModule tessellationEvalModule
660 DE_NULL, // const VkShaderModule geometryShaderModule
661 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
662 *m_renderPass, // const VkRenderPass renderPass
663 viewports, // const std::vector<VkViewport>& viewports
664 scissors, // const std::vector<VkRect2D>& scissors
665 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
666 1u, // const deUint32 subpass
667 0u, // const deUint32 patchControlPoints
668 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
669 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
670 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
671 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
672 &colorBlendStateCreateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
673
674 m_graphicsPipeline2 = makeGraphicsPipeline(vk, // const DeviceInterface& vk
675 vkDevice, // const VkDevice device
676 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
677 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
678 DE_NULL, // const VkShaderModule tessellationControlModule
679 DE_NULL, // const VkShaderModule tessellationEvalModule
680 DE_NULL, // const VkShaderModule geometryShaderModule
681 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
682 *m_renderPass, // const VkRenderPass renderPass
683 viewports, // const std::vector<VkViewport>& viewports
684 scissors, // const std::vector<VkRect2D>& scissors
685 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
686 2u, // const deUint32 subpass
687 0u, // const deUint32 patchControlPoints
688 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
689 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
690 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
691 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
692 &colorBlendStateCreateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
693
694 }
695
696 // Create command pool
697 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
698
699 // Create command buffer
700 createCommandBuffer(vk, vkDevice);
701 }
702
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice)703 void MultipleSubpassesMultipleCommandBuffersTestInstance::createCommandBuffer (const DeviceInterface& vk,
704 VkDevice vkDevice)
705 {
706 const VkRenderPassBeginInfo renderPassBeginInfoA =
707 {
708 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
709 DE_NULL, // const void* pNext;
710 *m_renderPass, // VkRenderPass renderPass;
711 *m_framebufferA, // VkFramebuffer framebuffer;
712 makeRect2D(m_renderSize), // VkRect2D renderArea;
713 0u, // uint32_t clearValueCount;
714 DE_NULL // const VkClearValue* pClearValues;
715 };
716 const VkRenderPassBeginInfo renderPassBeginInfoB =
717 {
718 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
719 DE_NULL, // const void* pNext;
720 *m_renderPass, // VkRenderPass renderPass;
721 *m_framebufferB, // VkFramebuffer framebuffer;
722 makeRect2D(m_renderSize), // VkRect2D renderArea;
723 0u, // uint32_t clearValueCount;
724 DE_NULL // const VkClearValue* pClearValues;
725 };
726
727 m_cmdBufferA = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
728 m_cmdBufferB = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
729
730 const VkClearRect clearRect =
731 {
732 { // VkRect2D rect;
733 { 0, 0, }, // VkOffset2D offset;
734 { kImageWidth, kImageHeight } // VkExtent2D extent;
735 },
736 0u, // uint32_t baseArrayLayer;
737 1u // uint32_t layerCount;
738 };
739
740 const VkClearAttachment clearAttachment =
741 {
742 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
743 0u, // uint32_t colorAttachment;
744 m_clearColor // VkClearValue clearValue;
745 };
746
747 VkDeviceSize vertexBufferOffset = 0u;
748
749 // Command Buffer A will set its own event but wait for the B's event before continuing to the next subpass.
750 beginCommandBuffer(vk, *m_cmdBufferA, 0u);
751 beginCommandBuffer(vk, *m_cmdBufferB, 0u);
752 vk.cmdBeginRenderPass(*m_cmdBufferA, &renderPassBeginInfoA, VK_SUBPASS_CONTENTS_INLINE);
753 vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline0);
754 vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
755 vk.cmdClearAttachments(*m_cmdBufferA, 1u, &clearAttachment, 1u, &clearRect);
756
757 vk.cmdBeginRenderPass(*m_cmdBufferB, &renderPassBeginInfoB, VK_SUBPASS_CONTENTS_INLINE);
758 vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline0);
759 vk.cmdClearAttachments(*m_cmdBufferB, 1u, &clearAttachment, 1u, &clearRect);
760 vk.cmdNextSubpass(*m_cmdBufferB, VK_SUBPASS_CONTENTS_INLINE);
761
762 vk.cmdNextSubpass(*m_cmdBufferA, VK_SUBPASS_CONTENTS_INLINE);
763 vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline1);
764 vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
765 vk.cmdDraw(*m_cmdBufferA, 4u, 1u, 0u, 0u);
766
767 vertexBufferOffset = 8 * sizeof(Vertex);
768 vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline1);
769 vk.cmdBindVertexBuffers(*m_cmdBufferB, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
770 vk.cmdDraw(*m_cmdBufferB, 4u, 1u, 0u, 0u);
771 vk.cmdNextSubpass(*m_cmdBufferB, VK_SUBPASS_CONTENTS_INLINE);
772
773 vertexBufferOffset = 0u;
774 vk.cmdNextSubpass(*m_cmdBufferA, VK_SUBPASS_CONTENTS_INLINE);
775 vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline2);
776 vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
777 vk.cmdDraw(*m_cmdBufferA, 4u, 1u, 4u, 0u);
778
779 vertexBufferOffset = 8 * sizeof(Vertex);
780 vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline2);
781 vk.cmdDraw(*m_cmdBufferB, 4u, 1u, 4u, 0u);
782 vk.cmdEndRenderPass(*m_cmdBufferB);
783 vk.cmdEndRenderPass(*m_cmdBufferA);
784 endCommandBuffer(vk, *m_cmdBufferA);
785 endCommandBuffer(vk, *m_cmdBufferB);
786 }
787
iterate(void)788 tcu::TestStatus MultipleSubpassesMultipleCommandBuffersTestInstance::iterate (void)
789 {
790 const DeviceInterface& vk = m_context.getDeviceInterface();
791 const VkDevice vkDevice = m_context.getDevice();
792 const VkQueue queue = m_context.getUniversalQueue();
793 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
794 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
795
796 {
797 const Unique<VkFence> fence (createFence(vk, vkDevice));
798 std::vector<VkCommandBuffer> commandBuffers;
799 commandBuffers.emplace_back(m_cmdBufferA.get());
800 commandBuffers.emplace_back(m_cmdBufferB.get());
801
802 const VkSubmitInfo submitInfo =
803 {
804 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
805 DE_NULL, // const void* pNext;
806 0u, // deUint32 waitSemaphoreCount;
807 DE_NULL, // const VkSemaphore* pWaitSemaphores;
808 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
809 static_cast<deUint32>(commandBuffers.size()), // deUint32 commandBufferCount;
810 commandBuffers.data(), // const VkCommandBuffer* pCommandBuffers;
811 0u, // deUint32 signalSemaphoreCount;
812 DE_NULL, // const VkSemaphore* pSignalSemaphores;
813 };
814
815 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
816 VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), DE_TRUE, ~0ull));
817 }
818
819 {
820 // Colors to compare to.
821 const tcu::Vec4 red = {1.0f, 0.0f, 0.0f, 1.0f};
822 const tcu::Vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
823 const tcu::Vec4 blue = {0.0f, 0.0f, 1.0f, 1.0f};
824 const tcu::Vec4 yellow = {1.0f, 1.0f, 0.0f, 1.0f};
825
826 // Read result images.
827 de::MovePtr<tcu::TextureLevel> imagePixelsA = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImageA, VK_FORMAT_R32G32B32A32_SFLOAT, m_renderSize);
828 de::MovePtr<tcu::TextureLevel> imagePixelsB = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImageB, VK_FORMAT_R32G32B32A32_SFLOAT, m_renderSize);
829
830 // Verify pixel colors match.
831 const tcu::ConstPixelBufferAccess& imageAccessA = imagePixelsA->getAccess();
832 const tcu::ConstPixelBufferAccess& imageAccessB = imagePixelsB->getAccess();
833
834
835 tcu::TextureLevel referenceImageA(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_renderSize.x(), m_renderSize.y());
836 tcu::TextureLevel referenceImageB(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_renderSize.x(), m_renderSize.y());
837
838 tcu::clear(tcu::getSubregion(referenceImageA.getAccess(), 0u, 0u,
839 imageAccessA.getWidth() / 2, imageAccessA.getHeight()),
840 red);
841 tcu::clear(tcu::getSubregion(referenceImageA.getAccess(), imageAccessA.getWidth() / 2, 0u,
842 imageAccessA.getWidth() / 2, imageAccessA.getHeight()),
843 green);
844
845 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImageA.getAccess(), imageAccessA, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
846 TCU_FAIL("[A] Rendered image is not correct");
847
848 tcu::clear(tcu::getSubregion(referenceImageB.getAccess(), 0u, 0u,
849 imageAccessB.getWidth() / 2, imageAccessB.getHeight()),
850 blue);
851 tcu::clear(tcu::getSubregion(referenceImageB.getAccess(), imageAccessB.getWidth() / 2, 0u,
852 imageAccessA.getWidth() / 2, imageAccessB.getHeight()),
853 yellow);
854
855 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImageB.getAccess(), imageAccessB, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
856 TCU_FAIL("[B] Rendered image is not correct");
857
858 }
859
860 return tcu::TestStatus::pass("Pass");
861 }
862 } // anonymous
863
createRenderPassMultipleSubpassesMultipleCommandBuffersTests(tcu::TestContext & testCtx)864 tcu::TestCaseGroup* createRenderPassMultipleSubpassesMultipleCommandBuffersTests (tcu::TestContext& testCtx)
865 {
866 de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "multiple_subpasses_multiple_command_buffers"));
867
868 testGroup->addChild(new MultipleSubpassesMultipleCommandBuffersTest(testCtx, "test"));
869
870 return testGroup.release();
871 }
872
873 } // renderpass
874 } // vkt
875