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