1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2020 The Khronos Group Inc.
6 * Copyright (c) 2020 ARM Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief VK_ARM_rasterization_order_attachment_access tests.
23 *//*--------------------------------------------------------------------*/
24
25 #include "deDefs.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "tcuImageCompare.hpp"
29 #include "tcuResource.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuStringTemplate.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkDefs.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkMemUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "vkPlatform.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkQueryUtil.hpp"
42 #include "vkRef.hpp"
43 #include "vkRefUtil.hpp"
44 #include "vktRasterizationOrderAttachmentAccessTests.hpp"
45 #include "vktRasterizationTests.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vktTestCase.hpp"
48 #include "vktTestCaseUtil.hpp"
49 #include "vktTestGroupUtil.hpp"
50
51 using namespace vk;
52 using namespace std;
53 using namespace vkt;
54 using de::MovePtr;
55
56 namespace vkt
57 {
58
59 namespace rasterization
60 {
61
62 namespace
63 {
64
65 class AttachmentAccessOrderTestCase : public TestCase
66 {
67 public:
68 enum
69 {
70 ELEM_NUM = 6
71 };
72
73 AttachmentAccessOrderTestCase(tcu::TestContext &context, const std::string &name, bool explicitSync,
74 bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
75 VkSampleCountFlagBits sampleCount, uint32_t inputAttachmentNum, bool integerFormat);
76 virtual ~AttachmentAccessOrderTestCase(void);
77
78 virtual void initPrograms(SourceCollections &programCollection) const;
79 virtual TestInstance *createInstance(Context &context) const;
80 virtual void checkSupport(Context &context) const;
81
82 virtual uint32_t getInputAttachmentNum() const = 0;
83 virtual uint32_t getColorAttachmentNum() const = 0;
84 virtual bool hasDepthStencil() const = 0;
85 virtual VkImageAspectFlagBits getDSAspect() const = 0;
86
87 uint32_t m_inputAttachmentNum;
88 const bool m_explicitSync;
89 const bool m_overlapDraws;
90 const bool m_overlapPrimitives;
91 const bool m_overlapInstances;
92 VkSampleCountFlagBits m_sampleCount;
93 const uint32_t m_sampleNum;
94 const bool m_integerFormat;
95 static uint32_t getSampleNum(VkSampleCountFlagBits sampleCount);
96
getColorFormat() const97 VkFormat getColorFormat() const
98 {
99 return m_integerFormat ? VK_FORMAT_R32G32_UINT : VK_FORMAT_R32G32_SFLOAT;
100 }
101
102 VkFormat checkAndGetDSFormat(Context &context) const;
103
getColorImageType()104 static VkImageType getColorImageType()
105 {
106 return VK_IMAGE_TYPE_2D;
107 }
108
getColorImageTiling()109 static VkImageTiling getColorImageTiling()
110 {
111 return VK_IMAGE_TILING_OPTIMAL;
112 }
113
getColorImageUsageFlags()114 static VkImageUsageFlags getColorImageUsageFlags()
115 {
116 return (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
117 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
118 }
119
getDSImageUsageFlags()120 static VkImageUsageFlags getDSImageUsageFlags()
121 {
122 return (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
123 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
124 }
125
getBlendStateFlags() const126 VkPipelineColorBlendStateCreateFlags getBlendStateFlags() const
127 {
128 return m_explicitSync ? 0 : VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM;
129 }
getDSStateFlags() const130 virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
131 {
132 return 0;
133 }
hasDepth() const134 virtual bool hasDepth() const
135 {
136 return false;
137 }
hasStencil() const138 virtual bool hasStencil() const
139 {
140 return false;
141 }
142
143 protected:
144 virtual void addShadersInternal(SourceCollections &programCollection,
145 const std::map<std::string, std::string> ¶ms) const = 0;
146 void addSimpleVertexShader(SourceCollections &programCollection, const std::string &dest) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const147 virtual void checkAdditionalRasterizationFlags(
148 VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
149 {
150 // unused parameter
151 DE_UNREF(rasterizationAccess);
152 }
153 };
154
155 class AttachmentAccessOrderColorTestCase : public AttachmentAccessOrderTestCase
156 {
157 public:
AttachmentAccessOrderColorTestCase(tcu::TestContext & context,const std::string & name,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount,uint32_t inputAttachmentNum,bool integerFormat)158 AttachmentAccessOrderColorTestCase(tcu::TestContext &context, const std::string &name, bool explicitSync,
159 bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
160 VkSampleCountFlagBits sampleCount, uint32_t inputAttachmentNum,
161 bool integerFormat)
162 : AttachmentAccessOrderTestCase(context, name, explicitSync, overlapDraws, overlapPrimitives, overlapInstances,
163 sampleCount, inputAttachmentNum, integerFormat)
164 {
165 }
166
getInputAttachmentNum() const167 virtual uint32_t getInputAttachmentNum() const
168 {
169 return m_inputAttachmentNum;
170 }
171
getColorAttachmentNum() const172 virtual uint32_t getColorAttachmentNum() const
173 {
174 return m_inputAttachmentNum;
175 }
176
hasDepthStencil() const177 virtual bool hasDepthStencil() const
178 {
179 return false;
180 }
181
getDSAspect() const182 virtual VkImageAspectFlagBits getDSAspect() const
183 {
184 /* not relevant, this return value will not be used */
185 return VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
186 }
187
188 protected:
189 virtual void addShadersInternal(SourceCollections &programCollection,
190 const std::map<std::string, std::string> ¶ms) const;
191 };
192
193 class AttachmentAccessOrderDepthTestCase : public AttachmentAccessOrderTestCase
194 {
195 public:
AttachmentAccessOrderDepthTestCase(tcu::TestContext & context,const std::string & name,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount)196 AttachmentAccessOrderDepthTestCase(tcu::TestContext &context, const std::string &name, bool explicitSync,
197 bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
198 VkSampleCountFlagBits sampleCount)
199 : AttachmentAccessOrderTestCase(context, name, explicitSync, overlapDraws, overlapPrimitives, overlapInstances,
200 sampleCount, 1, false)
201 {
202 }
getInputAttachmentNum() const203 virtual uint32_t getInputAttachmentNum() const
204 {
205 return m_inputAttachmentNum + 1;
206 }
207
getColorAttachmentNum() const208 virtual uint32_t getColorAttachmentNum() const
209 {
210 return m_inputAttachmentNum;
211 }
212
hasDepth() const213 virtual bool hasDepth() const
214 {
215 return true;
216 }
hasDepthStencil() const217 virtual bool hasDepthStencil() const
218 {
219 return true;
220 }
221
getDSAspect() const222 virtual VkImageAspectFlagBits getDSAspect() const
223 {
224 return VK_IMAGE_ASPECT_DEPTH_BIT;
225 }
getDSStateFlags() const226 virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
227 {
228 return m_explicitSync ?
229 0 :
230 VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
231 }
232
233 protected:
234 virtual void addShadersInternal(SourceCollections &programCollection,
235 const std::map<std::string, std::string> ¶ms) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const236 virtual void checkAdditionalRasterizationFlags(
237 VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
238 {
239 if (!m_explicitSync && !rasterizationAccess.rasterizationOrderDepthAttachmentAccess)
240 {
241 TCU_THROW(NotSupportedError,
242 "Implicit attachment access rasterization order not guaranteed for depth attachments");
243 }
244 }
245 };
246
247 class AttachmentAccessOrderStencilTestCase : public AttachmentAccessOrderTestCase
248 {
249 public:
AttachmentAccessOrderStencilTestCase(tcu::TestContext & context,const std::string & name,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount)250 AttachmentAccessOrderStencilTestCase(tcu::TestContext &context, const std::string &name, bool explicitSync,
251 bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
252 VkSampleCountFlagBits sampleCount)
253 : AttachmentAccessOrderTestCase(context, name, explicitSync, overlapDraws, overlapPrimitives, overlapInstances,
254 sampleCount, 1, true)
255 {
256 }
getInputAttachmentNum() const257 virtual uint32_t getInputAttachmentNum() const
258 {
259 return m_inputAttachmentNum + 1;
260 }
261
getColorAttachmentNum() const262 virtual uint32_t getColorAttachmentNum() const
263 {
264 return m_inputAttachmentNum;
265 }
266
hasStencil() const267 virtual bool hasStencil() const
268 {
269 return true;
270 }
hasDepthStencil() const271 virtual bool hasDepthStencil() const
272 {
273 return true;
274 }
275
getDSAspect() const276 virtual VkImageAspectFlagBits getDSAspect() const
277 {
278 return VK_IMAGE_ASPECT_STENCIL_BIT;
279 }
getDSStateFlags() const280 virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
281 {
282 return m_explicitSync ?
283 0 :
284 VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
285 }
286
287 protected:
288 virtual void addShadersInternal(SourceCollections &programCollection,
289 const std::map<std::string, std::string> ¶ms) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const290 virtual void checkAdditionalRasterizationFlags(
291 VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
292 {
293 if (!m_explicitSync && !rasterizationAccess.rasterizationOrderStencilAttachmentAccess)
294 {
295 TCU_THROW(NotSupportedError,
296 "Implicit attachment access rasterization order not guaranteed for stencil attachments");
297 }
298 }
299 };
300
301 class AttachmentAccessOrderTestInstance : public TestInstance
302 {
303 public:
304 AttachmentAccessOrderTestInstance(Context &context, const AttachmentAccessOrderTestCase *testCase);
305 virtual ~AttachmentAccessOrderTestInstance(void);
306 virtual tcu::TestStatus iterate(void);
307
308 protected:
309 class RenderSubpass
310 {
311 public:
312 const AttachmentAccessOrderTestCase *m_testCase;
313 uint32_t m_subpass;
314 VkSampleCountFlagBits m_sampleCount;
315 Move<VkPipeline> m_pipeline;
316 Move<VkPipelineLayout> m_pipelineLayout;
317 uint32_t m_colorAttNum;
318 std::vector<Move<VkImage>> m_inputAtt;
319 std::vector<MovePtr<Allocation>> m_inputAttMemory;
320 std::vector<Move<VkImageView>> m_inputAttView;
321 std::vector<VkAttachmentReference> m_attachmentReferences;
322
323 void createAttachments(int subpass, uint32_t inputAttachmentNum, uint32_t colorAttachmentNum,
324 VkSampleCountFlagBits sampleCount, Context &context, vector<VkImageView> &views,
325 VkDescriptorSetLayout *pDsetLayout, const AttachmentAccessOrderTestCase *tc);
326 void createPipeline(VkRenderPass renderPass, Context &context);
327
getColorAttachmentNum()328 uint32_t getColorAttachmentNum()
329 {
330 return m_colorAttNum;
331 }
getInputAttachmentNum()332 uint32_t getInputAttachmentNum()
333 {
334 return static_cast<uint32_t>(m_inputAtt.size());
335 }
getDepthStencilAttachment()336 VkAttachmentReference *getDepthStencilAttachment()
337 {
338 return (getColorAttachmentNum() == getInputAttachmentNum()) ? DE_NULL :
339 &m_attachmentReferences[m_colorAttNum];
340 }
341 };
342 void addPipelineBarrier(VkCommandBuffer cmdBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout,
343 VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkPipelineStageFlags srcStageMask,
344 VkPipelineStageFlags dstStageMask, VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT);
345
346 void addClearColor(VkCommandBuffer cmdBuffer, VkImage image);
347 void addClearDepthStencil(VkCommandBuffer cmdBuffer, VkImage image);
348
349 void writeDescriptorSets();
350 Move<VkRenderPass> createRenderPass(VkFormat attFormat);
351 void createVertexBuffer();
352 void createResultBuffer();
353 void addDependency(vector<VkSubpassDependency> &dependencies, uint32_t source, uint32_t dst,
354 VkPipelineStageFlags pipelineFlags, VkAccessFlags accessFlags);
355
356 tcu::TestStatus validateResults(uint32_t numDraws, uint32_t numPrimitives, uint32_t numInstances);
357
358 const AttachmentAccessOrderTestCase *m_testCase;
359
360 const DeviceInterface &m_vk;
361 vector<RenderSubpass> m_subpasses;
362 Move<VkRenderPass> m_renderPass;
363 Move<VkFramebuffer> m_framebuffer;
364 Move<VkBuffer> m_vertexBuffer;
365 MovePtr<Allocation> m_vertexBufferMemory;
366 Move<VkCommandPool> m_cmdPool;
367 Move<VkCommandBuffer> m_cmdBuffer;
368 Move<VkSampler> m_sampler;
369 Move<VkDescriptorSetLayout> m_descSetLayout;
370 Move<VkDescriptorPool> m_descPool;
371 Move<VkDescriptorSet> m_descSet;
372
373 Move<VkBuffer> m_resultBuffer;
374 MovePtr<Allocation> m_resultBufferMemory;
375
376 enum
377 {
378 WIDTH = 8,
379 HEIGHT = 8,
380 };
381 };
382
AttachmentAccessOrderTestCase(tcu::TestContext & context,const std::string & name,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount,uint32_t inputAttachmentNum,bool integerFormat)383 AttachmentAccessOrderTestCase::AttachmentAccessOrderTestCase(tcu::TestContext &context, const std::string &name,
384 bool explicitSync, bool overlapDraws,
385 bool overlapPrimitives, bool overlapInstances,
386 VkSampleCountFlagBits sampleCount,
387 uint32_t inputAttachmentNum, bool integerFormat)
388 : TestCase(context, name)
389 , m_inputAttachmentNum(inputAttachmentNum)
390 , m_explicitSync(explicitSync)
391 , m_overlapDraws(overlapDraws)
392 , m_overlapPrimitives(overlapPrimitives)
393 , m_overlapInstances(overlapInstances)
394 , m_sampleCount(sampleCount)
395 , m_sampleNum(getSampleNum(sampleCount))
396 , m_integerFormat(integerFormat)
397 {
398 }
399
~AttachmentAccessOrderTestCase(void)400 AttachmentAccessOrderTestCase::~AttachmentAccessOrderTestCase(void)
401 {
402 }
addSimpleVertexShader(SourceCollections & programCollection,const std::string & dest) const403 void AttachmentAccessOrderTestCase::addSimpleVertexShader(SourceCollections &programCollection,
404 const std::string &dest) const
405 {
406 /*
407 * The "prim_id" variable here (and in other tests below) is emulating gl_PrimitiveID.
408 * This is done to avoid having this test dependon the geometry shader feature.
409 * Note that this emulation only works because the draw calls used in the tests are
410 * non-indexed independent triangles.
411 */
412 std::stringstream vertShader;
413 vertShader << "#version 310 es\n"
414 << "layout(location = 0) in highp vec2 v_position;\n"
415 << "layout(location = 1) flat out int prim_id;\n"
416 << "void main ()\n"
417 << "{\n"
418 << " prim_id = gl_VertexIndex / 3;\n"
419 << " gl_Position = vec4(v_position, float(gl_InstanceIndex)/256.0, 1);\n"
420 << "}\n";
421
422 programCollection.glslSources.add(dest) << glu::VertexSource(vertShader.str());
423 }
424
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const425 void AttachmentAccessOrderColorTestCase::addShadersInternal(SourceCollections &programCollection,
426 const std::map<std::string, std::string> ¶ms) const
427 {
428 addSimpleVertexShader(programCollection, "vert1");
429 addSimpleVertexShader(programCollection, "vert2");
430
431 std::stringstream fragShader;
432 fragShader << "#version 450\n"
433 << "precision highp ${SCALAR_NAME};\n"
434 << "precision highp ${SUBPASS_INPUT};\n";
435 for (uint32_t i = 0; i < m_inputAttachmentNum; i++)
436 {
437 fragShader << "layout( set = 0, binding = " << i << ", input_attachment_index = " << i
438 << " ) uniform ${SUBPASS_INPUT} in" << i << ";\n"
439 << "layout( location = " << i << " ) out ${VEC_NAME}2 out" << i << ";\n";
440 }
441
442 fragShader
443 << "layout( push_constant ) uniform ConstBlock\n"
444 << "{\n"
445 << " uint drawCur;\n"
446 << "};\n"
447 << "layout(location = 1) flat in int prim_id;\n"
448 << "void main()\n"
449 << "{\n"
450 << " uint instanceCur = uint(round(gl_FragCoord.z * 256.0));\n"
451 << " uint primitiveCur = uint(prim_id) / 2u;\n"
452 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
453 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
454 << " uint drawNum = ${DRAW_NUM}u;\n"
455 << " uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
456 << " uint total = drawNum * instanceNum * primitiveNum;\n"
457 << " uint zero = curIndex / total;\n"
458 << " uint index;\n"
459 << " uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - "
460 "drawCur * primitiveNum - primitiveCur);\n"
461 << " uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - "
462 "drawCur * instanceNum - instanceCur);\n"
463 << " for(index = 0u; index < pre_fetch_loop; index++)\n"
464 << " {\n"
465 << " zero = uint(sin(float(zero)));\n"
466 << " }\n"
467 << " ${VEC_NAME}2 previous[${ATT_NUM}];\n";
468
469 for (uint32_t i = 0; i < m_inputAttachmentNum; i++)
470 {
471 if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
472 {
473 fragShader << " previous[" << i << "] = subpassLoad( in" << i << ").xy;\n";
474 }
475 else
476 {
477 fragShader << " previous[" << i << "] = subpassLoad( in" << i << ", gl_SampleID).xy;\n";
478 }
479 }
480 fragShader << " for(index = 0u; index < post_fetch_loop; index++)\n"
481 << " {\n"
482 << " zero = uint(sin(float(zero)));\n"
483 << " }\n";
484 for (uint32_t i = 0; i < m_inputAttachmentNum; i++)
485 {
486 fragShader << " if (previous[" << i << "].y == 0 && curIndex == 0)\n"
487 << " {\n"
488 << " out" << i << ".y = previous[" << i << "].y + (1u + zero + gl_SampleID + " << i << "u);\n"
489 << " out" << i << ".x = previous[" << i << "].x;\n"
490 << " }\n"
491 << " else if (previous[" << i << "].y == curIndex + gl_SampleID + " << i << ")\n"
492 << " {\n"
493 << " out" << i << ".y = previous[" << i << "].y + 1 + zero;\n"
494 << " out" << i << ".x = previous[" << i << "].x;\n"
495 << " }\n"
496 << " else\n"
497 << " {\n"
498 << " out" << i << ".y = 0u;\n"
499 << " out" << i << ".x = 1u;\n"
500 << " }\n";
501 }
502 fragShader << "}\n";
503
504 tcu::StringTemplate fragShaderTpl(fragShader.str());
505
506 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
507 }
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const508 void AttachmentAccessOrderDepthTestCase::addShadersInternal(SourceCollections &programCollection,
509 const std::map<std::string, std::string> ¶ms) const
510 {
511 std::stringstream vertShader;
512 vertShader << "#version 460\n"
513 << "layout(location = 0) in highp vec2 v_position;\n"
514 << "layout(location = 1) flat out uint instance_index;\n"
515 << "layout(location = 2) flat out int prim_id;\n"
516 << "layout( push_constant ) uniform ConstBlock\n"
517 << "{\n"
518 << " uint drawCur;\n"
519 << "};\n"
520 << "void main ()\n"
521 << "{\n"
522 << " uint primitiveCur = uint(gl_VertexIndex) / 6u;\n"
523 << " prim_id = gl_VertexIndex / 3;\n"
524 << " uint instanceNum = ${INSTANCE_NUM};\n"
525 << " uint primitiveNum = ${PRIMITIVE_NUM};\n"
526 << " uint drawNum = ${DRAW_NUM};\n"
527 << " uint curIndex = drawCur * instanceNum * primitiveNum + gl_InstanceIndex * primitiveNum + "
528 "primitiveCur;\n"
529 << " uint indexNum = drawNum * instanceNum * primitiveNum;\n"
530 << " instance_index = gl_InstanceIndex;\n"
531 << " gl_Position = vec4(v_position, 0.125 * float(curIndex) / float(indexNum), 1);\n"
532 << "}\n";
533
534 tcu::StringTemplate vertShaderTpl(vertShader.str());
535 programCollection.glslSources.add("vert1") << glu::VertexSource(vertShaderTpl.specialize(params));
536 addSimpleVertexShader(programCollection, "vert2");
537
538 std::stringstream fragShader;
539 fragShader
540 << "#version 450\n"
541 << "precision highp ${SCALAR_NAME};\n"
542 << "precision highp ${SUBPASS_INPUT};\n"
543 << "layout( set = 0, binding = 0, input_attachment_index = 0 ) uniform ${SUBPASS_INPUT} in_color;\n"
544 << "layout( set = 0, binding = 1, input_attachment_index = 1 ) uniform ${SUBPASS_INPUT} in_ds;\n"
545 << "layout( location = 0 ) out ${VEC_NAME}2 out0;\n"
546 << "layout( location = 1 ) flat in uint instance_index;\n"
547 << "layout( location = 2 ) flat in int prim_id;\n"
548 << "layout( push_constant ) uniform ConstBlock\n"
549 << "{\n"
550 << " uint drawCur;\n"
551 << "};\n"
552 << "void main()\n"
553 << "{\n"
554 << " uint instanceCur = instance_index;\n"
555 << " uint primitiveCur = uint(prim_id) / 2u;\n"
556 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
557 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
558 << " uint drawNum = ${DRAW_NUM}u;\n"
559 << " uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
560 << " uint total = drawNum * instanceNum * primitiveNum;\n"
561 << " uint zero = curIndex / total;\n"
562 << " uint index;\n"
563 << " uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - "
564 "drawCur * primitiveNum - primitiveCur);\n"
565 << " uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - "
566 "drawCur * instanceNum - instanceCur);\n"
567 << " for(index = 0u; index < pre_fetch_loop; index++)\n"
568 << " {\n"
569 << " zero = uint(sin(float(zero)));\n"
570 << " }\n";
571 if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
572 {
573 fragShader << " vec2 ds = subpassLoad( in_ds ).xy;\n"
574 << " ${VEC_NAME}2 color = subpassLoad( in_color ).xy;\n";
575 }
576 else
577 {
578 fragShader << " vec2 ds = subpassLoad( in_ds, gl_SampleID ).xy;\n"
579 << " ${VEC_NAME}2 color = subpassLoad( in_color, gl_SampleID ).xy;\n";
580 }
581 fragShader << " for(index = 0u; index < post_fetch_loop; index++)\n"
582 << " {\n"
583 << " zero = uint(sin(float(zero)));\n"
584 << " }\n"
585 << " if (curIndex == 0 && ds.x == 0)\n"
586 << " {\n"
587 << " out0.x = color.x;\n"
588 << " out0.y = curIndex + 1 + gl_SampleID + zero;\n";
589 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
590 {
591 fragShader << " gl_FragDepth = 0.125 * (float(curIndex) / float(total)) + gl_SampleID / 128.0;\n";
592 }
593 fragShader << " }\n"
594 << " else\n"
595 << " {\n"
596 << " const float expected = 0.125 * float(curIndex - 1) / float(total) + gl_SampleID / 128.0;\n"
597 << " const float threshold = 0.0000001;\n"
598 << " if (ds.x >= expected - threshold && ds.x <= expected + threshold)\n"
599 << " {\n"
600 << " out0.x = color.x;\n"
601 << " out0.y = curIndex + 1 + gl_SampleID + zero;\n";
602 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
603 {
604 fragShader << " gl_FragDepth = 0.125 * (float(curIndex) / float(total)) + gl_SampleID / 128.0;\n";
605 }
606 fragShader << " }\n"
607 << " else\n"
608 << " {\n"
609 << " out0.y = 0;\n"
610 << " out0.x = 1u;\n"
611 << " }\n"
612 << " }\n"
613 << "}\n";
614
615 tcu::StringTemplate fragShaderTpl(fragShader.str());
616
617 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
618 }
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const619 void AttachmentAccessOrderStencilTestCase::addShadersInternal(SourceCollections &programCollection,
620 const std::map<std::string, std::string> ¶ms) const
621 {
622 std::stringstream vertShader;
623 vertShader << "#version 460\n"
624 << "layout(location = 0) in highp vec2 v_position;\n"
625 << "layout(location = 1) flat out uint instance_index;"
626 << "layout(location = 2) flat out int prim_id;\n"
627 << "layout( push_constant ) uniform ConstBlock\n"
628 << "{\n"
629 << " uint drawCur;\n"
630 << "};\n"
631 << "void main ()\n"
632 << "{\n"
633 << " uint primitiveCur = uint(gl_VertexIndex) / 6u;\n"
634 << " prim_id = gl_VertexIndex / 3;\n"
635 << " uint instanceNum = ${INSTANCE_NUM};\n"
636 << " uint primitiveNum = ${PRIMITIVE_NUM};\n"
637 << " uint drawNum = ${DRAW_NUM};\n"
638 << " uint curIndex = drawCur * instanceNum * primitiveNum + gl_InstanceIndex * primitiveNum + "
639 "primitiveCur;\n"
640 << " uint indexNum = drawNum * instanceNum * primitiveNum;\n"
641 << " instance_index = gl_InstanceIndex;\n"
642 << " gl_Position = vec4(v_position, 0.125 * float(curIndex) / float(indexNum), 1);\n"
643 << "}\n";
644
645 tcu::StringTemplate vertShaderTpl(vertShader.str());
646 programCollection.glslSources.add("vert1") << glu::VertexSource(vertShaderTpl.specialize(params));
647 addSimpleVertexShader(programCollection, "vert2");
648
649 std::stringstream fragShader;
650 fragShader
651 << "#version 450\n"
652 << "precision highp ${SCALAR_NAME};\n"
653 << "precision highp ${SUBPASS_INPUT};\n"
654 << "layout( set = 0, binding = 0, input_attachment_index = 0 ) uniform ${SUBPASS_INPUT} in_color;\n"
655 << "layout( set = 0, binding = 1, input_attachment_index = 1 ) uniform ${SUBPASS_INPUT} in_ds;\n"
656 << "layout( location = 0 ) out ${VEC_NAME}2 out0;\n"
657 << "layout( location = 1 ) flat in uint instance_index;\n"
658 << "layout( location = 2 ) flat in int prim_id;\n"
659 << "layout( push_constant ) uniform ConstBlock\n"
660 << "{\n"
661 << " uint drawCur;\n"
662 << "};\n"
663 << "void main()\n"
664 << "{\n"
665 << " uint instanceCur = instance_index;\n"
666 << " uint primitiveCur = uint(prim_id) / 2u;\n"
667 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
668 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
669 << " uint drawNum = ${DRAW_NUM}u;\n"
670 << " uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
671 << " uint total = drawNum * instanceNum * primitiveNum;\n"
672 << " uint zero = curIndex / total;\n"
673 << " uint index;\n"
674 << " uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - "
675 "drawCur * primitiveNum - primitiveCur);\n"
676 << " uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - "
677 "drawCur * instanceNum - instanceCur);\n"
678 << " for(index = 0u; index < pre_fetch_loop; index++)\n"
679 << " {\n"
680 << " zero = uint(sin(float(zero)));\n"
681 << " }\n";
682 if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
683 {
684 fragShader << " ${VEC_NAME}2 ds = subpassLoad( in_ds ).xy;\n"
685 << " ${VEC_NAME}2 color = subpassLoad( in_color ).xy;\n";
686 }
687 else
688 {
689 fragShader << " ${VEC_NAME}2 ds = subpassLoad( in_ds, gl_SampleID).xy;\n"
690 << " ${VEC_NAME}2 color = subpassLoad( in_color, gl_SampleID).xy;\n";
691 }
692 fragShader << " for(index = 0u; index < post_fetch_loop; index++)\n"
693 << " {\n"
694 << " zero = uint(sin(float(zero)));\n"
695 << " }\n"
696 << " if (ds.x == curIndex)\n"
697 << " {\n"
698 << " out0.x = color.x;\n"
699 << " out0.y = curIndex + 1 + gl_SampleID + zero;\n"
700 << " }\n"
701 << " else\n"
702 << " {\n"
703 << " out0.y = 0;\n"
704 << " out0.x = 1u;\n"
705 << " }\n"
706 << "}\n";
707
708 tcu::StringTemplate fragShaderTpl(fragShader.str());
709
710 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
711 }
712
initPrograms(SourceCollections & programCollection) const713 void AttachmentAccessOrderTestCase::initPrograms(SourceCollections &programCollection) const
714 {
715 std::map<std::string, std::string> params;
716
717 params["PRIMITIVE_NUM"] = std::to_string(m_overlapPrimitives ? ELEM_NUM : 1);
718 params["INSTANCE_NUM"] = std::to_string(m_overlapInstances ? ELEM_NUM : 1);
719 params["DRAW_NUM"] = std::to_string(m_overlapDraws ? ELEM_NUM : 1);
720 params["ATT_NUM"] = std::to_string(m_inputAttachmentNum);
721 params["SAMPLE_NUM"] = std::to_string(m_sampleNum);
722
723 if (m_integerFormat)
724 {
725 params["SUBPASS_INPUT"] = "usubpassInput";
726 params["SCALAR_NAME"] = "int";
727 params["VEC_NAME"] = "uvec";
728 }
729 else
730 {
731 params["SUBPASS_INPUT"] = "subpassInput";
732 params["SCALAR_NAME"] = "float";
733 params["VEC_NAME"] = "vec";
734 }
735 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
736 {
737 params["SUBPASS_INPUT"] = params["SUBPASS_INPUT"] + "MS";
738 }
739
740 /* add the vertex (for both renderpasses) and fragment shaders for first renderpass */
741 addShadersInternal(programCollection, params);
742
743 std::stringstream fragShaderResolve;
744 fragShaderResolve << "#version 450\n"
745 << "precision highp ${SCALAR_NAME};\n"
746 << "precision highp ${SUBPASS_INPUT};\n";
747 for (uint32_t i = 0; i < m_inputAttachmentNum; i++)
748 {
749 fragShaderResolve << "layout( set = 0, binding = " << i << ", input_attachment_index = " << i
750 << " ) uniform ${SUBPASS_INPUT} in" << i << ";\n";
751 }
752 fragShaderResolve << "layout( location = 0 ) out ${VEC_NAME}2 out0;\n";
753
754 fragShaderResolve << "void main()\n"
755 << "{\n"
756 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
757 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
758 << " uint drawNum = ${DRAW_NUM}u;\n"
759 << " uint sampleNum = ${SAMPLE_NUM}u;\n"
760 << " uint totalNum = primitiveNum * instanceNum * drawNum;\n"
761 << " out0.y = totalNum;\n"
762 << " out0.x = 0u;\n"
763 << " ${VEC_NAME}2 val;\n"
764 << " int i;\n";
765
766 for (uint32_t i = 0; i < m_inputAttachmentNum; i++)
767 {
768 if (m_sampleNum == 1)
769 {
770 fragShaderResolve << " val = subpassLoad(in" << i << ").xy;\n"
771 << " if (val.x != 0u || val.y != totalNum + " << i << "){\n"
772 << " out0.y = val.y;\n"
773 << " out0.x = val.x;\n"
774 << " }\n";
775 }
776 else
777 {
778 fragShaderResolve << " for (i = 0; i < sampleNum; i++) {\n"
779 << " val = subpassLoad(in" << i << ", i).xy;\n"
780 << " if (val.x != 0u || val.y != totalNum + i + " << i << "){\n"
781 << " out0.y = val.y;\n"
782 << " out0.x = val.x;\n"
783 << " }\n"
784 << " }\n";
785 }
786 }
787
788 fragShaderResolve << "}\n";
789
790 tcu::StringTemplate fragShaderResolveTpl(fragShaderResolve.str());
791
792 programCollection.glslSources.add("frag_resolve") << glu::FragmentSource(fragShaderResolveTpl.specialize(params));
793 }
794
createInstance(Context & context) const795 TestInstance *AttachmentAccessOrderTestCase::createInstance(Context &context) const
796 {
797 return new AttachmentAccessOrderTestInstance(context, this);
798 }
799
checkAndGetDSFormat(Context & context) const800 VkFormat AttachmentAccessOrderTestCase::checkAndGetDSFormat(Context &context) const
801 {
802 const auto &vki = context.getInstanceInterface();
803 const auto physicalDevice = context.getPhysicalDevice();
804 const auto imageType = getColorImageType();
805 const auto imageTiling = getColorImageTiling();
806 const auto imageUsage = getDSImageUsageFlags();
807
808 const std::vector<VkFormat> dsFormats{VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT};
809 VkFormat supportedFormat = VK_FORMAT_UNDEFINED;
810 VkImageFormatProperties formatProperties;
811
812 for (const auto &dsFormat : dsFormats)
813 {
814 const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, dsFormat, imageType, imageTiling,
815 imageUsage, 0u, &formatProperties);
816
817 if (result == VK_SUCCESS)
818 {
819 if ((formatProperties.sampleCounts & m_sampleCount) != 0)
820 {
821 supportedFormat = dsFormat;
822 break;
823 }
824 }
825 else if (result != VK_ERROR_FORMAT_NOT_SUPPORTED)
826 TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error");
827 }
828
829 return supportedFormat;
830 }
831
checkSupport(Context & context) const832 void AttachmentAccessOrderTestCase::checkSupport(Context &context) const
833 {
834 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
835
836 // When explicit synchronization is used, there's no need for the extension.
837 if (!m_explicitSync)
838 if (!context.isDeviceFunctionalitySupported("VK_ARM_rasterization_order_attachment_access") &&
839 !context.isDeviceFunctionalitySupported("VK_EXT_rasterization_order_attachment_access"))
840 TCU_THROW(NotSupportedError, "Neither VK_ARM_rasterization_order_attachment_access nor "
841 "VK_EXT_rasterization_order_attachment_access is supported");
842
843 const auto &vki = context.getInstanceInterface();
844 const auto physicalDevice = context.getPhysicalDevice();
845
846 VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT rasterizationAccess = initVulkanStructure();
847 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(m_explicitSync ? nullptr : &rasterizationAccess);
848
849 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
850
851 VkPhysicalDeviceProperties2 properties2 = initVulkanStructure();
852
853 vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
854
855 if (m_integerFormat)
856 {
857 const auto format = getColorFormat();
858 const auto imageType = getColorImageType();
859 const auto imageTiling = getColorImageTiling();
860 const auto imageUsage = getColorImageUsageFlags();
861
862 VkImageFormatProperties formatProperties;
863
864 const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, imageType, imageTiling,
865 imageUsage, 0u, &formatProperties);
866 if (result != VK_SUCCESS)
867 {
868 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
869 TCU_THROW(NotSupportedError,
870 "format " + de::toString(format) + " does not support the required features");
871 else
872 TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error");
873 }
874
875 if ((formatProperties.sampleCounts & m_sampleCount) == 0 ||
876 (properties2.properties.limits.sampledImageIntegerSampleCounts & m_sampleCount) == 0)
877 {
878 TCU_THROW(NotSupportedError, "Sample count not supported");
879 }
880 }
881 else
882 {
883 if ((properties2.properties.limits.framebufferColorSampleCounts & m_sampleCount) == 0 ||
884 (properties2.properties.limits.sampledImageColorSampleCounts & m_sampleCount) == 0)
885 {
886 TCU_THROW(NotSupportedError, "Sample count not supported");
887 }
888 }
889
890 // Check depth/stencil format support if needed.
891 if (getInputAttachmentNum() > getColorAttachmentNum())
892 {
893 const auto format = checkAndGetDSFormat(context);
894 if (format == VK_FORMAT_UNDEFINED)
895 TCU_THROW(NotSupportedError, "No support for any of the required depth/stencil formats");
896 }
897
898 /* sampleRateShading must be enabled to call fragment shader for all the samples in multisampling */
899 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT && !features2.features.sampleRateShading)
900 {
901 TCU_THROW(NotSupportedError, "sampleRateShading feature not supported");
902 }
903
904 if (properties2.properties.limits.maxFragmentOutputAttachments < m_inputAttachmentNum ||
905 properties2.properties.limits.maxPerStageDescriptorInputAttachments < m_inputAttachmentNum)
906 {
907 TCU_THROW(NotSupportedError, "Feedback attachment number not supported");
908 }
909
910 if (!m_explicitSync && !rasterizationAccess.rasterizationOrderColorAttachmentAccess)
911 {
912 TCU_THROW(NotSupportedError,
913 "Implicit attachment access rasterization order not guaranteed for color attachments");
914 }
915
916 checkAdditionalRasterizationFlags(rasterizationAccess);
917 }
918
getSampleNum(VkSampleCountFlagBits sampleCount)919 uint32_t AttachmentAccessOrderTestCase::getSampleNum(VkSampleCountFlagBits sampleCount)
920 {
921 uint32_t ret = 0;
922 switch (sampleCount)
923 {
924 case VK_SAMPLE_COUNT_1_BIT:
925 ret = 1;
926 break;
927 case VK_SAMPLE_COUNT_2_BIT:
928 ret = 2;
929 break;
930 case VK_SAMPLE_COUNT_4_BIT:
931 ret = 4;
932 break;
933 case VK_SAMPLE_COUNT_8_BIT:
934 ret = 8;
935 break;
936 case VK_SAMPLE_COUNT_16_BIT:
937 ret = 16;
938 break;
939 case VK_SAMPLE_COUNT_32_BIT:
940 ret = 32;
941 break;
942 case VK_SAMPLE_COUNT_64_BIT:
943 ret = 64;
944 break;
945 default:
946 DE_ASSERT(false);
947 };
948 return ret;
949 }
950
createAttachments(int subpass,uint32_t inputAttachmentNum,uint32_t colorAttachmentNum,VkSampleCountFlagBits sampleCount,Context & context,vector<VkImageView> & views,VkDescriptorSetLayout * pDsetLayout,const AttachmentAccessOrderTestCase * tc)951 void AttachmentAccessOrderTestInstance::RenderSubpass::createAttachments(int subpass, uint32_t inputAttachmentNum,
952 uint32_t colorAttachmentNum,
953 VkSampleCountFlagBits sampleCount,
954 Context &context, vector<VkImageView> &views,
955 VkDescriptorSetLayout *pDsetLayout,
956 const AttachmentAccessOrderTestCase *tc)
957 {
958 m_testCase = tc;
959 m_subpass = subpass;
960 m_sampleCount = sampleCount;
961 m_colorAttNum = colorAttachmentNum;
962 const DeviceInterface &vk = context.getDeviceInterface();
963 const VkDevice device = context.getDevice();
964 const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
965 Allocator &allocator = context.getDefaultAllocator();
966
967 // Pipeline Layout
968 {
969 VkPushConstantRange pushConstantsInfo = {
970 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
971 0, // uint32_t offset;
972 4, // uint32_t size;
973 };
974 if (m_testCase->hasDepthStencil())
975 {
976 pushConstantsInfo.stageFlags |= VK_SHADER_STAGE_VERTEX_BIT;
977 }
978 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
979 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
980 DE_NULL, // const void* pNext;
981 0u, // VkPipelineLayoutCreateFlags flags;
982 1u, // uint32_t descriptorSetCount;
983 pDsetLayout, // const VkDescriptorSetLayout* pSetLayouts;
984 m_subpass == 0 ? 1u : 0u, // uint32_t pushConstantRangeCount;
985 m_subpass == 0 ? &pushConstantsInfo : nullptr // const VkPushConstantRange* pPushConstantRanges;
986 };
987 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
988 }
989 VkFormat attFormat = m_testCase->getColorFormat();
990
991 /* Same create info for all the color attachments */
992 const auto imageType = AttachmentAccessOrderTestCase::getColorImageType();
993 const auto imageTiling = AttachmentAccessOrderTestCase::getColorImageTiling();
994 const auto imageUsage = AttachmentAccessOrderTestCase::getColorImageUsageFlags();
995
996 VkImageCreateInfo colorImageCreateInfo = {
997 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
998 DE_NULL, // const void* pNext;
999 0u, // VkImageCreateFlags flags;
1000 imageType, // VkImageType imageType;
1001 attFormat, // VkFormat format;
1002 {WIDTH, HEIGHT, 1u}, // VkExtent3D extent;
1003 1u, // uint32_t mipLevels;
1004 1u, // uint32_t arrayLayers;
1005 sampleCount, // VkSampleCountFlagBits samples;
1006 imageTiling, // VkImageTiling tiling;
1007 imageUsage, // VkImageUsageFlags usage;
1008 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1009 1u, // uint32_t queueFamilyIndexCount;
1010 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
1011 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1012 };
1013
1014 for (uint32_t i = 0; i < inputAttachmentNum; i++)
1015 {
1016 VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT;
1017
1018 /* Image for the DS attachment */
1019 if (i >= colorAttachmentNum)
1020 {
1021 attFormat = m_testCase->checkAndGetDSFormat(context);
1022 DE_ASSERT(attFormat != VK_FORMAT_UNDEFINED);
1023 colorImageCreateInfo.format = attFormat;
1024 colorImageCreateInfo.usage = AttachmentAccessOrderTestCase::getDSImageUsageFlags();
1025 aspect = m_testCase->getDSAspect();
1026 }
1027
1028 m_inputAtt.push_back(createImage(vk, device, &colorImageCreateInfo, DE_NULL));
1029 VkImageViewCreateInfo colorTargetViewInfo = {
1030 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1031 DE_NULL, // const void* pNext;
1032 0u, // VkImageViewCreateFlags flags;
1033 *m_inputAtt.back(), // VkImage image;
1034 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1035 attFormat, // VkFormat format;
1036 makeComponentMappingRGBA(), // VkComponentMapping components;
1037 {
1038 (VkImageAspectFlags)aspect, // VkImageAspectFlags aspectMask;
1039 0u, // uint32_t baseMipLevel;
1040 1u, // uint32_t mipLevels;
1041 0u, // uint32_t baseArrayLayer;
1042 1u, // uint32_t arraySize;
1043 }, // VkImageSubresourceRange subresourceRange;
1044 };
1045 m_inputAttMemory.push_back(
1046 allocator.allocate(getImageMemoryRequirements(vk, device, *m_inputAtt.back()), MemoryRequirement::Any));
1047 VK_CHECK(vk.bindImageMemory(device, *m_inputAtt.back(), m_inputAttMemory.back()->getMemory(),
1048 m_inputAttMemory.back()->getOffset()));
1049 m_inputAttView.push_back(createImageView(vk, device, &colorTargetViewInfo));
1050
1051 m_attachmentReferences.push_back({(uint32_t)views.size(), VK_IMAGE_LAYOUT_GENERAL});
1052 views.push_back(*m_inputAttView.back());
1053 }
1054 }
1055
createPipeline(VkRenderPass renderPass,Context & context)1056 void AttachmentAccessOrderTestInstance::RenderSubpass::createPipeline(VkRenderPass renderPass, Context &context)
1057 {
1058
1059 const DeviceInterface &vk = context.getDeviceInterface();
1060 const VkDevice device = context.getDevice();
1061 const Unique<VkShaderModule> vs(
1062 createShaderModule(vk, device, context.getBinaryCollection().get(m_subpass == 0 ? "vert1" : "vert2"), 0));
1063 const Unique<VkShaderModule> fs(
1064 createShaderModule(vk, device, context.getBinaryCollection().get(m_subpass == 0 ? "frag" : "frag_resolve"), 0));
1065
1066 const VkVertexInputBindingDescription vertexInputBindingDescription = {
1067 0, // uint32_t binding;
1068 sizeof(tcu::Vec2), // uint32_t strideInBytes;
1069 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputStepRate stepRate;
1070 };
1071
1072 const VkVertexInputAttributeDescription vertexInputAttributeDescription = {
1073 0u, // uint32_t location;
1074 0u, // uint32_t binding;
1075 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1076 0u, // uint32_t offsetInBytes;
1077 };
1078
1079 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1080 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1081 DE_NULL, // const void* pNext;
1082 0, // VkPipelineVertexInputStateCreateFlags flags;
1083 1u, // uint32_t bindingCount;
1084 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1085 1u, // uint32_t attributeCount;
1086 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1087 };
1088
1089 const std::vector<VkViewport> viewports(1, {0, 0, WIDTH, HEIGHT, 0, 1});
1090 const std::vector<VkRect2D> scissors(1, {{0, 0}, {WIDTH, HEIGHT}});
1091 const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = {
1092 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1093 DE_NULL, // const void* pNext;
1094 0u, // VkPipelineRasterizationStateCreateFlags flags;
1095 VK_FALSE, // VkBool32 depthClampEnable;
1096 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1097 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1098 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1099 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1100 VK_FALSE, // VkBool32 depthBiasEnable;
1101 0.0f, // float depthBiasConstantFactor;
1102 0.0f, // float depthBiasClamp;
1103 0.0f, // float depthBiasSlopeFactor;
1104 1.0f, // float lineWidth;
1105 };
1106 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
1107 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1108 DE_NULL, // const void* pNext;
1109 0u, // VkPipelineMultisampleStateCreateFlags flags;
1110 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
1111 VK_TRUE, // VkBool32 sampleShadingEnable;
1112 1.0f, // float minSampleShading;
1113 DE_NULL, // const VkSampleMask* pSampleMask;
1114 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1115 VK_FALSE // VkBool32 alphaToOneEnable;
1116 };
1117 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(
1118 m_colorAttNum,
1119 {
1120 false, // VkBool32 blendEnable;
1121 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1122 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
1123 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1124 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1125 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
1126 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1127 (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT) // VkChannelFlags channelWriteMask;
1128 });
1129
1130 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = {
1131 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1132 DE_NULL, // const void* pNext;
1133 /* always needed */
1134 m_testCase->getBlendStateFlags(), // VkPipelineColorBlendStateCreateFlags flags;
1135 false, // VkBool32 logicOpEnable;
1136 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1137 (uint32_t)colorBlendAttachmentState.size(), // uint32_t attachmentCount;
1138 colorBlendAttachmentState.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
1139 {0.0f, 0.0f, 0.0f, 0.0f}, // float blendConst[4];
1140 };
1141
1142 VkStencilOpState stencilOpState = {
1143 VK_STENCIL_OP_ZERO, // VkStencilOp failOp;
1144 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp passOp;
1145 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp depthFailOp;
1146 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1147 0xff, // uint32_t compareMask;
1148 0xff, // uint32_t writeMask;
1149 0, // uint32_t reference;
1150 };
1151 VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = {
1152 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1153 // VkStructureType sType;
1154 DE_NULL, // const void* pNext;
1155 m_testCase->getDSStateFlags(),
1156 // VkPipelineDepthStencilStateCreateFlags flags;
1157 VK_TRUE, // VkBool32 depthTestEnable;
1158 VK_TRUE, // VkBool32 depthWriteEnable;
1159 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
1160 VK_FALSE, // VkBool32 depthBoundsTestEnable;
1161 VK_TRUE, // VkBool32 stencilTestEnable;
1162 stencilOpState, // VkStencilOpState front;
1163 stencilOpState, // VkStencilOpState back;
1164 0.0f, // float minDepthBounds;
1165 1.0f, // float maxDepthBounds;
1166 };
1167
1168 m_pipeline = makeGraphicsPipeline(
1169 vk, // const DeviceInterface& vk
1170 device, // const VkDevice device
1171 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
1172 *vs, // const VkShaderModule vertexShaderModule
1173 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1174 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1175 DE_NULL, // const VkShaderModule geometryShaderModule
1176 *fs, // const VkShaderModule fragmentShaderModule
1177 renderPass, // const VkRenderPass renderPass
1178 viewports, // const std::vector<VkViewport>& viewports
1179 scissors, // const std::vector<VkRect2D>& scissors
1180 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
1181 m_subpass, // const uint32_t subpass
1182 0u, // const uint32_t patchControlPoints
1183 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1184 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1185 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1186 &depthStencilStateCreateInfo, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
1187 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo,
1188 DE_NULL); // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
1189 }
1190
makeSampler(const DeviceInterface & vk,const VkDevice & device)1191 static Move<VkSampler> makeSampler(const DeviceInterface &vk, const VkDevice &device)
1192 {
1193 const VkSamplerCreateInfo createInfo = {
1194 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
1195 DE_NULL, // const void* pNext;
1196 0u, // VkSamplerCreateFlags flags;
1197 VK_FILTER_NEAREST, // VkFilter magFilter;
1198 VK_FILTER_NEAREST, // VkFilter minFilter;
1199 VK_SAMPLER_MIPMAP_MODE_LINEAR, // VkSamplerMipmapMode mipmapMode;
1200 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
1201 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
1202 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
1203 0.0f, // float mipLodBias;
1204 VK_FALSE, // VkBool32 anisotropyEnable;
1205 1.0f, // float maxAnisotropy;
1206 VK_FALSE, // VkBool32 compareEnable;
1207 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1208 0.0f, // float minLod;
1209 0.0f, // float maxLod;
1210 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
1211 VK_FALSE // VkBool32 unnormalizedCoordinates;
1212 };
1213
1214 return createSampler(vk, device, &createInfo);
1215 }
1216
makeDescriptorSetLayout(const DeviceInterface & vk,const VkDevice device,uint32_t attNum)1217 static Move<VkDescriptorSetLayout> makeDescriptorSetLayout(const DeviceInterface &vk, const VkDevice device,
1218 uint32_t attNum)
1219 {
1220 vector<VkDescriptorSetLayoutBinding> bindings(attNum,
1221 {
1222 0, // binding
1223 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // descriptorType
1224 1u, // descriptorCount
1225 VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags
1226 DE_NULL, // pImmutableSamplers
1227 });
1228 for (uint32_t i = 0; i < attNum; i++)
1229 {
1230 bindings[i].binding = i;
1231 }
1232
1233 const VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {
1234 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1235 DE_NULL, // pNext
1236 0u, // flags
1237 attNum, // bindingCount
1238 bindings.data(), // pBindings
1239 };
1240
1241 return vk::createDescriptorSetLayout(vk, device, &layoutCreateInfo);
1242 }
writeDescriptorSets()1243 void AttachmentAccessOrderTestInstance::writeDescriptorSets()
1244 {
1245 uint32_t attNum = m_testCase->getInputAttachmentNum();
1246 for (uint32_t i = 0; i < attNum; i++)
1247 {
1248 VkDescriptorImageInfo img_info = {};
1249 img_info.sampler = *m_sampler;
1250 img_info.imageView = *m_subpasses[0].m_inputAttView[i];
1251 img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1252
1253 VkWriteDescriptorSet write = {};
1254 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1255 write.dstSet = *m_descSet;
1256 write.dstBinding = i;
1257 write.dstArrayElement = 0;
1258 write.descriptorCount = 1;
1259 write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
1260 write.pImageInfo = &img_info;
1261
1262 m_vk.updateDescriptorSets(m_context.getDevice(), 1u, &write, 0u, DE_NULL);
1263 }
1264 }
1265
addDependency(vector<VkSubpassDependency> & dependencies,uint32_t source,uint32_t dst,VkPipelineStageFlags pipelineFlags,VkAccessFlags accessFlags)1266 void AttachmentAccessOrderTestInstance::addDependency(vector<VkSubpassDependency> &dependencies, uint32_t source,
1267 uint32_t dst, VkPipelineStageFlags pipelineFlags,
1268 VkAccessFlags accessFlags)
1269 {
1270 dependencies.push_back({
1271 source, //uint32_t srcSubpass;
1272 dst, //uint32_t dstSubpass;
1273 pipelineFlags, //VkPipelineStageFlags srcStageMask;
1274 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, //VkPipelineStageFlags dstStageMask;
1275 accessFlags, //VkAccessFlags srcAccessMask;
1276 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, //VkAccessFlags dstAccessMask;
1277 VK_DEPENDENCY_BY_REGION_BIT, //VkDependencyFlags dependencyFlags;
1278 });
1279 }
createRenderPass(VkFormat attFormat)1280 Move<VkRenderPass> AttachmentAccessOrderTestInstance::createRenderPass(VkFormat attFormat)
1281 {
1282 const VkDevice device = m_context.getDevice();
1283 vector<VkAttachmentDescription> attachmentDescs;
1284 for (uint32_t subpass = 0; subpass < 2; subpass++)
1285 {
1286 for (uint32_t i = 0; i < m_subpasses[subpass].getInputAttachmentNum(); i++)
1287 {
1288 VkFormat format = attFormat;
1289 if (i >= m_subpasses[subpass].getColorAttachmentNum())
1290 {
1291 format = m_testCase->checkAndGetDSFormat(m_context);
1292 DE_ASSERT(format != VK_FORMAT_UNDEFINED);
1293 }
1294 attachmentDescs.push_back({
1295 0, // VkAttachmentDescriptionFlags flags;
1296 format, // VkFormat format;
1297 m_subpasses[subpass].m_sampleCount, // VkSampleCountFlagBits samples;
1298 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1299 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1300 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
1301 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
1302 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1303 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout finalLayout;
1304 });
1305 }
1306 }
1307
1308 std::vector<VkSubpassDescription> subpasses(2, VkSubpassDescription{});
1309
1310 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1311 subpasses[0].inputAttachmentCount = m_subpasses[0].getInputAttachmentNum();
1312 subpasses[0].pInputAttachments = m_subpasses[0].m_attachmentReferences.data();
1313 subpasses[0].colorAttachmentCount = m_subpasses[0].getColorAttachmentNum();
1314 subpasses[0].pColorAttachments = m_subpasses[0].m_attachmentReferences.data();
1315 subpasses[0].pDepthStencilAttachment = m_subpasses[0].getDepthStencilAttachment();
1316
1317 subpasses[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1318 subpasses[1].inputAttachmentCount = m_subpasses[0].getColorAttachmentNum();
1319 subpasses[1].pInputAttachments = m_subpasses[0].m_attachmentReferences.data();
1320 subpasses[1].colorAttachmentCount = m_subpasses[1].getColorAttachmentNum();
1321 subpasses[1].pColorAttachments = m_subpasses[1].m_attachmentReferences.data();
1322
1323 /* self dependency for subpass 0 and dependency from subpass 0 to 1 */
1324 vector<VkSubpassDependency> dependencies;
1325 addDependency(dependencies, 0, 1, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1326 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1327 if (m_testCase->m_explicitSync)
1328 {
1329 addDependency(dependencies, 0, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1330 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1331 if (m_testCase->hasDepthStencil())
1332 {
1333 const auto fragTests =
1334 (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1335 addDependency(dependencies, 0, 0, fragTests, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1336 }
1337 }
1338 else
1339 {
1340 subpasses[0].flags = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM;
1341 subpasses[1].flags = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM;
1342 if (m_testCase->hasDepth())
1343 {
1344 subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
1345 subpasses[1].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
1346 }
1347 else if (m_testCase->hasStencil())
1348 {
1349 subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
1350 subpasses[1].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
1351 }
1352 }
1353
1354 VkRenderPassCreateInfo renderPassCreateInfo = {
1355 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1356 NULL, // const void* pNext;
1357 0, // VkRenderPassCreateFlags flags;
1358 (uint32_t)attachmentDescs.size(), // uint32_t attachmentCount;
1359 attachmentDescs.data(), // const VkAttachmentDescription* pAttachments;
1360 (uint32_t)subpasses.size(), // uint32_t subpassCount;
1361 subpasses.data(), // const VkSubpassDescription* pSubpasses;
1362 (uint32_t)dependencies.size(), // uint32_t dependencyCount;
1363 dependencies.data(), // const VkSubpassDependency* pDependencies;
1364 };
1365
1366 return ::createRenderPass(m_vk, device, &renderPassCreateInfo);
1367 }
1368
createVertexBuffer()1369 void AttachmentAccessOrderTestInstance::createVertexBuffer()
1370 {
1371 uint32_t primitiveNum = m_testCase->m_overlapPrimitives ? AttachmentAccessOrderTestCase::ELEM_NUM * 2 : 2;
1372 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1373 const VkDevice device = m_context.getDevice();
1374 Allocator &allocator = m_context.getDefaultAllocator();
1375 std::vector<tcu::Vec2> vbo(3 * primitiveNum);
1376 for (uint32_t i = 0; i < primitiveNum / 2; i++)
1377 {
1378 vbo[i * 6 + 0] = {-1, -1};
1379 vbo[i * 6 + 1] = {1, -1};
1380 vbo[i * 6 + 2] = {-1, 1};
1381 vbo[i * 6 + 3] = {1, 1};
1382 vbo[i * 6 + 4] = {-1, 1};
1383 vbo[i * 6 + 5] = {1, -1};
1384 }
1385
1386 const size_t dataSize = vbo.size() * sizeof(tcu::Vec2);
1387 {
1388 const VkBufferCreateInfo vertexBufferParams = {
1389 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1390 DE_NULL, // const void* pNext;
1391 0u, // VkBufferCreateFlags flags;
1392 dataSize, // VkDeviceSize size;
1393 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1394 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1395 1u, // uint32_t queueFamilyCount;
1396 &queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
1397 };
1398 m_vertexBuffer = createBuffer(m_vk, device, &vertexBufferParams);
1399 m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(m_vk, device, *m_vertexBuffer),
1400 MemoryRequirement::HostVisible);
1401
1402 VK_CHECK(m_vk.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(),
1403 m_vertexBufferMemory->getOffset()));
1404 }
1405
1406 /* Load vertices into vertex buffer */
1407 deMemcpy(m_vertexBufferMemory->getHostPtr(), vbo.data(), dataSize);
1408 flushAlloc(m_vk, device, *m_vertexBufferMemory);
1409 }
1410
createResultBuffer()1411 void AttachmentAccessOrderTestInstance::createResultBuffer()
1412 {
1413 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1414 const VkDevice device = m_context.getDevice();
1415 Allocator &allocator = m_context.getDefaultAllocator();
1416 /* result buffer */
1417 const VkBufferCreateInfo resultBufferInfo = {
1418 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1419 DE_NULL, // const void* pNext;
1420 0u, // VkBufferCreateFlags flags;
1421 WIDTH * HEIGHT * sizeof(tcu::UVec2), // VkDeviceSize size;
1422 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1423 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1424 1u, // uint32_t queueFamilyCount;
1425 &queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
1426 };
1427 m_resultBuffer = createBuffer(m_vk, device, &resultBufferInfo);
1428 m_resultBufferMemory =
1429 allocator.allocate(getBufferMemoryRequirements(m_vk, device, *m_resultBuffer), MemoryRequirement::HostVisible);
1430
1431 VK_CHECK(m_vk.bindBufferMemory(device, *m_resultBuffer, m_resultBufferMemory->getMemory(),
1432 m_resultBufferMemory->getOffset()));
1433 }
1434
AttachmentAccessOrderTestInstance(Context & context,const AttachmentAccessOrderTestCase * testCase)1435 AttachmentAccessOrderTestInstance::AttachmentAccessOrderTestInstance(Context &context,
1436 const AttachmentAccessOrderTestCase *testCase)
1437 : TestInstance(context)
1438 , m_testCase(testCase)
1439 , m_vk(m_context.getDeviceInterface())
1440 , m_subpasses(2)
1441 {
1442 const VkDevice device = m_context.getDevice();
1443 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1444
1445 m_descSetLayout = makeDescriptorSetLayout(m_vk, device, m_testCase->getInputAttachmentNum());
1446
1447 m_descPool = DescriptorPoolBuilder()
1448 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_testCase->getInputAttachmentNum())
1449 .build(m_vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1450
1451 m_descSet = makeDescriptorSet(m_vk, device, *m_descPool, *m_descSetLayout, nullptr);
1452
1453 vector<VkImageView> attachmentHandles;
1454 VkDescriptorSetLayout dsetLayout = *m_descSetLayout;
1455
1456 m_subpasses[0].createAttachments(0, m_testCase->getInputAttachmentNum(), m_testCase->getColorAttachmentNum(),
1457 m_testCase->m_sampleCount, m_context, attachmentHandles, &dsetLayout, m_testCase);
1458 m_subpasses[1].createAttachments(1, 1, 1, VK_SAMPLE_COUNT_1_BIT, m_context, attachmentHandles, &dsetLayout,
1459 m_testCase);
1460
1461 m_sampler = makeSampler(m_vk, device);
1462
1463 writeDescriptorSets();
1464 m_renderPass = createRenderPass(m_testCase->getColorFormat());
1465
1466 m_framebuffer = makeFramebuffer(m_vk, device, *m_renderPass, (uint32_t)attachmentHandles.size(),
1467 attachmentHandles.data(), WIDTH, HEIGHT, 1);
1468
1469 m_subpasses[0].createPipeline(*m_renderPass, m_context);
1470 m_subpasses[1].createPipeline(*m_renderPass, m_context);
1471
1472 createVertexBuffer();
1473
1474 createResultBuffer();
1475
1476 m_cmdPool = createCommandPool(m_vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1477 m_cmdBuffer = allocateCommandBuffer(m_vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1478 }
1479
~AttachmentAccessOrderTestInstance(void)1480 AttachmentAccessOrderTestInstance::~AttachmentAccessOrderTestInstance(void)
1481 {
1482 }
1483
addPipelineBarrier(VkCommandBuffer cmdBuffer,VkImage image,VkImageLayout oldLayout,VkImageLayout newLayout,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkImageAspectFlags aspect)1484 void AttachmentAccessOrderTestInstance::addPipelineBarrier(VkCommandBuffer cmdBuffer, VkImage image,
1485 VkImageLayout oldLayout, VkImageLayout newLayout,
1486 VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
1487 VkPipelineStageFlags srcStageMask,
1488 VkPipelineStageFlags dstStageMask, VkImageAspectFlags aspect)
1489 {
1490 VkImageMemoryBarrier barrier = {
1491 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1492 DE_NULL, // const void* pNext;
1493 srcAccessMask, // VkAccessFlags srcAccessMask;
1494 dstAccessMask, // VkAccessFlags dstAccessMask;
1495 oldLayout, // VkImageLayout oldLayout;
1496 newLayout, // VkImageLayout newLayout;
1497 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1498 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1499 image, // VkImage image;
1500 {
1501 aspect, //VkImageAspectFlags aspectMask;
1502 0u, //uint32_t baseMipLevel;
1503 1u, //uint32_t levelCount;
1504 0u, //uint32_t baseArrayLayer;
1505 1u, //uint32_t layerCount;
1506 }, // VkImageSubresourceRange subresourceRange;
1507 };
1508
1509 m_vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr,
1510 1, &barrier);
1511 }
addClearColor(VkCommandBuffer cmdBuffer,VkImage image)1512 void AttachmentAccessOrderTestInstance::addClearColor(VkCommandBuffer cmdBuffer, VkImage image)
1513 {
1514 VkClearColorValue clearColor;
1515 clearColor.float32[0] = 0.0;
1516 clearColor.float32[1] = 0.0;
1517 clearColor.float32[2] = 0.0;
1518 clearColor.float32[3] = 1.0;
1519
1520 const VkImageSubresourceRange subresourceRange = {
1521 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask;
1522 0u, //uint32_t baseMipLevel;
1523 1u, //uint32_t levelCount;
1524 0u, //uint32_t baseArrayLayer;
1525 1u, //uint32_t layerCount;
1526 };
1527
1528 m_vk.cmdClearColorImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
1529 }
1530
addClearDepthStencil(VkCommandBuffer cmdBuffer,VkImage image)1531 void AttachmentAccessOrderTestInstance::addClearDepthStencil(VkCommandBuffer cmdBuffer, VkImage image)
1532 {
1533 VkClearDepthStencilValue clearValue;
1534 clearValue.depth = 0.0;
1535 clearValue.stencil = 0;
1536
1537 const VkImageSubresourceRange subresourceRange = {
1538 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, //VkImageAspectFlags aspectMask;
1539 0u, //uint32_t baseMipLevel;
1540 1u, //uint32_t levelCount;
1541 0u, //uint32_t baseArrayLayer;
1542 1u, //uint32_t layerCount;
1543 };
1544
1545 m_vk.cmdClearDepthStencilImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearValue, 1, &subresourceRange);
1546 }
1547
iterate(void)1548 tcu::TestStatus AttachmentAccessOrderTestInstance::iterate(void)
1549 {
1550 const VkQueue queue = m_context.getUniversalQueue();
1551 const VkDevice device = m_context.getDevice();
1552
1553 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
1554
1555 for (uint32_t i = 0; i < m_subpasses.size(); i++)
1556 {
1557 for (uint32_t j = 0; j < m_subpasses[i].getColorAttachmentNum(); j++)
1558 {
1559 addPipelineBarrier(*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED,
1560 VK_IMAGE_LAYOUT_GENERAL, 0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1561 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1562
1563 addClearColor(*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1564 }
1565 for (uint32_t j = m_subpasses[i].getColorAttachmentNum(); j < m_subpasses[i].getInputAttachmentNum(); j++)
1566 {
1567 addPipelineBarrier(*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED,
1568 VK_IMAGE_LAYOUT_GENERAL, 0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1569 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1570 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1571 addClearDepthStencil(*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1572 }
1573 }
1574
1575 const vk::VkAccessFlags colorOnlyAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
1576 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1577 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1578 const vk::VkAccessFlags depthStencilColorAccessMask = colorOnlyAccessMask |
1579 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
1580 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1581 const vk::VkAccessFlags dstAccessMask =
1582 m_testCase->hasDepthStencil() ? depthStencilColorAccessMask : colorOnlyAccessMask;
1583
1584 const VkMemoryBarrier memBarrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT,
1585 dstAccessMask};
1586
1587 const vk::VkPipelineStageFlags colorOnlyStageFlags =
1588 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1589 const vk::VkPipelineStageFlags depthStencilColorStageFlags =
1590 colorOnlyStageFlags | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
1591 const vk::VkPipelineStageFlags dstStageFlags =
1592 m_testCase->hasDepthStencil() ? depthStencilColorStageFlags : colorOnlyStageFlags;
1593 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageFlags, 0, 1, &memBarrier, 0, DE_NULL,
1594 0, DE_NULL);
1595
1596 const VkRect2D renderArea = makeRect2D(WIDTH, HEIGHT);
1597 beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
1598
1599 const VkDeviceSize vertexBufferOffset = 0;
1600 const VkBuffer vertexBuffer = *m_vertexBuffer;
1601
1602 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1603 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipeline);
1604 VkDescriptorSet dset = *m_descSet;
1605 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipelineLayout, 0, 1,
1606 &dset, 0, DE_NULL);
1607
1608 uint32_t numDraws = m_testCase->m_overlapDraws ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1609 uint32_t numPrimitives = m_testCase->m_overlapPrimitives ? 2 * AttachmentAccessOrderTestCase::ELEM_NUM : 2;
1610 uint32_t numInstances = m_testCase->m_overlapInstances ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1611
1612 for (uint32_t i = 0; i < numDraws; i++)
1613 {
1614 m_vk.cmdPushConstants(
1615 *m_cmdBuffer, *m_subpasses[0].m_pipelineLayout,
1616 VK_SHADER_STAGE_FRAGMENT_BIT | (m_testCase->hasDepthStencil() ? VK_SHADER_STAGE_VERTEX_BIT : 0), 0, 4, &i);
1617 for (uint32_t j = 0; m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getColorAttachmentNum(); j++)
1618 {
1619 addPipelineBarrier(*m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL,
1620 VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1621 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1622 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1623 }
1624 for (uint32_t j = m_subpasses[0].getColorAttachmentNum();
1625 m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getInputAttachmentNum(); j++)
1626 {
1627 const auto fragTests =
1628 (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1629 addPipelineBarrier(*m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL,
1630 VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1631 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, fragTests, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1632 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1633 }
1634 m_vk.cmdDraw(*m_cmdBuffer, numPrimitives * 3, numInstances, 0, 0);
1635 }
1636
1637 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1638
1639 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipeline);
1640
1641 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipelineLayout, 0, 1,
1642 &dset, 0, DE_NULL);
1643
1644 m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 0, 0);
1645
1646 endRenderPass(m_vk, *m_cmdBuffer);
1647
1648 copyImageToBuffer(m_vk, *m_cmdBuffer, *m_subpasses[1].m_inputAtt[0], *m_resultBuffer, tcu::IVec2(WIDTH, HEIGHT),
1649 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
1650
1651 endCommandBuffer(m_vk, *m_cmdBuffer);
1652
1653 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1654
1655 return validateResults(numDraws, numPrimitives, numInstances);
1656 }
1657
validateResults(uint32_t numDraws,uint32_t numPrimitives,uint32_t numInstances)1658 tcu::TestStatus AttachmentAccessOrderTestInstance::validateResults(uint32_t numDraws, uint32_t numPrimitives,
1659 uint32_t numInstances)
1660 {
1661 const VkDevice device = m_context.getDevice();
1662 qpTestResult res = QP_TEST_RESULT_PASS;
1663
1664 invalidateAlloc(m_vk, device, *m_resultBufferMemory);
1665 if (m_testCase->m_integerFormat)
1666 {
1667 tcu::UVec2 *resBuf = static_cast<tcu::UVec2 *>(m_resultBufferMemory->getHostPtr());
1668
1669 for (uint32_t y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y++)
1670 {
1671 for (uint32_t x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x++)
1672 {
1673 tcu::UVec2 pixel = resBuf[y * WIDTH + x];
1674 if (pixel[0] != 0 || pixel[1] != numDraws * numPrimitives / 2 * numInstances)
1675 {
1676 res = QP_TEST_RESULT_FAIL;
1677 }
1678 }
1679 }
1680 }
1681 else
1682 {
1683 tcu::Vec2 *resBuf = static_cast<tcu::Vec2 *>(m_resultBufferMemory->getHostPtr());
1684
1685 for (uint32_t y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y++)
1686 {
1687 for (uint32_t x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x++)
1688 {
1689 tcu::Vec2 pixel = resBuf[y * WIDTH + x];
1690 if (pixel[0] != 0 || pixel[1] != (float)(numDraws * numPrimitives / 2 * numInstances))
1691 {
1692 res = QP_TEST_RESULT_FAIL;
1693 }
1694 }
1695 }
1696 }
1697
1698 return tcu::TestStatus(res, qpGetTestResultName(res));
1699 }
1700
1701 } // namespace
1702
createRasterizationOrderAttachmentAccessTestVariations(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,const string & prefix_name,const string & prefix_desc,uint32_t inputNum,bool integerFormat,bool depth,bool stencil)1703 static void createRasterizationOrderAttachmentAccessTestVariations(tcu::TestContext &testCtx, tcu::TestCaseGroup *gr,
1704 const string &prefix_name, const string &prefix_desc,
1705 uint32_t inputNum, bool integerFormat, bool depth,
1706 bool stencil)
1707 {
1708 const struct
1709 {
1710 const std::string name;
1711 bool explicitSync;
1712 bool overlapDraws;
1713 bool overlapPrimitives;
1714 bool overlapInstances;
1715 } leafTestCreateParams[] = {
1716 // Basic test with overlapping draw commands with barriers
1717 {
1718 "multi_draw_barriers",
1719 true,
1720 true,
1721 false,
1722 false,
1723 },
1724 // Test with overlapping draw commands without barriers
1725 {
1726 "multi_draw",
1727 false,
1728 true,
1729 false,
1730 false,
1731 },
1732 // Test with a draw command with overlapping primitives
1733 {
1734 "multi_primitives",
1735 false,
1736 false,
1737 true,
1738 false,
1739 },
1740 // Test with a draw command with overlapping instances
1741 {
1742 "multi_instances",
1743 false,
1744 false,
1745 false,
1746 true,
1747 },
1748 // Test with overlapping draw commands, each with overlapping primitives and instances
1749 {
1750 "all",
1751 false,
1752 true,
1753 true,
1754 true,
1755 },
1756 };
1757 constexpr uint32_t leafTestCreateParamsNum = sizeof(leafTestCreateParams) / sizeof(leafTestCreateParams[0]);
1758
1759 VkSampleCountFlagBits sampleCountValues[] = {
1760 VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT,
1761 VK_SAMPLE_COUNT_16_BIT, VK_SAMPLE_COUNT_32_BIT, VK_SAMPLE_COUNT_64_BIT,
1762 };
1763 constexpr uint32_t sampleCountValuesNum = sizeof(sampleCountValues) / sizeof(sampleCountValues[0]);
1764
1765 for (uint32_t i = 0; i < sampleCountValuesNum; i++)
1766 {
1767 stringstream name;
1768 stringstream desc;
1769 name << prefix_name << "samples_" << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i]);
1770 desc << prefix_desc << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i])
1771 << " samples per pixel";
1772 tcu::TestCaseGroup *subgr = new tcu::TestCaseGroup(testCtx, name.str().c_str());
1773
1774 for (uint32_t k = 0; k < leafTestCreateParamsNum; k++)
1775 {
1776 if (depth)
1777 {
1778 subgr->addChild(new AttachmentAccessOrderDepthTestCase(
1779 testCtx, leafTestCreateParams[k].name, leafTestCreateParams[k].explicitSync,
1780 leafTestCreateParams[k].overlapDraws, leafTestCreateParams[k].overlapPrimitives,
1781 leafTestCreateParams[k].overlapInstances, sampleCountValues[i]));
1782 }
1783 else if (stencil)
1784 {
1785 subgr->addChild(new AttachmentAccessOrderStencilTestCase(
1786 testCtx, leafTestCreateParams[k].name, leafTestCreateParams[k].explicitSync,
1787 leafTestCreateParams[k].overlapDraws, leafTestCreateParams[k].overlapPrimitives,
1788 leafTestCreateParams[k].overlapInstances, sampleCountValues[i]));
1789 }
1790 else
1791 {
1792 subgr->addChild(new AttachmentAccessOrderColorTestCase(
1793 testCtx, leafTestCreateParams[k].name, leafTestCreateParams[k].explicitSync,
1794 leafTestCreateParams[k].overlapDraws, leafTestCreateParams[k].overlapPrimitives,
1795 leafTestCreateParams[k].overlapInstances, sampleCountValues[i], inputNum, integerFormat));
1796 }
1797 }
1798 gr->addChild(subgr);
1799 }
1800 }
1801
createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,bool integerFormat)1802 static void createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext &testCtx, tcu::TestCaseGroup *gr,
1803 bool integerFormat)
1804 {
1805 const uint32_t inputNum[] = {1, 4, 8};
1806 const uint32_t inputNumSize = sizeof(inputNum) / sizeof(inputNum[0]);
1807
1808 tcu::TestCaseGroup *formatGr;
1809
1810 if (integerFormat)
1811 {
1812 formatGr = new tcu::TestCaseGroup(testCtx, "format_integer");
1813 }
1814 else
1815 {
1816 formatGr = new tcu::TestCaseGroup(testCtx, "format_float");
1817 }
1818
1819 for (uint32_t i = 0; i < inputNumSize; i++)
1820 {
1821 stringstream numName;
1822 stringstream numDesc;
1823 numName << "attachments_" << inputNum[i] << "_";
1824 numDesc << "Tests with " << inputNum[i] << " attachments and ";
1825 createRasterizationOrderAttachmentAccessTestVariations(testCtx, formatGr, numName.str(), numDesc.str(),
1826 inputNum[i], integerFormat, false, false);
1827 }
1828 gr->addChild(formatGr);
1829 }
1830
createRasterizationOrderAttachmentAccessTests(tcu::TestContext & testCtx)1831 tcu::TestCaseGroup *createRasterizationOrderAttachmentAccessTests(tcu::TestContext &testCtx)
1832 {
1833 /* Add the color tests */
1834 // Rasterization Order Attachment access tests
1835 tcu::TestCaseGroup *gr = new tcu::TestCaseGroup(testCtx, "rasterization_order_attachment_access");
1836 createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, false);
1837 createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, true);
1838
1839 /* Add the D/S tests */
1840 tcu::TestCaseGroup *depth_gr = new tcu::TestCaseGroup(testCtx, "depth");
1841 tcu::TestCaseGroup *stencil_gr = new tcu::TestCaseGroup(testCtx, "stencil");
1842 string name_prefix = "";
1843 string desc_prefix = "Tests with ";
1844 createRasterizationOrderAttachmentAccessTestVariations(testCtx, depth_gr, name_prefix, desc_prefix, 1, false, true,
1845 false);
1846 createRasterizationOrderAttachmentAccessTestVariations(testCtx, stencil_gr, name_prefix, desc_prefix, 1, false,
1847 false, true);
1848 gr->addChild(depth_gr);
1849 gr->addChild(stencil_gr);
1850
1851 return gr;
1852 }
1853
1854 } // namespace rasterization
1855 } // namespace vkt
1856