1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 ARM Limited. 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 PushConstant Tests 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktPipelinePushConstantTests.hpp" 26#include "vktPipelineClearUtil.hpp" 27#include "vktPipelineImageUtil.hpp" 28#include "vktPipelineVertexUtil.hpp" 29#include "vktPipelineReferenceRenderer.hpp" 30#include "vktTestCase.hpp" 31#include "vkImageUtil.hpp" 32#include "vkMemUtil.hpp" 33#include "vkPrograms.hpp" 34#include "vkQueryUtil.hpp" 35#include "vkRef.hpp" 36#include "vkRefUtil.hpp" 37#include "vkBuilderUtil.hpp" 38#include "vkTypeUtil.hpp" 39#include "tcuImageCompare.hpp" 40#include "deMemory.h" 41#include "deRandom.hpp" 42#include "deStringUtil.hpp" 43#include "deUniquePtr.hpp" 44 45#include <algorithm> 46#include <sstream> 47#include <vector> 48 49namespace vkt 50{ 51namespace pipeline 52{ 53 54using namespace vk; 55 56namespace 57{ 58 59enum 60{ 61 TRIANGLE_COUNT = 2, 62 MAX_RANGE_COUNT = 5 63}; 64 65enum RangeSizeCase 66{ 67 SIZE_CASE_4 = 0, 68 SIZE_CASE_16, 69 SIZE_CASE_32, 70 SIZE_CASE_48, 71 SIZE_CASE_128, 72 SIZE_CASE_UNSUPPORTED 73}; 74 75struct PushConstantData 76{ 77 struct PushConstantRange 78 { 79 VkShaderStageFlags shaderStage; 80 deUint32 offset; 81 deUint32 size; 82 } range; 83 struct PushConstantUpdate 84 { 85 deUint32 offset; 86 deUint32 size; 87 } update; 88}; 89 90// These values will be loaded from push constants and used as an index 91static const deUint32 DYNAMIC_VEC_INDEX = 2u; 92static const deUint32 DYNAMIC_MAT_INDEX = 0u; 93static const deUint32 DYNAMIC_ARR_INDEX = 3u; 94 95// These reference values will be compared in the shader to ensure the correct index was read 96static const float DYNAMIC_VEC_CONSTANT = 0.25f; 97static const float DYNAMIC_MAT_CONSTANT = 0.50f; 98static const float DYNAMIC_ARR_CONSTANT = 0.75f; 99 100enum IndexType 101{ 102 INDEX_TYPE_CONST_LITERAL = 0, 103 INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR, 104 105 INDEX_TYPE_LAST 106}; 107 108class PushConstantGraphicsTest : public vkt::TestCase 109{ 110public: 111 PushConstantGraphicsTest (tcu::TestContext& testContext, 112 const std::string& name, 113 const std::string& description, 114 const deUint32 rangeCount, 115 const PushConstantData pushConstantRange[MAX_RANGE_COUNT], 116 const deBool multipleUpdate, 117 const IndexType indexType); 118 virtual ~PushConstantGraphicsTest (void); 119 virtual void initPrograms (SourceCollections& sourceCollections) const; 120 virtual TestInstance* createInstance (Context& context) const; 121 RangeSizeCase getRangeSizeCase (deUint32 rangeSize) const; 122 123private: 124 const deUint32 m_rangeCount; 125 PushConstantData m_pushConstantRange[MAX_RANGE_COUNT]; 126 const deBool m_multipleUpdate; 127 const IndexType m_indexType; 128}; 129 130class PushConstantGraphicsTestInstance : public vkt::TestInstance 131{ 132public: 133 PushConstantGraphicsTestInstance (Context& context, 134 const deUint32 rangeCount, 135 const PushConstantData pushConstantRange[MAX_RANGE_COUNT], 136 const deBool multipleUpdate, 137 const IndexType indexType); 138 virtual ~PushConstantGraphicsTestInstance (void); 139 virtual tcu::TestStatus iterate (void); 140 141 void createShaderStage (const DeviceInterface& vk, 142 VkDevice device, 143 const BinaryCollection& programCollection, 144 const char* name, 145 VkShaderStageFlagBits stage, 146 Move<VkShaderModule>* module); 147 std::vector<Vertex4RGBA> createQuad (const float size); 148 149private: 150 tcu::TestStatus verifyImage (void); 151 152private: 153 const tcu::UVec2 m_renderSize; 154 const VkFormat m_colorFormat; 155 const deUint32 m_rangeCount; 156 PushConstantData m_pushConstantRange[MAX_RANGE_COUNT]; 157 const deBool m_multipleUpdate; 158 const IndexType m_indexType; 159 160 VkImageCreateInfo m_colorImageCreateInfo; 161 Move<VkImage> m_colorImage; 162 de::MovePtr<Allocation> m_colorImageAlloc; 163 Move<VkImageView> m_colorAttachmentView; 164 Move<VkRenderPass> m_renderPass; 165 Move<VkFramebuffer> m_framebuffer; 166 167 Move<VkShaderModule> m_vertexShaderModule; 168 Move<VkShaderModule> m_fragmentShaderModule; 169 Move<VkShaderModule> m_geometryShaderModule; 170 Move<VkShaderModule> m_tessControlShaderModule; 171 Move<VkShaderModule> m_tessEvaluationShaderModule; 172 173 VkShaderStageFlags m_shaderFlags; 174 std::vector<VkPipelineShaderStageCreateInfo> m_shaderStage; 175 176 Move<VkBuffer> m_vertexBuffer; 177 std::vector<Vertex4RGBA> m_vertices; 178 de::MovePtr<Allocation> m_vertexBufferAlloc; 179 180 Move<VkBuffer> m_uniformBuffer; 181 de::MovePtr<Allocation> m_uniformBufferAlloc; 182 Move<VkDescriptorPool> m_descriptorPool; 183 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 184 Move<VkDescriptorSet> m_descriptorSet; 185 186 Move<VkPipelineLayout> m_pipelineLayout; 187 Move<VkPipeline> m_graphicsPipelines; 188 189 Move<VkCommandPool> m_cmdPool; 190 Move<VkCommandBuffer> m_cmdBuffer; 191 192 Move<VkFence> m_fence; 193}; 194 195PushConstantGraphicsTest::PushConstantGraphicsTest (tcu::TestContext& testContext, 196 const std::string& name, 197 const std::string& description, 198 const deUint32 rangeCount, 199 const PushConstantData pushConstantRange[MAX_RANGE_COUNT], 200 const deBool multipleUpdate, 201 const IndexType indexType) 202 : vkt::TestCase (testContext, name, description) 203 , m_rangeCount (rangeCount) 204 , m_multipleUpdate (multipleUpdate) 205 , m_indexType (indexType) 206{ 207 deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT); 208} 209 210PushConstantGraphicsTest::~PushConstantGraphicsTest (void) 211{ 212} 213 214TestInstance* PushConstantGraphicsTest::createInstance (Context& context) const 215{ 216 return new PushConstantGraphicsTestInstance(context, m_rangeCount, m_pushConstantRange, m_multipleUpdate, m_indexType); 217} 218 219RangeSizeCase PushConstantGraphicsTest::getRangeSizeCase (deUint32 rangeSize) const 220{ 221 switch (rangeSize) 222 { 223 case 4: 224 return SIZE_CASE_4; 225 case 16: 226 return SIZE_CASE_16; 227 case 32: 228 return SIZE_CASE_32; 229 case 48: 230 return SIZE_CASE_48; 231 case 128: 232 return SIZE_CASE_128; 233 default: 234 DE_FATAL("Range size unsupported yet"); 235 return SIZE_CASE_UNSUPPORTED; 236 } 237} 238 239void PushConstantGraphicsTest::initPrograms (SourceCollections& sourceCollections) const 240{ 241 std::ostringstream vertexSrc; 242 std::ostringstream fragmentSrc; 243 std::ostringstream geometrySrc; 244 std::ostringstream tessControlSrc; 245 std::ostringstream tessEvaluationSrc; 246 247 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++) 248 { 249 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_VERTEX_BIT) 250 { 251 vertexSrc << "#version 450\n" 252 << "layout(location = 0) in highp vec4 position;\n" 253 << "layout(location = 1) in highp vec4 color;\n" 254 << "layout(location = 0) out highp vec4 vtxColor;\n" 255 << "out gl_PerVertex { vec4 gl_Position; };\n" 256 << "layout(push_constant) uniform Material {\n"; 257 258 switch (m_indexType) 259 { 260 case INDEX_TYPE_CONST_LITERAL: 261 switch (getRangeSizeCase(m_pushConstantRange[rangeNdx].range.size)) 262 { 263 case SIZE_CASE_4: 264 vertexSrc << "int kind;\n" 265 << "} matInst;\n"; 266 break; 267 case SIZE_CASE_16: 268 vertexSrc << "vec4 color;\n" 269 << "} matInst;\n" 270 << "layout(std140, binding = 0) uniform UniformBuf {\n" 271 << "vec4 element;\n" 272 << "} uniformBuf;\n"; 273 break; 274 case SIZE_CASE_32: 275 vertexSrc << "vec4 color[2];\n" 276 << "} matInst;\n"; 277 break; 278 case SIZE_CASE_48: 279 vertexSrc << "int dummy1;\n" 280 << "vec4 dummy2;\n" 281 << "vec4 color;\n" 282 << "} matInst;\n"; 283 break; 284 case SIZE_CASE_128: 285 vertexSrc << "vec4 color[8];\n" 286 << "} matInst;\n"; 287 break; 288 default: 289 DE_FATAL("Not implemented yet"); 290 break; 291 } 292 break; 293 case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR: 294 vertexSrc << " layout(offset = 0) vec4 index; \n" 295 << " layout(offset = 16) vec4 vecType; \n" 296 << " layout(offset = 32) mat2 matType; \n" 297 << " layout(offset = 48) float[4] arrType; \n" 298 << "} matInst;\n"; 299 break; 300 default: 301 DE_FATAL("Unhandled IndexType"); 302 break; 303 } 304 305 vertexSrc << "void main()\n" 306 << "{\n" 307 << " gl_Position = position;\n"; 308 309 switch (m_indexType) 310 { 311 case INDEX_TYPE_CONST_LITERAL: 312 switch (getRangeSizeCase(m_pushConstantRange[rangeNdx].range.size)) 313 { 314 case SIZE_CASE_4: 315 vertexSrc << "switch (matInst.kind) {\n" 316 << "case 0: vtxColor = vec4(0.0, 1.0, 0, 1.0); break;\n" 317 << "case 1: vtxColor = vec4(0.0, 0.0, 1.0, 1.0); break;\n" 318 << "case 2: vtxColor = vec4(1.0, 0.0, 0, 1.0); break;\n" 319 << "default: vtxColor = color; break;}\n" 320 << "}\n"; 321 break; 322 case SIZE_CASE_16: 323 vertexSrc << "vtxColor = (matInst.color + uniformBuf.element) * 0.5;\n" 324 << "}\n"; 325 break; 326 case SIZE_CASE_32: 327 vertexSrc << "vtxColor = (matInst.color[0] + matInst.color[1]) * 0.5;\n" 328 << "}\n"; 329 break; 330 case SIZE_CASE_48: 331 vertexSrc << "vtxColor = matInst.color;\n" 332 << "}\n"; 333 break; 334 case SIZE_CASE_128: 335 vertexSrc << "vec4 color = vec4(0.0, 0, 0, 0.0);\n" 336 << "for (int i = 0; i < 8; i++)\n" 337 << "{\n" 338 << " color = color + matInst.color[i];\n" 339 << "}\n" 340 << "vtxColor = color * 0.125;\n" 341 << "}\n"; 342 break; 343 default: 344 DE_FATAL("Not implemented yet"); 345 break; 346 } 347 break; 348 case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR: 349 { 350 vertexSrc << " vtxColor = vec4(1.0, 0.0, 0.0, 1.0);\n" 351 // Mix in gl_Position to (hopefully) prevent optimizing our index away 352 << " int vec_selector = int(abs(gl_Position.x) * 0.0000001 + 0);\n" 353 << " int mat_selector = int(abs(gl_Position.x) * 0.0000001 + 1);\n" 354 << " int arr_selector = int(abs(gl_Position.x) * 0.0000001 + 2);\n"; 355 356 // Use the dynamic index to pull our real index value from push constants 357 // Then use that value to index into three variable types 358 std::string vecValue = "matInst.vecType[int(matInst.index[vec_selector])]"; 359 std::string matValue = "matInst.matType[int(matInst.index[mat_selector])][0]"; 360 std::string arrValue = "matInst.arrType[int(matInst.index[arr_selector])]"; 361 362 // Test vector indexing 363 vertexSrc << " if (" << vecValue << " != " << DYNAMIC_VEC_CONSTANT << ")\n" 364 << " vtxColor += vec4(0.0, 0.5, 0.0, 1.0);\n"; 365 366 // Test matrix indexing 367 vertexSrc << " if (" << matValue << " != " << DYNAMIC_MAT_CONSTANT << ")\n" 368 << " vtxColor += vec4(0.0, 0.0, 0.5, 1.0);\n"; 369 370 // Test array indexing 371 vertexSrc << " if (" << arrValue << " != " << DYNAMIC_ARR_CONSTANT << ")\n" 372 << " vtxColor = vec4(0.0, 0.5, 0.5, 1.0);\n"; 373 374 vertexSrc << "}\n"; 375 } 376 break; 377 default: 378 DE_FATAL("Unhandled IndexType"); 379 break; 380 } 381 382 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(vertexSrc.str()); 383 } 384 385 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) 386 { 387 tessControlSrc << "#version 450\n" 388 << "layout (vertices = 3) out;\n" 389 << "layout(push_constant) uniform TessLevel {\n" 390 << " layout(offset = 24) int level;\n" 391 << "} tessLevel;\n" 392 << "layout(location = 0) in highp vec4 color[];\n" 393 << "layout(location = 0) out highp vec4 vtxColor[];\n" 394 << "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n" 395 << "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n" 396 << "void main()\n" 397 << "{\n" 398 << " gl_TessLevelInner[0] = tessLevel.level;\n" 399 << " gl_TessLevelOuter[0] = tessLevel.level;\n" 400 << " gl_TessLevelOuter[1] = tessLevel.level;\n" 401 << " gl_TessLevelOuter[2] = tessLevel.level;\n" 402 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 403 << " vtxColor[gl_InvocationID] = color[gl_InvocationID];\n" 404 << "}\n"; 405 406 sourceCollections.glslSources.add("color_tesc") << glu::TessellationControlSource(tessControlSrc.str()); 407 } 408 409 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 410 { 411 tessEvaluationSrc << "#version 450\n" 412 << "layout (triangles) in;\n" 413 << "layout(push_constant) uniform Material {\n" 414 << " layout(offset = 32) vec4 color;\n" 415 << "} matInst;\n" 416 << "layout(location = 0) in highp vec4 color[];\n" 417 << "layout(location = 0) out highp vec4 vtxColor;\n" 418 << "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n" 419 << "out gl_PerVertex { vec4 gl_Position; };\n" 420 << "void main()\n" 421 << "{\n" 422 << " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n" 423 << " vtxColor = matInst.color;\n" 424 << "}\n"; 425 426 sourceCollections.glslSources.add("color_tese") << glu::TessellationEvaluationSource(tessEvaluationSrc.str()); 427 } 428 429 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_GEOMETRY_BIT) 430 { 431 geometrySrc << "#version 450\n" 432 << "layout(triangles) in;\n" 433 << "layout(triangle_strip, max_vertices=3) out;\n" 434 << "layout(push_constant) uniform Material {\n" 435 << " layout(offset = 20) int kind;\n" 436 << "} matInst;\n" 437 << "layout(location = 0) in highp vec4 color[];\n" 438 << "layout(location = 0) out highp vec4 vtxColor;\n" 439 << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n" 440 << "out gl_PerVertex { vec4 gl_Position; };\n" 441 << "void main()\n" 442 << "{\n" 443 << " for(int i=0; i<3; i++)\n" 444 << " {\n" 445 << " gl_Position.xyz = gl_in[i].gl_Position.xyz / matInst.kind;\n" 446 << " gl_Position.w = gl_in[i].gl_Position.w;\n" 447 << " vtxColor = color[i];\n" 448 << " EmitVertex();\n" 449 << " }\n" 450 << " EndPrimitive();\n" 451 << "}\n"; 452 453 sourceCollections.glslSources.add("color_geom") << glu::GeometrySource(geometrySrc.str()); 454 } 455 456 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_FRAGMENT_BIT) 457 { 458 fragmentSrc << "#version 450\n" 459 << "layout(location = 0) in highp vec4 vtxColor;\n" 460 << "layout(location = 0) out highp vec4 fragColor;\n" 461 << "layout(push_constant) uniform Material {\n"; 462 463 switch (m_indexType) 464 { 465 case INDEX_TYPE_CONST_LITERAL: 466 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_VERTEX_BIT) 467 { 468 fragmentSrc << " layout(offset = 0) int kind; \n" 469 << "} matInst;\n"; 470 } 471 else 472 { 473 fragmentSrc << " layout(offset = 16) int kind;\n" 474 << "} matInst;\n"; 475 } 476 477 fragmentSrc << "void main (void)\n" 478 << "{\n" 479 << " switch (matInst.kind) {\n" 480 << " case 0: fragColor = vec4(0, 1.0, 0, 1.0); break;\n" 481 << " case 1: fragColor = vec4(0, 0.0, 1.0, 1.0); break;\n" 482 << " case 2: fragColor = vtxColor; break;\n" 483 << " default: fragColor = vec4(1.0, 1.0, 1.0, 1.0); break;}\n" 484 << "}\n"; 485 break; 486 case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR: 487 { 488 fragmentSrc << " layout(offset = 0) vec4 index; \n" 489 << " layout(offset = 16) vec4 vecType; \n" 490 << " layout(offset = 32) mat2 matType; \n" 491 << " layout(offset = 48) float[4] arrType; \n" 492 << "} matInst;\n"; 493 494 fragmentSrc << "void main (void)\n" 495 << "{\n" 496 << " fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" 497 498 // Mix in gl_FragCoord to (hopefully) prevent optimizing our index away 499 << " int vec_selector = int(gl_FragCoord.x * 0.0000001 + 0);\n" 500 << " int mat_selector = int(gl_FragCoord.x * 0.0000001 + 1);\n" 501 << " int arr_selector = int(gl_FragCoord.x * 0.0000001 + 2);\n"; 502 503 // Use the dynamic index to pull our real index value from push constants 504 // Then use that value to index into three variable types 505 std::string vecValue = "matInst.vecType[int(matInst.index[vec_selector])]"; 506 std::string matValue = "matInst.matType[int(matInst.index[mat_selector])][0]"; 507 std::string arrValue = "matInst.arrType[int(matInst.index[arr_selector])]"; 508 509 // Test vector indexing 510 fragmentSrc << " if (" << vecValue << " != " << DYNAMIC_VEC_CONSTANT << ")\n" 511 << " fragColor += vec4(0.0, 0.5, 0.0, 1.0);\n"; 512 513 // Test matrix indexing 514 fragmentSrc << " if (" << matValue << " != " << DYNAMIC_MAT_CONSTANT << ")\n" 515 << " fragColor += vec4(0.0, 0.0, 0.5, 1.0);\n"; 516 517 // Test array indexing 518 fragmentSrc << " if (" << arrValue << " != " << DYNAMIC_ARR_CONSTANT << ")\n" 519 << " fragColor = vec4(0.0, 0.5, 0.5, 1.0);\n"; 520 521 fragmentSrc << "}\n"; 522 } 523 break; 524 default: 525 DE_FATAL("Unhandled IndexType"); 526 break; 527 } 528 529 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSrc.str()); 530 } 531 } 532 533 // add a pass through fragment shader if it's not activated in push constant ranges 534 if (fragmentSrc.str().empty()) 535 { 536 fragmentSrc << "#version 450\n" 537 << "layout(location = 0) in highp vec4 vtxColor;\n" 538 << "layout(location = 0) out highp vec4 fragColor;\n" 539 << "void main (void)\n" 540 << "{\n" 541 << " fragColor = vtxColor;\n" 542 << "}\n"; 543 544 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSrc.str()); 545 } 546} 547 548void PushConstantGraphicsTestInstance::createShaderStage (const DeviceInterface& vk, 549 VkDevice device, 550 const BinaryCollection& programCollection, 551 const char* name, 552 VkShaderStageFlagBits stage, 553 Move<VkShaderModule>* module) 554{ 555 *module = createShaderModule(vk, device, programCollection.get(name), 0); 556 557 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo = 558 { 559 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 560 DE_NULL, // const void* pNext; 561 0u, // VkPipelineShaderStageCreateFlags flags; 562 stage, // VkShaderStageFlagBits stage; 563 **module, // VkShaderModule module; 564 "main", // const char* pName; 565 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 566 }; 567 568 m_shaderStage.push_back(stageCreateInfo); 569} 570 571std::vector<Vertex4RGBA> PushConstantGraphicsTestInstance::createQuad(const float size) 572{ 573 std::vector<Vertex4RGBA> vertices; 574 575 const tcu::Vec4 color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); 576 const Vertex4RGBA lowerLeftVertex = {tcu::Vec4(-size, -size, 0.0f, 1.0f), color}; 577 const Vertex4RGBA lowerRightVertex = {tcu::Vec4(size, -size, 0.0f, 1.0f), color}; 578 const Vertex4RGBA UpperLeftVertex = {tcu::Vec4(-size, size, 0.0f, 1.0f), color}; 579 const Vertex4RGBA UpperRightVertex = {tcu::Vec4(size, size, 0.0f, 1.0f), color}; 580 581 vertices.push_back(lowerLeftVertex); 582 vertices.push_back(lowerRightVertex); 583 vertices.push_back(UpperLeftVertex); 584 vertices.push_back(UpperLeftVertex); 585 vertices.push_back(lowerRightVertex); 586 vertices.push_back(UpperRightVertex); 587 588 return vertices; 589} 590 591PushConstantGraphicsTestInstance::PushConstantGraphicsTestInstance (Context& context, 592 const deUint32 rangeCount, 593 const PushConstantData pushConstantRange[MAX_RANGE_COUNT], 594 deBool multipleUpdate, 595 IndexType indexType) 596 : vkt::TestInstance (context) 597 , m_renderSize (32, 32) 598 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 599 , m_rangeCount (rangeCount) 600 , m_multipleUpdate (multipleUpdate) 601 , m_indexType (indexType) 602 , m_shaderFlags (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) 603{ 604 const DeviceInterface& vk = context.getDeviceInterface(); 605 const VkDevice vkDevice = context.getDevice(); 606 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 607 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 608 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 609 610 deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT); 611 612 // Create color image 613 { 614 const VkImageCreateInfo colorImageParams = 615 { 616 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 617 DE_NULL, // const void* pNext; 618 0u, // VkImageCreateFlags flags; 619 VK_IMAGE_TYPE_2D, // VkImageType imageType; 620 m_colorFormat, // VkFormat format; 621 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 622 1u, // deUint32 mipLevels; 623 1u, // deUint32 arrayLayers; 624 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 625 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 626 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 627 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 628 1u, // deUint32 queueFamilyIndexCount; 629 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 630 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 631 }; 632 633 m_colorImageCreateInfo = colorImageParams; 634 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo); 635 636 // Allocate and bind color image memory 637 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 638 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 639 } 640 641 // Create color attachment view 642 { 643 const VkImageViewCreateInfo colorAttachmentViewParams = 644 { 645 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 646 DE_NULL, // const void* pNext; 647 0u, // VkImageViewCreateFlags flags; 648 *m_colorImage, // VkImage image; 649 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 650 m_colorFormat, // VkFormat format; 651 componentMappingRGBA, // VkChannelMapping channels; 652 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 653 }; 654 655 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 656 } 657 658 // Create render pass 659 { 660 const VkAttachmentDescription colorAttachmentDescription = 661 { 662 0u, // VkAttachmentDescriptionFlags flags; 663 m_colorFormat, // VkFormat format; 664 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 665 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 666 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 667 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 668 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 669 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 670 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 671 }; 672 673 const VkAttachmentDescription attachments[1] = 674 { 675 colorAttachmentDescription 676 }; 677 678 const VkAttachmentReference colorAttachmentReference = 679 { 680 0u, // deUint32 attachment; 681 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 682 }; 683 684 const VkAttachmentReference depthAttachmentReference = 685 { 686 VK_ATTACHMENT_UNUSED, // deUint32 attachment; 687 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; 688 }; 689 690 const VkSubpassDescription subpassDescription = 691 { 692 0u, // VkSubpassDescriptionFlags flags; 693 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 694 0u, // deUint32 inputAttachmentCount; 695 DE_NULL, // const VkAttachmentReference* pInputAttachments; 696 1u, // deUint32 colorAttachmentCount; 697 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 698 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 699 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 700 0u, // deUint32 preserveAttachmentCount; 701 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 702 }; 703 704 const VkRenderPassCreateInfo renderPassParams = 705 { 706 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 707 DE_NULL, // const void* pNext; 708 0u, // VkRenderPassCreateFlags flags; 709 1u, // deUint32 attachmentCount; 710 attachments, // const VkAttachmentDescription* pAttachments; 711 1u, // deUint32 subpassCount; 712 &subpassDescription, // const VkSubpassDescription* pSubpasses; 713 0u, // deUint32 dependencyCount; 714 DE_NULL // const VkSubpassDependency* pDependencies; 715 }; 716 717 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 718 } 719 720 // Create framebuffer 721 { 722 const VkImageView attachmentBindInfos[1] = 723 { 724 *m_colorAttachmentView 725 }; 726 727 const VkFramebufferCreateInfo framebufferParams = 728 { 729 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 730 DE_NULL, // const void* pNext; 731 0u, // VkFramebufferCreateFlags flags; 732 *m_renderPass, // VkRenderPass renderPass; 733 1u, // deUint32 attachmentCount; 734 attachmentBindInfos, // const VkImageView* pAttachments; 735 (deUint32)m_renderSize.x(), // deUint32 width; 736 (deUint32)m_renderSize.y(), // deUint32 height; 737 1u // deUint32 layers; 738 }; 739 740 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 741 } 742 743 // Create pipeline layout 744 { 745 // create push constant range 746 VkPushConstantRange pushConstantRanges[MAX_RANGE_COUNT]; 747 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++) 748 { 749 pushConstantRanges[rangeNdx].stageFlags = m_pushConstantRange[rangeNdx].range.shaderStage; 750 pushConstantRanges[rangeNdx].offset = m_pushConstantRange[rangeNdx].range.offset; 751 pushConstantRanges[rangeNdx].size = m_pushConstantRange[rangeNdx].range.size; 752 } 753 754 // create descriptor set layout 755 m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT).build(vk, vkDevice); 756 757 // create descriptor pool 758 m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 759 760 // create uniform buffer 761 const VkBufferCreateInfo uniformBufferCreateInfo = 762 { 763 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 764 DE_NULL, // const void* pNext; 765 0u, // VkBufferCreateFlags flags 766 16u, // VkDeviceSize size; 767 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage; 768 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 769 1u, // deUint32 queueFamilyCount; 770 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 771 }; 772 773 m_uniformBuffer = createBuffer(vk, vkDevice, &uniformBufferCreateInfo); 774 m_uniformBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible); 775 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferAlloc->getMemory(), m_uniformBufferAlloc->getOffset())); 776 777 tcu::Vec4 value = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); 778 deMemcpy(m_uniformBufferAlloc->getHostPtr(), &value, 16u); 779 flushMappedMemoryRange(vk, vkDevice, m_uniformBufferAlloc->getMemory(), m_uniformBufferAlloc->getOffset(), 16u); 780 781 // create and update descriptor set 782 const VkDescriptorSetAllocateInfo allocInfo = 783 { 784 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 785 DE_NULL, // const void* pNext; 786 *m_descriptorPool, // VkDescriptorPool descriptorPool; 787 1u, // uint32_t setLayoutCount; 788 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts; 789 }; 790 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 791 792 const VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(*m_uniformBuffer, (VkDeviceSize)0u, (VkDeviceSize)16u); 793 794 DescriptorSetUpdateBuilder() 795 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorInfo) 796 .update(vk, vkDevice); 797 798 // create pipeline layout 799 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 800 { 801 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 802 DE_NULL, // const void* pNext; 803 0u, // VkPipelineLayoutCreateFlags flags; 804 1u, // deUint32 descriptorSetCount; 805 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts; 806 m_rangeCount, // deUint32 pushConstantRangeCount; 807 pushConstantRanges // const VkPushConstantRange* pPushConstantRanges; 808 }; 809 810 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 811 } 812 813 // Create shaders 814 { 815 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++) 816 { 817 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_GEOMETRY_BIT) 818 { 819 m_shaderFlags |= VK_SHADER_STAGE_GEOMETRY_BIT; 820 } 821 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) 822 { 823 m_shaderFlags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; 824 } 825 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 826 { 827 m_shaderFlags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; 828 } 829 } 830 831 VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures(); 832 833 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_vert", VK_SHADER_STAGE_VERTEX_BIT , &m_vertexShaderModule); 834 if (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) 835 { 836 if (features.tessellationShader == VK_FALSE) 837 { 838 TCU_THROW(NotSupportedError, "Tessellation Not Supported"); 839 } 840 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_tesc", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessControlShaderModule); 841 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_tese", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvaluationShaderModule); 842 } 843 if (m_shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT) 844 { 845 if (features.geometryShader == VK_FALSE) 846 { 847 TCU_THROW(NotSupportedError, "Geometry Not Supported"); 848 } 849 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_geom", VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule); 850 } 851 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_frag", VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule); 852 } 853 854 // Create pipeline 855 { 856 const VkVertexInputBindingDescription vertexInputBindingDescription = 857 { 858 0u, // deUint32 binding; 859 sizeof(Vertex4RGBA), // deUint32 strideInBytes; 860 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; 861 }; 862 863 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = 864 { 865 { 866 0u, // deUint32 location; 867 0u, // deUint32 binding; 868 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 869 0u // deUint32 offsetInBytes; 870 }, 871 { 872 1u, // deUint32 location; 873 0u, // deUint32 binding; 874 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 875 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset; 876 } 877 }; 878 879 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 880 { 881 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 882 DE_NULL, // const void* pNext; 883 0u, // vkPipelineVertexInputStateCreateFlags flags; 884 1u, // deUint32 bindingCount; 885 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 886 2u, // deUint32 attributeCount; 887 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 888 }; 889 890 const VkPrimitiveTopology topology = (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 891 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 892 { 893 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 894 DE_NULL, // const void* pNext; 895 (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags; 896 topology, // VkPrimitiveTopology topology; 897 false // VkBool32 primitiveRestartEnable; 898 }; 899 900 const VkViewport viewport = 901 { 902 0.0f, // float originX; 903 0.0f, // float originY; 904 (float)m_renderSize.x(), // float width; 905 (float)m_renderSize.y(), // float height; 906 0.0f, // float minDepth; 907 1.0f // float maxDepth; 908 }; 909 910 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }; 911 912 const VkPipelineViewportStateCreateInfo viewportStateParams = 913 { 914 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 915 DE_NULL, // const void* pNext; 916 (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags; 917 1u, // deUint32 viewportCount; 918 &viewport, // const VkViewport* pViewports; 919 1u, // deUint32 scissorCount; 920 &scissor, // const VkRect2D* pScissors; 921 }; 922 923 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 924 { 925 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 926 DE_NULL, // const void* pNext; 927 0u, // VkPipelineRasterizationStateCreateFlags flags; 928 false, // VkBool32 depthClampEnable; 929 false, // VkBool32 rasterizerDiscardEnable; 930 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 931 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 932 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 933 VK_FALSE, // VkBool32 depthBiasEnable; 934 0.0f, // float depthBiasConstantFactor; 935 0.0f, // float depthBiasClamp; 936 0.0f, // float depthBiasSlopeFactor; 937 1.0f, // float lineWidth; 938 }; 939 940 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 941 { 942 false, // VkBool32 blendEnable; 943 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 944 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 945 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 946 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 947 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 948 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 949 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 950 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 951 }; 952 953 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 954 { 955 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 956 DE_NULL, // const void* pNext; 957 0, // VkPipelineColorBlendStateCreateFlags flags; 958 false, // VkBool32 logicOpEnable; 959 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 960 1u, // deUint32 attachmentCount; 961 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 962 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 963 }; 964 965 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 966 { 967 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 968 DE_NULL, // const void* pNext; 969 0u, // VkPipelineMultisampleStateCreateFlags flags; 970 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 971 false, // VkBool32 sampleShadingEnable; 972 0.0f, // float minSampleShading; 973 DE_NULL, // const VkSampleMask* pSampleMask; 974 false, // VkBool32 alphaToCoverageEnable; 975 false // VkBool32 alphaToOneEnable; 976 }; 977 978 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 979 { 980 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 981 DE_NULL, // const void* pNext; 982 0u, // VkPipelineDepthStencilStateCreateFlags flags; 983 false, // VkBool32 depthTestEnable; 984 false, // VkBool32 depthWriteEnable; 985 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 986 false, // VkBool32 depthBoundsTestEnable; 987 false, // VkBool32 stencilTestEnable; 988 // VkStencilOpState front; 989 { 990 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp; 991 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp; 992 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp; 993 VK_COMPARE_OP_NEVER, // VkCompareOp stencilCompareOp; 994 0u, // deUint32 stencilCompareMask; 995 0u, // deUint32 stencilWriteMask; 996 0u, // deUint32 stencilReference; 997 }, 998 // VkStencilOpState back; 999 { 1000 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp; 1001 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp; 1002 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp; 1003 VK_COMPARE_OP_NEVER, // VkCompareOp stencilCompareOp; 1004 0u, // deUint32 stencilCompareMask; 1005 0u, // deUint32 stencilWriteMask; 1006 0u, // deUint32 stencilReference; 1007 }, 1008 0.0f, // float minDepthBounds; 1009 1.0f, // float maxDepthBounds; 1010 }; 1011 1012 const VkPipelineTessellationStateCreateInfo tessellationStateParams = 1013 { 1014 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 1015 DE_NULL, // const void* pNext; 1016 0u, // VkPipelineTessellationStateCreateFlags flags; 1017 3u, // uint32_t patchControlPoints; 1018 }; 1019 1020 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 1021 { 1022 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1023 DE_NULL, // const void* pNext; 1024 0u, // VkPipelineCreateFlags flags; 1025 (deUint32)m_shaderStage.size(), // deUint32 stageCount; 1026 &m_shaderStage[0], // const VkPipelineShaderStageCreateInfo* pStages; 1027 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1028 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1029 (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &tessellationStateParams: DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1030 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1031 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 1032 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1033 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1034 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1035 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1036 *m_pipelineLayout, // VkPipelineLayout layout; 1037 *m_renderPass, // VkRenderPass renderPass; 1038 0u, // deUint32 subpass; 1039 0u, // VkPipeline basePipelineHandle; 1040 0u // deInt32 basePipelineIndex; 1041 }; 1042 1043 m_graphicsPipelines = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 1044 } 1045 1046 // Create vertex buffer 1047 { 1048 m_vertices = createQuad(1.0f); 1049 1050 const VkBufferCreateInfo vertexBufferParams = 1051 { 1052 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1053 DE_NULL, // const void* pNext; 1054 0u, // VkBufferCreateFlags flags; 1055 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size; 1056 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1057 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1058 1u, // deUint32 queueFamilyCount; 1059 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1060 }; 1061 1062 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 1063 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 1064 1065 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); 1066 1067 // Load vertices into vertex buffer 1068 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA)); 1069 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size); 1070 } 1071 1072 // Create command pool 1073 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 1074 1075 // Create command buffer 1076 { 1077 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1078 { 1079 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1080 DE_NULL, // const void* pNext; 1081 0u, // VkCommandBufferUsageFlags flags; 1082 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1083 }; 1084 1085 const VkClearValue attachmentClearValues[] = 1086 { 1087 defaultClearValue(m_colorFormat) 1088 }; 1089 1090 const VkRenderPassBeginInfo renderPassBeginInfo = 1091 { 1092 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1093 DE_NULL, // const void* pNext; 1094 *m_renderPass, // VkRenderPass renderPass; 1095 *m_framebuffer, // VkFramebuffer framebuffer; 1096 { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 1097 1, // deUint32 clearValueCount; 1098 attachmentClearValues // const VkClearValue* pClearValues; 1099 }; 1100 1101 const VkImageMemoryBarrier attachmentLayoutBarrier = 1102 { 1103 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1104 DE_NULL, // const void* pNext; 1105 0u, // VkAccessFlags srcAccessMask; 1106 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 1107 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1108 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 1109 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1110 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1111 *m_colorImage, // VkImage image; 1112 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 1113 }; 1114 1115 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1116 1117 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1118 1119 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 1120 0u, DE_NULL, 0u, DE_NULL, 1u, &attachmentLayoutBarrier); 1121 1122 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1123 1124 // update push constant 1125 std::vector<tcu::Vec4> color(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1126 std::vector<tcu::Vec4> allOnes(8, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 1127 1128 switch (m_indexType) 1129 { 1130 case INDEX_TYPE_CONST_LITERAL: 1131 // Do nothing 1132 break; 1133 case INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR: 1134 // Stick our dynamic index at the beginning of a vector 1135 color[0] = tcu::Vec4( float(DYNAMIC_VEC_INDEX), 1136 float(DYNAMIC_MAT_INDEX), 1137 float(DYNAMIC_ARR_INDEX), 1138 1.0f); 1139 1140 // Place our reference values at each type offset 1141 1142 // vec4[i] 1143 DE_ASSERT(DYNAMIC_VEC_INDEX <= 3); 1144 color[1] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 1145 color[1][DYNAMIC_VEC_INDEX] = DYNAMIC_VEC_CONSTANT; 1146 1147 // mat2[i][0] 1148 DE_ASSERT(DYNAMIC_MAT_INDEX <= 1); 1149 color[2] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 1150 color[2][DYNAMIC_MAT_INDEX * 2] = DYNAMIC_MAT_CONSTANT; 1151 1152 // float[i] 1153 DE_ASSERT(DYNAMIC_ARR_INDEX <= 3); 1154 color[3] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 1155 color[3][DYNAMIC_ARR_INDEX] = DYNAMIC_ARR_CONSTANT; 1156 break; 1157 default: 1158 DE_FATAL("Unhandled IndexType"); 1159 break; 1160 } 1161 1162 const deUint32 kind = 2u; 1163 const void* value = DE_NULL; 1164 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++) 1165 { 1166 value = (m_pushConstantRange[rangeNdx].range.size == 4u) ? (void*)(&kind) : (void*)(&color[0]); 1167 1168 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].range.offset, m_pushConstantRange[rangeNdx].range.size, value); 1169 1170 if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size) 1171 { 1172 value = (void*)(&allOnes[0]); 1173 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].update.offset, m_pushConstantRange[rangeNdx].update.size, value); 1174 } 1175 } 1176 1177 // draw quad 1178 const VkDeviceSize triangleOffset = (m_vertices.size() / TRIANGLE_COUNT) * sizeof(Vertex4RGBA); 1179 for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++) 1180 { 1181 VkDeviceSize vertexBufferOffset = triangleOffset * triangleNdx; 1182 1183 if (m_multipleUpdate) 1184 { 1185 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[0].range.shaderStage, m_pushConstantRange[0].range.offset, m_pushConstantRange[0].range.size, &triangleNdx); 1186 } 1187 1188 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines); 1189 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 1190 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL); 1191 1192 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / TRIANGLE_COUNT), 1, 0, 0); 1193 } 1194 1195 vk.cmdEndRenderPass(*m_cmdBuffer); 1196 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1197 } 1198 1199 // Create fence 1200 m_fence = createFence(vk, vkDevice); 1201} 1202 1203PushConstantGraphicsTestInstance::~PushConstantGraphicsTestInstance (void) 1204{ 1205} 1206 1207tcu::TestStatus PushConstantGraphicsTestInstance::iterate (void) 1208{ 1209 const DeviceInterface& vk = m_context.getDeviceInterface(); 1210 const VkDevice vkDevice = m_context.getDevice(); 1211 const VkQueue queue = m_context.getUniversalQueue(); 1212 const VkSubmitInfo submitInfo = 1213 { 1214 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 1215 DE_NULL, // const void* pNext; 1216 0u, // deUint32 waitSemaphoreCount; 1217 DE_NULL, // const VkSemaphore* pWaitSemaphores; 1218 (const VkPipelineStageFlags*)DE_NULL, 1219 1u, // deUint32 commandBufferCount; 1220 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 1221 0u, // deUint32 signalSemaphoreCount; 1222 DE_NULL // const VkSemaphore* pSignalSemaphores; 1223 }; 1224 1225 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1226 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1227 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 1228 1229 return verifyImage(); 1230} 1231 1232tcu::TestStatus PushConstantGraphicsTestInstance::verifyImage (void) 1233{ 1234 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); 1235 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat(); 1236 const ColorVertexShader vertexShader; 1237 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat); 1238 const rr::Program program (&vertexShader, &fragmentShader); 1239 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program); 1240 bool compareOk = false; 1241 1242 // Render reference image 1243 { 1244 if (m_shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT) 1245 { 1246 m_vertices = createQuad(0.5f); 1247 } 1248 1249 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++) 1250 { 1251 if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size) 1252 { 1253 for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++) 1254 { 1255 m_vertices[vertexNdx].color.xyzw() = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f); 1256 } 1257 } 1258 } 1259 1260 if (m_multipleUpdate) 1261 { 1262 for (size_t vertexNdx = 0; vertexNdx < 3; vertexNdx++) 1263 { 1264 m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); 1265 } 1266 for (size_t vertexNdx = 3; vertexNdx < m_vertices.size(); vertexNdx++) 1267 { 1268 m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 0.0f, 1.0f); 1269 } 1270 } 1271 1272 for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++) 1273 { 1274 rr::RenderState renderState(refRenderer.getViewportState()); 1275 1276 refRenderer.draw(renderState, 1277 rr::PRIMITIVETYPE_TRIANGLES, 1278 std::vector<Vertex4RGBA>(m_vertices.begin() + triangleNdx * 3, 1279 m_vertices.begin() + (triangleNdx + 1) * 3)); 1280 } 1281 } 1282 1283 // Compare result with reference image 1284 { 1285 const DeviceInterface& vk = m_context.getDeviceInterface(); 1286 const VkDevice vkDevice = m_context.getDevice(); 1287 const VkQueue queue = m_context.getUniversalQueue(); 1288 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1289 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 1290 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize); 1291 1292 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), 1293 "IntImageCompare", 1294 "Image comparison", 1295 refRenderer.getAccess(), 1296 result->getAccess(), 1297 tcu::UVec4(2, 2, 2, 2), 1298 tcu::IVec3(1, 1, 0), 1299 true, 1300 tcu::COMPARE_LOG_RESULT); 1301 } 1302 1303 if (compareOk) 1304 return tcu::TestStatus::pass("Result image matches reference"); 1305 else 1306 return tcu::TestStatus::fail("Image mismatch"); 1307} 1308 1309class PushConstantComputeTest : public vkt::TestCase 1310{ 1311public: 1312 PushConstantComputeTest (tcu::TestContext& testContext, 1313 const std::string& name, 1314 const std::string& description, 1315 const PushConstantData pushConstantRange); 1316 virtual ~PushConstantComputeTest (void); 1317 virtual void initPrograms (SourceCollections& sourceCollections) const; 1318 virtual TestInstance* createInstance (Context& context) const; 1319 1320private: 1321 const PushConstantData m_pushConstantRange; 1322}; 1323 1324class PushConstantComputeTestInstance : public vkt::TestInstance 1325{ 1326public: 1327 PushConstantComputeTestInstance (Context& context, 1328 const PushConstantData pushConstantRange); 1329 virtual ~PushConstantComputeTestInstance (void); 1330 virtual tcu::TestStatus iterate (void); 1331 1332private: 1333 const PushConstantData m_pushConstantRange; 1334 1335 Move<VkBuffer> m_outBuffer; 1336 de::MovePtr<Allocation> m_outBufferAlloc; 1337 Move<VkDescriptorPool> m_descriptorPool; 1338 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 1339 Move<VkDescriptorSet> m_descriptorSet; 1340 1341 Move<VkPipelineLayout> m_pipelineLayout; 1342 Move<VkPipeline> m_computePipelines; 1343 1344 Move<VkShaderModule> m_computeShaderModule; 1345 1346 Move<VkCommandPool> m_cmdPool; 1347 Move<VkCommandBuffer> m_cmdBuffer; 1348 1349 Move<VkFence> m_fence; 1350}; 1351 1352PushConstantComputeTest::PushConstantComputeTest (tcu::TestContext& testContext, 1353 const std::string& name, 1354 const std::string& description, 1355 const PushConstantData pushConstantRange) 1356 : vkt::TestCase (testContext, name, description) 1357 , m_pushConstantRange (pushConstantRange) 1358{ 1359} 1360 1361PushConstantComputeTest::~PushConstantComputeTest (void) 1362{ 1363} 1364 1365TestInstance* PushConstantComputeTest::createInstance (Context& context) const 1366{ 1367 return new PushConstantComputeTestInstance(context, m_pushConstantRange); 1368} 1369 1370void PushConstantComputeTest::initPrograms (SourceCollections& sourceCollections) const 1371{ 1372 std::ostringstream computeSrc; 1373 1374 computeSrc << "#version 450\n" 1375 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 1376 << "layout(std140, set = 0, binding = 0) writeonly buffer Output {\n" 1377 << " vec4 elements[];\n" 1378 << "} outData;\n" 1379 << "layout(push_constant) uniform Material{\n" 1380 << " vec4 element;\n" 1381 << "} matInst;\n" 1382 << "void main (void)\n" 1383 << "{\n" 1384 << " outData.elements[gl_GlobalInvocationID.x] = matInst.element;\n" 1385 << "}\n"; 1386 1387 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc.str()); 1388} 1389 1390PushConstantComputeTestInstance::PushConstantComputeTestInstance (Context& context, 1391 const PushConstantData pushConstantRange) 1392 : vkt::TestInstance (context) 1393 , m_pushConstantRange (pushConstantRange) 1394{ 1395 const DeviceInterface& vk = context.getDeviceInterface(); 1396 const VkDevice vkDevice = context.getDevice(); 1397 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1398 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 1399 1400 // Create pipeline layout 1401 { 1402 // create push constant range 1403 VkPushConstantRange pushConstantRanges; 1404 pushConstantRanges.stageFlags = m_pushConstantRange.range.shaderStage; 1405 pushConstantRanges.offset = m_pushConstantRange.range.offset; 1406 pushConstantRanges.size = m_pushConstantRange.range.size; 1407 1408 // create descriptor set layout 1409 m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT).build(vk, vkDevice); 1410 1411 // create descriptor pool 1412 m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1413 1414 // create uniform buffer 1415 const VkDeviceSize bufferSize = sizeof(tcu::Vec4) * 8; 1416 const VkBufferCreateInfo bufferCreateInfo = 1417 { 1418 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1419 DE_NULL, // const void* pNext; 1420 0u, // VkBufferCreateFlags flags 1421 bufferSize, // VkDeviceSize size; 1422 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage; 1423 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1424 1u, // deUint32 queueFamilyCount; 1425 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1426 }; 1427 1428 m_outBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo); 1429 m_outBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outBuffer), MemoryRequirement::HostVisible); 1430 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outBuffer, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset())); 1431 1432 // create and update descriptor set 1433 const VkDescriptorSetAllocateInfo allocInfo = 1434 { 1435 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 1436 DE_NULL, // const void* pNext; 1437 *m_descriptorPool, // VkDescriptorPool descriptorPool; 1438 1u, // uint32_t setLayoutCount; 1439 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts; 1440 }; 1441 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 1442 1443 const VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(*m_outBuffer, (VkDeviceSize)0u, bufferSize); 1444 1445 DescriptorSetUpdateBuilder() 1446 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo) 1447 .update(vk, vkDevice); 1448 1449 // create pipeline layout 1450 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1451 { 1452 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1453 DE_NULL, // const void* pNext; 1454 0u, // VkPipelineLayoutCreateFlags flags; 1455 1u, // deUint32 descriptorSetCount; 1456 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts; 1457 1u, // deUint32 pushConstantRangeCount; 1458 &pushConstantRanges // const VkPushConstantRange* pPushConstantRanges; 1459 }; 1460 1461 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 1462 } 1463 1464 // create pipeline 1465 { 1466 m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0); 1467 1468 const VkPipelineShaderStageCreateInfo stageCreateInfo = 1469 { 1470 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1471 DE_NULL, // const void* pNext; 1472 0u, // VkPipelineShaderStageCreateFlags flags; 1473 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 1474 *m_computeShaderModule, // VkShaderModule module; 1475 "main", // const char* pName; 1476 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1477 }; 1478 1479 const VkComputePipelineCreateInfo createInfo = 1480 { 1481 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 1482 DE_NULL, // const void* pNext; 1483 0u, // VkPipelineCreateFlags flags; 1484 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage; 1485 *m_pipelineLayout, // VkPipelineLayout layout; 1486 (VkPipeline)0, // VkPipeline basePipelineHandle; 1487 0u, // int32_t basePipelineIndex; 1488 }; 1489 1490 m_computePipelines = createComputePipeline(vk, vkDevice, (vk::VkPipelineCache)0u, &createInfo); 1491 } 1492 1493 // Create command pool 1494 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 1495 1496 // Create command buffer 1497 { 1498 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1499 1500 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1501 { 1502 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1503 DE_NULL, // const void* pNext; 1504 0u, // VkCommandBufferUsageFlags flags; 1505 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1506 }; 1507 1508 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1509 1510 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines); 1511 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL); 1512 1513 // update push constant 1514 tcu::Vec4 value = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); 1515 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange.range.shaderStage, m_pushConstantRange.range.offset, m_pushConstantRange.range.size, &value); 1516 1517 vk.cmdDispatch(*m_cmdBuffer, 8, 1, 1); 1518 1519 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1520 } 1521 1522 // Create fence 1523 m_fence = createFence(vk, vkDevice); 1524} 1525 1526PushConstantComputeTestInstance::~PushConstantComputeTestInstance (void) 1527{ 1528} 1529 1530tcu::TestStatus PushConstantComputeTestInstance::iterate (void) 1531{ 1532 const DeviceInterface& vk = m_context.getDeviceInterface(); 1533 const VkDevice vkDevice = m_context.getDevice(); 1534 const VkQueue queue = m_context.getUniversalQueue(); 1535 const VkSubmitInfo submitInfo = 1536 { 1537 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 1538 DE_NULL, // const void* pNext; 1539 0u, // deUint32 waitSemaphoreCount; 1540 DE_NULL, // const VkSemaphore* pWaitSemaphores; 1541 (const VkPipelineStageFlags*)DE_NULL, 1542 1u, // deUint32 commandBufferCount; 1543 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 1544 0u, // deUint32 signalSemaphoreCount; 1545 DE_NULL // const VkSemaphore* pSignalSemaphores; 1546 }; 1547 1548 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1549 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1550 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 1551 1552 invalidateMappedMemoryRange(vk, vkDevice, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset(), (size_t)(sizeof(tcu::Vec4) * 8)); 1553 1554 // verify result 1555 std::vector<tcu::Vec4> expectValue(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1556 if (deMemCmp((void*)(&expectValue[0]), m_outBufferAlloc->getHostPtr(), (size_t)(sizeof(tcu::Vec4) * 8))) 1557 { 1558 return tcu::TestStatus::fail("Image mismatch"); 1559 } 1560 return tcu::TestStatus::pass("result image matches with reference"); 1561} 1562 1563} // anonymous 1564 1565tcu::TestCaseGroup* createPushConstantTests (tcu::TestContext& testCtx) 1566{ 1567 static const struct 1568 { 1569 const char* name; 1570 const char* description; 1571 deUint32 count; 1572 PushConstantData range[MAX_RANGE_COUNT]; 1573 deBool hasMultipleUpdates; 1574 IndexType indexType; 1575 } graphicsParams[] = 1576 { 1577 // test range size from minimum valid size to maximum 1578 { 1579 "range_size_4", 1580 "test range size is 4 bytes(minimum valid size)", 1581 1u, 1582 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 } , { 0, 4 } } }, 1583 false, 1584 INDEX_TYPE_CONST_LITERAL 1585 }, 1586 { 1587 "range_size_16", 1588 "test range size is 16 bytes, and together with a normal uniform", 1589 1u, 1590 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } } }, 1591 false, 1592 INDEX_TYPE_CONST_LITERAL 1593 }, 1594 { 1595 "range_size_128", 1596 "test range size is 128 bytes(maximum valid size)", 1597 1u, 1598 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 128 }, { 0, 128 } } }, 1599 false, 1600 INDEX_TYPE_CONST_LITERAL 1601 }, 1602 // test range count, including all valid shader stage in graphics pipeline, and also multiple shader stages share one single range 1603 { 1604 "count_2_shaders_vert_frag", 1605 "test range count is 2, use vertex and fragment shaders", 1606 2u, 1607 { 1608 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } }, 1609 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } }, 1610 }, 1611 false, 1612 INDEX_TYPE_CONST_LITERAL 1613 }, 1614 { 1615 "count_3_shaders_vert_geom_frag", 1616 "test range count is 3, use vertex, geometry and fragment shaders", 1617 3u, 1618 { 1619 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } }, 1620 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } }, 1621 { { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } }, 1622 }, 1623 false, 1624 INDEX_TYPE_CONST_LITERAL 1625 }, 1626 { 1627 "count_5_shaders_vert_tess_geom_frag", 1628 "test range count is 5, use vertex, tessellation, geometry and fragment shaders", 1629 5u, 1630 { 1631 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } }, 1632 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } }, 1633 { { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } }, 1634 { { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 24, 4 }, { 24, 4 } }, 1635 { { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 32, 16 }, { 32, 16 } }, 1636 }, 1637 false, 1638 INDEX_TYPE_CONST_LITERAL 1639 }, 1640 { 1641 "count_1_shader_vert_frag", 1642 "test range count is 1, vertex and fragment shaders share one range", 1643 1u, 1644 { { { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4 }, { 0, 4 } } }, 1645 false, 1646 INDEX_TYPE_CONST_LITERAL 1647 }, 1648 // test data partial update and multiple times update 1649 { 1650 "data_update_partial_1", 1651 "test partial update of the values", 1652 1u, 1653 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 32 }, { 4, 24 } } }, 1654 false, 1655 INDEX_TYPE_CONST_LITERAL 1656 }, 1657 { 1658 "data_update_partial_2", 1659 "test partial update of the values", 1660 1u, 1661 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 48 }, { 32, 16 } } }, 1662 false, 1663 INDEX_TYPE_CONST_LITERAL 1664 }, 1665 { 1666 "data_update_multiple", 1667 "test multiple times update of the values", 1668 1u, 1669 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 }, { 0, 4 } } }, 1670 true, 1671 INDEX_TYPE_CONST_LITERAL 1672 }, 1673 { 1674 "dynamic_index_vert", 1675 "dynamically uniform indexing of vertex, matrix, and array in vertex shader", 1676 1u, 1677 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 64 }, { 0, 64 } } }, 1678 false, 1679 INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR 1680 }, 1681 { 1682 "dynamic_index_frag", 1683 "dynamically uniform indexing of vertex, matrix, and array in fragment shader", 1684 1u, 1685 { { { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 64 }, { 0, 64 } } }, 1686 false, 1687 INDEX_TYPE_DYNAMICALLY_UNIFORM_EXPR 1688 }, 1689 }; 1690 1691 static const struct 1692 { 1693 const char* name; 1694 const char* description; 1695 PushConstantData range; 1696 } computeParams[] = 1697 { 1698 { 1699 "simple_test", 1700 "test compute pipeline", 1701 { { VK_SHADER_STAGE_COMPUTE_BIT, 0, 16 }, { 0, 16 } }, 1702 }, 1703 }; 1704 1705 de::MovePtr<tcu::TestCaseGroup> pushConstantTests (new tcu::TestCaseGroup(testCtx, "push_constant", "PushConstant tests")); 1706 1707 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics_pipeline", "graphics pipeline")); 1708 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(graphicsParams); ndx++) 1709 { 1710 graphicsTests->addChild(new PushConstantGraphicsTest(testCtx, graphicsParams[ndx].name, graphicsParams[ndx].description, graphicsParams[ndx].count, graphicsParams[ndx].range, graphicsParams[ndx].hasMultipleUpdates, graphicsParams[ndx].indexType)); 1711 } 1712 pushConstantTests->addChild(graphicsTests.release()); 1713 1714 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute_pipeline", "compute pipeline")); 1715 computeTests->addChild(new PushConstantComputeTest(testCtx, computeParams[0].name, computeParams[0].description, computeParams[0].range)); 1716 pushConstantTests->addChild(computeTests.release()); 1717 1718 return pushConstantTests.release(); 1719} 1720 1721} // pipeline 1722} // vkt 1723