1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 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 Timestamp Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineTimestampTests.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktPipelineReferenceRenderer.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "deUniquePtr.hpp"
44 #include "deStringUtil.hpp"
45 #include "deMemory.h"
46
47 #include <sstream>
48 #include <vector>
49 #include <cctype>
50 #include <locale>
51
52 namespace vkt
53 {
54 namespace pipeline
55 {
56
57 using namespace vk;
58
59 namespace
60 {
61 typedef std::vector<VkPipelineStageFlagBits> StageFlagVector;
62
63 // helper functions
64 #define GEN_DESC_STRING(name,postfix) \
65 do { \
66 for (std::string::size_type ndx = 0; ndx<strlen(#name); ++ndx) \
67 if(isDescription && #name[ndx] == '_') \
68 desc << " "; \
69 else \
70 desc << std::tolower(#name[ndx],loc); \
71 if (isDescription) \
72 desc << " " << #postfix; \
73 else \
74 desc << "_" << #postfix; \
75 } while (deGetFalse())
76
getPipelineStageFlagStr(const VkPipelineStageFlagBits stage,bool isDescription)77 std::string getPipelineStageFlagStr (const VkPipelineStageFlagBits stage,
78 bool isDescription)
79 {
80 std::ostringstream desc;
81 std::locale loc;
82 switch(stage)
83 {
84 #define STAGE_CASE(p) \
85 case VK_PIPELINE_STAGE_##p##_BIT: \
86 { \
87 GEN_DESC_STRING(p, stage); \
88 break; \
89 }
90 STAGE_CASE(TOP_OF_PIPE);
91 STAGE_CASE(DRAW_INDIRECT);
92 STAGE_CASE(VERTEX_INPUT);
93 STAGE_CASE(VERTEX_SHADER);
94 STAGE_CASE(TESSELLATION_CONTROL_SHADER);
95 STAGE_CASE(TESSELLATION_EVALUATION_SHADER);
96 STAGE_CASE(GEOMETRY_SHADER);
97 STAGE_CASE(FRAGMENT_SHADER);
98 STAGE_CASE(EARLY_FRAGMENT_TESTS);
99 STAGE_CASE(LATE_FRAGMENT_TESTS);
100 STAGE_CASE(COLOR_ATTACHMENT_OUTPUT);
101 STAGE_CASE(COMPUTE_SHADER);
102 STAGE_CASE(TRANSFER);
103 STAGE_CASE(HOST);
104 STAGE_CASE(ALL_GRAPHICS);
105 STAGE_CASE(ALL_COMMANDS);
106 #undef STAGE_CASE
107 default:
108 desc << "unknown stage!";
109 DE_FATAL("Unknown Stage!");
110 break;
111 };
112
113 return desc.str();
114 }
115
116 enum TransferMethod
117 {
118 TRANSFER_METHOD_COPY_BUFFER = 0,
119 TRANSFER_METHOD_COPY_IMAGE,
120 TRANSFER_METHOD_BLIT_IMAGE,
121 TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE,
122 TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER,
123 TRANSFER_METHOD_UPDATE_BUFFER,
124 TRANSFER_METHOD_FILL_BUFFER,
125 TRANSFER_METHOD_CLEAR_COLOR_IMAGE,
126 TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE,
127 TRANSFER_METHOD_RESOLVE_IMAGE,
128 TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS,
129 TRANSFER_METHOD_LAST
130 };
131
getTransferMethodStr(const TransferMethod method,bool isDescription)132 std::string getTransferMethodStr(const TransferMethod method,
133 bool isDescription)
134 {
135 std::ostringstream desc;
136 std::locale loc;
137 switch(method)
138 {
139 #define METHOD_CASE(p) \
140 case TRANSFER_METHOD_##p: \
141 { \
142 GEN_DESC_STRING(p, method); \
143 break; \
144 }
145 METHOD_CASE(COPY_BUFFER)
146 METHOD_CASE(COPY_IMAGE)
147 METHOD_CASE(BLIT_IMAGE)
148 METHOD_CASE(COPY_BUFFER_TO_IMAGE)
149 METHOD_CASE(COPY_IMAGE_TO_BUFFER)
150 METHOD_CASE(UPDATE_BUFFER)
151 METHOD_CASE(FILL_BUFFER)
152 METHOD_CASE(CLEAR_COLOR_IMAGE)
153 METHOD_CASE(CLEAR_DEPTH_STENCIL_IMAGE)
154 METHOD_CASE(RESOLVE_IMAGE)
155 METHOD_CASE(COPY_QUERY_POOL_RESULTS)
156 #undef METHOD_CASE
157 default:
158 desc << "unknown method!";
159 DE_FATAL("Unknown method!");
160 break;
161 };
162
163 return desc.str();
164 }
165
166 // helper classes
167 class TimestampTestParam
168 {
169 public:
170 TimestampTestParam (const VkPipelineStageFlagBits* stages,
171 const deUint32 stageCount,
172 const bool inRenderPass);
173 ~TimestampTestParam (void);
174 virtual const std::string generateTestName (void) const;
175 virtual const std::string generateTestDescription (void) const;
getStageVector(void) const176 StageFlagVector getStageVector (void) const { return m_stageVec; }
getInRenderPass(void) const177 bool getInRenderPass (void) const { return m_inRenderPass; }
toggleInRenderPass(void)178 void toggleInRenderPass (void) { m_inRenderPass = !m_inRenderPass; }
179 protected:
180 StageFlagVector m_stageVec;
181 bool m_inRenderPass;
182 };
183
TimestampTestParam(const VkPipelineStageFlagBits * stages,const deUint32 stageCount,const bool inRenderPass)184 TimestampTestParam::TimestampTestParam(const VkPipelineStageFlagBits* stages,
185 const deUint32 stageCount,
186 const bool inRenderPass)
187 : m_inRenderPass(inRenderPass)
188 {
189 for (deUint32 ndx = 0; ndx < stageCount; ndx++)
190 {
191 m_stageVec.push_back(stages[ndx]);
192 }
193 }
194
~TimestampTestParam(void)195 TimestampTestParam::~TimestampTestParam(void)
196 {
197 }
198
generateTestName(void) const199 const std::string TimestampTestParam::generateTestName(void) const
200 {
201 std::string result("");
202
203 for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
204 {
205 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
206 {
207 result += getPipelineStageFlagStr(*it, false) + '_';
208 }
209 }
210 if(m_inRenderPass)
211 result += "in_render_pass";
212 else
213 result += "out_of_render_pass";
214
215 return result;
216 }
217
generateTestDescription(void) const218 const std::string TimestampTestParam::generateTestDescription(void) const
219 {
220 std::string result("Record timestamp after ");
221
222 for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
223 {
224 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
225 {
226 result += getPipelineStageFlagStr(*it, true) + ' ';
227 }
228 }
229 if(m_inRenderPass)
230 result += " in the renderpass";
231 else
232 result += " out of the render pass";
233
234 return result;
235 }
236
237 class TransferTimestampTestParam : public TimestampTestParam
238 {
239 public:
240 TransferTimestampTestParam (const VkPipelineStageFlagBits* stages,
241 const deUint32 stageCount,
242 const bool inRenderPass,
243 const deUint32 methodNdx);
~TransferTimestampTestParam(void)244 ~TransferTimestampTestParam (void) { }
245 const std::string generateTestName (void) const;
246 const std::string generateTestDescription (void) const;
getMethod(void) const247 TransferMethod getMethod (void) const { return m_method; }
248 protected:
249 TransferMethod m_method;
250 };
251
TransferTimestampTestParam(const VkPipelineStageFlagBits * stages,const deUint32 stageCount,const bool inRenderPass,const deUint32 methodNdx)252 TransferTimestampTestParam::TransferTimestampTestParam(const VkPipelineStageFlagBits* stages,
253 const deUint32 stageCount,
254 const bool inRenderPass,
255 const deUint32 methodNdx)
256 : TimestampTestParam(stages, stageCount, inRenderPass)
257 {
258 DE_ASSERT(methodNdx < (deUint32)TRANSFER_METHOD_LAST);
259
260 m_method = (TransferMethod)methodNdx;
261 }
262
generateTestName(void) const263 const std::string TransferTimestampTestParam::generateTestName(void) const
264 {
265 std::string result("");
266
267 for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
268 {
269 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
270 {
271 result += getPipelineStageFlagStr(*it, false) + '_';
272 }
273 }
274
275 result += "with_" + getTransferMethodStr(m_method, false);
276
277 return result;
278 }
279
generateTestDescription(void) const280 const std::string TransferTimestampTestParam::generateTestDescription(void) const
281 {
282 std::string result("");
283
284 for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
285 {
286 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
287 {
288 result += getPipelineStageFlagStr(*it, true) + ' ';
289 }
290 }
291
292 result += "with " + getTransferMethodStr(m_method, true);
293
294 return result;
295 }
296
297 class TwoCmdBuffersTestParam : public TimestampTestParam
298 {
299 public:
300 TwoCmdBuffersTestParam (const VkPipelineStageFlagBits* stages,
301 const deUint32 stageCount,
302 const bool inRenderPass,
303 const VkCommandBufferLevel cmdBufferLevel);
~TwoCmdBuffersTestParam(void)304 ~TwoCmdBuffersTestParam (void) { }
getCmdBufferLevel(void) const305 VkCommandBufferLevel getCmdBufferLevel (void) const { return m_cmdBufferLevel; }
306 protected:
307 VkCommandBufferLevel m_cmdBufferLevel;
308 };
309
TwoCmdBuffersTestParam(const VkPipelineStageFlagBits * stages,const deUint32 stageCount,const bool inRenderPass,const VkCommandBufferLevel cmdBufferLevel)310 TwoCmdBuffersTestParam::TwoCmdBuffersTestParam (const VkPipelineStageFlagBits* stages,
311 const deUint32 stageCount,
312 const bool inRenderPass,
313 const VkCommandBufferLevel cmdBufferLevel)
314 : TimestampTestParam(stages, stageCount, inRenderPass), m_cmdBufferLevel(cmdBufferLevel)
315 {
316 }
317
318 class SimpleGraphicsPipelineBuilder
319 {
320 public:
321 SimpleGraphicsPipelineBuilder (Context& context);
~SimpleGraphicsPipelineBuilder(void)322 ~SimpleGraphicsPipelineBuilder (void) { }
323 void bindShaderStage (VkShaderStageFlagBits stage,
324 const char* source_name);
325 void enableTessellationStage (deUint32 patchControlPoints);
326 Move<VkPipeline> buildPipeline (tcu::UVec2 renderSize,
327 VkRenderPass renderPass);
328 protected:
329 enum
330 {
331 VK_MAX_SHADER_STAGES = 6,
332 };
333
334 Context& m_context;
335
336 Move<VkShaderModule> m_shaderModules[VK_MAX_SHADER_STAGES];
337 deUint32 m_shaderStageCount;
338 VkShaderStageFlagBits m_shaderStages[VK_MAX_SHADER_STAGES];
339
340 deUint32 m_patchControlPoints;
341
342 Move<VkPipelineLayout> m_pipelineLayout;
343 Move<VkPipeline> m_graphicsPipelines;
344
345 };
346
SimpleGraphicsPipelineBuilder(Context & context)347 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder(Context& context)
348 : m_context(context)
349 {
350 m_patchControlPoints = 0;
351 m_shaderStageCount = 0;
352 }
353
bindShaderStage(VkShaderStageFlagBits stage,const char * source_name)354 void SimpleGraphicsPipelineBuilder::bindShaderStage(VkShaderStageFlagBits stage,
355 const char* source_name)
356 {
357 const DeviceInterface& vk = m_context.getDeviceInterface();
358 const VkDevice vkDevice = m_context.getDevice();
359
360 // Create shader module
361 deUint32* pCode = (deUint32*)m_context.getBinaryCollection().get(source_name).getBinary();
362 deUint32 codeSize = (deUint32)m_context.getBinaryCollection().get(source_name).getSize();
363
364 const VkShaderModuleCreateInfo moduleCreateInfo =
365 {
366 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType;
367 DE_NULL, // const void* pNext;
368 0u, // VkShaderModuleCreateFlags flags;
369 codeSize, // deUintptr codeSize;
370 pCode, // const deUint32* pCode;
371 };
372
373 m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
374 m_shaderStages[m_shaderStageCount] = stage;
375
376 m_shaderStageCount++;
377 }
378
buildPipeline(tcu::UVec2 renderSize,VkRenderPass renderPass)379 Move<VkPipeline> SimpleGraphicsPipelineBuilder::buildPipeline(tcu::UVec2 renderSize, VkRenderPass renderPass)
380 {
381 const DeviceInterface& vk = m_context.getDeviceInterface();
382 const VkDevice vkDevice = m_context.getDevice();
383 VkShaderModule vertShaderModule = DE_NULL;
384 VkShaderModule tessControlShaderModule = DE_NULL;
385 VkShaderModule tessEvalShaderModule = DE_NULL;
386 VkShaderModule geomShaderModule = DE_NULL;
387 VkShaderModule fragShaderModule = DE_NULL;
388
389 for (deUint32 i = 0; i < m_shaderStageCount; i++)
390 {
391 if (m_shaderStages[i] == VK_SHADER_STAGE_VERTEX_BIT)
392 vertShaderModule = *m_shaderModules[i];
393 else if (m_shaderStages[i] == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
394 tessControlShaderModule = *m_shaderModules[i];
395 else if (m_shaderStages[i] == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
396 tessEvalShaderModule = *m_shaderModules[i];
397 else if (m_shaderStages[i] == VK_SHADER_STAGE_GEOMETRY_BIT)
398 geomShaderModule = *m_shaderModules[i];
399 else if (m_shaderStages[i] == VK_SHADER_STAGE_FRAGMENT_BIT)
400 fragShaderModule = *m_shaderModules[i];
401 }
402
403 // Create pipeline layout
404 {
405 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
406 {
407 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
408 DE_NULL, // const void* pNext;
409 0u, // VkPipelineLayoutCreateFlags flags;
410 0u, // deUint32 setLayoutCount;
411 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
412 0u, // deUint32 pushConstantRangeCount;
413 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
414 };
415
416 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
417 }
418
419 // Create pipeline
420 const VkVertexInputBindingDescription vertexInputBindingDescription =
421 {
422 0u, // deUint32 binding;
423 sizeof(Vertex4RGBA), // deUint32 strideInBytes;
424 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
425 };
426
427 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
428 {
429 {
430 0u, // deUint32 location;
431 0u, // deUint32 binding;
432 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
433 0u // deUint32 offsetInBytes;
434 },
435 {
436 1u, // deUint32 location;
437 0u, // deUint32 binding;
438 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
439 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offsetInBytes;
440 }
441 };
442
443 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
444 {
445 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
446 DE_NULL, // const void* pNext;
447 0u, // VkPipelineVertexInputStateCreateFlags flags;
448 1u, // deUint32 vertexBindingDescriptionCount;
449 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
450 2u, // deUint32 vertexAttributeDescriptionCount;
451 vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
452 };
453
454 VkPrimitiveTopology primitiveTopology = (m_patchControlPoints > 0) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
455
456 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
457 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
458
459 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
460 {
461 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
462 DE_NULL, // const void* pNext;
463 0u, // VkPipelineDepthStencilStateCreateFlags flags;
464 VK_TRUE, // VkBool32 depthTestEnable;
465 VK_TRUE, // VkBool32 depthWriteEnable;
466 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp;
467 VK_FALSE, // VkBool32 depthBoundsTestEnable;
468 VK_FALSE, // VkBool32 stencilTestEnable;
469 // VkStencilOpState front;
470 {
471 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
472 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
473 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
474 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
475 0u, // deUint32 compareMask;
476 0u, // deUint32 writeMask;
477 0u, // deUint32 reference;
478 },
479 // VkStencilOpState back;
480 {
481 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
482 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
483 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
484 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
485 0u, // deUint32 compareMask;
486 0u, // deUint32 writeMask;
487 0u, // deUint32 reference;
488 },
489 0.0f, // float minDepthBounds;
490 1.0f, // float maxDepthBounds;
491 };
492
493 return makeGraphicsPipeline(vk, // const DeviceInterface& vk
494 vkDevice, // const VkDevice device
495 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
496 vertShaderModule, // const VkShaderModule vertexShaderModule
497 tessControlShaderModule, // const VkShaderModule tessellationControlModule
498 tessEvalShaderModule, // const VkShaderModule tessellationEvalModule
499 geomShaderModule, // const VkShaderModule geometryShaderModule
500 fragShaderModule, // const VkShaderModule fragmentShaderModule
501 renderPass, // const VkRenderPass renderPass
502 viewports, // const std::vector<VkViewport>& viewports
503 scissors, // const std::vector<VkRect2D>& scissors
504 primitiveTopology, // const VkPrimitiveTopology topology
505 0u, // const deUint32 subpass
506 m_patchControlPoints, // const deUint32 patchControlPoints
507 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
508 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
509 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
510 &depthStencilStateParams); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
511 }
512
enableTessellationStage(deUint32 patchControlPoints)513 void SimpleGraphicsPipelineBuilder::enableTessellationStage(deUint32 patchControlPoints)
514 {
515 m_patchControlPoints = patchControlPoints;
516 }
517
518 template <class Test>
newTestCase(tcu::TestContext & testContext,TimestampTestParam * testParam)519 vkt::TestCase* newTestCase(tcu::TestContext& testContext,
520 TimestampTestParam* testParam)
521 {
522 return new Test(testContext,
523 testParam->generateTestName().c_str(),
524 testParam->generateTestDescription().c_str(),
525 testParam);
526 }
527
528 // Test Classes
529 class TimestampTest : public vkt::TestCase
530 {
531 public:
532 enum
533 {
534 ENTRY_COUNT = 8
535 };
536
TimestampTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)537 TimestampTest(tcu::TestContext& testContext,
538 const std::string& name,
539 const std::string& description,
540 const TimestampTestParam* param)
541 : vkt::TestCase (testContext, name, description)
542 , m_stages (param->getStageVector())
543 , m_inRenderPass (param->getInRenderPass())
544 { }
~TimestampTest(void)545 virtual ~TimestampTest (void) { }
546 virtual void initPrograms (SourceCollections& programCollection) const;
547 virtual TestInstance* createInstance (Context& context) const;
548 protected:
549 const StageFlagVector m_stages;
550 const bool m_inRenderPass;
551 };
552
553 class TimestampTestInstance : public vkt::TestInstance
554 {
555 public:
556 TimestampTestInstance (Context& context,
557 const StageFlagVector& stages,
558 const bool inRenderPass);
559 virtual ~TimestampTestInstance (void);
560 virtual tcu::TestStatus iterate (void);
561 protected:
562 virtual tcu::TestStatus verifyTimestamp (void);
563 virtual void configCommandBuffer (void);
564 Move<VkBuffer> createBufferAndBindMemory (VkDeviceSize size,
565 VkBufferUsageFlags usage,
566 de::MovePtr<Allocation>* pAlloc);
567 Move<VkImage> createImage2DAndBindMemory (VkFormat format,
568 deUint32 width,
569 deUint32 height,
570 VkImageUsageFlags usage,
571 VkSampleCountFlagBits sampleCount,
572 de::MovePtr<Allocation>* pAlloc);
573 protected:
574 const StageFlagVector m_stages;
575 bool m_inRenderPass;
576
577 Move<VkCommandPool> m_cmdPool;
578 Move<VkCommandBuffer> m_cmdBuffer;
579 Move<VkQueryPool> m_queryPool;
580 deUint64* m_timestampValues;
581 };
582
initPrograms(SourceCollections & programCollection) const583 void TimestampTest::initPrograms(SourceCollections& programCollection) const
584 {
585 vkt::TestCase::initPrograms(programCollection);
586 }
587
createInstance(Context & context) const588 TestInstance* TimestampTest::createInstance(Context& context) const
589 {
590 return new TimestampTestInstance(context,m_stages,m_inRenderPass);
591 }
592
TimestampTestInstance(Context & context,const StageFlagVector & stages,const bool inRenderPass)593 TimestampTestInstance::TimestampTestInstance(Context& context,
594 const StageFlagVector& stages,
595 const bool inRenderPass)
596 : TestInstance (context)
597 , m_stages (stages)
598 , m_inRenderPass(inRenderPass)
599 {
600 const DeviceInterface& vk = context.getDeviceInterface();
601 const VkDevice vkDevice = context.getDevice();
602 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
603
604 // Check support for timestamp queries
605 {
606 const std::vector<VkQueueFamilyProperties> queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
607
608 DE_ASSERT(queueFamilyIndex < (deUint32)queueProperties.size());
609
610 if (!queueProperties[queueFamilyIndex].timestampValidBits)
611 throw tcu::NotSupportedError("Universal queue does not support timestamps");
612 }
613
614 // Create Query Pool
615 {
616 const VkQueryPoolCreateInfo queryPoolParams =
617 {
618 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType;
619 DE_NULL, // const void* pNext;
620 0u, // VkQueryPoolCreateFlags flags;
621 VK_QUERY_TYPE_TIMESTAMP, // VkQueryType queryType;
622 TimestampTest::ENTRY_COUNT, // deUint32 entryCount;
623 0u, // VkQueryPipelineStatisticFlags pipelineStatistics;
624 };
625
626 m_queryPool = createQueryPool(vk, vkDevice, &queryPoolParams);
627 }
628
629 // Create command pool
630 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
631
632 // Create command buffer
633 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
634
635 // alloc timestamp values
636 m_timestampValues = new deUint64[m_stages.size()];
637 }
638
~TimestampTestInstance(void)639 TimestampTestInstance::~TimestampTestInstance(void)
640 {
641 if(m_timestampValues)
642 {
643 delete[] m_timestampValues;
644 m_timestampValues = NULL;
645 }
646 }
647
configCommandBuffer(void)648 void TimestampTestInstance::configCommandBuffer(void)
649 {
650 const DeviceInterface& vk = m_context.getDeviceInterface();
651
652 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
653
654 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
655
656 deUint32 timestampEntry = 0;
657 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
658 {
659 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
660 }
661
662 endCommandBuffer(vk, *m_cmdBuffer);
663 }
664
iterate(void)665 tcu::TestStatus TimestampTestInstance::iterate(void)
666 {
667 const DeviceInterface& vk = m_context.getDeviceInterface();
668 const VkDevice vkDevice = m_context.getDevice();
669 const VkQueue queue = m_context.getUniversalQueue();
670
671 configCommandBuffer();
672
673 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
674
675 // Generate the timestamp mask
676 deUint64 timestampMask;
677 const std::vector<VkQueueFamilyProperties> queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
678 if(queueProperties[0].timestampValidBits == 0)
679 {
680 return tcu::TestStatus::fail("Device does not support timestamp!");
681 }
682 else if(queueProperties[0].timestampValidBits == 64)
683 {
684 timestampMask = 0xFFFFFFFFFFFFFFFF;
685 }
686 else
687 {
688 timestampMask = ((deUint64)1 << queueProperties[0].timestampValidBits) - 1;
689 }
690
691 // Get timestamp value from query pool
692 deUint32 stageSize = (deUint32)m_stages.size();
693
694 vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, stageSize, sizeof(deUint64) * stageSize, (void*)m_timestampValues, sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
695
696 for (deUint32 ndx = 0; ndx < stageSize; ndx++)
697 {
698 m_timestampValues[ndx] &= timestampMask;
699 }
700
701 return verifyTimestamp();
702 }
703
verifyTimestamp(void)704 tcu::TestStatus TimestampTestInstance::verifyTimestamp(void)
705 {
706 for (deUint32 first = 0; first < m_stages.size(); first++)
707 {
708 for (deUint32 second = 0; second < first; second++)
709 {
710 if(m_timestampValues[first] < m_timestampValues[second])
711 {
712 return tcu::TestStatus::fail("Latter stage timestamp is smaller than the former stage timestamp.");
713 }
714 }
715 }
716
717 return tcu::TestStatus::pass("Timestamp increases steadily.");
718 }
719
createBufferAndBindMemory(VkDeviceSize size,VkBufferUsageFlags usage,de::MovePtr<Allocation> * pAlloc)720 Move<VkBuffer> TimestampTestInstance::createBufferAndBindMemory(VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
721 {
722 const DeviceInterface& vk = m_context.getDeviceInterface();
723 const VkDevice vkDevice = m_context.getDevice();
724 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
725 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
726
727 const VkBufferCreateInfo vertexBufferParams =
728 {
729 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
730 DE_NULL, // const void* pNext;
731 0u, // VkBufferCreateFlags flags;
732 size, // VkDeviceSize size;
733 usage, // VkBufferUsageFlags usage;
734 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
735 1u, // deUint32 queueFamilyCount;
736 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
737 };
738
739 Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
740 de::MovePtr<Allocation> vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
741
742 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
743
744 DE_ASSERT(pAlloc);
745 *pAlloc = vertexBufferAlloc;
746
747 return vertexBuffer;
748 }
749
createImage2DAndBindMemory(VkFormat format,deUint32 width,deUint32 height,VkImageUsageFlags usage,VkSampleCountFlagBits sampleCount,de::details::MovePtr<Allocation> * pAlloc)750 Move<VkImage> TimestampTestInstance::createImage2DAndBindMemory(VkFormat format,
751 deUint32 width,
752 deUint32 height,
753 VkImageUsageFlags usage,
754 VkSampleCountFlagBits sampleCount,
755 de::details::MovePtr<Allocation>* pAlloc)
756 {
757 const DeviceInterface& vk = m_context.getDeviceInterface();
758 const VkDevice vkDevice = m_context.getDevice();
759 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
760 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
761
762 // Optimal tiling feature check
763 VkFormatProperties formatProperty;
764 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), format, &formatProperty);
765 if((usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(formatProperty.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
766 {
767 // Remove color attachment usage if the optimal tiling feature does not support it
768 usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
769 }
770 if((usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(formatProperty.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
771 {
772 // Remove storage usage if the optimal tiling feature does not support it
773 usage &= ~VK_IMAGE_USAGE_STORAGE_BIT;
774 }
775
776 const VkImageCreateInfo colorImageParams =
777 {
778 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
779 DE_NULL, // const void* pNext;
780 0u, // VkImageCreateFlags flags;
781 VK_IMAGE_TYPE_2D, // VkImageType imageType;
782 format, // VkFormat format;
783 { width, height, 1u }, // VkExtent3D extent;
784 1u, // deUint32 mipLevels;
785 1u, // deUint32 arraySize;
786 sampleCount, // deUint32 samples;
787 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
788 usage, // VkImageUsageFlags usage;
789 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
790 1u, // deUint32 queueFamilyCount;
791 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
792 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
793 };
794
795 Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
796
797 // Allocate and bind image memory
798 de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
799 VK_CHECK(vk.bindImageMemory(vkDevice, *image, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
800
801 DE_ASSERT(pAlloc);
802 *pAlloc = colorImageAlloc;
803
804 return image;
805 }
806
807 class BasicGraphicsTest : public TimestampTest
808 {
809 public:
BasicGraphicsTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)810 BasicGraphicsTest(tcu::TestContext& testContext,
811 const std::string& name,
812 const std::string& description,
813 const TimestampTestParam* param)
814 : TimestampTest (testContext, name, description, param)
815 { }
~BasicGraphicsTest(void)816 virtual ~BasicGraphicsTest (void) { }
817 virtual void initPrograms (SourceCollections& programCollection) const;
818 virtual TestInstance* createInstance (Context& context) const;
819 };
820
821 class BasicGraphicsTestInstance : public TimestampTestInstance
822 {
823 public:
824 enum
825 {
826 VK_MAX_SHADER_STAGES = 6,
827 };
828 BasicGraphicsTestInstance (Context& context,
829 const StageFlagVector stages,
830 const bool inRenderPass);
831 virtual ~BasicGraphicsTestInstance (void);
832 protected:
833 virtual void configCommandBuffer (void);
834 virtual void buildVertexBuffer (void);
835 virtual void buildRenderPass (VkFormat colorFormat,
836 VkFormat depthFormat);
837 virtual void buildFrameBuffer (tcu::UVec2 renderSize,
838 VkFormat colorFormat,
839 VkFormat depthFormat);
840 protected:
841 const tcu::UVec2 m_renderSize;
842 const VkFormat m_colorFormat;
843 const VkFormat m_depthFormat;
844
845 Move<VkImage> m_colorImage;
846 de::MovePtr<Allocation> m_colorImageAlloc;
847 Move<VkImage> m_depthImage;
848 de::MovePtr<Allocation> m_depthImageAlloc;
849 Move<VkImageView> m_colorAttachmentView;
850 Move<VkImageView> m_depthAttachmentView;
851 Move<VkRenderPass> m_renderPass;
852 Move<VkFramebuffer> m_framebuffer;
853 VkImageMemoryBarrier m_imageLayoutBarriers[2];
854
855 de::MovePtr<Allocation> m_vertexBufferAlloc;
856 Move<VkBuffer> m_vertexBuffer;
857 std::vector<Vertex4RGBA> m_vertices;
858
859 SimpleGraphicsPipelineBuilder m_pipelineBuilder;
860 Move<VkPipeline> m_graphicsPipelines;
861 };
862
initPrograms(SourceCollections & programCollection) const863 void BasicGraphicsTest::initPrograms (SourceCollections& programCollection) const
864 {
865 programCollection.glslSources.add("color_vert") << glu::VertexSource(
866 "#version 310 es\n"
867 "layout(location = 0) in vec4 position;\n"
868 "layout(location = 1) in vec4 color;\n"
869 "layout(location = 0) out highp vec4 vtxColor;\n"
870 "void main (void)\n"
871 "{\n"
872 " gl_Position = position;\n"
873 " vtxColor = color;\n"
874 "}\n");
875
876 programCollection.glslSources.add("color_frag") << glu::FragmentSource(
877 "#version 310 es\n"
878 "layout(location = 0) in highp vec4 vtxColor;\n"
879 "layout(location = 0) out highp vec4 fragColor;\n"
880 "void main (void)\n"
881 "{\n"
882 " fragColor = vtxColor;\n"
883 "}\n");
884 }
885
createInstance(Context & context) const886 TestInstance* BasicGraphicsTest::createInstance(Context& context) const
887 {
888 return new BasicGraphicsTestInstance(context,m_stages,m_inRenderPass);
889 }
890
buildVertexBuffer(void)891 void BasicGraphicsTestInstance::buildVertexBuffer(void)
892 {
893 const DeviceInterface& vk = m_context.getDeviceInterface();
894 const VkDevice vkDevice = m_context.getDevice();
895
896 // Create vertex buffer
897 {
898 m_vertexBuffer = createBufferAndBindMemory(1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferAlloc);
899
900 m_vertices = createOverlappingQuads();
901 // Load vertices into vertex buffer
902 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
903 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
904 }
905 }
906
buildRenderPass(VkFormat colorFormat,VkFormat depthFormat)907 void BasicGraphicsTestInstance::buildRenderPass(VkFormat colorFormat, VkFormat depthFormat)
908 {
909 const DeviceInterface& vk = m_context.getDeviceInterface();
910 const VkDevice vkDevice = m_context.getDevice();
911
912 // Create render pass
913 m_renderPass = makeRenderPass(vk, vkDevice, colorFormat, depthFormat);
914 }
915
buildFrameBuffer(tcu::UVec2 renderSize,VkFormat colorFormat,VkFormat depthFormat)916 void BasicGraphicsTestInstance::buildFrameBuffer(tcu::UVec2 renderSize, VkFormat colorFormat, VkFormat depthFormat)
917 {
918 const DeviceInterface& vk = m_context.getDeviceInterface();
919 const VkDevice vkDevice = m_context.getDevice();
920 const VkComponentMapping ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
921
922 // Create color image
923 {
924 m_colorImage = createImage2DAndBindMemory(colorFormat,
925 renderSize.x(),
926 renderSize.y(),
927 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
928 VK_SAMPLE_COUNT_1_BIT,
929 &m_colorImageAlloc);
930 }
931
932 // Create depth image
933 {
934 m_depthImage = createImage2DAndBindMemory(depthFormat,
935 renderSize.x(),
936 renderSize.y(),
937 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
938 VK_SAMPLE_COUNT_1_BIT,
939 &m_depthImageAlloc);
940 }
941
942 // Set up image layout transition barriers
943 {
944 const VkImageMemoryBarrier colorImageBarrier =
945 {
946 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
947 DE_NULL, // const void* pNext;
948 0u, // VkAccessFlags srcAccessMask;
949 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
950 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
951 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
952 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
953 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
954 *m_colorImage, // VkImage image;
955 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
956 };
957 const VkImageMemoryBarrier depthImageBarrier =
958 {
959 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
960 DE_NULL, // const void* pNext;
961 0u, // VkAccessFlags srcAccessMask;
962 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
963 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
964 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
965 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
966 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
967 *m_depthImage, // VkImage image;
968 { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
969 };
970
971 m_imageLayoutBarriers[0] = colorImageBarrier;
972 m_imageLayoutBarriers[1] = depthImageBarrier;
973 }
974
975 // Create color attachment view
976 {
977 const VkImageViewCreateInfo colorAttachmentViewParams =
978 {
979 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
980 DE_NULL, // const void* pNext;
981 0u, // VkImageViewCreateFlags flags;
982 *m_colorImage, // VkImage image;
983 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
984 colorFormat, // VkFormat format;
985 ComponentMappingRGBA, // VkComponentMapping components;
986 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
987 };
988
989 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
990 }
991
992 // Create depth attachment view
993 {
994 const VkImageViewCreateInfo depthAttachmentViewParams =
995 {
996 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
997 DE_NULL, // const void* pNext;
998 0u, // VkImageViewCreateFlags flags;
999 *m_depthImage, // VkImage image;
1000 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1001 depthFormat, // VkFormat format;
1002 ComponentMappingRGBA, // VkComponentMapping components;
1003 { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
1004 };
1005
1006 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
1007 }
1008
1009 // Create framebuffer
1010 {
1011 const VkImageView attachmentBindInfos[2] =
1012 {
1013 *m_colorAttachmentView,
1014 *m_depthAttachmentView,
1015 };
1016
1017 const VkFramebufferCreateInfo framebufferParams =
1018 {
1019 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1020 DE_NULL, // const void* pNext;
1021 0u, // VkFramebufferCreateFlags flags;
1022 *m_renderPass, // VkRenderPass renderPass;
1023 2u, // deUint32 attachmentCount;
1024 attachmentBindInfos, // const VkImageView* pAttachments;
1025 (deUint32)renderSize.x(), // deUint32 width;
1026 (deUint32)renderSize.y(), // deUint32 height;
1027 1u, // deUint32 layers;
1028 };
1029
1030 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1031 }
1032
1033 }
1034
BasicGraphicsTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass)1035 BasicGraphicsTestInstance::BasicGraphicsTestInstance(Context& context,
1036 const StageFlagVector stages,
1037 const bool inRenderPass)
1038 : TimestampTestInstance (context,stages,inRenderPass)
1039 , m_renderSize (32, 32)
1040 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
1041 , m_depthFormat (VK_FORMAT_D16_UNORM)
1042 , m_pipelineBuilder (context)
1043 {
1044 buildVertexBuffer();
1045
1046 buildRenderPass(m_colorFormat, m_depthFormat);
1047
1048 buildFrameBuffer(m_renderSize, m_colorFormat, m_depthFormat);
1049
1050 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert");
1051 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag");
1052
1053 m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1054
1055 }
1056
~BasicGraphicsTestInstance(void)1057 BasicGraphicsTestInstance::~BasicGraphicsTestInstance(void)
1058 {
1059 }
1060
configCommandBuffer(void)1061 void BasicGraphicsTestInstance::configCommandBuffer(void)
1062 {
1063 const DeviceInterface& vk = m_context.getDeviceInterface();
1064
1065 const VkClearValue attachmentClearValues[2] =
1066 {
1067 defaultClearValue(m_colorFormat),
1068 defaultClearValue(m_depthFormat),
1069 };
1070
1071 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1072
1073 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1074 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
1075
1076 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1077
1078 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
1079
1080 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1081 VkDeviceSize offsets = 0u;
1082 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1083 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
1084
1085 if(m_inRenderPass)
1086 {
1087 deUint32 timestampEntry = 0u;
1088 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1089 {
1090 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1091 }
1092 }
1093
1094 endRenderPass(vk, *m_cmdBuffer);
1095
1096 if(!m_inRenderPass)
1097 {
1098 deUint32 timestampEntry = 0u;
1099 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1100 {
1101 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1102 }
1103 }
1104
1105 endCommandBuffer(vk, *m_cmdBuffer);
1106 }
1107
1108 class AdvGraphicsTest : public BasicGraphicsTest
1109 {
1110 public:
AdvGraphicsTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)1111 AdvGraphicsTest (tcu::TestContext& testContext,
1112 const std::string& name,
1113 const std::string& description,
1114 const TimestampTestParam* param)
1115 : BasicGraphicsTest(testContext, name, description, param)
1116 { }
~AdvGraphicsTest(void)1117 virtual ~AdvGraphicsTest (void) { }
1118 virtual void initPrograms (SourceCollections& programCollection) const;
1119 virtual TestInstance* createInstance (Context& context) const;
1120 };
1121
1122 class AdvGraphicsTestInstance : public BasicGraphicsTestInstance
1123 {
1124 public:
1125 AdvGraphicsTestInstance (Context& context,
1126 const StageFlagVector stages,
1127 const bool inRenderPass);
1128 virtual ~AdvGraphicsTestInstance (void);
1129 virtual void configCommandBuffer (void);
1130 protected:
1131 virtual void featureSupportCheck (void);
1132 protected:
1133 VkPhysicalDeviceFeatures m_features;
1134 deUint32 m_draw_count;
1135 de::MovePtr<Allocation> m_indirectBufferAlloc;
1136 Move<VkBuffer> m_indirectBuffer;
1137 };
1138
initPrograms(SourceCollections & programCollection) const1139 void AdvGraphicsTest::initPrograms(SourceCollections& programCollection) const
1140 {
1141 BasicGraphicsTest::initPrograms(programCollection);
1142
1143 programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
1144 "#version 310 es\n"
1145 "#extension GL_EXT_geometry_shader : enable\n"
1146 "layout(triangles) in;\n"
1147 "layout(triangle_strip, max_vertices = 3) out;\n"
1148 "layout(location = 0) in highp vec4 in_vtxColor[];\n"
1149 "layout(location = 0) out highp vec4 vtxColor;\n"
1150 "void main (void)\n"
1151 "{\n"
1152 " for(int ndx=0; ndx<3; ndx++)\n"
1153 " {\n"
1154 " gl_Position = gl_in[ndx].gl_Position;\n"
1155 " vtxColor = in_vtxColor[ndx];\n"
1156 " EmitVertex();\n"
1157 " }\n"
1158 " EndPrimitive();\n"
1159 "}\n");
1160
1161 programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
1162 "#version 310 es\n"
1163 "#extension GL_EXT_tessellation_shader : enable\n"
1164 "layout(vertices = 3) out;\n"
1165 "layout(location = 0) in highp vec4 color[];\n"
1166 "layout(location = 0) out highp vec4 vtxColor[];\n"
1167 "void main()\n"
1168 "{\n"
1169 " gl_TessLevelOuter[0] = 4.0;\n"
1170 " gl_TessLevelOuter[1] = 4.0;\n"
1171 " gl_TessLevelOuter[2] = 4.0;\n"
1172 " gl_TessLevelInner[0] = 4.0;\n"
1173 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1174 " vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
1175 "}\n");
1176
1177 programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
1178 "#version 310 es\n"
1179 "#extension GL_EXT_tessellation_shader : enable\n"
1180 "layout(triangles, fractional_even_spacing, ccw) in;\n"
1181 "layout(location = 0) in highp vec4 colors[];\n"
1182 "layout(location = 0) out highp vec4 vtxColor;\n"
1183 "void main() \n"
1184 "{\n"
1185 " float u = gl_TessCoord.x;\n"
1186 " float v = gl_TessCoord.y;\n"
1187 " float w = gl_TessCoord.z;\n"
1188 " vec4 pos = vec4(0);\n"
1189 " vec4 color = vec4(0);\n"
1190 " pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
1191 " color.xyz += u * colors[0].xyz;\n"
1192 " pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
1193 " color.xyz += v * colors[1].xyz;\n"
1194 " pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
1195 " color.xyz += w * colors[2].xyz;\n"
1196 " pos.w = 1.0;\n"
1197 " color.w = 1.0;\n"
1198 " gl_Position = pos;\n"
1199 " vtxColor = color;\n"
1200 "}\n");
1201 }
1202
createInstance(Context & context) const1203 TestInstance* AdvGraphicsTest::createInstance(Context& context) const
1204 {
1205 return new AdvGraphicsTestInstance(context,m_stages,m_inRenderPass);
1206 }
1207
featureSupportCheck(void)1208 void AdvGraphicsTestInstance::featureSupportCheck(void)
1209 {
1210 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1211 {
1212 switch(*it)
1213 {
1214 case VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT:
1215 if (m_features.geometryShader == VK_FALSE)
1216 {
1217 TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1218 }
1219 break;
1220 case VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT:
1221 case VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT:
1222 if (m_features.tessellationShader == VK_FALSE)
1223 {
1224 TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1225 }
1226 break;
1227 case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
1228 default:
1229 break;
1230 };
1231 }
1232 }
1233
AdvGraphicsTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass)1234 AdvGraphicsTestInstance::AdvGraphicsTestInstance(Context& context,
1235 const StageFlagVector stages,
1236 const bool inRenderPass)
1237 : BasicGraphicsTestInstance(context, stages, inRenderPass)
1238 {
1239 m_features = m_context.getDeviceFeatures();
1240
1241 // If necessary feature is not supported, throw error and fail current test
1242 featureSupportCheck();
1243
1244 if(m_features.geometryShader == VK_TRUE)
1245 {
1246 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo");
1247 }
1248
1249 if(m_features.tessellationShader == VK_TRUE)
1250 {
1251 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs");
1252 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes");
1253 m_pipelineBuilder.enableTessellationStage(3);
1254 }
1255
1256 m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1257
1258 // Prepare the indirect draw buffer
1259 const DeviceInterface& vk = m_context.getDeviceInterface();
1260 const VkDevice vkDevice = m_context.getDevice();
1261
1262 if(m_features.multiDrawIndirect == VK_TRUE)
1263 {
1264 m_draw_count = 2;
1265 }
1266 else
1267 {
1268 m_draw_count = 1;
1269 }
1270 m_indirectBuffer = createBufferAndBindMemory(32u, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, &m_indirectBufferAlloc);
1271
1272 const VkDrawIndirectCommand indirectCmds[] =
1273 {
1274 {
1275 12u, // deUint32 vertexCount;
1276 1u, // deUint32 instanceCount;
1277 0u, // deUint32 firstVertex;
1278 0u, // deUint32 firstInstance;
1279 },
1280 {
1281 12u, // deUint32 vertexCount;
1282 1u, // deUint32 instanceCount;
1283 11u, // deUint32 firstVertex;
1284 0u, // deUint32 firstInstance;
1285 },
1286 };
1287 // Load data into indirect draw buffer
1288 deMemcpy(m_indirectBufferAlloc->getHostPtr(), indirectCmds, m_draw_count * sizeof(VkDrawIndirectCommand));
1289 flushAlloc(vk, vkDevice, *m_indirectBufferAlloc);
1290
1291 }
1292
~AdvGraphicsTestInstance(void)1293 AdvGraphicsTestInstance::~AdvGraphicsTestInstance(void)
1294 {
1295 }
1296
configCommandBuffer(void)1297 void AdvGraphicsTestInstance::configCommandBuffer(void)
1298 {
1299 const DeviceInterface& vk = m_context.getDeviceInterface();
1300
1301 const VkClearValue attachmentClearValues[2] =
1302 {
1303 defaultClearValue(m_colorFormat),
1304 defaultClearValue(m_depthFormat),
1305 };
1306
1307 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1308
1309 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1310 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
1311
1312 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1313
1314 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
1315
1316 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1317
1318 VkDeviceSize offsets = 0u;
1319 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1320
1321 vk.cmdDrawIndirect(*m_cmdBuffer, *m_indirectBuffer, 0u, m_draw_count, sizeof(VkDrawIndirectCommand));
1322
1323 if(m_inRenderPass)
1324 {
1325 deUint32 timestampEntry = 0u;
1326 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1327 {
1328 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1329 }
1330 }
1331
1332 endRenderPass(vk, *m_cmdBuffer);
1333
1334 if(!m_inRenderPass)
1335 {
1336 deUint32 timestampEntry = 0u;
1337 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1338 {
1339 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1340 }
1341 }
1342
1343 endCommandBuffer(vk, *m_cmdBuffer);
1344 }
1345
1346 class BasicComputeTest : public TimestampTest
1347 {
1348 public:
BasicComputeTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)1349 BasicComputeTest (tcu::TestContext& testContext,
1350 const std::string& name,
1351 const std::string& description,
1352 const TimestampTestParam* param)
1353 : TimestampTest(testContext, name, description, param)
1354 { }
~BasicComputeTest(void)1355 virtual ~BasicComputeTest (void) { }
1356 virtual void initPrograms (SourceCollections& programCollection) const;
1357 virtual TestInstance* createInstance (Context& context) const;
1358 };
1359
1360 class BasicComputeTestInstance : public TimestampTestInstance
1361 {
1362 public:
1363 BasicComputeTestInstance (Context& context,
1364 const StageFlagVector stages,
1365 const bool inRenderPass);
1366 virtual ~BasicComputeTestInstance (void);
1367 virtual void configCommandBuffer (void);
1368 protected:
1369 de::MovePtr<Allocation> m_inputBufAlloc;
1370 Move<VkBuffer> m_inputBuf;
1371 de::MovePtr<Allocation> m_outputBufAlloc;
1372 Move<VkBuffer> m_outputBuf;
1373
1374 Move<VkDescriptorPool> m_descriptorPool;
1375 Move<VkDescriptorSet> m_descriptorSet;
1376 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1377
1378 Move<VkPipelineLayout> m_pipelineLayout;
1379 Move<VkShaderModule> m_computeShaderModule;
1380 Move<VkPipeline> m_computePipelines;
1381 };
1382
initPrograms(SourceCollections & programCollection) const1383 void BasicComputeTest::initPrograms(SourceCollections& programCollection) const
1384 {
1385 TimestampTest::initPrograms(programCollection);
1386
1387 programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
1388 "#version 310 es\n"
1389 "layout(local_size_x = 128) in;\n"
1390 "layout(std430) buffer;\n"
1391 "layout(binding = 0) readonly buffer Input0\n"
1392 "{\n"
1393 " vec4 elements[];\n"
1394 "} input_data0;\n"
1395 "layout(binding = 1) writeonly buffer Output\n"
1396 "{\n"
1397 " vec4 elements[];\n"
1398 "} output_data;\n"
1399 "void main()\n"
1400 "{\n"
1401 " uint ident = gl_GlobalInvocationID.x;\n"
1402 " output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1403 "}");
1404 }
1405
createInstance(Context & context) const1406 TestInstance* BasicComputeTest::createInstance(Context& context) const
1407 {
1408 return new BasicComputeTestInstance(context,m_stages,m_inRenderPass);
1409 }
1410
BasicComputeTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass)1411 BasicComputeTestInstance::BasicComputeTestInstance(Context& context,
1412 const StageFlagVector stages,
1413 const bool inRenderPass)
1414 : TimestampTestInstance(context, stages, inRenderPass)
1415 {
1416 const DeviceInterface& vk = context.getDeviceInterface();
1417 const VkDevice vkDevice = context.getDevice();
1418
1419 // Create buffer object, allocate storage, and generate input data
1420 const VkDeviceSize size = sizeof(tcu::Vec4) * 128u * 128u;
1421 m_inputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_inputBufAlloc);
1422 // Load vertices into buffer
1423 tcu::Vec4* pVec = reinterpret_cast<tcu::Vec4*>(m_inputBufAlloc->getHostPtr());
1424 for (deUint32 ndx = 0u; ndx < (128u * 128u); ndx++)
1425 {
1426 for (deUint32 component = 0u; component < 4u; component++)
1427 {
1428 pVec[ndx][component]= (float)(ndx * (component + 1u));
1429 }
1430 }
1431 flushAlloc(vk, vkDevice, *m_inputBufAlloc);
1432
1433 m_outputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_outputBufAlloc);
1434
1435 std::vector<VkDescriptorBufferInfo> descriptorInfos;
1436 descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, size));
1437 descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf, 0u, size));
1438
1439 // Create descriptor set layout
1440 DescriptorSetLayoutBuilder descLayoutBuilder;
1441
1442 for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1443 {
1444 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1445 }
1446
1447 m_descriptorSetLayout = descLayoutBuilder.build(vk, vkDevice);
1448
1449 // Create descriptor pool
1450 m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1451
1452 // Create descriptor set
1453 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1454 {
1455 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
1456 DE_NULL, // const void* pNext;
1457 *m_descriptorPool, // VkDescriptorPool descriptorPool;
1458 1u, // deUint32 setLayoutCount;
1459 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
1460 };
1461 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);
1462
1463 DescriptorSetUpdateBuilder builder;
1464 for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
1465 {
1466 builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(descriptorNdx), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfos[descriptorNdx]);
1467 }
1468 builder.update(vk, vkDevice);
1469
1470 // Create compute pipeline layout
1471 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1472 {
1473 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1474 DE_NULL, // const void* pNext;
1475 0u, // VkPipelineLayoutCreateFlags flags;
1476 1u, // deUint32 setLayoutCount;
1477 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
1478 0u, // deUint32 pushConstantRangeCount;
1479 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
1480 };
1481
1482 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1483
1484 // Create compute shader
1485 VkShaderModuleCreateInfo shaderModuleCreateInfo =
1486 {
1487 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType;
1488 DE_NULL, // const void* pNext;
1489 0u, // VkShaderModuleCreateFlags flags;
1490 m_context.getBinaryCollection().get("basic_compute").getSize(), // deUintptr codeSize;
1491 (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(), // const deUint32* pCode;
1492
1493 };
1494
1495 m_computeShaderModule = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1496
1497 // Create compute pipeline
1498 const VkPipelineShaderStageCreateInfo stageCreateInfo =
1499 {
1500 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1501 DE_NULL, // const void* pNext;
1502 0u, // VkPipelineShaderStageCreateFlags flags;
1503 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
1504 *m_computeShaderModule, // VkShaderModule module;
1505 "main", // const char* pName;
1506 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
1507 };
1508
1509 const VkComputePipelineCreateInfo pipelineCreateInfo =
1510 {
1511 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1512 DE_NULL, // const void* pNext;
1513 0u, // VkPipelineCreateFlags flags;
1514 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
1515 *m_pipelineLayout, // VkPipelineLayout layout;
1516 (VkPipeline)0, // VkPipeline basePipelineHandle;
1517 0u, // deInt32 basePipelineIndex;
1518 };
1519
1520 m_computePipelines = createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo);
1521
1522 }
1523
~BasicComputeTestInstance(void)1524 BasicComputeTestInstance::~BasicComputeTestInstance(void)
1525 {
1526 }
1527
configCommandBuffer(void)1528 void BasicComputeTestInstance::configCommandBuffer(void)
1529 {
1530 const DeviceInterface& vk = m_context.getDeviceInterface();
1531
1532 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1533
1534 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1535
1536 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
1537 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
1538 vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);
1539
1540 deUint32 timestampEntry = 0u;
1541 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1542 {
1543 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1544 }
1545
1546 endCommandBuffer(vk, *m_cmdBuffer);
1547 }
1548
1549 class TransferTest : public TimestampTest
1550 {
1551 public:
1552 TransferTest (tcu::TestContext& testContext,
1553 const std::string& name,
1554 const std::string& description,
1555 const TimestampTestParam* param);
~TransferTest(void)1556 virtual ~TransferTest (void) { }
1557 virtual void initPrograms (SourceCollections& programCollection) const;
1558 virtual TestInstance* createInstance (Context& context) const;
1559 protected:
1560 TransferMethod m_method;
1561 };
1562
1563 class TransferTestInstance : public TimestampTestInstance
1564 {
1565 public:
1566 TransferTestInstance (Context& context,
1567 const StageFlagVector stages,
1568 const bool inRenderPass,
1569 const TransferMethod method);
1570 virtual ~TransferTestInstance (void);
1571 virtual void configCommandBuffer (void);
1572 virtual void initialImageTransition (VkCommandBuffer cmdBuffer,
1573 VkImage image,
1574 VkImageSubresourceRange subRange,
1575 VkImageLayout layout);
1576 protected:
1577 TransferMethod m_method;
1578
1579 VkDeviceSize m_bufSize;
1580 Move<VkBuffer> m_srcBuffer;
1581 Move<VkBuffer> m_dstBuffer;
1582 de::MovePtr<Allocation> m_srcBufferAlloc;
1583 de::MovePtr<Allocation> m_dstBufferAlloc;
1584
1585 VkFormat m_imageFormat;
1586 deInt32 m_imageWidth;
1587 deInt32 m_imageHeight;
1588 VkDeviceSize m_imageSize;
1589 Move<VkImage> m_srcImage;
1590 Move<VkImage> m_dstImage;
1591 Move<VkImage> m_depthImage;
1592 Move<VkImage> m_msImage;
1593 de::MovePtr<Allocation> m_srcImageAlloc;
1594 de::MovePtr<Allocation> m_dstImageAlloc;
1595 de::MovePtr<Allocation> m_depthImageAlloc;
1596 de::MovePtr<Allocation> m_msImageAlloc;
1597 };
1598
TransferTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TimestampTestParam * param)1599 TransferTest::TransferTest(tcu::TestContext& testContext,
1600 const std::string& name,
1601 const std::string& description,
1602 const TimestampTestParam* param)
1603 : TimestampTest(testContext, name, description, param)
1604 {
1605 const TransferTimestampTestParam* transferParam = dynamic_cast<const TransferTimestampTestParam*>(param);
1606 m_method = transferParam->getMethod();
1607 }
1608
initPrograms(SourceCollections & programCollection) const1609 void TransferTest::initPrograms(SourceCollections& programCollection) const
1610 {
1611 TimestampTest::initPrograms(programCollection);
1612 }
1613
createInstance(Context & context) const1614 TestInstance* TransferTest::createInstance(Context& context) const
1615 {
1616 return new TransferTestInstance(context, m_stages, m_inRenderPass, m_method);
1617 }
1618
TransferTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass,const TransferMethod method)1619 TransferTestInstance::TransferTestInstance(Context& context,
1620 const StageFlagVector stages,
1621 const bool inRenderPass,
1622 const TransferMethod method)
1623 : TimestampTestInstance(context, stages, inRenderPass)
1624 , m_method(method)
1625 , m_bufSize(256u)
1626 , m_imageFormat(VK_FORMAT_R8G8B8A8_UNORM)
1627 , m_imageWidth(4u)
1628 , m_imageHeight(4u)
1629 , m_imageSize(256u)
1630 {
1631 const DeviceInterface& vk = context.getDeviceInterface();
1632 const VkDevice vkDevice = context.getDevice();
1633
1634 // Create src buffer
1635 m_srcBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &m_srcBufferAlloc);
1636
1637 // Init the source buffer memory
1638 char* pBuf = reinterpret_cast<char*>(m_srcBufferAlloc->getHostPtr());
1639 memset(pBuf, 0xFF, sizeof(char)*(size_t)m_bufSize);
1640 flushAlloc(vk, vkDevice, *m_srcBufferAlloc);
1641
1642 // Create dst buffer
1643 m_dstBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &m_dstBufferAlloc);
1644
1645 // Create src/dst/depth image
1646 m_srcImage = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1647 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1648 VK_SAMPLE_COUNT_1_BIT,
1649 &m_srcImageAlloc);
1650 m_dstImage = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1651 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1652 VK_SAMPLE_COUNT_1_BIT,
1653 &m_dstImageAlloc);
1654 m_depthImage = createImage2DAndBindMemory(VK_FORMAT_D16_UNORM, m_imageWidth, m_imageHeight,
1655 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1656 VK_SAMPLE_COUNT_1_BIT,
1657 &m_depthImageAlloc);
1658 m_msImage = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1659 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1660 VK_SAMPLE_COUNT_4_BIT,
1661 &m_msImageAlloc);
1662 }
1663
~TransferTestInstance(void)1664 TransferTestInstance::~TransferTestInstance(void)
1665 {
1666 }
1667
configCommandBuffer(void)1668 void TransferTestInstance::configCommandBuffer(void)
1669 {
1670 const DeviceInterface& vk = m_context.getDeviceInterface();
1671
1672 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1673
1674 // Initialize buffer/image
1675 vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
1676
1677 const VkClearColorValue srcClearValue =
1678 {
1679 {1.0f, 1.0f, 1.0f, 1.0f}
1680 };
1681 const VkClearColorValue dstClearValue =
1682 {
1683 {0.0f, 0.0f, 0.0f, 0.0f}
1684 };
1685 const struct VkImageSubresourceRange subRangeColor =
1686 {
1687 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1688 0u, // deUint32 baseMipLevel;
1689 1u, // deUint32 mipLevels;
1690 0u, // deUint32 baseArrayLayer;
1691 1u, // deUint32 arraySize;
1692 };
1693 const struct VkImageSubresourceRange subRangeDepth =
1694 {
1695 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
1696 0u, // deUint32 baseMipLevel;
1697 1u, // deUint32 mipLevels;
1698 0u, // deUint32 baseArrayLayer;
1699 1u, // deUint32 arraySize;
1700 };
1701
1702 initialImageTransition(*m_cmdBuffer, *m_srcImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
1703 initialImageTransition(*m_cmdBuffer, *m_dstImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
1704
1705 vk.cmdClearColorImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
1706 vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &dstClearValue, 1u, &subRangeColor);
1707
1708 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1709
1710 // Copy Operations
1711 const VkImageSubresourceLayers imgSubResCopy =
1712 {
1713 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1714 0u, // deUint32 mipLevel;
1715 0u, // deUint32 baseArrayLayer;
1716 1u, // deUint32 layerCount;
1717 };
1718
1719 const VkOffset3D nullOffset = {0u, 0u, 0u};
1720 const VkExtent3D imageExtent = {(deUint32)m_imageWidth, (deUint32)m_imageHeight, 1u};
1721 const VkOffset3D imageOffset = {(int)m_imageWidth, (int)m_imageHeight, 1};
1722 switch(m_method)
1723 {
1724 case TRANSFER_METHOD_COPY_BUFFER:
1725 {
1726 const VkBufferCopy copyBufRegion =
1727 {
1728 0u, // VkDeviceSize srcOffset;
1729 0u, // VkDeviceSize destOffset;
1730 512u, // VkDeviceSize copySize;
1731 };
1732 vk.cmdCopyBuffer(*m_cmdBuffer, *m_srcBuffer, *m_dstBuffer, 1u, ©BufRegion);
1733 break;
1734 }
1735 case TRANSFER_METHOD_COPY_IMAGE:
1736 {
1737 const VkImageCopy copyImageRegion =
1738 {
1739 imgSubResCopy, // VkImageSubresourceCopy srcSubresource;
1740 nullOffset, // VkOffset3D srcOffset;
1741 imgSubResCopy, // VkImageSubresourceCopy destSubresource;
1742 nullOffset, // VkOffset3D destOffset;
1743 imageExtent, // VkExtent3D extent;
1744
1745 };
1746 vk.cmdCopyImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, ©ImageRegion);
1747 break;
1748 }
1749 case TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE:
1750 {
1751 const VkBufferImageCopy bufImageCopy =
1752 {
1753 0u, // VkDeviceSize bufferOffset;
1754 (deUint32)m_imageWidth, // deUint32 bufferRowLength;
1755 (deUint32)m_imageHeight, // deUint32 bufferImageHeight;
1756 imgSubResCopy, // VkImageSubresourceCopy imageSubresource;
1757 nullOffset, // VkOffset3D imageOffset;
1758 imageExtent, // VkExtent3D imageExtent;
1759 };
1760 vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_srcBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &bufImageCopy);
1761 break;
1762 }
1763 case TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER:
1764 {
1765 const VkBufferImageCopy imgBufferCopy =
1766 {
1767 0u, // VkDeviceSize bufferOffset;
1768 (deUint32)m_imageWidth, // deUint32 bufferRowLength;
1769 (deUint32)m_imageHeight, // deUint32 bufferImageHeight;
1770 imgSubResCopy, // VkImageSubresourceCopy imageSubresource;
1771 nullOffset, // VkOffset3D imageOffset;
1772 imageExtent, // VkExtent3D imageExtent;
1773 };
1774 vk.cmdCopyImageToBuffer(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstBuffer, 1u, &imgBufferCopy);
1775 break;
1776 }
1777 case TRANSFER_METHOD_BLIT_IMAGE:
1778 {
1779 const VkImageBlit imageBlt =
1780 {
1781 imgSubResCopy, // VkImageSubresourceCopy srcSubresource;
1782 {
1783 nullOffset,
1784 imageOffset,
1785 },
1786 imgSubResCopy, // VkImageSubresourceCopy destSubresource;
1787 {
1788 nullOffset,
1789 imageOffset,
1790 }
1791 };
1792 vk.cmdBlitImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageBlt, VK_FILTER_NEAREST);
1793 break;
1794 }
1795 case TRANSFER_METHOD_CLEAR_COLOR_IMAGE:
1796 {
1797 vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
1798 break;
1799 }
1800 case TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE:
1801 {
1802 initialImageTransition(*m_cmdBuffer, *m_depthImage, subRangeDepth, VK_IMAGE_LAYOUT_GENERAL);
1803 const VkClearDepthStencilValue clearDSValue =
1804 {
1805 1.0f, // float depth;
1806 0u, // deUint32 stencil;
1807 };
1808 vk.cmdClearDepthStencilImage(*m_cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_GENERAL, &clearDSValue, 1u, &subRangeDepth);
1809 break;
1810 }
1811 case TRANSFER_METHOD_FILL_BUFFER:
1812 {
1813 vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
1814 break;
1815 }
1816 case TRANSFER_METHOD_UPDATE_BUFFER:
1817 {
1818 const deUint32 data[] =
1819 {
1820 0xdeadbeef, 0xabcdef00, 0x12345678
1821 };
1822 vk.cmdUpdateBuffer(*m_cmdBuffer, *m_dstBuffer, 0x10, sizeof(data), data);
1823 break;
1824 }
1825 case TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS:
1826 {
1827 vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
1828 vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 8u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
1829 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
1830 break;
1831 }
1832 case TRANSFER_METHOD_RESOLVE_IMAGE:
1833 {
1834 const VkImageResolve imageResolve =
1835 {
1836 imgSubResCopy, // VkImageSubresourceLayers srcSubresource;
1837 nullOffset, // VkOffset3D srcOffset;
1838 imgSubResCopy, // VkImageSubresourceLayers destSubresource;
1839 nullOffset, // VkOffset3D destOffset;
1840 imageExtent, // VkExtent3D extent;
1841 };
1842 initialImageTransition(*m_cmdBuffer, *m_msImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
1843 vk.cmdClearColorImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
1844 vk.cmdResolveImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolve);
1845 break;
1846 }
1847 default:
1848 DE_FATAL("Unknown Transfer Method!");
1849 break;
1850 };
1851
1852 deUint32 timestampEntry = 0u;
1853 for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1854 {
1855 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1856 }
1857
1858 endCommandBuffer(vk, *m_cmdBuffer);
1859 }
1860
initialImageTransition(VkCommandBuffer cmdBuffer,VkImage image,VkImageSubresourceRange subRange,VkImageLayout layout)1861 void TransferTestInstance::initialImageTransition (VkCommandBuffer cmdBuffer, VkImage image, VkImageSubresourceRange subRange, VkImageLayout layout)
1862 {
1863 const DeviceInterface& vk = m_context.getDeviceInterface();
1864 const VkImageMemoryBarrier imageMemBarrier =
1865 {
1866 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1867 DE_NULL, // const void* pNext;
1868 0u, // VkAccessFlags srcAccessMask;
1869 0u, // VkAccessFlags dstAccessMask;
1870 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1871 layout, // VkImageLayout newLayout;
1872 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1873 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1874 image, // VkImage image;
1875 subRange // VkImageSubresourceRange subresourceRange;
1876 };
1877
1878 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageMemBarrier);
1879 }
1880
1881 class TwoCmdBuffersTest : public TimestampTest
1882 {
1883 public:
TwoCmdBuffersTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TwoCmdBuffersTestParam * param)1884 TwoCmdBuffersTest (tcu::TestContext& testContext,
1885 const std::string& name,
1886 const std::string& description,
1887 const TwoCmdBuffersTestParam* param)
1888 : TimestampTest (testContext, name, description, param), m_cmdBufferLevel(param->getCmdBufferLevel()) { }
~TwoCmdBuffersTest(void)1889 virtual ~TwoCmdBuffersTest (void) { }
1890 virtual TestInstance* createInstance (Context& context) const;
1891
1892 protected:
1893 VkCommandBufferLevel m_cmdBufferLevel;
1894 };
1895
1896 class TwoCmdBuffersTestInstance : public TimestampTestInstance
1897 {
1898 public:
1899 TwoCmdBuffersTestInstance (Context& context,
1900 const StageFlagVector stages,
1901 const bool inRenderPass,
1902 VkCommandBufferLevel cmdBufferLevel);
1903 virtual ~TwoCmdBuffersTestInstance (void);
1904 virtual tcu::TestStatus iterate (void);
1905 protected:
1906 virtual void configCommandBuffer (void);
1907
1908 protected:
1909 Move<VkCommandBuffer> m_secondCmdBuffer;
1910 Move<VkBuffer> m_dstBuffer;
1911 de::MovePtr<Allocation> m_dstBufferAlloc;
1912 VkCommandBufferLevel m_cmdBufferLevel;
1913 };
1914
createInstance(Context & context) const1915 TestInstance* TwoCmdBuffersTest::createInstance (Context& context) const
1916 {
1917 return new TwoCmdBuffersTestInstance(context, m_stages, m_inRenderPass, m_cmdBufferLevel);
1918 }
1919
TwoCmdBuffersTestInstance(Context & context,const StageFlagVector stages,const bool inRenderPass,VkCommandBufferLevel cmdBufferLevel)1920 TwoCmdBuffersTestInstance::TwoCmdBuffersTestInstance (Context& context,
1921 const StageFlagVector stages,
1922 const bool inRenderPass,
1923 VkCommandBufferLevel cmdBufferLevel)
1924 : TimestampTestInstance (context, stages, inRenderPass), m_cmdBufferLevel(cmdBufferLevel)
1925 {
1926 const DeviceInterface& vk = context.getDeviceInterface();
1927 const VkDevice vkDevice = context.getDevice();
1928
1929 m_secondCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, cmdBufferLevel);
1930 m_dstBuffer = createBufferAndBindMemory(1024, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &m_dstBufferAlloc);
1931 }
1932
~TwoCmdBuffersTestInstance(void)1933 TwoCmdBuffersTestInstance::~TwoCmdBuffersTestInstance (void)
1934 {
1935 }
1936
configCommandBuffer(void)1937 void TwoCmdBuffersTestInstance::configCommandBuffer (void)
1938 {
1939 const DeviceInterface& vk = m_context.getDeviceInterface();
1940
1941 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1942 {
1943 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1944 DE_NULL, // const void* pNext;
1945 0u, // VkCommandBufferUsageFlags flags;
1946 (const VkCommandBufferInheritanceInfo*)DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
1947 };
1948
1949 if (m_cmdBufferLevel == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
1950 {
1951 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1952 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1953 vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, *m_queryPool, 0);
1954 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1955 VK_CHECK(vk.beginCommandBuffer(*m_secondCmdBuffer, &cmdBufferBeginInfo));
1956 vk.cmdCopyQueryPoolResults(*m_secondCmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 0u, 0u);
1957 VK_CHECK(vk.endCommandBuffer(*m_secondCmdBuffer));
1958 }
1959 else
1960 {
1961 const VkCommandBufferInheritanceInfo inheritanceInfo =
1962 {
1963 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
1964 DE_NULL, // const void* pNext;
1965 DE_NULL, // VkRenderPass renderPass;
1966 0u, // deUint32 subpass;
1967 DE_NULL, // VkFramebuffer framebuffer;
1968 VK_FALSE, // VkBool32 occlusionQueryEnable;
1969 0u, // VkQueryControlFlags queryFlags;
1970 0u // VkQueryPipelineStatisticFlags pipelineStatistics;
1971 };
1972
1973 const VkCommandBufferBeginInfo cmdBufferBeginInfoSecondary =
1974 {
1975 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1976 DE_NULL, // const void* pNext;
1977 0u, // VkCommandBufferUsageFlags flags;
1978 &inheritanceInfo // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
1979 };
1980
1981 VK_CHECK(vk.beginCommandBuffer(*m_secondCmdBuffer, &cmdBufferBeginInfoSecondary));
1982 vk.cmdResetQueryPool(*m_secondCmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1983 vk.cmdWriteTimestamp(*m_secondCmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, *m_queryPool, 0);
1984 VK_CHECK(vk.endCommandBuffer(*m_secondCmdBuffer));
1985 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1986 vk.cmdExecuteCommands(m_cmdBuffer.get(), 1u, &m_secondCmdBuffer.get());
1987 vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 0u, 0u);
1988 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1989 }
1990 }
1991
iterate(void)1992 tcu::TestStatus TwoCmdBuffersTestInstance::iterate (void)
1993 {
1994 const DeviceInterface& vk = m_context.getDeviceInterface();
1995 const VkQueue queue = m_context.getUniversalQueue();
1996
1997 configCommandBuffer();
1998
1999 const VkCommandBuffer cmdBuffers[] = { m_cmdBuffer.get(), m_secondCmdBuffer.get() };
2000
2001 const VkSubmitInfo submitInfo =
2002 {
2003 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
2004 DE_NULL, // const void* pNext;
2005 0u, // deUint32 waitSemaphoreCount;
2006 DE_NULL, // const VkSemaphore* pWaitSemaphores;
2007 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
2008 m_cmdBufferLevel == VK_COMMAND_BUFFER_LEVEL_PRIMARY ? 2u : 1u, // deUint32 commandBufferCount;
2009 cmdBuffers, // const VkCommandBuffer* pCommandBuffers;
2010 0u, // deUint32 signalSemaphoreCount;
2011 DE_NULL, // const VkSemaphore* pSignalSemaphores;
2012 };
2013
2014 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
2015 VK_CHECK(vk.queueWaitIdle(queue));
2016
2017 // Always pass in case no crash occurred.
2018 return tcu::TestStatus::pass("Pass");
2019 }
2020
2021 } // anonymous
2022
createTimestampTests(tcu::TestContext & testCtx)2023 tcu::TestCaseGroup* createTimestampTests (tcu::TestContext& testCtx)
2024 {
2025 de::MovePtr<tcu::TestCaseGroup> timestampTests (new tcu::TestCaseGroup(testCtx, "timestamp", "timestamp tests"));
2026
2027 // Basic Graphics Tests
2028 {
2029 de::MovePtr<tcu::TestCaseGroup> basicGraphicsTests (new tcu::TestCaseGroup(testCtx, "basic_graphics_tests", "Record timestamp in different pipeline stages of basic graphics tests"));
2030
2031 const VkPipelineStageFlagBits basicGraphicsStages0[][2] =
2032 {
2033 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT},
2034 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
2035 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
2036 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT},
2037 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
2038 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
2039 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT},
2040 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
2041 };
2042 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages0); stageNdx++)
2043 {
2044 TimestampTestParam param(basicGraphicsStages0[stageNdx], 2u, true);
2045 basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, ¶m));
2046 param.toggleInRenderPass();
2047 basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, ¶m));
2048 }
2049
2050 const VkPipelineStageFlagBits basicGraphicsStages1[][3] =
2051 {
2052 {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
2053 {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
2054 };
2055 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages1); stageNdx++)
2056 {
2057 TimestampTestParam param(basicGraphicsStages1[stageNdx], 3u, true);
2058 basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, ¶m));
2059 param.toggleInRenderPass();
2060 basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, ¶m));
2061 }
2062
2063 timestampTests->addChild(basicGraphicsTests.release());
2064 }
2065
2066 // Advanced Graphics Tests
2067 {
2068 de::MovePtr<tcu::TestCaseGroup> advGraphicsTests (new tcu::TestCaseGroup(testCtx, "advanced_graphics_tests", "Record timestamp in different pipeline stages of advanced graphics tests"));
2069
2070 const VkPipelineStageFlagBits advGraphicsStages[][2] =
2071 {
2072 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT},
2073 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT},
2074 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT},
2075 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
2076 };
2077 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(advGraphicsStages); stageNdx++)
2078 {
2079 TimestampTestParam param(advGraphicsStages[stageNdx], 2u, true);
2080 advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, ¶m));
2081 param.toggleInRenderPass();
2082 advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, ¶m));
2083 }
2084
2085 timestampTests->addChild(advGraphicsTests.release());
2086 }
2087
2088 // Basic Compute Tests
2089 {
2090 de::MovePtr<tcu::TestCaseGroup> basicComputeTests (new tcu::TestCaseGroup(testCtx, "basic_compute_tests", "Record timestamp for compute stages"));
2091
2092 const VkPipelineStageFlagBits basicComputeStages[][2] =
2093 {
2094 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
2095 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
2096 };
2097 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicComputeStages); stageNdx++)
2098 {
2099 TimestampTestParam param(basicComputeStages[stageNdx], 2u, false);
2100 basicComputeTests->addChild(newTestCase<BasicComputeTest>(testCtx, ¶m));
2101 }
2102
2103 timestampTests->addChild(basicComputeTests.release());
2104 }
2105
2106 // Transfer Tests
2107 {
2108 de::MovePtr<tcu::TestCaseGroup> transferTests (new tcu::TestCaseGroup(testCtx, "transfer_tests", "Record timestamp for transfer stages"));
2109
2110 const VkPipelineStageFlagBits transferStages[][2] =
2111 {
2112 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT},
2113 {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT},
2114 };
2115 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(transferStages); stageNdx++)
2116 {
2117 for (deUint32 method = 0u; method < TRANSFER_METHOD_LAST; method++)
2118 {
2119 TransferTimestampTestParam param(transferStages[stageNdx], 2u, false, method);
2120 transferTests->addChild(newTestCase<TransferTest>(testCtx, ¶m));
2121 }
2122 }
2123
2124 timestampTests->addChild(transferTests.release());
2125 }
2126
2127 // Misc Tests
2128 {
2129 de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc_tests", "Misc tests that can not be categorized to other group."));
2130
2131 const VkPipelineStageFlagBits miscStages[] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
2132 TimestampTestParam param(miscStages, 1u, false);
2133 miscTests->addChild(new TimestampTest(testCtx,
2134 "timestamp_only",
2135 "Only write timestamp command in the commmand buffer",
2136 ¶m));
2137
2138 TwoCmdBuffersTestParam twoCmdBuffersParamPrimary(miscStages, 1u, false, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2139 miscTests->addChild(new TwoCmdBuffersTest(testCtx,
2140 "two_cmd_buffers_primary",
2141 "Issue query in a command buffer and copy it on another primary command buffer",
2142 &twoCmdBuffersParamPrimary));
2143
2144 TwoCmdBuffersTestParam twoCmdBuffersParamSecondary(miscStages, 1u, false, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2145 miscTests->addChild(new TwoCmdBuffersTest(testCtx,
2146 "two_cmd_buffers_secondary",
2147 "Issue query in a secondary command buffer and copy it on a primary command buffer",
2148 &twoCmdBuffersParamSecondary));
2149
2150 timestampTests->addChild(miscTests.release());
2151 }
2152
2153 return timestampTests.release();
2154 }
2155
2156 } // pipeline
2157
2158 } // vkt
2159