1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief RenderPass tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassTests.hpp"
25
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
28
29 #include "vkDefs.hpp"
30 #include "vkDeviceUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkStrUtil.hpp"
39 #include "vkTypeUtil.hpp"
40
41 #include "tcuFloat.hpp"
42 #include "tcuFormatUtil.hpp"
43 #include "tcuMaybe.hpp"
44 #include "tcuResultCollector.hpp"
45 #include "tcuTestLog.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuVectorUtil.hpp"
48
49 #include "deRandom.hpp"
50 #include "deSTLUtil.hpp"
51 #include "deSharedPtr.hpp"
52 #include "deStringUtil.hpp"
53 #include "deUniquePtr.hpp"
54
55 #include <limits>
56 #include <set>
57 #include <string>
58 #include <vector>
59
60 using namespace vk;
61
62 using tcu::BVec4;
63 using tcu::IVec2;
64 using tcu::IVec4;
65 using tcu::UVec2;
66 using tcu::UVec4;
67 using tcu::Vec2;
68 using tcu::Vec4;
69
70 using tcu::Maybe;
71 using tcu::just;
72 using tcu::nothing;
73
74 using tcu::ConstPixelBufferAccess;
75 using tcu::PixelBufferAccess;
76
77 using tcu::TestLog;
78
79 using de::UniquePtr;
80
81 using std::pair;
82 using std::set;
83 using std::string;
84 using std::vector;
85
86 namespace vkt
87 {
88 namespace
89 {
90 enum BoolOp
91 {
92 BOOLOP_AND,
93 BOOLOP_OR,
94 BOOLOP_EQ,
95 BOOLOP_NEQ
96 };
97
boolOpToString(BoolOp op)98 const char* boolOpToString (BoolOp op)
99 {
100 switch (op)
101 {
102 case BOOLOP_OR:
103 return "||";
104
105 case BOOLOP_AND:
106 return "&&";
107
108 case BOOLOP_EQ:
109 return "==";
110
111 case BOOLOP_NEQ:
112 return "!=";
113
114 default:
115 DE_FATAL("Unknown boolean operation.");
116 return DE_NULL;
117 }
118 }
119
performBoolOp(BoolOp op,bool a,bool b)120 bool performBoolOp (BoolOp op, bool a, bool b)
121 {
122 switch (op)
123 {
124 case BOOLOP_OR:
125 return a || b;
126
127 case BOOLOP_AND:
128 return a && b;
129
130 case BOOLOP_EQ:
131 return a == b;
132
133 case BOOLOP_NEQ:
134 return a != b;
135
136 default:
137 DE_FATAL("Unknown boolean operation.");
138 return false;
139 }
140 }
141
boolOpFromIndex(size_t index)142 BoolOp boolOpFromIndex (size_t index)
143 {
144 const BoolOp ops[] =
145 {
146 BOOLOP_OR,
147 BOOLOP_AND,
148 BOOLOP_EQ,
149 BOOLOP_NEQ
150 };
151
152 return ops[index % DE_LENGTH_OF_ARRAY(ops)];
153 }
154
155 // Utility functions using flattened structs
createFence(const DeviceInterface & vk,VkDevice device,VkFenceCreateFlags flags)156 Move<VkFence> createFence (const DeviceInterface& vk, VkDevice device, VkFenceCreateFlags flags)
157 {
158 const VkFenceCreateInfo pCreateInfo =
159 {
160 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
161 DE_NULL,
162
163 flags
164 };
165 return createFence(vk, device, &pCreateInfo);
166 }
167
createFramebuffer(const DeviceInterface & vk,VkDevice device,VkFramebufferCreateFlags pCreateInfo_flags,VkRenderPass pCreateInfo_renderPass,deUint32 pCreateInfo_attachmentCount,const VkImageView * pCreateInfo_pAttachments,deUint32 pCreateInfo_width,deUint32 pCreateInfo_height,deUint32 pCreateInfo_layers)168 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
169 VkDevice device,
170 VkFramebufferCreateFlags pCreateInfo_flags,
171 VkRenderPass pCreateInfo_renderPass,
172 deUint32 pCreateInfo_attachmentCount,
173 const VkImageView* pCreateInfo_pAttachments,
174 deUint32 pCreateInfo_width,
175 deUint32 pCreateInfo_height,
176 deUint32 pCreateInfo_layers)
177 {
178 const VkFramebufferCreateInfo pCreateInfo =
179 {
180 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
181 DE_NULL,
182 pCreateInfo_flags,
183 pCreateInfo_renderPass,
184 pCreateInfo_attachmentCount,
185 pCreateInfo_pAttachments,
186 pCreateInfo_width,
187 pCreateInfo_height,
188 pCreateInfo_layers,
189 };
190 return createFramebuffer(vk, device, &pCreateInfo);
191 }
192
createImage(const DeviceInterface & vk,VkDevice device,VkImageCreateFlags pCreateInfo_flags,VkImageType pCreateInfo_imageType,VkFormat pCreateInfo_format,VkExtent3D pCreateInfo_extent,deUint32 pCreateInfo_mipLevels,deUint32 pCreateInfo_arrayLayers,VkSampleCountFlagBits pCreateInfo_samples,VkImageTiling pCreateInfo_tiling,VkImageUsageFlags pCreateInfo_usage,VkSharingMode pCreateInfo_sharingMode,deUint32 pCreateInfo_queueFamilyCount,const deUint32 * pCreateInfo_pQueueFamilyIndices,VkImageLayout pCreateInfo_initialLayout)193 Move<VkImage> createImage (const DeviceInterface& vk,
194 VkDevice device,
195 VkImageCreateFlags pCreateInfo_flags,
196 VkImageType pCreateInfo_imageType,
197 VkFormat pCreateInfo_format,
198 VkExtent3D pCreateInfo_extent,
199 deUint32 pCreateInfo_mipLevels,
200 deUint32 pCreateInfo_arrayLayers,
201 VkSampleCountFlagBits pCreateInfo_samples,
202 VkImageTiling pCreateInfo_tiling,
203 VkImageUsageFlags pCreateInfo_usage,
204 VkSharingMode pCreateInfo_sharingMode,
205 deUint32 pCreateInfo_queueFamilyCount,
206 const deUint32* pCreateInfo_pQueueFamilyIndices,
207 VkImageLayout pCreateInfo_initialLayout)
208 {
209 const VkImageCreateInfo pCreateInfo =
210 {
211 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
212 DE_NULL,
213 pCreateInfo_flags,
214 pCreateInfo_imageType,
215 pCreateInfo_format,
216 pCreateInfo_extent,
217 pCreateInfo_mipLevels,
218 pCreateInfo_arrayLayers,
219 pCreateInfo_samples,
220 pCreateInfo_tiling,
221 pCreateInfo_usage,
222 pCreateInfo_sharingMode,
223 pCreateInfo_queueFamilyCount,
224 pCreateInfo_pQueueFamilyIndices,
225 pCreateInfo_initialLayout
226 };
227 return createImage(vk, device, &pCreateInfo);
228 }
229
bindBufferMemory(const DeviceInterface & vk,VkDevice device,VkBuffer buffer,VkDeviceMemory mem,VkDeviceSize memOffset)230 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
231 {
232 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
233 }
234
bindImageMemory(const DeviceInterface & vk,VkDevice device,VkImage image,VkDeviceMemory mem,VkDeviceSize memOffset)235 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
236 {
237 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
238 }
239
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags pCreateInfo_flags,VkImage pCreateInfo_image,VkImageViewType pCreateInfo_viewType,VkFormat pCreateInfo_format,VkComponentMapping pCreateInfo_components,VkImageSubresourceRange pCreateInfo_subresourceRange)240 Move<VkImageView> createImageView (const DeviceInterface& vk,
241 VkDevice device,
242 VkImageViewCreateFlags pCreateInfo_flags,
243 VkImage pCreateInfo_image,
244 VkImageViewType pCreateInfo_viewType,
245 VkFormat pCreateInfo_format,
246 VkComponentMapping pCreateInfo_components,
247 VkImageSubresourceRange pCreateInfo_subresourceRange)
248 {
249 const VkImageViewCreateInfo pCreateInfo =
250 {
251 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
252 DE_NULL,
253 pCreateInfo_flags,
254 pCreateInfo_image,
255 pCreateInfo_viewType,
256 pCreateInfo_format,
257 pCreateInfo_components,
258 pCreateInfo_subresourceRange,
259 };
260 return createImageView(vk, device, &pCreateInfo);
261 }
262
createBuffer(const DeviceInterface & vk,VkDevice device,VkBufferCreateFlags pCreateInfo_flags,VkDeviceSize pCreateInfo_size,VkBufferUsageFlags pCreateInfo_usage,VkSharingMode pCreateInfo_sharingMode,deUint32 pCreateInfo_queueFamilyCount,const deUint32 * pCreateInfo_pQueueFamilyIndices)263 Move<VkBuffer> createBuffer (const DeviceInterface& vk,
264 VkDevice device,
265 VkBufferCreateFlags pCreateInfo_flags,
266 VkDeviceSize pCreateInfo_size,
267 VkBufferUsageFlags pCreateInfo_usage,
268 VkSharingMode pCreateInfo_sharingMode,
269 deUint32 pCreateInfo_queueFamilyCount,
270 const deUint32* pCreateInfo_pQueueFamilyIndices)
271 {
272 const VkBufferCreateInfo pCreateInfo =
273 {
274 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
275 DE_NULL,
276 pCreateInfo_flags,
277 pCreateInfo_size,
278 pCreateInfo_usage,
279 pCreateInfo_sharingMode,
280 pCreateInfo_queueFamilyCount,
281 pCreateInfo_pQueueFamilyIndices,
282 };
283 return createBuffer(vk, device, &pCreateInfo);
284 }
285
createCommandPool(const DeviceInterface & vk,VkDevice device,VkCommandPoolCreateFlags pCreateInfo_flags,deUint32 pCreateInfo_queueFamilyIndex)286 Move<VkCommandPool> createCommandPool (const DeviceInterface& vk,
287 VkDevice device,
288 VkCommandPoolCreateFlags pCreateInfo_flags,
289 deUint32 pCreateInfo_queueFamilyIndex)
290 {
291 const VkCommandPoolCreateInfo pCreateInfo =
292 {
293 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
294 DE_NULL,
295 pCreateInfo_flags,
296 pCreateInfo_queueFamilyIndex,
297 };
298 return createCommandPool(vk, device, &pCreateInfo);
299 }
300
cmdBeginRenderPass(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkRenderPass pRenderPassBegin_renderPass,VkFramebuffer pRenderPassBegin_framebuffer,VkRect2D pRenderPassBegin_renderArea,deUint32 pRenderPassBegin_clearValueCount,const VkClearValue * pRenderPassBegin_pAttachmentClearValues,VkSubpassContents contents)301 void cmdBeginRenderPass (const DeviceInterface& vk,
302 VkCommandBuffer cmdBuffer,
303 VkRenderPass pRenderPassBegin_renderPass,
304 VkFramebuffer pRenderPassBegin_framebuffer,
305 VkRect2D pRenderPassBegin_renderArea,
306 deUint32 pRenderPassBegin_clearValueCount,
307 const VkClearValue* pRenderPassBegin_pAttachmentClearValues,
308 VkSubpassContents contents)
309 {
310 const VkRenderPassBeginInfo pRenderPassBegin =
311 {
312 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
313 DE_NULL,
314 pRenderPassBegin_renderPass,
315 pRenderPassBegin_framebuffer,
316 pRenderPassBegin_renderArea,
317 pRenderPassBegin_clearValueCount,
318 pRenderPassBegin_pAttachmentClearValues,
319 };
320 vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
321 }
322
allocateCommandBuffer(const DeviceInterface & vk,VkDevice device,VkCommandPool pCreateInfo_commandPool,VkCommandBufferLevel pCreateInfo_level)323 Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface& vk,
324 VkDevice device,
325 VkCommandPool pCreateInfo_commandPool,
326 VkCommandBufferLevel pCreateInfo_level)
327 {
328 const VkCommandBufferAllocateInfo pAllocateInfo =
329 {
330 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
331 DE_NULL,
332 pCreateInfo_commandPool,
333 pCreateInfo_level,
334 1u, // bufferCount
335 };
336 return allocateCommandBuffer(vk, device, &pAllocateInfo);
337 }
338
beginCommandBuffer(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkCommandBufferUsageFlags pBeginInfo_flags,VkRenderPass pInheritanceInfo_renderPass,deUint32 pInheritanceInfo_subpass,VkFramebuffer pInheritanceInfo_framebuffer,VkBool32 pInheritanceInfo_occlusionQueryEnable,VkQueryControlFlags pInheritanceInfo_queryFlags,VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)339 void beginCommandBuffer (const DeviceInterface& vk,
340 VkCommandBuffer cmdBuffer,
341 VkCommandBufferUsageFlags pBeginInfo_flags,
342 VkRenderPass pInheritanceInfo_renderPass,
343 deUint32 pInheritanceInfo_subpass,
344 VkFramebuffer pInheritanceInfo_framebuffer,
345 VkBool32 pInheritanceInfo_occlusionQueryEnable,
346 VkQueryControlFlags pInheritanceInfo_queryFlags,
347 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)
348 {
349 const VkCommandBufferInheritanceInfo pInheritanceInfo =
350 {
351 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
352 DE_NULL,
353 pInheritanceInfo_renderPass,
354 pInheritanceInfo_subpass,
355 pInheritanceInfo_framebuffer,
356 pInheritanceInfo_occlusionQueryEnable,
357 pInheritanceInfo_queryFlags,
358 pInheritanceInfo_pipelineStatistics,
359 };
360 const VkCommandBufferBeginInfo pBeginInfo =
361 {
362 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
363 DE_NULL,
364 pBeginInfo_flags,
365 &pInheritanceInfo,
366 };
367 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
368 }
369
endCommandBuffer(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)370 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
371 {
372 VK_CHECK(vk.endCommandBuffer(cmdBuffer));
373 }
374
queueSubmit(const DeviceInterface & vk,VkQueue queue,deUint32 cmdBufferCount,const VkCommandBuffer * pCmdBuffers,VkFence fence)375 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
376 {
377 const VkSubmitInfo submitInfo =
378 {
379 VK_STRUCTURE_TYPE_SUBMIT_INFO,
380 DE_NULL,
381 0u, // waitSemaphoreCount
382 (const VkSemaphore*)DE_NULL, // pWaitSemaphores
383 (const VkPipelineStageFlags*)DE_NULL,
384 cmdBufferCount, // commandBufferCount
385 pCmdBuffers,
386 0u, // signalSemaphoreCount
387 (const VkSemaphore*)DE_NULL, // pSignalSemaphores
388 };
389 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
390 }
391
waitForFences(const DeviceInterface & vk,VkDevice device,deUint32 fenceCount,const VkFence * pFences,VkBool32 waitAll,deUint64 timeout)392 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
393 {
394 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
395 }
396
getImageAspectFlags(VkFormat vkFormat)397 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
398 {
399 const tcu::TextureFormat format = mapVkFormat(vkFormat);
400
401 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
402
403 switch (format.order)
404 {
405 case tcu::TextureFormat::DS:
406 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
407
408 case tcu::TextureFormat::D:
409 return VK_IMAGE_ASPECT_DEPTH_BIT;
410
411 case tcu::TextureFormat::S:
412 return VK_IMAGE_ASPECT_STENCIL_BIT;
413
414 default:
415 return VK_IMAGE_ASPECT_COLOR_BIT;
416 }
417 }
418
getAllMemoryReadFlags(void)419 VkAccessFlags getAllMemoryReadFlags (void)
420 {
421 return VK_ACCESS_TRANSFER_READ_BIT
422 | VK_ACCESS_UNIFORM_READ_BIT
423 | VK_ACCESS_HOST_READ_BIT
424 | VK_ACCESS_INDEX_READ_BIT
425 | VK_ACCESS_SHADER_READ_BIT
426 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
427 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
428 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
429 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
430 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
431 }
432
getAllMemoryWriteFlags(void)433 VkAccessFlags getAllMemoryWriteFlags (void)
434 {
435 return VK_ACCESS_TRANSFER_WRITE_BIT
436 | VK_ACCESS_HOST_WRITE_BIT
437 | VK_ACCESS_SHADER_WRITE_BIT
438 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
439 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
440 }
441
getMemoryFlagsForLayout(const VkImageLayout layout)442 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
443 {
444 switch (layout)
445 {
446 case VK_IMAGE_LAYOUT_GENERAL: return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
447 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
448 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
449 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
450 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_ACCESS_SHADER_READ_BIT;
451 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_ACCESS_TRANSFER_READ_BIT;
452 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_ACCESS_TRANSFER_WRITE_BIT;
453
454 default:
455 return (VkAccessFlags)0;
456 }
457 }
458
getAllPipelineStageFlags(void)459 VkPipelineStageFlags getAllPipelineStageFlags (void)
460 {
461 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
462 | VK_PIPELINE_STAGE_TRANSFER_BIT
463 | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
464 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
465 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
466 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
467 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
468 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
469 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
470 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
471 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
472 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
473 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
474 }
475
476 class AttachmentReference
477 {
478 public:
AttachmentReference(deUint32 attachment,VkImageLayout layout)479 AttachmentReference (deUint32 attachment,
480 VkImageLayout layout)
481 : m_attachment (attachment)
482 , m_layout (layout)
483 {
484 }
485
getAttachment(void) const486 deUint32 getAttachment (void) const { return m_attachment; }
getImageLayout(void) const487 VkImageLayout getImageLayout (void) const { return m_layout; }
488
489 private:
490 deUint32 m_attachment;
491 VkImageLayout m_layout;
492 };
493
494 class Subpass
495 {
496 public:
Subpass(VkPipelineBindPoint pipelineBindPoint,VkSubpassDescriptionFlags flags,const vector<AttachmentReference> & inputAttachments,const vector<AttachmentReference> & colorAttachments,const vector<AttachmentReference> & resolveAttachments,AttachmentReference depthStencilAttachment,const vector<deUint32> & preserveAttachments)497 Subpass (VkPipelineBindPoint pipelineBindPoint,
498 VkSubpassDescriptionFlags flags,
499 const vector<AttachmentReference>& inputAttachments,
500 const vector<AttachmentReference>& colorAttachments,
501 const vector<AttachmentReference>& resolveAttachments,
502 AttachmentReference depthStencilAttachment,
503 const vector<deUint32>& preserveAttachments)
504 : m_pipelineBindPoint (pipelineBindPoint)
505 , m_flags (flags)
506 , m_inputAttachments (inputAttachments)
507 , m_colorAttachments (colorAttachments)
508 , m_resolveAttachments (resolveAttachments)
509 , m_depthStencilAttachment (depthStencilAttachment)
510 , m_preserveAttachments (preserveAttachments)
511 {
512 }
513
getPipelineBindPoint(void) const514 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; }
getFlags(void) const515 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; }
getInputAttachments(void) const516 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; }
getColorAttachments(void) const517 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; }
getResolveAttachments(void) const518 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; }
getDepthStencilAttachment(void) const519 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; }
getPreserveAttachments(void) const520 const vector<deUint32>& getPreserveAttachments (void) const { return m_preserveAttachments; }
521
522 private:
523 VkPipelineBindPoint m_pipelineBindPoint;
524 VkSubpassDescriptionFlags m_flags;
525
526 vector<AttachmentReference> m_inputAttachments;
527 vector<AttachmentReference> m_colorAttachments;
528 vector<AttachmentReference> m_resolveAttachments;
529 AttachmentReference m_depthStencilAttachment;
530
531 vector<deUint32> m_preserveAttachments;
532 };
533
534 class SubpassDependency
535 {
536 public:
SubpassDependency(deUint32 srcPass,deUint32 dstPass,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags outputMask,VkAccessFlags inputMask,VkDependencyFlags flags)537 SubpassDependency (deUint32 srcPass,
538 deUint32 dstPass,
539
540 VkPipelineStageFlags srcStageMask,
541 VkPipelineStageFlags dstStageMask,
542
543 VkAccessFlags outputMask,
544 VkAccessFlags inputMask,
545
546 VkDependencyFlags flags)
547 : m_srcPass (srcPass)
548 , m_dstPass (dstPass)
549
550 , m_srcStageMask (srcStageMask)
551 , m_dstStageMask (dstStageMask)
552
553 , m_outputMask (outputMask)
554 , m_inputMask (inputMask)
555 , m_flags (flags)
556 {
557 }
558
getSrcPass(void) const559 deUint32 getSrcPass (void) const { return m_srcPass; }
getDstPass(void) const560 deUint32 getDstPass (void) const { return m_dstPass; }
561
getSrcStageMask(void) const562 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; }
getDstStageMask(void) const563 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; }
564
getOutputMask(void) const565 VkAccessFlags getOutputMask (void) const { return m_outputMask; }
getInputMask(void) const566 VkAccessFlags getInputMask (void) const { return m_inputMask; }
567
getFlags(void) const568 VkDependencyFlags getFlags (void) const { return m_flags; }
569
570 private:
571 deUint32 m_srcPass;
572 deUint32 m_dstPass;
573
574 VkPipelineStageFlags m_srcStageMask;
575 VkPipelineStageFlags m_dstStageMask;
576
577 VkAccessFlags m_outputMask;
578 VkAccessFlags m_inputMask;
579 VkDependencyFlags m_flags;
580 };
581
582 class Attachment
583 {
584 public:
Attachment(VkFormat format,VkSampleCountFlagBits samples,VkAttachmentLoadOp loadOp,VkAttachmentStoreOp storeOp,VkAttachmentLoadOp stencilLoadOp,VkAttachmentStoreOp stencilStoreOp,VkImageLayout initialLayout,VkImageLayout finalLayout)585 Attachment (VkFormat format,
586 VkSampleCountFlagBits samples,
587
588 VkAttachmentLoadOp loadOp,
589 VkAttachmentStoreOp storeOp,
590
591 VkAttachmentLoadOp stencilLoadOp,
592 VkAttachmentStoreOp stencilStoreOp,
593
594 VkImageLayout initialLayout,
595 VkImageLayout finalLayout)
596 : m_format (format)
597 , m_samples (samples)
598
599 , m_loadOp (loadOp)
600 , m_storeOp (storeOp)
601
602 , m_stencilLoadOp (stencilLoadOp)
603 , m_stencilStoreOp (stencilStoreOp)
604
605 , m_initialLayout (initialLayout)
606 , m_finalLayout (finalLayout)
607 {
608 }
609
getFormat(void) const610 VkFormat getFormat (void) const { return m_format; }
getSamples(void) const611 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
612
getLoadOp(void) const613 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; }
getStoreOp(void) const614 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; }
615
616
getStencilLoadOp(void) const617 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; }
getStencilStoreOp(void) const618 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; }
619
getInitialLayout(void) const620 VkImageLayout getInitialLayout (void) const { return m_initialLayout; }
getFinalLayout(void) const621 VkImageLayout getFinalLayout (void) const { return m_finalLayout; }
622
623 private:
624 VkFormat m_format;
625 VkSampleCountFlagBits m_samples;
626
627 VkAttachmentLoadOp m_loadOp;
628 VkAttachmentStoreOp m_storeOp;
629
630 VkAttachmentLoadOp m_stencilLoadOp;
631 VkAttachmentStoreOp m_stencilStoreOp;
632
633 VkImageLayout m_initialLayout;
634 VkImageLayout m_finalLayout;
635 };
636
637 class RenderPass
638 {
639 public:
RenderPass(const vector<Attachment> & attachments,const vector<Subpass> & subpasses,const vector<SubpassDependency> & dependencies)640 RenderPass (const vector<Attachment>& attachments,
641 const vector<Subpass>& subpasses,
642 const vector<SubpassDependency>& dependencies)
643 : m_attachments (attachments)
644 , m_subpasses (subpasses)
645 , m_dependencies (dependencies)
646 {
647 }
648
getAttachments(void) const649 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
getSubpasses(void) const650 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
getDependencies(void) const651 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
652
653 private:
654 const vector<Attachment> m_attachments;
655 const vector<Subpass> m_subpasses;
656 const vector<SubpassDependency> m_dependencies;
657 };
658
659 struct TestConfig
660 {
661 enum RenderTypes
662 {
663 RENDERTYPES_NONE = 0,
664 RENDERTYPES_CLEAR = (1<<1),
665 RENDERTYPES_DRAW = (1<<2)
666 };
667
668 enum CommandBufferTypes
669 {
670 COMMANDBUFFERTYPES_INLINE = (1<<0),
671 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
672 };
673
674 enum ImageMemory
675 {
676 IMAGEMEMORY_STRICT = (1<<0),
677 IMAGEMEMORY_LAZY = (1<<1)
678 };
679
TestConfigvkt::__anon30da2d3d0111::TestConfig680 TestConfig (const RenderPass& renderPass_,
681 RenderTypes renderTypes_,
682 CommandBufferTypes commandBufferTypes_,
683 ImageMemory imageMemory_,
684 const UVec2& targetSize_,
685 const UVec2& renderPos_,
686 const UVec2& renderSize_,
687 deUint32 seed_)
688 : renderPass (renderPass_)
689 , renderTypes (renderTypes_)
690 , commandBufferTypes (commandBufferTypes_)
691 , imageMemory (imageMemory_)
692 , targetSize (targetSize_)
693 , renderPos (renderPos_)
694 , renderSize (renderSize_)
695 , seed (seed_)
696 {
697 }
698
699 RenderPass renderPass;
700 RenderTypes renderTypes;
701 CommandBufferTypes commandBufferTypes;
702 ImageMemory imageMemory;
703 UVec2 targetSize;
704 UVec2 renderPos;
705 UVec2 renderSize;
706 deUint32 seed;
707 };
708
operator |(TestConfig::RenderTypes a,TestConfig::RenderTypes b)709 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
710 {
711 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
712 }
713
operator |(TestConfig::CommandBufferTypes a,TestConfig::CommandBufferTypes b)714 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
715 {
716 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
717 }
718
operator |(TestConfig::ImageMemory a,TestConfig::ImageMemory b)719 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
720 {
721 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
722 }
723
logRenderPassInfo(TestLog & log,const RenderPass & renderPass)724 void logRenderPassInfo (TestLog& log,
725 const RenderPass& renderPass)
726 {
727 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
728
729 {
730 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
731 const vector<Attachment>& attachments = renderPass.getAttachments();
732
733 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
734 {
735 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
736 const Attachment& attachment = attachments[attachmentNdx];
737
738 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
739 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
740
741 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
742 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
743
744 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
745 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
746
747 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
748 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
749 }
750 }
751
752 {
753 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
754 const vector<Subpass>& subpasses = renderPass.getSubpasses();
755
756 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
757 {
758 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
759 const Subpass& subpass = subpasses[subpassNdx];
760
761 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
762 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
763 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
764 const vector<deUint32>& preserveAttachments = subpass.getPreserveAttachments();
765
766 if (!inputAttachments.empty())
767 {
768 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
769
770 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
771 {
772 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
773 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
774
775 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
776 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
777 }
778 }
779
780 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
781 {
782 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
783 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
784
785 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
786 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
787 }
788
789 if (!colorAttachments.empty())
790 {
791 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
792
793 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
794 {
795 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
796 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
797
798 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
799 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
800 }
801 }
802
803 if (!resolveAttachments.empty())
804 {
805 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
806
807 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
808 {
809 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
810 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
811
812 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
813 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
814 }
815 }
816
817 if (!preserveAttachments.empty())
818 {
819 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
820
821 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
822 {
823 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
824 const deUint32 preserveAttachment = preserveAttachments[preserveNdx];
825
826 log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
827 }
828 }
829 }
830
831 }
832
833 if (!renderPass.getDependencies().empty())
834 {
835 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
836
837 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
838 {
839 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
840 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
841
842 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
843 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
844
845 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
846 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
847
848 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
849 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
850 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
851 }
852 }
853 }
854
clearColorToString(VkFormat vkFormat,VkClearColorValue value)855 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
856 {
857 const tcu::TextureFormat format = mapVkFormat(vkFormat);
858 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
859 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
860
861 std::ostringstream stream;
862
863 stream << "(";
864
865 switch (channelClass)
866 {
867 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
868 for (int i = 0; i < 4; i++)
869 {
870 if (i > 0)
871 stream << ", ";
872
873 if (channelMask[i])
874 stream << value.int32[i];
875 else
876 stream << "Undef";
877 }
878 break;
879
880 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
881 for (int i = 0; i < 4; i++)
882 {
883 if (i > 0)
884 stream << ", ";
885
886 if (channelMask[i])
887 stream << value.uint32[i];
888 else
889 stream << "Undef";
890 }
891 break;
892
893 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
894 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
895 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
896 for (int i = 0; i < 4; i++)
897 {
898 if (i > 0)
899 stream << ", ";
900
901 if (channelMask[i])
902 stream << value.float32[i];
903 else
904 stream << "Undef";
905 }
906 break;
907
908 default:
909 DE_FATAL("Unknown channel class");
910 }
911
912 stream << ")";
913
914 return stream.str();
915 }
916
clearValueToString(VkFormat vkFormat,VkClearValue value)917 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
918 {
919 const tcu::TextureFormat format = mapVkFormat(vkFormat);
920
921 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
922 {
923 std::ostringstream stream;
924
925 stream << "(";
926
927 if (tcu::hasStencilComponent(format.order))
928 stream << "stencil: " << value.depthStencil.stencil;
929
930 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
931 stream << ", ";
932
933 if (tcu::hasDepthComponent(format.order))
934 stream << "depth: " << value.depthStencil.depth;
935
936 stream << ")";
937
938 return stream.str();
939 }
940 else
941 return clearColorToString(vkFormat, value.color);
942 }
943
randomColorClearValue(const Attachment & attachment,de::Random & rng)944 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
945 {
946 const float clearNan = tcu::Float32::nan().asFloat();
947 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
948 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
949 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
950 VkClearColorValue clearColor;
951
952 switch (channelClass)
953 {
954 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
955 {
956 for (int ndx = 0; ndx < 4; ndx++)
957 {
958 if (!channelMask[ndx])
959 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
960 else
961 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
962 }
963 break;
964 }
965
966 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
967 {
968 for (int ndx = 0; ndx < 4; ndx++)
969 {
970 if (!channelMask[ndx])
971 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
972 else
973 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
974 }
975 break;
976 }
977
978 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
979 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
980 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
981 {
982 for (int ndx = 0; ndx < 4; ndx++)
983 {
984 if (!channelMask[ndx])
985 clearColor.float32[ndx] = clearNan;
986 else
987 clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
988 }
989 break;
990 }
991
992 default:
993 DE_FATAL("Unknown channel class");
994 }
995
996 return clearColor;
997 }
998
createAttachmentDescription(const Attachment & attachment)999 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
1000 {
1001 const VkAttachmentDescription attachmentDescription =
1002 {
1003 0, // flags
1004
1005 attachment.getFormat(), // format
1006 attachment.getSamples(), // samples
1007
1008 attachment.getLoadOp(), // loadOp
1009 attachment.getStoreOp(), // storeOp
1010
1011 attachment.getStencilLoadOp(), // stencilLoadOp
1012 attachment.getStencilStoreOp(), // stencilStoreOp
1013
1014 attachment.getInitialLayout(), // initialLayout
1015 attachment.getFinalLayout(), // finalLayout
1016 };
1017
1018 return attachmentDescription;
1019 }
1020
createAttachmentReference(const AttachmentReference & referenceInfo)1021 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
1022 {
1023 const VkAttachmentReference reference =
1024 {
1025 referenceInfo.getAttachment(), // attachment;
1026 referenceInfo.getImageLayout() // layout;
1027 };
1028
1029 return reference;
1030 }
1031
createSubpassDescription(const Subpass & subpass,vector<VkAttachmentReference> * attachmentReferenceLists,vector<deUint32> * preserveAttachmentReferences)1032 VkSubpassDescription createSubpassDescription (const Subpass& subpass,
1033 vector<VkAttachmentReference>* attachmentReferenceLists,
1034 vector<deUint32>* preserveAttachmentReferences)
1035 {
1036 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0];
1037 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1];
1038 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2];
1039 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
1040
1041 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
1042 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
1043
1044 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
1045 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
1046
1047 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
1048 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
1049
1050 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
1051
1052 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
1053 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
1054
1055 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
1056
1057 {
1058 const VkSubpassDescription subpassDescription =
1059 {
1060 subpass.getFlags(), // flags;
1061 subpass.getPipelineBindPoint(), // pipelineBindPoint;
1062
1063 (deUint32)inputAttachmentReferences.size(), // inputCount;
1064 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments;
1065
1066 (deUint32)colorAttachmentReferences.size(), // colorCount;
1067 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments;
1068 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments;
1069
1070 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment;
1071 (deUint32)preserveAttachmentReferences->size(), // preserveCount;
1072 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // preserveAttachments;
1073 };
1074
1075 return subpassDescription;
1076 }
1077 }
1078
createSubpassDependency(const SubpassDependency & dependencyInfo)1079 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo)
1080 {
1081 const VkSubpassDependency dependency =
1082 {
1083 dependencyInfo.getSrcPass(), // srcSubpass;
1084 dependencyInfo.getDstPass(), // destSubpass;
1085
1086 dependencyInfo.getSrcStageMask(), // srcStageMask;
1087 dependencyInfo.getDstStageMask(), // destStageMask;
1088
1089 dependencyInfo.getOutputMask(), // outputMask;
1090 dependencyInfo.getInputMask(), // inputMask;
1091
1092 dependencyInfo.getFlags() // dependencyFlags;
1093 };
1094
1095 return dependency;
1096 }
1097
createRenderPass(const DeviceInterface & vk,VkDevice device,const RenderPass & renderPassInfo)1098 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1099 VkDevice device,
1100 const RenderPass& renderPassInfo)
1101 {
1102 const size_t perSubpassAttachmentReferenceLists = 4;
1103 vector<VkAttachmentDescription> attachments;
1104 vector<VkSubpassDescription> subpasses;
1105 vector<VkSubpassDependency> dependencies;
1106 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1107 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size());
1108
1109 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1110 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1111
1112 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1113 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1114
1115 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1116 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1117
1118 {
1119 const VkRenderPassCreateInfo createInfo =
1120 {
1121 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1122 DE_NULL,
1123 (VkRenderPassCreateFlags)0u,
1124 (deUint32)attachments.size(),
1125 (attachments.empty() ? DE_NULL : &attachments[0]),
1126 (deUint32)subpasses.size(),
1127 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1128 (deUint32)dependencies.size(),
1129 (dependencies.empty() ? DE_NULL : &dependencies[0])
1130 };
1131
1132 return createRenderPass(vk, device, &createInfo);
1133 }
1134 }
1135
createFramebuffer(const DeviceInterface & vk,VkDevice device,VkRenderPass renderPass,const UVec2 & size,const vector<VkImageView> & attachments)1136 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1137 VkDevice device,
1138 VkRenderPass renderPass,
1139 const UVec2& size,
1140 const vector<VkImageView>& attachments)
1141 {
1142 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1143 }
1144
createAttachmentImage(const DeviceInterface & vk,VkDevice device,deUint32 queueIndex,const UVec2 & size,VkFormat format,VkSampleCountFlagBits samples,VkImageUsageFlags usageFlags,VkImageLayout layout)1145 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1146 VkDevice device,
1147 deUint32 queueIndex,
1148 const UVec2& size,
1149 VkFormat format,
1150 VkSampleCountFlagBits samples,
1151 VkImageUsageFlags usageFlags,
1152 VkImageLayout layout)
1153 {
1154 VkImageUsageFlags targetUsageFlags = 0;
1155 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1156
1157 DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1158 || ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
1159
1160 DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1161 || ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
1162
1163 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1164 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1165 else
1166 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1167
1168 return createImage(vk, device,
1169 (VkImageCreateFlags)0,
1170 VK_IMAGE_TYPE_2D,
1171 format,
1172 vk::makeExtent3D(size.x(), size.y(), 1u),
1173 1u /* mipLevels */,
1174 1u /* arraySize */,
1175 samples,
1176 VK_IMAGE_TILING_OPTIMAL,
1177 usageFlags | targetUsageFlags,
1178 VK_SHARING_MODE_EXCLUSIVE,
1179 1,
1180 &queueIndex,
1181 layout);
1182 }
1183
createImageMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkImage image,bool lazy)1184 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
1185 VkDevice device,
1186 Allocator& allocator,
1187 VkImage image,
1188 bool lazy)
1189 {
1190 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any));
1191 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1192 return allocation;
1193 }
1194
createImageAttachmentView(const DeviceInterface & vk,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)1195 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1196 VkDevice device,
1197 VkImage image,
1198 VkFormat format,
1199 VkImageAspectFlags aspect)
1200 {
1201 const VkImageSubresourceRange range =
1202 {
1203 aspect,
1204 0,
1205 1,
1206 0,
1207 1
1208 };
1209
1210 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1211 }
1212
randomClearValue(const Attachment & attachment,de::Random & rng)1213 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1214 {
1215 const float clearNan = tcu::Float32::nan().asFloat();
1216 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1217
1218 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1219 {
1220 VkClearValue clearValue;
1221
1222 clearValue.depthStencil.depth = clearNan;
1223 clearValue.depthStencil.stencil = 0xCDu;
1224
1225 if (tcu::hasStencilComponent(format.order))
1226 clearValue.depthStencil.stencil = rng.getBool()
1227 ? 0xFFu
1228 : 0x0u;
1229
1230 if (tcu::hasDepthComponent(format.order))
1231 clearValue.depthStencil.depth = rng.getBool()
1232 ? 1.0f
1233 : 0.0f;
1234
1235 return clearValue;
1236 }
1237 else
1238 {
1239 VkClearValue clearValue;
1240
1241 clearValue.color = randomColorClearValue(attachment, rng);
1242
1243 return clearValue;
1244 }
1245 }
1246
1247 class AttachmentResources
1248 {
1249 public:
AttachmentResources(const DeviceInterface & vk,VkDevice device,Allocator & allocator,deUint32 queueIndex,const UVec2 & size,const Attachment & attachmentInfo,VkImageUsageFlags usageFlags)1250 AttachmentResources (const DeviceInterface& vk,
1251 VkDevice device,
1252 Allocator& allocator,
1253 deUint32 queueIndex,
1254 const UVec2& size,
1255 const Attachment& attachmentInfo,
1256 VkImageUsageFlags usageFlags)
1257 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1258 , m_imageMemory (createImageMemory(vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)))
1259 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1260 {
1261 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1262 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1263 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1264
1265 if (isDepthFormat && isStencilFormat)
1266 {
1267 m_depthInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
1268 m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);
1269
1270 m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
1271 }
1272 else
1273 m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
1274
1275 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1276 {
1277 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1278 {
1279 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1280 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1281
1282 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1283 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1284
1285 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1286 m_bufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1287
1288 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1289
1290 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1291 m_secondaryBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_secondaryBuffer), MemoryRequirement::HostVisible);
1292
1293 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1294 }
1295 else
1296 {
1297 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1298
1299 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1300 m_bufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1301
1302 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1303 }
1304 }
1305 }
1306
getInputAttachmentViews(void) const1307 const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
1308 {
1309 return m_inputAttachmentViews;
1310 }
1311
~AttachmentResources(void)1312 ~AttachmentResources (void)
1313 {
1314 }
1315
getAttachmentView(void) const1316 VkImageView getAttachmentView (void) const
1317 {
1318 return *m_attachmentView;
1319 }
1320
getImage(void) const1321 VkImage getImage (void) const
1322 {
1323 return *m_image;
1324 }
1325
getBuffer(void) const1326 VkBuffer getBuffer (void) const
1327 {
1328 DE_ASSERT(*m_buffer != DE_NULL);
1329 return *m_buffer;
1330 }
1331
getBufferSize(void) const1332 VkDeviceSize getBufferSize (void) const
1333 {
1334 DE_ASSERT(*m_buffer != DE_NULL);
1335 return m_bufferSize;
1336 }
1337
getResultMemory(void) const1338 const Allocation& getResultMemory (void) const
1339 {
1340 DE_ASSERT(m_bufferMemory);
1341 return *m_bufferMemory;
1342 }
1343
getSecondaryBuffer(void) const1344 VkBuffer getSecondaryBuffer (void) const
1345 {
1346 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1347 return *m_secondaryBuffer;
1348 }
1349
getSecondaryBufferSize(void) const1350 VkDeviceSize getSecondaryBufferSize (void) const
1351 {
1352 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1353 return m_secondaryBufferSize;
1354 }
1355
getSecondaryResultMemory(void) const1356 const Allocation& getSecondaryResultMemory (void) const
1357 {
1358 DE_ASSERT(m_secondaryBufferMemory);
1359 return *m_secondaryBufferMemory;
1360 }
1361
1362 private:
1363 const Unique<VkImage> m_image;
1364 const UniquePtr<Allocation> m_imageMemory;
1365 const Unique<VkImageView> m_attachmentView;
1366
1367 Move<VkImageView> m_depthInputAttachmentView;
1368 Move<VkImageView> m_stencilInputAttachmentView;
1369 pair<VkImageView, VkImageView> m_inputAttachmentViews;
1370
1371 Move<VkBuffer> m_buffer;
1372 VkDeviceSize m_bufferSize;
1373 de::MovePtr<Allocation> m_bufferMemory;
1374
1375 Move<VkBuffer> m_secondaryBuffer;
1376 VkDeviceSize m_secondaryBufferSize;
1377 de::MovePtr<Allocation> m_secondaryBufferMemory;
1378 };
1379
uploadBufferData(const DeviceInterface & vk,VkDevice device,const Allocation & memory,size_t size,const void * data)1380 void uploadBufferData (const DeviceInterface& vk,
1381 VkDevice device,
1382 const Allocation& memory,
1383 size_t size,
1384 const void* data)
1385 {
1386 const VkMappedMemoryRange range =
1387 {
1388 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1389 DE_NULL, // pNext;
1390 memory.getMemory(), // mem;
1391 memory.getOffset(), // offset;
1392 (VkDeviceSize)size // size;
1393 };
1394 void* const ptr = memory.getHostPtr();
1395
1396 deMemcpy(ptr, data, size);
1397 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1398 }
1399
getPrimaryImageAspect(tcu::TextureFormat::ChannelOrder order)1400 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1401 {
1402 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1403
1404 switch (order)
1405 {
1406 case tcu::TextureFormat::D:
1407 case tcu::TextureFormat::DS:
1408 return VK_IMAGE_ASPECT_DEPTH_BIT;
1409
1410 case tcu::TextureFormat::S:
1411 return VK_IMAGE_ASPECT_STENCIL_BIT;
1412
1413 default:
1414 return VK_IMAGE_ASPECT_COLOR_BIT;
1415 }
1416 }
1417
1418 class RenderQuad
1419 {
1420 public:
RenderQuad(const Vec2 & posA,const Vec2 & posB)1421 RenderQuad (const Vec2& posA, const Vec2& posB)
1422 : m_vertices(6)
1423 {
1424 m_vertices[0] = posA;
1425 m_vertices[1] = Vec2(posA[0], posB[1]);
1426 m_vertices[2] = posB;
1427
1428 m_vertices[3] = posB;
1429 m_vertices[4] = Vec2(posB[0], posA[1]);
1430 m_vertices[5] = posA;
1431 }
1432
getCornerA(void) const1433 const Vec2& getCornerA (void) const
1434 {
1435 return m_vertices[0];
1436 }
1437
getCornerB(void) const1438 const Vec2& getCornerB (void) const
1439 {
1440 return m_vertices[2];
1441 }
1442
getVertexPointer(void) const1443 const void* getVertexPointer (void) const
1444 {
1445 return &m_vertices[0];
1446 }
1447
getVertexDataSize(void) const1448 size_t getVertexDataSize (void) const
1449 {
1450 return sizeof(Vec2) * m_vertices.size();
1451 }
1452
1453 private:
1454 vector<Vec2> m_vertices;
1455 };
1456
1457 class ColorClear
1458 {
1459 public:
ColorClear(const UVec2 & offset,const UVec2 & size,const VkClearColorValue & color)1460 ColorClear (const UVec2& offset,
1461 const UVec2& size,
1462 const VkClearColorValue& color)
1463 : m_offset (offset)
1464 , m_size (size)
1465 , m_color (color)
1466 {
1467 }
1468
getOffset(void) const1469 const UVec2& getOffset (void) const { return m_offset; }
getSize(void) const1470 const UVec2& getSize (void) const { return m_size; }
getColor(void) const1471 const VkClearColorValue& getColor (void) const { return m_color; }
1472
1473 private:
1474 UVec2 m_offset;
1475 UVec2 m_size;
1476 VkClearColorValue m_color;
1477 };
1478
1479 class DepthStencilClear
1480 {
1481 public:
DepthStencilClear(const UVec2 & offset,const UVec2 & size,float depth,deUint32 stencil)1482 DepthStencilClear (const UVec2& offset,
1483 const UVec2& size,
1484 float depth,
1485 deUint32 stencil)
1486 : m_offset (offset)
1487 , m_size (size)
1488 , m_depth (depth)
1489 , m_stencil (stencil)
1490 {
1491 }
1492
getOffset(void) const1493 const UVec2& getOffset (void) const { return m_offset; }
getSize(void) const1494 const UVec2& getSize (void) const { return m_size; }
getDepth(void) const1495 float getDepth (void) const { return m_depth; }
getStencil(void) const1496 deUint32 getStencil (void) const { return m_stencil; }
1497
1498 private:
1499 const UVec2 m_offset;
1500 const UVec2 m_size;
1501
1502 const float m_depth;
1503 const deUint32 m_stencil;
1504 };
1505
1506 class SubpassRenderInfo
1507 {
1508 public:
SubpassRenderInfo(const RenderPass & renderPass,deUint32 subpassIndex,bool isSecondary_,const UVec2 & viewportOffset,const UVec2 & viewportSize,const Maybe<RenderQuad> & renderQuad,const vector<ColorClear> & colorClears,const Maybe<DepthStencilClear> & depthStencilClear)1509 SubpassRenderInfo (const RenderPass& renderPass,
1510 deUint32 subpassIndex,
1511
1512 bool isSecondary_,
1513
1514 const UVec2& viewportOffset,
1515 const UVec2& viewportSize,
1516
1517 const Maybe<RenderQuad>& renderQuad,
1518 const vector<ColorClear>& colorClears,
1519 const Maybe<DepthStencilClear>& depthStencilClear)
1520 : m_viewportOffset (viewportOffset)
1521 , m_viewportSize (viewportSize)
1522 , m_subpassIndex (subpassIndex)
1523 , m_isSecondary (isSecondary_)
1524 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1525 , m_renderQuad (renderQuad)
1526 , m_colorClears (colorClears)
1527 , m_depthStencilClear (depthStencilClear)
1528 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1529 , m_inputAttachments (renderPass.getSubpasses()[subpassIndex].getInputAttachments())
1530 {
1531 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1532 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1533
1534 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1535 {
1536 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1537 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1538 }
1539 }
1540
getViewportOffset(void) const1541 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
getViewportSize(void) const1542 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1543
getSubpassIndex(void) const1544 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
isSecondary(void) const1545 bool isSecondary (void) const { return m_isSecondary; }
1546
getRenderQuad(void) const1547 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
getColorClears(void) const1548 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
getDepthStencilClear(void) const1549 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1550
getInputAttachmentCount(void) const1551 deUint32 getInputAttachmentCount (void) const { return (deUint32)m_inputAttachments.size(); }
getInputAttachmentIndex(deUint32 attachmentNdx) const1552 deUint32 getInputAttachmentIndex (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
getInputAttachmentLayout(deUint32 attachmentNdx) const1553 VkImageLayout getInputAttachmentLayout (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }
1554
getColorAttachmentCount(void) const1555 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
getColorAttachmentLayout(deUint32 attachmentNdx) const1556 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
getColorAttachmentIndex(deUint32 attachmentNdx) const1557 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
getColorAttachment(deUint32 attachmentNdx) const1558 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
getDepthStencilAttachmentLayout(void) const1559 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
getDepthStencilAttachmentIndex(void) const1560 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
getDepthStencilAttachment(void) const1561 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
getSubpassFlags(void) const1562 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1563
1564 private:
1565 UVec2 m_viewportOffset;
1566 UVec2 m_viewportSize;
1567
1568 deUint32 m_subpassIndex;
1569 bool m_isSecondary;
1570 VkSubpassDescriptionFlags m_flags;
1571
1572 Maybe<RenderQuad> m_renderQuad;
1573 vector<ColorClear> m_colorClears;
1574 Maybe<DepthStencilClear> m_depthStencilClear;
1575
1576 vector<AttachmentReference> m_colorAttachments;
1577 vector<Attachment> m_colorAttachmentInfo;
1578
1579 Maybe<AttachmentReference> m_depthStencilAttachment;
1580 Maybe<Attachment> m_depthStencilAttachmentInfo;
1581
1582 vector<AttachmentReference> m_inputAttachments;
1583 };
1584
createSubpassPipeline(const DeviceInterface & vk,VkDevice device,VkRenderPass renderPass,VkShaderModule vertexShaderModule,VkShaderModule fragmentShaderModule,VkPipelineLayout pipelineLayout,const SubpassRenderInfo & renderInfo)1585 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1586 VkDevice device,
1587 VkRenderPass renderPass,
1588 VkShaderModule vertexShaderModule,
1589 VkShaderModule fragmentShaderModule,
1590 VkPipelineLayout pipelineLayout,
1591 const SubpassRenderInfo& renderInfo)
1592 {
1593 const VkSpecializationInfo emptyShaderSpecializations =
1594 {
1595 0u, // mapEntryCount
1596 DE_NULL, // pMap
1597 0u, // dataSize
1598 DE_NULL, // pData
1599 };
1600
1601 Maybe<VkSampleCountFlagBits> rasterSamples;
1602 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1603
1604 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1605 {
1606 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1607
1608 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1609
1610 rasterSamples = attachment.getSamples();
1611
1612 {
1613 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1614 {
1615 VK_FALSE, // blendEnable
1616 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1617 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1618 VK_BLEND_OP_ADD, // blendOpColor
1619 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1620 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1621 VK_BLEND_OP_ADD, // blendOpAlpha
1622 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask
1623 };
1624
1625 attachmentBlendStates.push_back(attachmentBlendState);
1626 }
1627 }
1628
1629 if (renderInfo.getDepthStencilAttachment())
1630 {
1631 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1632
1633 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1634 rasterSamples = attachment.getSamples();
1635 }
1636
1637 // If there are no attachment use single sample
1638 if (!rasterSamples)
1639 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1640
1641 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1642 {
1643 {
1644 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1645 DE_NULL, // pNext
1646 (VkPipelineShaderStageCreateFlags)0u,
1647 VK_SHADER_STAGE_VERTEX_BIT, // stage
1648 vertexShaderModule, // shader
1649 "main",
1650 &emptyShaderSpecializations
1651 },
1652 {
1653 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1654 DE_NULL, // pNext
1655 (VkPipelineShaderStageCreateFlags)0u,
1656 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1657 fragmentShaderModule, // shader
1658 "main",
1659 &emptyShaderSpecializations
1660 }
1661 };
1662 const VkVertexInputBindingDescription vertexBinding =
1663 {
1664 0u, // binding
1665 (deUint32)sizeof(tcu::Vec2), // strideInBytes
1666 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1667 };
1668 const VkVertexInputAttributeDescription vertexAttrib =
1669 {
1670 0u, // location
1671 0u, // binding
1672 VK_FORMAT_R32G32_SFLOAT, // format
1673 0u, // offsetInBytes
1674 };
1675 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1676 {
1677 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1678 DE_NULL, // pNext
1679 (VkPipelineVertexInputStateCreateFlags)0u,
1680 1u, // bindingCount
1681 &vertexBinding, // pVertexBindingDescriptions
1682 1u, // attributeCount
1683 &vertexAttrib, // pVertexAttributeDescriptions
1684 };
1685 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1686 {
1687 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
1688 DE_NULL, // pNext
1689 (VkPipelineInputAssemblyStateCreateFlags)0u,
1690 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
1691 VK_FALSE, // primitiveRestartEnable
1692 };
1693 const VkViewport viewport =
1694 {
1695 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1696 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1697 0.0f, 1.0f
1698 };
1699 const VkRect2D scissor =
1700 {
1701 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1702 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() }
1703 };
1704 const VkPipelineViewportStateCreateInfo viewportState =
1705 {
1706 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1707 DE_NULL,
1708 (VkPipelineViewportStateCreateFlags)0u,
1709 1u,
1710 &viewport,
1711 1u,
1712 &scissor
1713 };
1714 const VkPipelineRasterizationStateCreateInfo rasterState =
1715 {
1716 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
1717 DE_NULL, // pNext
1718 (VkPipelineRasterizationStateCreateFlags)0u,
1719 VK_TRUE, // depthClipEnable
1720 VK_FALSE, // rasterizerDiscardEnable
1721 VK_POLYGON_MODE_FILL, // fillMode
1722 VK_CULL_MODE_NONE, // cullMode
1723 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1724 VK_FALSE, // depthBiasEnable
1725 0.0f, // depthBias
1726 0.0f, // depthBiasClamp
1727 0.0f, // slopeScaledDepthBias
1728 1.0f // lineWidth
1729 };
1730 const VkPipelineMultisampleStateCreateInfo multisampleState =
1731 {
1732 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1733 DE_NULL, // pNext
1734 (VkPipelineMultisampleStateCreateFlags)0u,
1735 *rasterSamples, // rasterSamples
1736 VK_FALSE, // sampleShadingEnable
1737 0.0f, // minSampleShading
1738 DE_NULL, // pSampleMask
1739 VK_FALSE, // alphaToCoverageEnable
1740 VK_FALSE, // alphaToOneEnable
1741 };
1742 const size_t stencilIndex = renderInfo.getSubpassIndex();
1743 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1744 {
1745 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1746 DE_NULL, // pNext
1747 (VkPipelineDepthStencilStateCreateFlags)0u,
1748 VK_TRUE, // depthTestEnable
1749 VK_TRUE, // depthWriteEnable
1750 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1751 VK_FALSE, // depthBoundsEnable
1752 VK_TRUE, // stencilTestEnable
1753 {
1754 VK_STENCIL_OP_REPLACE, // stencilFailOp
1755 VK_STENCIL_OP_REPLACE, // stencilPassOp
1756 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1757 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1758 ~0u, // stencilCompareMask
1759 ~0u, // stencilWriteMask
1760 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1761 }, // front
1762 {
1763 VK_STENCIL_OP_REPLACE, // stencilFailOp
1764 VK_STENCIL_OP_REPLACE, // stencilPassOp
1765 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1766 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1767 ~0u, // stencilCompareMask
1768 ~0u, // stencilWriteMask
1769 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1770 }, // back
1771
1772 0.0f, // minDepthBounds;
1773 1.0f // maxDepthBounds;
1774 };
1775 const VkPipelineColorBlendStateCreateInfo blendState =
1776 {
1777 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1778 DE_NULL, // pNext
1779 (VkPipelineColorBlendStateCreateFlags)0u,
1780 VK_FALSE, // logicOpEnable
1781 VK_LOGIC_OP_COPY, // logicOp
1782 (deUint32)attachmentBlendStates.size(), // attachmentCount
1783 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1784 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1785 };
1786 const VkGraphicsPipelineCreateInfo createInfo =
1787 {
1788 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
1789 DE_NULL, // pNext
1790 (VkPipelineCreateFlags)0u,
1791
1792 2, // stageCount
1793 shaderStages, // pStages
1794
1795 &vertexInputState, // pVertexInputState
1796 &inputAssemblyState, // pInputAssemblyState
1797 DE_NULL, // pTessellationState
1798 &viewportState, // pViewportState
1799 &rasterState, // pRasterState
1800 &multisampleState, // pMultisampleState
1801 &depthStencilState, // pDepthStencilState
1802 &blendState, // pColorBlendState
1803 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1804 pipelineLayout, // layout
1805
1806 renderPass, // renderPass
1807 renderInfo.getSubpassIndex(), // subpass
1808 DE_NULL, // basePipelineHandle
1809 0u // basePipelineIndex
1810 };
1811
1812 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1813 }
1814
1815 class SubpassRenderer
1816 {
1817 public:
SubpassRenderer(Context & context,const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkRenderPass renderPass,VkFramebuffer framebuffer,VkCommandPool commandBufferPool,deUint32 queueFamilyIndex,const vector<VkImage> & attachmentImages,const vector<pair<VkImageView,VkImageView>> & attachmentViews,const SubpassRenderInfo & renderInfo,const vector<Attachment> & attachmentInfos)1818 SubpassRenderer (Context& context,
1819 const DeviceInterface& vk,
1820 VkDevice device,
1821 Allocator& allocator,
1822 VkRenderPass renderPass,
1823 VkFramebuffer framebuffer,
1824 VkCommandPool commandBufferPool,
1825 deUint32 queueFamilyIndex,
1826 const vector<VkImage>& attachmentImages,
1827 const vector<pair<VkImageView, VkImageView> >& attachmentViews,
1828 const SubpassRenderInfo& renderInfo,
1829 const vector<Attachment>& attachmentInfos)
1830 : m_renderInfo (renderInfo)
1831 {
1832 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1833 vector<VkDescriptorSetLayoutBinding> bindings;
1834
1835 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
1836 m_colorAttachmentImages.push_back(attachmentImages[renderInfo.getColorAttachmentIndex(colorAttachmentNdx)]);
1837
1838 if (renderInfo.getDepthStencilAttachmentIndex())
1839 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
1840
1841 if (renderInfo.getRenderQuad())
1842 {
1843 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
1844
1845 if (renderInfo.getInputAttachmentCount() > 0)
1846 {
1847 deUint32 bindingIndex = 0;
1848
1849 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
1850 {
1851 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
1852 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1853 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1854 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1855 const deUint32 bindingCount = isDepthFormat && isStencilFormat ? 2u : 1u;
1856
1857 for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
1858 {
1859 const VkDescriptorSetLayoutBinding binding =
1860 {
1861 bindingIndex,
1862 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1863 1u,
1864 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1865 DE_NULL
1866 };
1867
1868 bindings.push_back(binding);
1869 bindingIndex++;
1870 }
1871 }
1872
1873 const VkDescriptorSetLayoutCreateInfo createInfo =
1874 {
1875 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1876 DE_NULL,
1877
1878 0u,
1879 (deUint32)bindings.size(),
1880 &bindings[0]
1881 };
1882
1883 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
1884 }
1885
1886 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout;
1887 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1888 {
1889 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
1890 DE_NULL, // pNext;
1891 (vk::VkPipelineLayoutCreateFlags)0,
1892 m_descriptorSetLayout ? 1u :0u , // setLayoutCount;
1893 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
1894 0u, // pushConstantRangeCount;
1895 DE_NULL, // pPushConstantRanges;
1896 };
1897
1898 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1899 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1900 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
1901 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
1902
1903 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
1904 m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1905
1906 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
1907 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
1908
1909 if (renderInfo.getInputAttachmentCount() > 0)
1910 {
1911 {
1912 const VkDescriptorPoolSize poolSize =
1913 {
1914 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1915 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
1916 renderInfo.getInputAttachmentCount() * 2u
1917 };
1918 const VkDescriptorPoolCreateInfo createInfo =
1919 {
1920 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1921 DE_NULL,
1922 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1923
1924 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
1925 renderInfo.getInputAttachmentCount() * 2u,
1926 1u,
1927 &poolSize
1928 };
1929
1930 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
1931 }
1932 {
1933 const VkDescriptorSetAllocateInfo allocateInfo =
1934 {
1935 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1936 DE_NULL,
1937
1938 *m_descriptorPool,
1939 1u,
1940 &descriptorSetLayout
1941 };
1942
1943 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
1944 }
1945 {
1946 vector<VkWriteDescriptorSet> writes (bindings.size());
1947 vector<VkDescriptorImageInfo> imageInfos (bindings.size());
1948 deUint32 bindingIndex = 0;
1949
1950 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
1951 {
1952 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
1953 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1954 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1955 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1956 const VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
1957
1958 if (isDepthFormat && isStencilFormat)
1959 {
1960 {
1961 const VkDescriptorImageInfo imageInfo =
1962 {
1963 (VkSampler)0,
1964 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
1965 inputAttachmentLayout
1966 };
1967 imageInfos[bindingIndex] = imageInfo;
1968
1969 {
1970 const VkWriteDescriptorSet write =
1971 {
1972 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1973 DE_NULL,
1974
1975 *m_descriptorSet,
1976 bindingIndex,
1977 0u,
1978 1u,
1979 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1980 &imageInfos[bindingIndex],
1981 DE_NULL,
1982 DE_NULL
1983 };
1984 writes[bindingIndex] = write;
1985
1986 bindingIndex++;
1987 }
1988 }
1989 {
1990 const VkDescriptorImageInfo imageInfo =
1991 {
1992 (VkSampler)0,
1993 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
1994 inputAttachmentLayout
1995 };
1996 imageInfos[bindingIndex] = imageInfo;
1997
1998 {
1999 const VkWriteDescriptorSet write =
2000 {
2001 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2002 DE_NULL,
2003
2004 *m_descriptorSet,
2005 bindingIndex,
2006 0u,
2007 1u,
2008 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2009 &imageInfos[bindingIndex],
2010 DE_NULL,
2011 DE_NULL
2012 };
2013 writes[bindingIndex] = write;
2014
2015 bindingIndex++;
2016 }
2017 }
2018 }
2019 else
2020 {
2021 const VkDescriptorImageInfo imageInfo =
2022 {
2023 (VkSampler)0,
2024 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2025 inputAttachmentLayout
2026 };
2027 imageInfos[bindingIndex] = imageInfo;
2028
2029 {
2030 const VkWriteDescriptorSet write =
2031 {
2032 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2033 DE_NULL,
2034
2035 *m_descriptorSet,
2036 bindingIndex,
2037 0u,
2038 1u,
2039 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2040 &imageInfos[bindingIndex],
2041 DE_NULL,
2042 DE_NULL
2043 };
2044 writes[bindingIndex] = write;
2045
2046 bindingIndex++;
2047 }
2048 }
2049 }
2050
2051 vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2052 }
2053 }
2054 }
2055
2056 if (renderInfo.isSecondary())
2057 {
2058 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2059
2060 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
2061 pushRenderCommands(vk, *m_commandBuffer);
2062 endCommandBuffer(vk, *m_commandBuffer);
2063 }
2064 }
2065
isSecondary(void) const2066 bool isSecondary (void) const
2067 {
2068 return m_commandBuffer;
2069 }
2070
getCommandBuffer(void) const2071 VkCommandBuffer getCommandBuffer (void) const
2072 {
2073 DE_ASSERT(isSecondary());
2074 return *m_commandBuffer;
2075 }
2076
pushRenderCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer)2077 void pushRenderCommands (const DeviceInterface& vk,
2078 VkCommandBuffer commandBuffer)
2079 {
2080 if (!m_renderInfo.getColorClears().empty())
2081 {
2082 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
2083
2084 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2085 {
2086 const ColorClear& colorClear = colorClears[attachmentNdx];
2087 const VkClearAttachment attachment =
2088 {
2089 VK_IMAGE_ASPECT_COLOR_BIT,
2090 attachmentNdx,
2091 makeClearValue(colorClear.getColor()),
2092 };
2093 const VkClearRect rect =
2094 {
2095 {
2096 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
2097 { colorClear.getSize().x(), colorClear.getSize().y() }
2098 }, // rect
2099 0u, // baseArrayLayer
2100 1u, // layerCount
2101 };
2102
2103 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2104 }
2105 }
2106
2107 if (m_renderInfo.getDepthStencilClear())
2108 {
2109 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
2110 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
2111 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2112 const VkClearAttachment attachment =
2113 {
2114 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2115 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2116 attachmentNdx,
2117 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2118 };
2119 const VkClearRect rect =
2120 {
2121 {
2122 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
2123 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
2124 }, // rect
2125 0u, // baseArrayLayer
2126 1u, // layerCount
2127 };
2128
2129 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2130 }
2131
2132 vector<VkImageMemoryBarrier> selfDeps;
2133 VkPipelineStageFlags srcStages = 0;
2134 VkPipelineStageFlags dstStages = 0;
2135
2136 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2137 {
2138 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2139 {
2140 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2141 {
2142 const VkImageMemoryBarrier barrier =
2143 {
2144 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2145 DE_NULL, // pNext
2146
2147 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2148 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2149
2150 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2151 VK_IMAGE_LAYOUT_GENERAL, // newLayout
2152
2153 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2154 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2155
2156 m_colorAttachmentImages[colorAttachmentNdx], // image
2157 { // subresourceRange
2158 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
2159 0, // baseMipLevel
2160 1, // mipLevels
2161 0, // baseArraySlice
2162 1 // arraySize
2163 }
2164 };
2165
2166 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2167 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2168
2169 selfDeps.push_back(barrier);
2170 }
2171 }
2172
2173 if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2174 {
2175 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2176 const bool hasDepth = hasDepthComponent(format.order);
2177 const bool hasStencil = hasStencilComponent(format.order);
2178 const VkImageMemoryBarrier barrier =
2179 {
2180 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2181 DE_NULL, // pNext;
2182
2183 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
2184 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2185
2186 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2187 VK_IMAGE_LAYOUT_GENERAL, // newLayout;
2188
2189 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
2190 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;
2191
2192 m_depthStencilAttachmentImage, // image;
2193 { // subresourceRange;
2194 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2195 | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
2196 0, // baseMipLevel;
2197 1, // mipLevels;
2198 0, // baseArraySlice;
2199 1 // arraySize;
2200 }
2201 };
2202
2203 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2204 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2205
2206 selfDeps.push_back(barrier);
2207 }
2208 }
2209
2210 if (!selfDeps.empty())
2211 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2212
2213 if (m_renderInfo.getRenderQuad())
2214 {
2215 const VkDeviceSize offset = 0;
2216 const VkBuffer vertexBuffer = *m_vertexBuffer;
2217
2218 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2219
2220 if (m_descriptorSet)
2221 {
2222 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2223 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2224 }
2225
2226 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2227 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2228 }
2229 }
2230
2231 private:
2232 const SubpassRenderInfo m_renderInfo;
2233 Move<VkCommandBuffer> m_commandBuffer;
2234 Move<VkPipeline> m_pipeline;
2235 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2236 Move<VkPipelineLayout> m_pipelineLayout;
2237
2238 Move<VkShaderModule> m_vertexShaderModule;
2239 Move<VkShaderModule> m_fragmentShaderModule;
2240
2241 Move<VkDescriptorPool> m_descriptorPool;
2242 Move<VkDescriptorSet> m_descriptorSet;
2243 Move<VkBuffer> m_vertexBuffer;
2244 de::MovePtr<Allocation> m_vertexBufferMemory;
2245 vector<VkImage> m_colorAttachmentImages;
2246 VkImage m_depthStencilAttachmentImage;
2247 };
2248
pushImageInitializationCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const vector<Attachment> & attachmentInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,deUint32 queueIndex,const vector<Maybe<VkClearValue>> & clearValues)2249 void pushImageInitializationCommands (const DeviceInterface& vk,
2250 VkCommandBuffer commandBuffer,
2251 const vector<Attachment>& attachmentInfo,
2252 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2253 deUint32 queueIndex,
2254 const vector<Maybe<VkClearValue> >& clearValues)
2255 {
2256 {
2257 vector<VkImageMemoryBarrier> initializeLayouts;
2258
2259 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2260 {
2261 if (!clearValues[attachmentNdx])
2262 continue;
2263
2264 const VkImageMemoryBarrier barrier =
2265 {
2266 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2267 DE_NULL, // pNext;
2268
2269 (VkAccessFlags)0, // srcAccessMask
2270 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
2271
2272 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
2273 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
2274
2275 queueIndex, // srcQueueFamilyIndex;
2276 queueIndex, // destQueueFamilyIndex;
2277
2278 attachmentResources[attachmentNdx]->getImage(), // image;
2279 { // subresourceRange;
2280 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2281 0, // baseMipLevel;
2282 1, // mipLevels;
2283 0, // baseArraySlice;
2284 1 // arraySize;
2285 }
2286 };
2287
2288 initializeLayouts.push_back(barrier);
2289 }
2290
2291 if (!initializeLayouts.empty())
2292 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2293 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2294 0, (const VkMemoryBarrier*)DE_NULL,
2295 0, (const VkBufferMemoryBarrier*)DE_NULL,
2296 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2297 }
2298
2299 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2300 {
2301 if (!clearValues[attachmentNdx])
2302 continue;
2303
2304 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2305
2306 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2307 {
2308 const float clearNan = tcu::Float32::nan().asFloat();
2309 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2310 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2311 const VkClearDepthStencilValue depthStencil =
2312 {
2313 clearDepth,
2314 clearStencil
2315 };
2316 const VkImageSubresourceRange range =
2317 {
2318 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2319 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2320 0,
2321 1,
2322 0,
2323 1
2324 };
2325
2326 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2327 }
2328 else
2329 {
2330 const VkImageSubresourceRange range =
2331 {
2332 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
2333 0, // baseMipLevel;
2334 1, // mipLevels;
2335 0, // baseArrayLayer;
2336 1 // layerCount;
2337 };
2338 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
2339
2340 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2341 }
2342 }
2343
2344 {
2345 vector<VkImageMemoryBarrier> renderPassLayouts;
2346
2347 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2348 {
2349 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2350 const VkImageMemoryBarrier barrier =
2351 {
2352 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2353 DE_NULL, // pNext;
2354
2355 (oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0), // srcAccessMask
2356 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
2357
2358 oldLayout, // oldLayout
2359 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
2360
2361 queueIndex, // srcQueueFamilyIndex;
2362 queueIndex, // destQueueFamilyIndex;
2363
2364 attachmentResources[attachmentNdx]->getImage(), // image;
2365 { // subresourceRange;
2366 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2367 0, // baseMipLevel;
2368 1, // mipLevels;
2369 0, // baseArraySlice;
2370 1 // arraySize;
2371 }
2372 };
2373
2374 renderPassLayouts.push_back(barrier);
2375 }
2376
2377 if (!renderPassLayouts.empty())
2378 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2379 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2380 0, (const VkMemoryBarrier*)DE_NULL,
2381 0, (const VkBufferMemoryBarrier*)DE_NULL,
2382 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2383 }
2384 }
2385
pushRenderPassCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,VkRenderPass renderPass,VkFramebuffer framebuffer,const vector<de::SharedPtr<SubpassRenderer>> & subpassRenderers,const UVec2 & renderPos,const UVec2 & renderSize,const vector<Maybe<VkClearValue>> & renderPassClearValues,TestConfig::RenderTypes render)2386 void pushRenderPassCommands (const DeviceInterface& vk,
2387 VkCommandBuffer commandBuffer,
2388 VkRenderPass renderPass,
2389 VkFramebuffer framebuffer,
2390 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2391 const UVec2& renderPos,
2392 const UVec2& renderSize,
2393 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2394 TestConfig::RenderTypes render)
2395 {
2396 const float clearNan = tcu::Float32::nan().asFloat();
2397 vector<VkClearValue> attachmentClearValues;
2398
2399 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2400 {
2401 if (renderPassClearValues[attachmentNdx])
2402 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2403 else
2404 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2405 }
2406
2407 {
2408 const VkRect2D renderArea =
2409 {
2410 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
2411 { renderSize.x(), renderSize.y() }
2412 };
2413
2414 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2415 {
2416 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2417
2418 if (subpassNdx == 0)
2419 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
2420 else
2421 vk.cmdNextSubpass(commandBuffer, contents);
2422
2423 if (render)
2424 {
2425 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2426 {
2427 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2428 }
2429 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2430 {
2431 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2432 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2433 }
2434 else
2435 DE_FATAL("Invalid contents");
2436 }
2437 }
2438
2439 vk.cmdEndRenderPass(commandBuffer);
2440 }
2441 }
2442
pushReadImagesToBuffers(const DeviceInterface & vk,VkCommandBuffer commandBuffer,deUint32 queueIndex,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const vector<Attachment> & attachmentInfo,const vector<bool> & isLazy,const UVec2 & targetSize)2443 void pushReadImagesToBuffers (const DeviceInterface& vk,
2444 VkCommandBuffer commandBuffer,
2445 deUint32 queueIndex,
2446
2447 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2448 const vector<Attachment>& attachmentInfo,
2449 const vector<bool>& isLazy,
2450
2451 const UVec2& targetSize)
2452 {
2453 {
2454 vector<VkImageMemoryBarrier> imageBarriers;
2455
2456 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2457 {
2458 if (isLazy[attachmentNdx])
2459 continue;
2460
2461 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
2462 const VkImageMemoryBarrier barrier =
2463 {
2464 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2465 DE_NULL, // pNext
2466
2467 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2468 getAllMemoryReadFlags(), // dstAccessMask
2469
2470 oldLayout, // oldLayout
2471 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
2472
2473 queueIndex, // srcQueueFamilyIndex
2474 queueIndex, // destQueueFamilyIndex
2475
2476 attachmentResources[attachmentNdx]->getImage(), // image
2477 { // subresourceRange
2478 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2479 0, // baseMipLevel
2480 1, // mipLevels
2481 0, // baseArraySlice
2482 1 // arraySize
2483 }
2484 };
2485
2486 imageBarriers.push_back(barrier);
2487 }
2488
2489 if (!imageBarriers.empty())
2490 vk.cmdPipelineBarrier(commandBuffer,
2491 getAllPipelineStageFlags(),
2492 getAllPipelineStageFlags(),
2493 (VkDependencyFlags)0,
2494 0, (const VkMemoryBarrier*)DE_NULL,
2495 0, (const VkBufferMemoryBarrier*)DE_NULL,
2496 (deUint32)imageBarriers.size(), &imageBarriers[0]);
2497 }
2498
2499 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2500 {
2501 if (isLazy[attachmentNdx])
2502 continue;
2503
2504 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2505 const VkBufferImageCopy rect =
2506 {
2507 0, // bufferOffset
2508 0, // bufferRowLength
2509 0, // bufferImageHeight
2510 { // imageSubresource
2511 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2512 0, // mipLevel
2513 0, // arraySlice
2514 1 // arraySize
2515 },
2516 { 0, 0, 0 }, // imageOffset
2517 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2518 };
2519
2520 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2521
2522 if (tcu::TextureFormat::DS == order)
2523 {
2524 const VkBufferImageCopy stencilRect =
2525 {
2526 0, // bufferOffset
2527 0, // bufferRowLength
2528 0, // bufferImageHeight
2529 { // imageSubresource
2530 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2531 0, // mipLevel
2532 0, // arraySlice
2533 1 // arraySize
2534 },
2535 { 0, 0, 0 }, // imageOffset
2536 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2537 };
2538
2539 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2540 }
2541 }
2542
2543 {
2544 vector<VkBufferMemoryBarrier> bufferBarriers;
2545
2546 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2547 {
2548 if (isLazy[attachmentNdx])
2549 continue;
2550
2551 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2552 const VkBufferMemoryBarrier bufferBarrier =
2553 {
2554 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2555 DE_NULL,
2556
2557 getAllMemoryWriteFlags(),
2558 getAllMemoryReadFlags(),
2559
2560 queueIndex,
2561 queueIndex,
2562
2563 attachmentResources[attachmentNdx]->getBuffer(),
2564 0,
2565 attachmentResources[attachmentNdx]->getBufferSize()
2566 };
2567
2568 bufferBarriers.push_back(bufferBarrier);
2569
2570 if (tcu::TextureFormat::DS == order)
2571 {
2572 const VkBufferMemoryBarrier secondaryBufferBarrier =
2573 {
2574 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2575 DE_NULL,
2576
2577 getAllMemoryWriteFlags(),
2578 getAllMemoryReadFlags(),
2579
2580 queueIndex,
2581 queueIndex,
2582
2583 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2584 0,
2585 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2586 };
2587
2588 bufferBarriers.push_back(secondaryBufferBarrier);
2589 }
2590 }
2591
2592 if (!bufferBarriers.empty())
2593 vk.cmdPipelineBarrier(commandBuffer,
2594 getAllPipelineStageFlags(),
2595 getAllPipelineStageFlags(),
2596 (VkDependencyFlags)0,
2597 0, (const VkMemoryBarrier*)DE_NULL,
2598 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2599 0, (const VkImageMemoryBarrier*)DE_NULL);
2600 }
2601 }
2602
2603 class PixelValue
2604 {
2605 public:
2606 PixelValue (const Maybe<bool>& x = nothing<bool>(),
2607 const Maybe<bool>& y = nothing<bool>(),
2608 const Maybe<bool>& z = nothing<bool>(),
2609 const Maybe<bool>& w = nothing<bool>());
2610
2611 void setUndefined (size_t ndx);
2612 void setValue (size_t ndx, bool value);
2613 Maybe<bool> getValue (size_t ndx) const;
2614
2615 private:
2616 deUint16 m_status;
2617 };
2618
PixelValue(const Maybe<bool> & x,const Maybe<bool> & y,const Maybe<bool> & z,const Maybe<bool> & w)2619 PixelValue::PixelValue (const Maybe<bool>& x,
2620 const Maybe<bool>& y,
2621 const Maybe<bool>& z,
2622 const Maybe<bool>& w)
2623 : m_status (0)
2624 {
2625 const Maybe<bool> values[] =
2626 {
2627 x, y, z, w
2628 };
2629
2630 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
2631 {
2632 if (values[ndx])
2633 setValue(ndx, *values[ndx]);
2634 else
2635 setUndefined(ndx);
2636 }
2637
2638 DE_ASSERT(m_status <= 0xFFu);
2639 }
2640
setUndefined(size_t ndx)2641 void PixelValue::setUndefined (size_t ndx)
2642 {
2643 DE_ASSERT(ndx < 4);
2644 DE_ASSERT(m_status <= 0xFFu);
2645
2646 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
2647 DE_ASSERT(m_status <= 0xFFu);
2648 }
2649
setValue(size_t ndx,bool value)2650 void PixelValue::setValue (size_t ndx, bool value)
2651 {
2652 DE_ASSERT(ndx < 4);
2653 DE_ASSERT(m_status <= 0xFFu);
2654
2655 m_status |= (deUint16)(0x1u << (ndx * 2));
2656
2657 if (value)
2658 m_status |= (deUint16)(0x1u << (ndx * 2 + 1));
2659 else
2660 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
2661
2662 DE_ASSERT(m_status <= 0xFFu);
2663 }
2664
getValue(size_t ndx) const2665 Maybe<bool> PixelValue::getValue (size_t ndx) const
2666 {
2667 DE_ASSERT(ndx < 4);
2668 DE_ASSERT(m_status <= 0xFFu);
2669
2670 if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
2671 {
2672 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
2673 }
2674 else
2675 return nothing<bool>();
2676 }
2677
clearReferenceValues(vector<PixelValue> & values,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size,const BVec4 & mask,const PixelValue & value)2678 void clearReferenceValues (vector<PixelValue>& values,
2679 const UVec2& targetSize,
2680 const UVec2& offset,
2681 const UVec2& size,
2682 const BVec4& mask,
2683 const PixelValue& value)
2684 {
2685 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2686 DE_ASSERT(offset.x() + size.x() <= targetSize.x());
2687 DE_ASSERT(offset.y() + size.y() <= targetSize.y());
2688
2689 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2690 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2691 {
2692 for (int compNdx = 0; compNdx < 4; compNdx++)
2693 {
2694 if (mask[compNdx])
2695 {
2696 if (value.getValue(compNdx))
2697 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
2698 else
2699 values[x + y * targetSize.x()].setUndefined(compNdx);
2700 }
2701 }
2702 }
2703 }
2704
markUndefined(vector<PixelValue> & values,const BVec4 & mask,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size)2705 void markUndefined (vector<PixelValue>& values,
2706 const BVec4& mask,
2707 const UVec2& targetSize,
2708 const UVec2& offset,
2709 const UVec2& size)
2710 {
2711 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2712
2713 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2714 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2715 {
2716 for (int compNdx = 0; compNdx < 4; compNdx++)
2717 {
2718 if (mask[compNdx])
2719 values[x + y * targetSize.x()].setUndefined(compNdx);
2720 }
2721 }
2722 }
2723
clearValueToPixelValue(const VkClearValue & value,const tcu::TextureFormat & format)2724 PixelValue clearValueToPixelValue (const VkClearValue& value,
2725 const tcu::TextureFormat& format)
2726 {
2727 const bool isDepthAttachment = hasDepthComponent(format.order);
2728 const bool isStencilAttachment = hasStencilComponent(format.order);
2729 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
2730 PixelValue pixelValue;
2731
2732 if (isDepthOrStencilAttachment)
2733 {
2734 if (isDepthAttachment)
2735 {
2736 if (value.depthStencil.depth == 1.0f)
2737 pixelValue.setValue(0, true);
2738 else if (value.depthStencil.depth == 0.0f)
2739 pixelValue.setValue(0, false);
2740 else
2741 DE_FATAL("Unknown depth value");
2742 }
2743
2744 if (isStencilAttachment)
2745 {
2746 if (value.depthStencil.stencil == 0xFFu)
2747 pixelValue.setValue(1, true);
2748 else if (value.depthStencil.stencil == 0x0u)
2749 pixelValue.setValue(1, false);
2750 else
2751 DE_FATAL("Unknown stencil value");
2752 }
2753 }
2754 else
2755 {
2756 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2757 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2758
2759 switch (channelClass)
2760 {
2761 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2762 for (int i = 0; i < 4; i++)
2763 {
2764 if (channelMask[i])
2765 {
2766 if (value.color.int32[i] == 1)
2767 pixelValue.setValue(i, true);
2768 else if (value.color.int32[i] == 0)
2769 pixelValue.setValue(i, false);
2770 else
2771 DE_FATAL("Unknown clear color value");
2772 }
2773 }
2774 break;
2775
2776 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2777 for (int i = 0; i < 4; i++)
2778 {
2779 if (channelMask[i])
2780 {
2781 if (value.color.uint32[i] == 1u)
2782 pixelValue.setValue(i, true);
2783 else if (value.color.uint32[i] == 0u)
2784 pixelValue.setValue(i, false);
2785 else
2786 DE_FATAL("Unknown clear color value");
2787 }
2788 }
2789 break;
2790
2791 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2792 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2793 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2794 for (int i = 0; i < 4; i++)
2795 {
2796 if (channelMask[i])
2797 {
2798 if (value.color.float32[i] == 1.0f)
2799 pixelValue.setValue(i, true);
2800 else if (value.color.float32[i] == 0.0f)
2801 pixelValue.setValue(i, false);
2802 else
2803 DE_FATAL("Unknown clear color value");
2804 }
2805 }
2806 break;
2807
2808 default:
2809 DE_FATAL("Unknown channel class");
2810 }
2811 }
2812
2813 return pixelValue;
2814 }
2815
renderReferenceValues(vector<vector<PixelValue>> & referenceAttachments,const RenderPass & renderPassInfo,const UVec2 & targetSize,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo,const UVec2 & renderPos,const UVec2 & renderSize)2816 void renderReferenceValues (vector<vector<PixelValue> >& referenceAttachments,
2817 const RenderPass& renderPassInfo,
2818 const UVec2& targetSize,
2819 const vector<Maybe<VkClearValue> >& imageClearValues,
2820 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2821 const vector<SubpassRenderInfo>& subpassRenderInfo,
2822 const UVec2& renderPos,
2823 const UVec2& renderSize)
2824 {
2825 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
2826 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
2827
2828 referenceAttachments.resize(renderPassInfo.getAttachments().size());
2829
2830 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2831 {
2832 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2833 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2834 vector<PixelValue>& reference = referenceAttachments[attachmentNdx];
2835
2836 reference.resize(targetSize.x() * targetSize.y());
2837
2838 if (imageClearValues[attachmentNdx])
2839 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format));
2840 }
2841
2842 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2843 {
2844 const Subpass& subpass = subpasses[subpassNdx];
2845 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
2846 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
2847
2848 // Apply load op if attachment was used for the first time
2849 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2850 {
2851 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2852
2853 if (!attachmentUsed[attachmentIndex])
2854 {
2855 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2856 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2857 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2858
2859 DE_ASSERT(!tcu::hasDepthComponent(format.order));
2860 DE_ASSERT(!tcu::hasStencilComponent(format.order));
2861
2862 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2863 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2864 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2865 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
2866
2867 attachmentUsed[attachmentIndex] = true;
2868 }
2869 }
2870
2871 // Apply load op to depth/stencil attachment if it was used for the first time
2872 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2873 {
2874 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2875
2876 // Apply load op if attachment was used for the first time
2877 if (!attachmentUsed[attachmentIndex])
2878 {
2879 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2880 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2881 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2882
2883 if (tcu::hasDepthComponent(format.order))
2884 {
2885 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2886 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2887 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2888 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
2889 }
2890
2891 if (tcu::hasStencilComponent(format.order))
2892 {
2893 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2894 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2895 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2896 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
2897 }
2898
2899 attachmentUsed[attachmentIndex] = true;
2900 }
2901 }
2902
2903 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
2904 {
2905 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
2906 const UVec2 offset = colorClear.getOffset();
2907 const UVec2 size = colorClear.getSize();
2908 const deUint32 attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
2909 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2910 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2911 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2912 VkClearValue value;
2913
2914 value.color = colorClear.getColor();
2915
2916 clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format));
2917 }
2918
2919 if (renderInfo.getDepthStencilClear())
2920 {
2921 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
2922 const UVec2 offset = dsClear.getOffset();
2923 const UVec2 size = dsClear.getSize();
2924 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2925 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2926 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2927 const bool hasStencil = tcu::hasStencilComponent(format.order);
2928 const bool hasDepth = tcu::hasDepthComponent(format.order);
2929 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2930 VkClearValue value;
2931
2932 value.depthStencil.depth = dsClear.getDepth();
2933 value.depthStencil.stencil = dsClear.getStencil();
2934
2935 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format));
2936 }
2937
2938 if (renderInfo.getRenderQuad())
2939 {
2940 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
2941 const Vec2 posA = renderQuad.getCornerA();
2942 const Vec2 posB = renderQuad.getCornerB();
2943 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2944 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2945 const IVec2 posAI (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
2946 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
2947 const IVec2 posBI (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
2948 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
2949
2950 DE_ASSERT(posAI.x() < posBI.x());
2951 DE_ASSERT(posAI.y() < posBI.y());
2952
2953 if (subpass.getInputAttachments().empty())
2954 {
2955 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
2956 {
2957 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
2958 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2959 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2960 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2961 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2962
2963 for (int y = posAI.y(); y < (int)posBI.y(); y++)
2964 for (int x = posAI.x(); x < (int)posBI.x(); x++)
2965 {
2966 for (int compNdx = 0; compNdx < 4; compNdx++)
2967 {
2968 const size_t index = subpassNdx + attachmentIndex + compNdx;
2969 const BoolOp op = boolOpFromIndex(index);
2970 const bool boolX = x % 2 == (int)(index % 2);
2971 const bool boolY = y % 2 == (int)((index / 2) % 2);
2972
2973 if (channelMask[compNdx])
2974 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
2975 }
2976 }
2977 }
2978
2979 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2980 {
2981 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2982 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2983 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2984 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2985
2986 for (int y = posAI.y(); y < (int)posBI.y(); y++)
2987 for (int x = posAI.x(); x < (int)posBI.x(); x++)
2988 {
2989 if (tcu::hasDepthComponent(format.order))
2990 {
2991 const size_t index = subpassNdx + 1;
2992 const BoolOp op = boolOpFromIndex(index);
2993 const bool boolX = x % 2 == (int)(index % 2);
2994 const bool boolY = y % 2 == (int)((index / 2) % 2);
2995
2996 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
2997 }
2998
2999 if (tcu::hasStencilComponent(format.order))
3000 {
3001 const size_t index = subpassNdx;
3002 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3003 }
3004 }
3005 }
3006 }
3007 else
3008 {
3009 size_t outputComponentCount = 0;
3010 vector<Maybe<bool> > inputs;
3011
3012 DE_ASSERT(posAI.x() < posBI.x());
3013 DE_ASSERT(posAI.y() < posBI.y());
3014
3015 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3016 {
3017 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3018 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3019 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3020 const int componentCount = tcu::getNumUsedChannels(format.order);
3021
3022 outputComponentCount += (size_t)componentCount;
3023 }
3024
3025 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3026 outputComponentCount++;
3027
3028 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3029 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3030 {
3031 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3032 {
3033 const deUint32 attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3034 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3035 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3036 const int componentCount = tcu::getNumUsedChannels(format.order);
3037
3038 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3039 inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3040 }
3041
3042 const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3043 ? ((inputs.size() / outputComponentCount)
3044 + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3045 : 1;
3046
3047 size_t outputValueNdx = 0;
3048
3049 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3050 {
3051 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3052 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3053 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3054 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3055 const int componentCount = tcu::getNumUsedChannels(format.order);
3056
3057 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3058 {
3059 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3060 const BoolOp op = boolOpFromIndex(index);
3061 const bool boolX = x % 2 == (int)(index % 2);
3062 const bool boolY = y % 2 == (int)((index / 2) % 2);
3063 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3064
3065 for (size_t i = 0; i < inputsPerOutput; i++)
3066 {
3067 if (!output)
3068 break;
3069 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3070 output = tcu::nothing<bool>();
3071 else
3072 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3073 }
3074
3075 if (output)
3076 reference[x + y * targetSize.x()].setValue(compNdx, *output);
3077 else
3078 reference[x + y * targetSize.x()].setUndefined(compNdx);
3079 }
3080
3081 outputValueNdx += componentCount;
3082 }
3083
3084 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3085 {
3086 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3087 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3088 const size_t index = subpassNdx + attachmentIndex;
3089 const BoolOp op = boolOpFromIndex(index);
3090 const bool boolX = x % 2 == (int)(index % 2);
3091 const bool boolY = y % 2 == (int)((index / 2) % 2);
3092 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3093
3094 for (size_t i = 0; i < inputsPerOutput; i++)
3095 {
3096 if (!output)
3097 break;
3098 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3099 output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3100 else
3101 output = tcu::nothing<bool>();
3102 }
3103
3104 if (output)
3105 reference[x + y * targetSize.x()].setValue(0, *output);
3106 else
3107 reference[x + y * targetSize.x()].setUndefined(0);
3108 }
3109
3110 inputs.clear();
3111 }
3112
3113 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3114 {
3115 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3116 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3117 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3118 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3119
3120 if (tcu::hasStencilComponent(format.order))
3121 {
3122 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3123 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3124 {
3125 const size_t index = subpassNdx;
3126 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3127 }
3128 }
3129 }
3130 }
3131 }
3132 }
3133
3134 // Mark all attachments that were used but not stored as undefined
3135 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3136 {
3137 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex];
3138 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3139 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3140 const bool isStencilAttachment = hasStencilComponent(format.order);
3141 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;
3142
3143 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3144 {
3145 if (isDepthOrStencilAttachment)
3146 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3147 else
3148 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3149 }
3150
3151 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3152 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3153 }
3154 }
3155
renderReferenceImagesFromValues(vector<tcu::TextureLevel> & referenceImages,const vector<vector<PixelValue>> & referenceValues,const UVec2 & targetSize,const RenderPass & renderPassInfo)3156 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>& referenceImages,
3157 const vector<vector<PixelValue> >& referenceValues,
3158 const UVec2& targetSize,
3159 const RenderPass& renderPassInfo)
3160 {
3161 referenceImages.resize(referenceValues.size());
3162
3163 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3164 {
3165 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3166 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3167 const vector<PixelValue>& reference = referenceValues[attachmentNdx];
3168 const bool hasDepth = tcu::hasDepthComponent(format.order);
3169 const bool hasStencil = tcu::hasStencilComponent(format.order);
3170 const bool hasDepthOrStencil = hasDepth || hasStencil;
3171 tcu::TextureLevel& referenceImage = referenceImages[attachmentNdx];
3172
3173 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3174
3175 if (hasDepthOrStencil)
3176 {
3177 if (hasDepth)
3178 {
3179 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3180
3181 for (deUint32 y = 0; y < targetSize.y(); y++)
3182 for (deUint32 x = 0; x < targetSize.x(); x++)
3183 {
3184 if (reference[x + y * targetSize.x()].getValue(0))
3185 {
3186 if (*reference[x + y * targetSize.x()].getValue(0))
3187 depthAccess.setPixDepth(1.0f, x, y);
3188 else
3189 depthAccess.setPixDepth(0.0f, x, y);
3190 }
3191 else // Fill with 3x3 grid
3192 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3193 }
3194 }
3195
3196 if (hasStencil)
3197 {
3198 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3199
3200 for (deUint32 y = 0; y < targetSize.y(); y++)
3201 for (deUint32 x = 0; x < targetSize.x(); x++)
3202 {
3203 if (reference[x + y * targetSize.x()].getValue(1))
3204 {
3205 if (*reference[x + y * targetSize.x()].getValue(1))
3206 stencilAccess.setPixStencil(0xFFu, x, y);
3207 else
3208 stencilAccess.setPixStencil(0x0u, x, y);
3209 }
3210 else // Fill with 3x3 grid
3211 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3212 }
3213 }
3214 }
3215 else
3216 {
3217 for (deUint32 y = 0; y < targetSize.y(); y++)
3218 for (deUint32 x = 0; x < targetSize.x(); x++)
3219 {
3220 tcu::Vec4 color;
3221
3222 for (int compNdx = 0; compNdx < 4; compNdx++)
3223 {
3224 if (reference[x + y * targetSize.x()].getValue(compNdx))
3225 {
3226 if (*reference[x + y * targetSize.x()].getValue(compNdx))
3227 color[compNdx] = 1.0f;
3228 else
3229 color[compNdx] = 0.0f;
3230 }
3231 else // Fill with 3x3 grid
3232 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3233 }
3234
3235 referenceImage.getAccess().setPixel(color, x, y);
3236 }
3237 }
3238 }
3239 }
3240
verifyColorAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)3241 bool verifyColorAttachment (const vector<PixelValue>& reference,
3242 const ConstPixelBufferAccess& result,
3243 const PixelBufferAccess& errorImage)
3244 {
3245 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3246 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3247 bool ok = true;
3248
3249 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3250 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3251 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3252
3253 for (int y = 0; y < result.getHeight(); y++)
3254 for (int x = 0; x < result.getWidth(); x++)
3255 {
3256 const Vec4 resultColor = result.getPixel(x, y);
3257 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3258 bool pixelOk = true;
3259
3260 for (int compNdx = 0; compNdx < 4; compNdx++)
3261 {
3262 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
3263
3264 if (maybeValue)
3265 {
3266 const bool value = *maybeValue;
3267
3268 if ((value && (resultColor[compNdx] != 1.0f))
3269 || (!value && resultColor[compNdx] != 0.0f))
3270 pixelOk = false;
3271 }
3272 }
3273
3274 if (!pixelOk)
3275 {
3276 errorImage.setPixel(red, x, y);
3277 ok = false;
3278 }
3279 else
3280 errorImage.setPixel(green, x, y);
3281 }
3282
3283 return ok;
3284 }
3285
verifyDepthAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)3286 bool verifyDepthAttachment (const vector<PixelValue>& reference,
3287 const ConstPixelBufferAccess& result,
3288 const PixelBufferAccess& errorImage)
3289 {
3290 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3291 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3292 bool ok = true;
3293
3294 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3295 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3296 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3297
3298 for (int y = 0; y < result.getHeight(); y++)
3299 for (int x = 0; x < result.getWidth(); x++)
3300 {
3301 bool pixelOk = true;
3302
3303 const float resultDepth = result.getPixDepth(x, y);
3304 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3305 const Maybe<bool> maybeValue = referenceValue.getValue(0);
3306
3307 if (maybeValue)
3308 {
3309 const bool value = *maybeValue;
3310
3311 if ((value && (resultDepth != 1.0f))
3312 || (!value && resultDepth != 0.0f))
3313 pixelOk = false;
3314 }
3315
3316 if (!pixelOk)
3317 {
3318 errorImage.setPixel(red, x, y);
3319 ok = false;
3320 }
3321 else
3322 errorImage.setPixel(green, x, y);
3323 }
3324
3325 return ok;
3326 }
3327
verifyStencilAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)3328 bool verifyStencilAttachment (const vector<PixelValue>& reference,
3329 const ConstPixelBufferAccess& result,
3330 const PixelBufferAccess& errorImage)
3331 {
3332 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3333 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3334 bool ok = true;
3335
3336 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3337 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3338 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3339
3340 for (int y = 0; y < result.getHeight(); y++)
3341 for (int x = 0; x < result.getWidth(); x++)
3342 {
3343 bool pixelOk = true;
3344
3345 const deUint32 resultStencil = result.getPixStencil(x, y);
3346 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3347 const Maybe<bool> maybeValue = referenceValue.getValue(1);
3348
3349 if (maybeValue)
3350 {
3351 const bool value = *maybeValue;
3352
3353 if ((value && (resultStencil != 0xFFu))
3354 || (!value && resultStencil != 0x0u))
3355 pixelOk = false;
3356 }
3357
3358 if (!pixelOk)
3359 {
3360 errorImage.setPixel(red, x, y);
3361 ok = false;
3362 }
3363 else
3364 errorImage.setPixel(green, x, y);
3365 }
3366
3367 return ok;
3368 }
3369
logAndVerifyImages(TestLog & log,const DeviceInterface & vk,VkDevice device,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const vector<bool> & attachmentIsLazy,const RenderPass & renderPassInfo,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo,const UVec2 & targetSize,const TestConfig & config)3370 bool logAndVerifyImages (TestLog& log,
3371 const DeviceInterface& vk,
3372 VkDevice device,
3373 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3374 const vector<bool>& attachmentIsLazy,
3375 const RenderPass& renderPassInfo,
3376 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3377 const vector<Maybe<VkClearValue> >& imageClearValues,
3378 const vector<SubpassRenderInfo>& subpassRenderInfo,
3379 const UVec2& targetSize,
3380 const TestConfig& config)
3381 {
3382 vector<vector<PixelValue> > referenceValues;
3383 vector<tcu::TextureLevel> referenceAttachments;
3384 bool isOk = true;
3385
3386 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
3387
3388 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3389 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo);
3390
3391 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3392 {
3393 if (!attachmentIsLazy[attachmentNdx])
3394 {
3395 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3396 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3397
3398 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3399 {
3400 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3401 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3402 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3403
3404 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3405 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3406 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3407
3408 const VkMappedMemoryRange ranges[] =
3409 {
3410 {
3411 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3412 DE_NULL, // pNext;
3413 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3414 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3415 depthBufferSize // size;
3416 },
3417 {
3418 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3419 DE_NULL, // pNext;
3420 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3421 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3422 stencilBufferSize // size;
3423 }
3424 };
3425 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3426
3427 {
3428 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3429 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3430 tcu::TextureLevel depthErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3431 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3432
3433 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3434 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3435
3436 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3437
3438 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3439 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess()))
3440 {
3441 log << TestLog::Image("DepthAttachmentError" + de::toString(attachmentNdx), "Depth Attachment Error " + de::toString(attachmentNdx), depthErrorImage.getAccess());
3442 isOk = false;
3443 }
3444
3445 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3446 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
3447 {
3448 log << TestLog::Image("StencilAttachmentError" + de::toString(attachmentNdx), "Stencil Attachment Error " + de::toString(attachmentNdx), stencilErrorImage.getAccess());
3449 isOk = false;
3450 }
3451 }
3452 }
3453 else
3454 {
3455 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3456 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3457
3458 const VkMappedMemoryRange range =
3459 {
3460 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3461 DE_NULL, // pNext;
3462 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3463 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3464 bufferSize // size;
3465 };
3466 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3467
3468 if (tcu::hasDepthComponent(format.order))
3469 {
3470 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3471 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3472
3473 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3474 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3475
3476 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3477 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3478 {
3479 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3480 isOk = false;
3481 }
3482 }
3483 else if (tcu::hasStencilComponent(format.order))
3484 {
3485 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3486 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3487
3488 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3489 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3490
3491 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3492 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3493 {
3494 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3495 isOk = false;
3496 }
3497 }
3498 else
3499 {
3500 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3501 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3502
3503 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3504 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3505
3506 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3507 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3508 {
3509 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3510 isOk = false;
3511 }
3512 }
3513 }
3514 }
3515 }
3516
3517 return isOk;
3518 }
3519
getInputAttachmentType(VkFormat vkFormat)3520 std::string getInputAttachmentType (VkFormat vkFormat)
3521 {
3522 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3523 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3524
3525 switch (channelClass)
3526 {
3527 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3528 return "isubpassInput";
3529
3530 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3531 return "usubpassInput";
3532
3533 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3534 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3535 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3536 return "subpassInput";
3537
3538 default:
3539 DE_FATAL("Unknown channel class");
3540 return "";
3541 }
3542 }
3543
getAttachmentType(VkFormat vkFormat)3544 std::string getAttachmentType (VkFormat vkFormat)
3545 {
3546 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3547 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3548
3549 switch (channelClass)
3550 {
3551 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3552 return "ivec4";
3553
3554 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3555 return "uvec4";
3556
3557 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3558 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3559 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3560 return "vec4";
3561
3562 default:
3563 DE_FATAL("Unknown channel class");
3564 return "";
3565 }
3566 }
3567
createTestShaders(SourceCollections & dst,TestConfig config)3568 void createTestShaders (SourceCollections& dst, TestConfig config)
3569 {
3570 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3571 {
3572 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3573
3574 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3575 {
3576 const Subpass& subpass = subpasses[subpassNdx];
3577 deUint32 inputAttachmentBinding = 0;
3578 std::ostringstream vertexShader;
3579 std::ostringstream fragmentShader;
3580
3581 vertexShader << "#version 310 es\n"
3582 << "layout(location = 0) in highp vec2 a_position;\n"
3583 << "void main (void) {\n"
3584 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
3585 << "}\n";
3586
3587 fragmentShader << "#version 310 es\n"
3588 << "precision highp float;\n";
3589
3590 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3591 {
3592 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3593 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3594 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3595 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3596 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3597
3598 if (isDepthFormat || isStencilFormat)
3599 {
3600 if (isDepthFormat)
3601 {
3602 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
3603 inputAttachmentBinding++;
3604 }
3605
3606 if (isStencilFormat)
3607 {
3608 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
3609 inputAttachmentBinding++;
3610 }
3611 }
3612 else
3613 {
3614 const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
3615
3616 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
3617 inputAttachmentBinding++;
3618 }
3619 }
3620
3621 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3622 {
3623 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3624 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3625 }
3626
3627 fragmentShader << "void main (void) {\n";
3628
3629 if (subpass.getInputAttachments().empty())
3630 {
3631 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3632 {
3633 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3634 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3635
3636 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4(";
3637
3638 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3639 {
3640 const size_t index = subpassNdx + attachmentIndex + compNdx;
3641 const BoolOp op = boolOpFromIndex(index);
3642
3643 if (compNdx > 0)
3644 fragmentShader << ",\n\t\t";
3645
3646 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2)
3647 << ") " << boolOpToString(op) << " ("
3648 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3649 << ") ? 1.0 : 0.0)";
3650 }
3651
3652 fragmentShader << "));\n";
3653 }
3654
3655 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3656 {
3657 const size_t index = subpassNdx + 1;
3658 const BoolOp op = boolOpFromIndex(index);
3659
3660 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
3661 << ") " << boolOpToString(op) << " ("
3662 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3663 << ") ? 1.0 : 0.0);\n";
3664 }
3665 }
3666 else
3667 {
3668 size_t inputComponentCount = 0;
3669 size_t outputComponentCount = 0;
3670
3671 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3672 {
3673 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3674 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3675 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3676 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3677
3678 inputComponentCount += componentCount;
3679 }
3680
3681 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3682 {
3683 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3684 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3685 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3686 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3687
3688 outputComponentCount += componentCount;
3689 }
3690
3691 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3692 outputComponentCount++;
3693
3694 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
3695 ? ((inputComponentCount / outputComponentCount)
3696 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
3697 : 1;
3698
3699 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n"
3700 "\tbool outputs[" << outputComponentCount << "];\n";
3701
3702 size_t inputValueNdx = 0;
3703
3704 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3705 {
3706 const char* const components[] =
3707 {
3708 "x", "y", "z", "w"
3709 };
3710 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3711 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3712 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3713 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3714 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3715 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3716
3717 if (isDepthFormat || isStencilFormat)
3718 {
3719 if (isDepthFormat)
3720 {
3721 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_depth" << attachmentNdx << ").x);\n";
3722 inputValueNdx++;
3723 }
3724
3725 if (isStencilFormat)
3726 {
3727 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
3728 inputValueNdx++;
3729 }
3730 }
3731 else
3732 {
3733 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3734 {
3735 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
3736 inputValueNdx++;
3737 }
3738 }
3739 }
3740
3741 size_t outputValueNdx = 0;
3742
3743 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3744 {
3745 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3746 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3747 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3748 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3749 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3750
3751 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3752 {
3753 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3754 const BoolOp op = boolOpFromIndex(index);
3755
3756 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
3757 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3758 << ") " << boolOpToString(op) << " ("
3759 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3760 << ");\n";
3761
3762 for (size_t i = 0; i < inputsPerOutput; i++)
3763 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount << "];\n";
3764 }
3765
3766 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
3767
3768 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3769 {
3770 if (compNdx > 0)
3771 fragmentShader << ", ";
3772
3773 if (compNdx < componentCount)
3774 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
3775 else
3776 fragmentShader << "0";
3777 }
3778
3779 outputValueNdx += componentCount;
3780
3781 fragmentShader << ");\n";
3782 }
3783
3784 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3785 {
3786 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3787 const size_t index = subpassNdx + attachmentIndex;
3788 const BoolOp op = boolOpFromIndex(index);
3789
3790 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
3791 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3792 << ") " << boolOpToString(op) << " ("
3793 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3794 << ");\n";
3795
3796 for (size_t i = 0; i < inputsPerOutput; i++)
3797 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";
3798
3799 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? 1.0 : 0.0;";
3800 }
3801 }
3802
3803 fragmentShader << "}\n";
3804
3805 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3806 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3807 }
3808 }
3809 }
3810
initializeAttachmentIsLazy(vector<bool> & attachmentIsLazy,const vector<Attachment> & attachments,TestConfig::ImageMemory imageMemory)3811 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3812 {
3813 bool lastAttachmentWasLazy = false;
3814
3815 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3816 {
3817 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3818 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3819 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3820 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3821 {
3822 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3823 {
3824 attachmentIsLazy.push_back(true);
3825 lastAttachmentWasLazy = true;
3826 }
3827 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3828 {
3829 attachmentIsLazy.push_back(false);
3830 lastAttachmentWasLazy = false;
3831 }
3832 else
3833 DE_FATAL("Unknown imageMemory");
3834 }
3835 else
3836 attachmentIsLazy.push_back(false);
3837 }
3838 }
3839
3840 enum AttachmentRefType
3841 {
3842 ATTACHMENTREFTYPE_COLOR,
3843 ATTACHMENTREFTYPE_DEPTH_STENCIL,
3844 ATTACHMENTREFTYPE_INPUT,
3845 ATTACHMENTREFTYPE_RESOLVE,
3846 };
3847
getImageUsageFromLayout(VkImageLayout layout)3848 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
3849 {
3850 switch (layout)
3851 {
3852 case VK_IMAGE_LAYOUT_GENERAL:
3853 case VK_IMAGE_LAYOUT_PREINITIALIZED:
3854 return 0;
3855
3856 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
3857 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3858
3859 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
3860 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
3861 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3862
3863 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
3864 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3865
3866 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3867 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3868
3869 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3870 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3871
3872 default:
3873 DE_FATAL("Unexpected image layout");
3874 return 0;
3875 }
3876 }
3877
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,size_t count,const AttachmentReference * references)3878 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
3879 {
3880 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
3881 {
3882 const deUint32 attachment = references[referenceNdx].getAttachment();
3883
3884 if (attachment != VK_ATTACHMENT_UNUSED)
3885 {
3886 VkImageUsageFlags usage;
3887
3888 switch (refType)
3889 {
3890 case ATTACHMENTREFTYPE_COLOR:
3891 case ATTACHMENTREFTYPE_RESOLVE:
3892 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3893 break;
3894
3895 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
3896 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3897 break;
3898
3899 case ATTACHMENTREFTYPE_INPUT:
3900 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3901 break;
3902
3903 default:
3904 DE_FATAL("Unexpected attachment reference type");
3905 usage = 0;
3906 break;
3907 }
3908
3909 attachmentImageUsage[attachment] |= usage;
3910 }
3911 }
3912 }
3913
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,const vector<AttachmentReference> & references)3914 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
3915 {
3916 if (!references.empty())
3917 {
3918 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
3919 }
3920 }
3921
initializeAttachmentImageUsage(Context & context,vector<VkImageUsageFlags> & attachmentImageUsage,const RenderPass & renderPassInfo,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & clearValues)3922 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
3923 {
3924 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
3925
3926 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
3927 {
3928 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
3929
3930 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
3931 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
3932 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
3933 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
3934 }
3935
3936 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3937 {
3938 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
3939 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
3940 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
3941
3942 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
3943 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
3944
3945 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
3946 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
3947
3948 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
3949 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
3950
3951 if (!attachmentIsLazy[attachmentNdx])
3952 {
3953 if (clearValues[attachmentNdx])
3954 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3955
3956 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3957 }
3958 }
3959 }
3960
initializeSubpassIsSecondary(vector<bool> & subpassIsSecondary,const vector<Subpass> & subpasses,TestConfig::CommandBufferTypes commandBuffer)3961 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
3962 {
3963 bool lastSubpassWasSecondary = false;
3964
3965 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3966 {
3967 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
3968 {
3969 subpassIsSecondary.push_back(true);
3970 lastSubpassWasSecondary = true;
3971 }
3972 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
3973 {
3974 subpassIsSecondary.push_back(false);
3975 lastSubpassWasSecondary = false;
3976 }
3977 else
3978 DE_FATAL("Unknown commandBuffer");
3979 }
3980 }
3981
initializeImageClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,const vector<bool> & isLazy)3982 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
3983 {
3984 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3985 {
3986 if (!isLazy[attachmentNdx])
3987 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3988 else
3989 clearValues.push_back(nothing<VkClearValue>());
3990 }
3991 }
3992
initializeRenderPassClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments)3993 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
3994 {
3995 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3996 {
3997 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
3998 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3999 {
4000 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
4001 }
4002 else
4003 clearValues.push_back(nothing<VkClearValue>());
4004 }
4005 }
4006
initializeSubpassClearValues(de::Random & rng,vector<vector<VkClearColorValue>> & clearValues,const RenderPass & renderPass)4007 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
4008 {
4009 clearValues.resize(renderPass.getSubpasses().size());
4010
4011 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4012 {
4013 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
4014 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4015
4016 clearValues[subpassNdx].resize(colorAttachments.size());
4017
4018 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4019 {
4020 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4021 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4022
4023 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
4024 }
4025 }
4026 }
4027
logSubpassRenderInfo(TestLog & log,const SubpassRenderInfo & info)4028 void logSubpassRenderInfo (TestLog& log,
4029 const SubpassRenderInfo& info)
4030 {
4031 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4032
4033 if (info.isSecondary())
4034 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4035 else
4036 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4037
4038 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4039 {
4040 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
4041
4042 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4043 << ". Offset: " << colorClear.getOffset()
4044 << ", Size: " << colorClear.getSize()
4045 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
4046 }
4047
4048 if (info.getDepthStencilClear())
4049 {
4050 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
4051
4052 log << TestLog::Message << "Clearing depth stencil attachment"
4053 << ". Offset: " << depthStencilClear.getOffset()
4054 << ", Size: " << depthStencilClear.getSize()
4055 << ", Depth: " << depthStencilClear.getDepth()
4056 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4057 }
4058
4059 if (info.getRenderQuad())
4060 {
4061 const RenderQuad& renderQuad = *info.getRenderQuad();
4062
4063 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4064 }
4065 }
4066
logTestCaseInfo(TestLog & log,const TestConfig & config,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo)4067 void logTestCaseInfo (TestLog& log,
4068 const TestConfig& config,
4069 const vector<bool>& attachmentIsLazy,
4070 const vector<Maybe<VkClearValue> >& imageClearValues,
4071 const vector<Maybe<VkClearValue> >& renderPassClearValues,
4072 const vector<SubpassRenderInfo>& subpassRenderInfo)
4073 {
4074 const RenderPass& renderPass = config.renderPass;
4075
4076 logRenderPassInfo(log, renderPass);
4077
4078 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4079 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4080 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4081
4082 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4083 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4084
4085 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4086 {
4087 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4088
4089 if (attachmentIsLazy[attachmentNdx])
4090 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4091
4092 if (imageClearValues[attachmentNdx])
4093 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
4094
4095 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4096 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
4097 }
4098
4099 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4100 {
4101 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4102
4103 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
4104 }
4105 }
4106
roundToViewport(float x,deUint32 offset,deUint32 size)4107 float roundToViewport (float x, deUint32 offset, deUint32 size)
4108 {
4109 const float origin = (float)(offset) + ((float(size) / 2.0f));
4110 const float p = (float)(size) / 2.0f;
4111 const deInt32 xi = deRoundFloatToInt32(origin + (p * x));
4112
4113 return (((float)xi) - origin) / p;
4114 }
4115
initializeSubpassRenderInfo(vector<SubpassRenderInfo> & renderInfos,de::Random & rng,const RenderPass & renderPass,const TestConfig & config)4116 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4117 {
4118 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
4119 const vector<Subpass>& subpasses = renderPass.getSubpasses();
4120 bool lastSubpassWasSecondary = false;
4121
4122 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
4123 {
4124 const Subpass& subpass = subpasses[subpassNdx];
4125 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
4126 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
4127 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
4128 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
4129 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
4130
4131 vector<ColorClear> colorClears;
4132 Maybe<DepthStencilClear> depthStencilClear;
4133 Maybe<RenderQuad> renderQuad;
4134
4135 lastSubpassWasSecondary = subpassIsSecondary;
4136
4137 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
4138 {
4139 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4140
4141 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4142 {
4143 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4144 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4145 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4146 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
4147 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
4148 const VkClearColorValue color = randomColorClearValue(attachment, rng);
4149
4150 colorClears.push_back(ColorClear(offset, size, color));
4151 }
4152
4153 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
4154 {
4155 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
4156 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4157 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
4158 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
4159 const VkClearValue value = randomClearValue(attachment, rng);
4160
4161 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
4162 }
4163 }
4164
4165 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4166 {
4167 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
4168 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
4169
4170 const float x0 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
4171 const float x1 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
4172
4173 const float y0 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
4174 const float y1 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
4175
4176 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
4177 }
4178
4179 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
4180 }
4181 }
4182
checkTextureFormatSupport(TestLog & log,const InstanceInterface & vk,VkPhysicalDevice device,const vector<Attachment> & attachments)4183 void checkTextureFormatSupport (TestLog& log,
4184 const InstanceInterface& vk,
4185 VkPhysicalDevice device,
4186 const vector<Attachment>& attachments)
4187 {
4188 bool supported = true;
4189
4190 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4191 {
4192 const Attachment& attachment = attachments[attachmentNdx];
4193 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4194 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
4195 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
4196 VkFormatProperties properties;
4197
4198 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
4199
4200 if ((properties.optimalTilingFeatures & flags) != flags)
4201 {
4202 supported = false;
4203 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
4204 }
4205 }
4206
4207 if (!supported)
4208 TCU_THROW(NotSupportedError, "Format not supported");
4209 }
4210
renderPassTest(Context & context,TestConfig config)4211 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
4212 {
4213 const UVec2 targetSize = config.targetSize;
4214 const UVec2 renderPos = config.renderPos;
4215 const UVec2 renderSize = config.renderSize;
4216 const RenderPass& renderPassInfo = config.renderPass;
4217
4218 TestLog& log = context.getTestContext().getLog();
4219 de::Random rng (config.seed);
4220
4221 vector<bool> attachmentIsLazy;
4222 vector<VkImageUsageFlags> attachmentImageUsage;
4223 vector<Maybe<VkClearValue> > imageClearValues;
4224 vector<Maybe<VkClearValue> > renderPassClearValues;
4225
4226 vector<bool> subpassIsSecondary;
4227 vector<SubpassRenderInfo> subpassRenderInfo;
4228 vector<vector<VkClearColorValue> > subpassColorClearValues;
4229
4230 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
4231 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
4232 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
4233 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
4234
4235 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
4236 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
4237 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
4238
4239 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
4240
4241 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
4242
4243 {
4244 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
4245
4246 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
4247
4248 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4249 {
4250 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
4251 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
4252 }
4253 }
4254
4255 {
4256 const VkDevice device = context.getDevice();
4257 const DeviceInterface& vk = context.getDeviceInterface();
4258 const VkQueue queue = context.getUniversalQueue();
4259 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
4260 Allocator& allocator = context.getDefaultAllocator();
4261
4262 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
4263 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
4264 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4265 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4266 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4267
4268 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
4269 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
4270 vector<VkImage> attachmentImages;
4271 vector<VkImageView> attachmentViews;
4272 vector<pair<VkImageView, VkImageView> > inputAttachmentViews;
4273
4274 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4275 {
4276 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
4277
4278 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx])));
4279 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
4280 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
4281
4282 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
4283 }
4284
4285 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4286 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
4287 endCommandBuffer(vk, *initializeImagesCommandBuffer);
4288
4289 {
4290 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
4291
4292 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4293 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews, subpassRenderInfo[subpassNdx], config.renderPass.getAttachments())));
4294
4295 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4296 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
4297 endCommandBuffer(vk, *renderCommandBuffer);
4298
4299 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4300 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
4301 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
4302 {
4303 const VkCommandBuffer commandBuffers[] =
4304 {
4305 *initializeImagesCommandBuffer,
4306 *renderCommandBuffer,
4307 *readImagesToBuffersCommandBuffer
4308 };
4309 const Unique<VkFence> fence (createFence(vk, device, 0u));
4310
4311 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
4312 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
4313 }
4314 }
4315
4316 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
4317 return tcu::TestStatus::pass("Pass");
4318 else
4319 return tcu::TestStatus::fail("Result verification failed");
4320 }
4321 }
4322
4323 static const VkFormat s_coreColorFormats[] =
4324 {
4325 VK_FORMAT_R5G6B5_UNORM_PACK16,
4326 VK_FORMAT_R8_UNORM,
4327 VK_FORMAT_R8_SNORM,
4328 VK_FORMAT_R8_UINT,
4329 VK_FORMAT_R8_SINT,
4330 VK_FORMAT_R8G8_UNORM,
4331 VK_FORMAT_R8G8_SNORM,
4332 VK_FORMAT_R8G8_UINT,
4333 VK_FORMAT_R8G8_SINT,
4334 VK_FORMAT_R8G8B8A8_UNORM,
4335 VK_FORMAT_R8G8B8A8_SNORM,
4336 VK_FORMAT_R8G8B8A8_UINT,
4337 VK_FORMAT_R8G8B8A8_SINT,
4338 VK_FORMAT_R8G8B8A8_SRGB,
4339 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
4340 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
4341 VK_FORMAT_A8B8G8R8_UINT_PACK32,
4342 VK_FORMAT_A8B8G8R8_SINT_PACK32,
4343 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
4344 VK_FORMAT_B8G8R8A8_UNORM,
4345 VK_FORMAT_B8G8R8A8_SRGB,
4346 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
4347 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
4348 VK_FORMAT_A2B10G10R10_UINT_PACK32,
4349 VK_FORMAT_R16_UNORM,
4350 VK_FORMAT_R16_SNORM,
4351 VK_FORMAT_R16_UINT,
4352 VK_FORMAT_R16_SINT,
4353 VK_FORMAT_R16_SFLOAT,
4354 VK_FORMAT_R16G16_UNORM,
4355 VK_FORMAT_R16G16_SNORM,
4356 VK_FORMAT_R16G16_UINT,
4357 VK_FORMAT_R16G16_SINT,
4358 VK_FORMAT_R16G16_SFLOAT,
4359 VK_FORMAT_R16G16B16A16_UNORM,
4360 VK_FORMAT_R16G16B16A16_SNORM,
4361 VK_FORMAT_R16G16B16A16_UINT,
4362 VK_FORMAT_R16G16B16A16_SINT,
4363 VK_FORMAT_R16G16B16A16_SFLOAT,
4364 VK_FORMAT_R32_UINT,
4365 VK_FORMAT_R32_SINT,
4366 VK_FORMAT_R32_SFLOAT,
4367 VK_FORMAT_R32G32_UINT,
4368 VK_FORMAT_R32G32_SINT,
4369 VK_FORMAT_R32G32_SFLOAT,
4370 VK_FORMAT_R32G32B32A32_UINT,
4371 VK_FORMAT_R32G32B32A32_SINT,
4372 VK_FORMAT_R32G32B32A32_SFLOAT
4373 };
4374
4375 static const VkFormat s_coreDepthStencilFormats[] =
4376 {
4377 VK_FORMAT_D16_UNORM,
4378
4379 VK_FORMAT_X8_D24_UNORM_PACK32,
4380 VK_FORMAT_D32_SFLOAT,
4381
4382 VK_FORMAT_D24_UNORM_S8_UINT,
4383 VK_FORMAT_D32_SFLOAT_S8_UINT
4384 };
4385
addAttachmentTests(tcu::TestCaseGroup * group)4386 void addAttachmentTests (tcu::TestCaseGroup* group)
4387 {
4388 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
4389 const VkAttachmentLoadOp loadOps[] =
4390 {
4391 VK_ATTACHMENT_LOAD_OP_LOAD,
4392 VK_ATTACHMENT_LOAD_OP_CLEAR,
4393 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4394 };
4395
4396 const VkAttachmentStoreOp storeOps[] =
4397 {
4398 VK_ATTACHMENT_STORE_OP_STORE,
4399 VK_ATTACHMENT_STORE_OP_DONT_CARE
4400 };
4401
4402 const VkImageLayout initialAndFinalColorLayouts[] =
4403 {
4404 VK_IMAGE_LAYOUT_GENERAL,
4405 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4406 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4407 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4408 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4409 };
4410
4411 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4412 {
4413 VK_IMAGE_LAYOUT_GENERAL,
4414 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4415 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4416 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4417 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4418 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4419 };
4420
4421 const VkImageLayout subpassLayouts[] =
4422 {
4423 VK_IMAGE_LAYOUT_GENERAL,
4424 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4425 };
4426
4427 const VkImageLayout depthStencilLayouts[] =
4428 {
4429 VK_IMAGE_LAYOUT_GENERAL,
4430 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
4431 };
4432
4433 const TestConfig::RenderTypes renderCommands[] =
4434 {
4435 TestConfig::RENDERTYPES_NONE,
4436 TestConfig::RENDERTYPES_CLEAR,
4437 TestConfig::RENDERTYPES_DRAW,
4438 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4439 };
4440
4441 const TestConfig::CommandBufferTypes commandBuffers[] =
4442 {
4443 TestConfig::COMMANDBUFFERTYPES_INLINE,
4444 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4445 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4446 };
4447
4448 const TestConfig::ImageMemory imageMemories[] =
4449 {
4450 TestConfig::IMAGEMEMORY_STRICT,
4451 TestConfig::IMAGEMEMORY_LAZY,
4452 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4453 };
4454
4455 const UVec2 targetSizes[] =
4456 {
4457 UVec2(64, 64),
4458 UVec2(63, 65)
4459 };
4460
4461 const UVec2 renderPositions[] =
4462 {
4463 UVec2(0, 0),
4464 UVec2(3, 17)
4465 };
4466
4467 const UVec2 renderSizes[] =
4468 {
4469 UVec2(32, 32),
4470 UVec2(60, 47)
4471 };
4472
4473 tcu::TestContext& testCtx = group->getTestContext();
4474 de::Random rng (1433774382u);
4475
4476 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
4477 {
4478 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
4479 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
4480 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
4481
4482 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4483 {
4484 const bool useDepthStencil = rng.getBool();
4485 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
4486 vector<Attachment> attachments;
4487 vector<AttachmentReference> colorAttachmentReferences;
4488
4489 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4490 {
4491 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4492 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4493 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4494 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4495
4496 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4497 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4498 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4499
4500 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4501 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4502
4503 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4504 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4505 }
4506
4507 if (useDepthStencil)
4508 {
4509 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4510 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4511 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4512 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4513
4514 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4515 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4516
4517 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4518 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4519
4520 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
4521 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4522 }
4523
4524 {
4525 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4526 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4527 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4528 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference((useDepthStencil ? (deUint32)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED), depthStencilLayout), vector<deUint32>()));
4529 const vector<SubpassDependency> deps;
4530
4531 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
4532 const RenderPass renderPass (attachments, subpasses, deps);
4533 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4534 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4535 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4536
4537 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809));
4538 }
4539 }
4540
4541 group->addChild(attachmentCountGroup.release());
4542 }
4543 }
4544
4545 template<typename T>
chooseRandom(de::Random & rng,const set<T> & values)4546 T chooseRandom (de::Random& rng, const set<T>& values)
4547 {
4548 size_t ndx = ((size_t)rng.getUint32()) % values.size();
4549 typename set<T>::const_iterator iter = values.begin();
4550
4551 for (; ndx > 0; ndx--)
4552 iter++;
4553
4554 return *iter;
4555 }
4556
addAttachmentAllocationTests(tcu::TestCaseGroup * group)4557 void addAttachmentAllocationTests (tcu::TestCaseGroup* group)
4558 {
4559 const deUint32 attachmentCounts[] = { 4, 8 };
4560 const VkAttachmentLoadOp loadOps[] =
4561 {
4562 VK_ATTACHMENT_LOAD_OP_LOAD,
4563 VK_ATTACHMENT_LOAD_OP_CLEAR,
4564 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4565 };
4566
4567 const VkAttachmentStoreOp storeOps[] =
4568 {
4569 VK_ATTACHMENT_STORE_OP_STORE,
4570 VK_ATTACHMENT_STORE_OP_DONT_CARE
4571 };
4572
4573 const VkImageLayout initialAndFinalColorLayouts[] =
4574 {
4575 VK_IMAGE_LAYOUT_GENERAL,
4576 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4577 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4578 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4579 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4580 };
4581
4582 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4583 {
4584 VK_IMAGE_LAYOUT_GENERAL,
4585 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4586 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4587 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4588 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4589 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4590 };
4591
4592 const VkImageLayout subpassLayouts[] =
4593 {
4594 VK_IMAGE_LAYOUT_GENERAL,
4595 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4596 };
4597
4598 enum AllocationType
4599 {
4600 // Each pass uses one more attachmen than previous one
4601 ALLOCATIONTYPE_GROW,
4602 // Each pass uses one less attachment than previous one
4603 ALLOCATIONTYPE_SHRINK,
4604 // Each pass drops one attachment and picks up new one
4605 ALLOCATIONTYPE_ROLL,
4606 // Start by growing and end by shrinking
4607 ALLOCATIONTYPE_GROW_SHRINK,
4608 // Each subpass has single input and single output attachment
4609 ALLOCATIONTYPE_IO_CHAIN,
4610 // Each subpass has multiple inputs and multiple outputs attachment
4611 ALLOCATIONTYPE_IO_GENERIC
4612 };
4613
4614 const AllocationType allocationTypes[] =
4615 {
4616 ALLOCATIONTYPE_GROW,
4617 ALLOCATIONTYPE_SHRINK,
4618 ALLOCATIONTYPE_ROLL,
4619 ALLOCATIONTYPE_GROW_SHRINK,
4620 ALLOCATIONTYPE_IO_CHAIN,
4621 ALLOCATIONTYPE_IO_GENERIC
4622 };
4623
4624 const char* const allocationTypeStr[] =
4625 {
4626 "grow",
4627 "shrink",
4628 "roll",
4629 "grow_shrink",
4630 "input_output_chain",
4631 "input_output",
4632 };
4633
4634 const TestConfig::RenderTypes renderCommands[] =
4635 {
4636 TestConfig::RENDERTYPES_NONE,
4637 TestConfig::RENDERTYPES_CLEAR,
4638 TestConfig::RENDERTYPES_DRAW,
4639 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4640 };
4641
4642 const TestConfig::CommandBufferTypes commandBuffers[] =
4643 {
4644 TestConfig::COMMANDBUFFERTYPES_INLINE,
4645 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4646 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4647 };
4648
4649 const TestConfig::ImageMemory imageMemories[] =
4650 {
4651 TestConfig::IMAGEMEMORY_STRICT,
4652 TestConfig::IMAGEMEMORY_LAZY,
4653 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4654 };
4655
4656 const UVec2 targetSizes[] =
4657 {
4658 UVec2(64, 64),
4659 UVec2(63, 65)
4660 };
4661
4662 const UVec2 renderPositions[] =
4663 {
4664 UVec2(0, 0),
4665 UVec2(3, 17)
4666 };
4667
4668 const UVec2 renderSizes[] =
4669 {
4670 UVec2(32, 32),
4671 UVec2(60, 47)
4672 };
4673
4674 tcu::TestContext& testCtx = group->getTestContext();
4675 de::Random rng (3700649827u);
4676
4677 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4678 {
4679 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4680 const size_t testCaseCount = 100;
4681 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4682
4683 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4684 {
4685 if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
4686 {
4687 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u;
4688 const deUint32 subpassCount = 4u + rng.getUint32() % 31u;
4689 vector<Attachment> attachments;
4690
4691 set<deUint32> definedAttachments;
4692
4693 vector<Subpass> subpasses;
4694 set<deUint32> colorAttachments;
4695 set<deUint32> depthStencilAttachments;
4696
4697 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
4698 {
4699 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f;
4700 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4701 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4702 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4703
4704 const VkImageLayout initialLayout = isDepthStencilAttachment
4705 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4706 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4707 const VkImageLayout finalizeLayout = isDepthStencilAttachment
4708 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4709 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4710
4711 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4712 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4713
4714 if (isDepthStencilAttachment)
4715 {
4716 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4717
4718 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
4719 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4720 definedAttachments.insert(attachmentIndex);
4721
4722 depthStencilAttachments.insert(attachmentIndex);
4723
4724 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4725 }
4726 else
4727 {
4728 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4729
4730 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4731 definedAttachments.insert(attachmentIndex);
4732
4733 colorAttachments.insert(attachmentIndex);
4734
4735 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4736 }
4737 }
4738 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), nothing<deUint32>());
4739 vector<SubpassDependency> deps;
4740
4741 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
4742 {
4743 const deUint32 colorAttachmentCount = depthStencilAttachments.empty()
4744 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
4745 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
4746 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
4747 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
4748 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount);
4749 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount);
4750 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment
4751 ? just(chooseRandom(rng, depthStencilAttachments))
4752 : nothing<deUint32>());
4753 std::vector<deUint32> subpassPreserveAttachments;
4754
4755 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
4756 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
4757
4758 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
4759 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
4760
4761 if (depthStencilAttachment)
4762 definedAttachments.insert(*depthStencilAttachment);
4763
4764 {
4765 std::vector<AttachmentReference> inputAttachmentReferences;
4766 std::vector<AttachmentReference> colorAttachmentReferences;
4767 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
4768
4769 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
4770 {
4771 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];
4772 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
4773 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
4774
4775 if (lastUseOfAttachment[colorAttachmentIndex])
4776 {
4777 const bool byRegion = rng.getBool();
4778
4779 deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex,
4780 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4781 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4782 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4783 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4784
4785 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4786 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4787 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4788 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4789
4790 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4791 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
4792
4793 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
4794 }
4795
4796 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
4797
4798 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout));
4799 }
4800
4801 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
4802 {
4803 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];
4804 // \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts
4805 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
4806
4807 if(lastUseOfAttachment[inputAttachmentIndex])
4808 {
4809 if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex)
4810 {
4811 deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
4812 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4813 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4814 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4815 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4816
4817 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4818 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4819 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4820 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4821
4822 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4823 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4824
4825 VK_DEPENDENCY_BY_REGION_BIT));
4826 }
4827 else
4828 {
4829 const bool byRegion = rng.getBool();
4830
4831 deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex,
4832 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4833 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4834 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4835 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4836
4837 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4838 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4839 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4840 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4841
4842 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4843 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4844
4845 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
4846 }
4847
4848 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
4849
4850 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout));
4851 }
4852 }
4853
4854 if (depthStencilAttachment)
4855 {
4856 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
4857 if (lastUseOfAttachment[*depthStencilAttachment])
4858 {
4859 if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex)
4860 {
4861 deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
4862 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4863 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4864 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4865 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4866
4867 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4868 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4869 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4870 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4871
4872 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4873 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4874
4875 VK_DEPENDENCY_BY_REGION_BIT));
4876 }
4877 else
4878 {
4879 const bool byRegion = rng.getBool();
4880
4881 deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex,
4882 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4883 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4884 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4885 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4886
4887 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4888 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4889 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4890 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4891
4892 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4893 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4894
4895 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
4896 }
4897 }
4898
4899 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
4900 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
4901 }
4902 else
4903 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
4904
4905 vector<deUint32> preserveAttachments;
4906 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
4907 {
4908 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
4909 preserveAttachments.push_back(attachmentIndex);
4910 }
4911
4912 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
4913 inputAttachmentReferences,
4914 colorAttachmentReferences,
4915 vector<AttachmentReference>(),
4916 depthStencilAttachmentReference,
4917 preserveAttachments));
4918 }
4919 }
4920 {
4921 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4922 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4923 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4924
4925 const string testCaseName = de::toString(testCaseNdx);
4926 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4927 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4928 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4929
4930 const RenderPass renderPass (attachments, subpasses, deps);
4931
4932 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
4933 }
4934 }
4935 else
4936 {
4937 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
4938 vector<Attachment> attachments;
4939 vector<Subpass> subpasses;
4940
4941 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4942 {
4943 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4944 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4945 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4946 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4947
4948 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4949 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4950
4951 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4952 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4953
4954 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4955 }
4956
4957 if (allocationType == ALLOCATIONTYPE_GROW)
4958 {
4959 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4960 {
4961 vector<AttachmentReference> colorAttachmentReferences;
4962
4963 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4964 {
4965 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4966
4967 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4968 }
4969
4970 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
4971 vector<AttachmentReference>(),
4972 colorAttachmentReferences,
4973 vector<AttachmentReference>(),
4974 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4975 vector<deUint32>()));
4976 }
4977 }
4978 else if (allocationType == ALLOCATIONTYPE_SHRINK)
4979 {
4980 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4981 {
4982 vector<AttachmentReference> colorAttachmentReferences;
4983
4984 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4985 {
4986 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4987
4988 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4989 }
4990
4991 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
4992 vector<AttachmentReference>(),
4993 colorAttachmentReferences,
4994 vector<AttachmentReference>(),
4995 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4996 vector<deUint32>()));
4997 }
4998 }
4999 else if (allocationType == ALLOCATIONTYPE_ROLL)
5000 {
5001 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
5002 {
5003 vector<AttachmentReference> colorAttachmentReferences;
5004
5005 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
5006 {
5007 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5008
5009 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
5010 }
5011
5012 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5013 vector<AttachmentReference>(),
5014 colorAttachmentReferences,
5015 vector<AttachmentReference>(),
5016 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5017 vector<deUint32>()));
5018 }
5019 }
5020 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
5021 {
5022 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5023 {
5024 vector<AttachmentReference> colorAttachmentReferences;
5025
5026 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5027 {
5028 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5029
5030 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5031 }
5032
5033 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5034 vector<AttachmentReference>(),
5035 colorAttachmentReferences,
5036 vector<AttachmentReference>(),
5037 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5038 vector<deUint32>()));
5039 }
5040
5041 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5042 {
5043 vector<AttachmentReference> colorAttachmentReferences;
5044
5045 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5046 {
5047 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5048
5049 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5050 }
5051
5052 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5053 vector<AttachmentReference>(),
5054 colorAttachmentReferences,
5055 vector<AttachmentReference>(),
5056 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5057 vector<deUint32>()));
5058 }
5059 }
5060 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
5061 {
5062 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5063 vector<AttachmentReference>(),
5064 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5065 vector<AttachmentReference>(),
5066 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5067 vector<deUint32>()));
5068
5069 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
5070 {
5071 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5072 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5073 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5074 vector<AttachmentReference>(),
5075 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5076 vector<deUint32>()));
5077 }
5078 }
5079 else
5080 DE_FATAL("Unknown allocation type");
5081
5082 {
5083 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5084 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5085 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5086
5087 const string testCaseName = de::toString(testCaseNdx);
5088 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5089 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5090 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5091
5092 vector<SubpassDependency> deps;
5093
5094 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
5095 {
5096 const bool byRegion = rng.getBool();
5097 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
5098 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5099 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5100 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5101 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5102
5103 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5104 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5105 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5106 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5107
5108 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5109 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5110
5111 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5112 }
5113
5114 const RenderPass renderPass (attachments, subpasses, deps);
5115
5116 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
5117 }
5118 }
5119 }
5120 group->addChild(allocationTypeGroup.release());
5121 }
5122 }
5123
addSimpleTests(tcu::TestCaseGroup * group)5124 void addSimpleTests (tcu::TestCaseGroup* group)
5125 {
5126 const UVec2 targetSize (64, 64);
5127 const UVec2 renderPos (0, 0);
5128 const UVec2 renderSize (64, 64);
5129
5130 // color
5131 {
5132 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5133 VK_SAMPLE_COUNT_1_BIT,
5134 VK_ATTACHMENT_LOAD_OP_CLEAR,
5135 VK_ATTACHMENT_STORE_OP_STORE,
5136 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5137 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5138 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5139 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5140 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5141 0u,
5142 vector<AttachmentReference>(),
5143 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5144 vector<AttachmentReference>(),
5145 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5146 vector<deUint32>())),
5147 vector<SubpassDependency>());
5148
5149 addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5150 }
5151
5152 // depth
5153 {
5154 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5155 VK_SAMPLE_COUNT_1_BIT,
5156 VK_ATTACHMENT_LOAD_OP_CLEAR,
5157 VK_ATTACHMENT_STORE_OP_STORE,
5158 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5159 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5160 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5161 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5162 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5163 0u,
5164 vector<AttachmentReference>(),
5165 vector<AttachmentReference>(),
5166 vector<AttachmentReference>(),
5167 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5168 vector<deUint32>())),
5169 vector<SubpassDependency>());
5170
5171 addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5172 }
5173
5174 // stencil
5175 {
5176 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
5177 VK_SAMPLE_COUNT_1_BIT,
5178 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5179 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5180 VK_ATTACHMENT_LOAD_OP_CLEAR,
5181 VK_ATTACHMENT_STORE_OP_STORE,
5182 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5183 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5184 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5185 0u,
5186 vector<AttachmentReference>(),
5187 vector<AttachmentReference>(),
5188 vector<AttachmentReference>(),
5189 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5190 vector<deUint32>())),
5191 vector<SubpassDependency>());
5192
5193 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5194 }
5195
5196 // depth_stencil
5197 {
5198 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5199 VK_SAMPLE_COUNT_1_BIT,
5200 VK_ATTACHMENT_LOAD_OP_CLEAR,
5201 VK_ATTACHMENT_STORE_OP_STORE,
5202 VK_ATTACHMENT_LOAD_OP_CLEAR,
5203 VK_ATTACHMENT_STORE_OP_STORE,
5204 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5205 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5206 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5207 0u,
5208 vector<AttachmentReference>(),
5209 vector<AttachmentReference>(),
5210 vector<AttachmentReference>(),
5211 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5212 vector<deUint32>())),
5213 vector<SubpassDependency>());
5214
5215 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5216 }
5217
5218 // color_depth
5219 {
5220 const Attachment attachments[] =
5221 {
5222 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5223 VK_SAMPLE_COUNT_1_BIT,
5224 VK_ATTACHMENT_LOAD_OP_CLEAR,
5225 VK_ATTACHMENT_STORE_OP_STORE,
5226 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5227 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5228 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5229 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5230 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5231 VK_SAMPLE_COUNT_1_BIT,
5232 VK_ATTACHMENT_LOAD_OP_CLEAR,
5233 VK_ATTACHMENT_STORE_OP_STORE,
5234 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5235 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5236 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5237 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5238 };
5239
5240 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5241 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5242 0u,
5243 vector<AttachmentReference>(),
5244 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5245 vector<AttachmentReference>(),
5246 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5247 vector<deUint32>())),
5248 vector<SubpassDependency>());
5249
5250 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5251 }
5252
5253 // color_stencil
5254 {
5255 const Attachment attachments[] =
5256 {
5257 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5258 VK_SAMPLE_COUNT_1_BIT,
5259 VK_ATTACHMENT_LOAD_OP_CLEAR,
5260 VK_ATTACHMENT_STORE_OP_STORE,
5261 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5262 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5263 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5264 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5265 Attachment(VK_FORMAT_S8_UINT,
5266 VK_SAMPLE_COUNT_1_BIT,
5267 VK_ATTACHMENT_LOAD_OP_CLEAR,
5268 VK_ATTACHMENT_STORE_OP_STORE,
5269 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5270 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5271 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5272 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5273 };
5274
5275 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5276 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5277 0u,
5278 vector<AttachmentReference>(),
5279 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5280 vector<AttachmentReference>(),
5281 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5282 vector<deUint32>())),
5283 vector<SubpassDependency>());
5284
5285
5286 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5287 }
5288
5289 // color_depth_stencil
5290 {
5291 const Attachment attachments[] =
5292 {
5293 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5294 VK_SAMPLE_COUNT_1_BIT,
5295 VK_ATTACHMENT_LOAD_OP_CLEAR,
5296 VK_ATTACHMENT_STORE_OP_STORE,
5297 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5298 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5299 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5300 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5301 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5302 VK_SAMPLE_COUNT_1_BIT,
5303 VK_ATTACHMENT_LOAD_OP_CLEAR,
5304 VK_ATTACHMENT_STORE_OP_STORE,
5305 VK_ATTACHMENT_LOAD_OP_CLEAR,
5306 VK_ATTACHMENT_STORE_OP_STORE,
5307 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5308 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5309 };
5310
5311 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5312 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5313 0u,
5314 vector<AttachmentReference>(),
5315 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5316 vector<AttachmentReference>(),
5317 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5318 vector<deUint32>())),
5319 vector<SubpassDependency>());
5320
5321 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5322 }
5323 }
5324
formatToName(VkFormat format)5325 std::string formatToName (VkFormat format)
5326 {
5327 const std::string formatStr = de::toString(format);
5328 const std::string prefix = "VK_FORMAT_";
5329
5330 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
5331
5332 return de::toLower(formatStr.substr(prefix.length()));
5333 }
5334
addFormatTests(tcu::TestCaseGroup * group)5335 void addFormatTests (tcu::TestCaseGroup* group)
5336 {
5337 tcu::TestContext& testCtx = group->getTestContext();
5338
5339 const UVec2 targetSize (64, 64);
5340 const UVec2 renderPos (0, 0);
5341 const UVec2 renderSize (64, 64);
5342
5343 const struct
5344 {
5345 const char* const str;
5346 const VkAttachmentStoreOp op;
5347 } storeOps[] =
5348 {
5349 { "store", VK_ATTACHMENT_STORE_OP_STORE },
5350 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE }
5351 };
5352
5353 const struct
5354 {
5355 const char* const str;
5356 const VkAttachmentLoadOp op;
5357 } loadOps[] =
5358 {
5359 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
5360 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
5361 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
5362 };
5363
5364 const struct
5365 {
5366 const char* const str;
5367 const TestConfig::RenderTypes types;
5368 } renderTypes[] =
5369 {
5370 { "clear", TestConfig::RENDERTYPES_CLEAR },
5371 { "draw", TestConfig::RENDERTYPES_DRAW },
5372 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
5373 };
5374
5375 // Color formats
5376 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
5377 {
5378 const VkFormat format = s_coreColorFormats[formatNdx];
5379 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
5380
5381 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5382 {
5383 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5384 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5385
5386 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5387 {
5388 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
5389 VK_SAMPLE_COUNT_1_BIT,
5390 loadOp,
5391 VK_ATTACHMENT_STORE_OP_STORE,
5392 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5393 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5394 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5395 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5396 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5397 0u,
5398 vector<AttachmentReference>(),
5399 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5400 vector<AttachmentReference>(),
5401 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5402 vector<deUint32>())),
5403 vector<SubpassDependency>());
5404
5405 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5406 }
5407
5408 formatGroup->addChild(loadOpGroup.release());
5409 }
5410
5411 {
5412 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5413
5414 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5415 {
5416 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5417 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5418
5419 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5420 {
5421 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5422 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5423
5424 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5425 {
5426 {
5427 vector<Attachment> attachments;
5428 vector<Subpass> subpasses;
5429 vector<SubpassDependency> deps;
5430
5431 attachments.push_back(Attachment(format,
5432 VK_SAMPLE_COUNT_1_BIT,
5433 loadOp,
5434 storeOp,
5435 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5436 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5437 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5438 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5439
5440 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5441 VK_SAMPLE_COUNT_1_BIT,
5442 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5443 VK_ATTACHMENT_STORE_OP_STORE,
5444 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5445 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5446 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5447 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5448
5449 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5450 0u,
5451 vector<AttachmentReference>(),
5452 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5453 vector<AttachmentReference>(),
5454 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5455 vector<deUint32>()));
5456 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5457 0u,
5458 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5459 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5460 vector<AttachmentReference>(),
5461 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5462 vector<deUint32>()));
5463
5464 deps.push_back(SubpassDependency(0, 1,
5465
5466 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5467 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5468
5469 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5470 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5471 vk::VK_DEPENDENCY_BY_REGION_BIT));
5472
5473 {
5474 const RenderPass renderPass (attachments, subpasses, deps);
5475
5476 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
5477 }
5478 }
5479 {
5480 vector<Attachment> attachments;
5481 vector<Subpass> subpasses;
5482 vector<SubpassDependency> deps;
5483
5484 attachments.push_back(Attachment(format,
5485 VK_SAMPLE_COUNT_1_BIT,
5486 loadOp,
5487 storeOp,
5488 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5489 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5490 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5491 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5492
5493 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5494 0u,
5495 vector<AttachmentReference>(),
5496 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5497 vector<AttachmentReference>(),
5498 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5499 vector<deUint32>()));
5500 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5501 0u,
5502 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5503 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5504 vector<AttachmentReference>(),
5505 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5506 vector<deUint32>()));
5507
5508 deps.push_back(SubpassDependency(0, 1,
5509 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5510 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5511
5512 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5513 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5514 vk::VK_DEPENDENCY_BY_REGION_BIT));
5515
5516 {
5517 const RenderPass renderPass (attachments, subpasses, deps);
5518
5519 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
5520 }
5521 }
5522 }
5523
5524 loadOpGroup->addChild(storeOpGroup.release());
5525 }
5526
5527 inputGroup->addChild(loadOpGroup.release());
5528 }
5529
5530 formatGroup->addChild(inputGroup.release());
5531 }
5532
5533 group->addChild(formatGroup.release());
5534 }
5535
5536 // Depth stencil formats
5537 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
5538 {
5539 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
5540 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
5541
5542 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5543 {
5544 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5545 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5546
5547 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5548 {
5549 const tcu::TextureFormat format = mapVkFormat(vkFormat);
5550 const bool isStencilAttachment = hasStencilComponent(format.order);
5551 const bool isDepthAttachment = hasDepthComponent(format.order);
5552 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
5553 VK_SAMPLE_COUNT_1_BIT,
5554 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5555 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5556 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5557 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5558 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5559 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5560 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5561 0u,
5562 vector<AttachmentReference>(),
5563 vector<AttachmentReference>(),
5564 vector<AttachmentReference>(),
5565 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5566 vector<deUint32>())),
5567 vector<SubpassDependency>());
5568
5569 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
5570 }
5571
5572 formatGroup->addChild(loadOpGroup.release());
5573 }
5574
5575 {
5576 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5577
5578 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5579 {
5580 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5581 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5582
5583 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5584 {
5585 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5586 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5587
5588 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5589 {
5590 {
5591 vector<Attachment> attachments;
5592 vector<Subpass> subpasses;
5593 vector<SubpassDependency> deps;
5594
5595 attachments.push_back(Attachment(vkFormat,
5596 VK_SAMPLE_COUNT_1_BIT,
5597 loadOp,
5598 storeOp,
5599 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5600 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5601 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5602 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
5603
5604 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5605 VK_SAMPLE_COUNT_1_BIT,
5606 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5607 VK_ATTACHMENT_STORE_OP_STORE,
5608 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5609 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5610 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5611 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5612
5613 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5614 0u,
5615 vector<AttachmentReference>(),
5616 vector<AttachmentReference>(),
5617 vector<AttachmentReference>(),
5618 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5619 vector<deUint32>()));
5620 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5621 0u,
5622 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5623 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5624 vector<AttachmentReference>(),
5625 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5626 vector<deUint32>()));
5627
5628 deps.push_back(SubpassDependency(0, 1,
5629 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5630 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5631
5632 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5633 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5634 0u));
5635
5636 deps.push_back(SubpassDependency(1, 1,
5637 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5638 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5639
5640 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5641 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5642 vk::VK_DEPENDENCY_BY_REGION_BIT));
5643 {
5644 const RenderPass renderPass (attachments, subpasses, deps);
5645
5646 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
5647 }
5648 }
5649 {
5650 vector<Attachment> attachments;
5651 vector<Subpass> subpasses;
5652 vector<SubpassDependency> deps;
5653
5654 attachments.push_back(Attachment(vkFormat,
5655 VK_SAMPLE_COUNT_1_BIT,
5656 loadOp,
5657 storeOp,
5658 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5659 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5660 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5661 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
5662
5663 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5664 0u,
5665 vector<AttachmentReference>(),
5666 vector<AttachmentReference>(),
5667 vector<AttachmentReference>(),
5668 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5669 vector<deUint32>()));
5670 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5671 0u,
5672 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5673 vector<AttachmentReference>(),
5674 vector<AttachmentReference>(),
5675 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
5676 vector<deUint32>()));
5677
5678 deps.push_back(SubpassDependency(0, 1,
5679 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5680 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5681
5682 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5683 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5684 vk::VK_DEPENDENCY_BY_REGION_BIT));
5685
5686 {
5687 const RenderPass renderPass (attachments, subpasses, deps);
5688
5689 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
5690 }
5691 }
5692 }
5693
5694 loadOpGroup->addChild(storeOpGroup.release());
5695 }
5696
5697 inputGroup->addChild(loadOpGroup.release());
5698 }
5699
5700 formatGroup->addChild(inputGroup.release());
5701 }
5702
5703 group->addChild(formatGroup.release());
5704 }
5705 }
5706
5707 } // anonymous
5708
createRenderPassTests(tcu::TestContext & testCtx)5709 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
5710 {
5711 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
5712
5713 addTestGroup(renderpassTests.get(), "simple", "Simple basic render pass tests", addSimpleTests);
5714 addTestGroup(renderpassTests.get(), "formats", "Tests for different image formats.", addFormatTests);
5715 addTestGroup(renderpassTests.get(), "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests);
5716 addTestGroup(renderpassTests.get(), "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests);
5717
5718 return renderpassTests.release();
5719 }
5720
5721 } // vkt
5722