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