1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 ARM Limited.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief PushConstant Tests
34 *//*--------------------------------------------------------------------*/
36 #include "vktPipelinePushConstantTests.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "vktPipelineImageUtil.hpp"
39 #include "vktPipelineVertexUtil.hpp"
40 #include "vktPipelineReferenceRenderer.hpp"
41 #include "vktTestCase.hpp"
42 #include "vkImageUtil.hpp"
43 #include "vkMemUtil.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkQueryUtil.hpp"
47 #include "vkRefUtil.hpp"
48 #include "vkBuilderUtil.hpp"
49 #include "vkTypeUtil.hpp"
50 #include "tcuImageCompare.hpp"
52 #include "deRandom.hpp"
53 #include "deStringUtil.hpp"
54 #include "deUniquePtr.hpp"
86 struct PushConstantData
88 struct PushConstantRange
90 VkShaderStageFlags shaderStage;
94 struct PushConstantUpdate
101 class PushConstantGraphicsTest : public vkt::TestCase
104 PushConstantGraphicsTest (tcu::TestContext& testContext,
105 const std::string& name,
106 const std::string& description,
107 const deUint32 rangeCount,
108 const PushConstantData pushConstantRange[MAX_RANGE_COUNT],
109 const deBool multipleUpdate);
110 virtual ~PushConstantGraphicsTest (void);
111 virtual void initPrograms (SourceCollections& sourceCollections) const;
112 virtual TestInstance* createInstance (Context& context) const;
113 RangeSizeCase getRangeSizeCase (deUint32 rangeSize) const;
116 const deUint32 m_rangeCount;
117 PushConstantData m_pushConstantRange[MAX_RANGE_COUNT];
118 const deBool m_multipleUpdate;
121 class PushConstantGraphicsTestInstance : public vkt::TestInstance
124 PushConstantGraphicsTestInstance (Context& context,
125 const deUint32 rangeCount,
126 const PushConstantData pushConstantRange[MAX_RANGE_COUNT],
127 const deBool multipleUpdate);
128 virtual ~PushConstantGraphicsTestInstance (void);
129 virtual tcu::TestStatus iterate (void);
131 void createShaderStage (const DeviceInterface& vk,
133 const BinaryCollection& programCollection,
135 VkShaderStageFlagBits stage,
136 Move<VkShaderModule>* module);
137 std::vector<Vertex4RGBA> createQuad (const float size);
140 tcu::TestStatus verifyImage (void);
143 const tcu::UVec2 m_renderSize;
144 const VkFormat m_colorFormat;
145 const deUint32 m_rangeCount;
146 PushConstantData m_pushConstantRange[MAX_RANGE_COUNT];
147 const deBool m_multipleUpdate;
149 VkImageCreateInfo m_colorImageCreateInfo;
150 Move<VkImage> m_colorImage;
151 de::MovePtr<Allocation> m_colorImageAlloc;
152 Move<VkImageView> m_colorAttachmentView;
153 Move<VkRenderPass> m_renderPass;
154 Move<VkFramebuffer> m_framebuffer;
156 Move<VkShaderModule> m_vertexShaderModule;
157 Move<VkShaderModule> m_fragmentShaderModule;
158 Move<VkShaderModule> m_geometryShaderModule;
159 Move<VkShaderModule> m_tessControlShaderModule;
160 Move<VkShaderModule> m_tessEvaluationShaderModule;
162 VkShaderStageFlags m_shaderFlags;
163 std::vector<VkPipelineShaderStageCreateInfo> m_shaderStage;
165 Move<VkBuffer> m_vertexBuffer;
166 std::vector<Vertex4RGBA> m_vertices;
167 de::MovePtr<Allocation> m_vertexBufferAlloc;
169 Move<VkBuffer> m_uniformBuffer;
170 de::MovePtr<Allocation> m_uniformBufferAlloc;
171 Move<VkDescriptorPool> m_descriptorPool;
172 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
173 Move<VkDescriptorSet> m_descriptorSet;
175 Move<VkPipelineLayout> m_pipelineLayout;
176 Move<VkPipeline> m_graphicsPipelines;
178 Move<VkCommandPool> m_cmdPool;
179 Move<VkCommandBuffer> m_cmdBuffer;
181 Move<VkFence> m_fence;
184 PushConstantGraphicsTest::PushConstantGraphicsTest (tcu::TestContext& testContext,
185 const std::string& name,
186 const std::string& description,
187 const deUint32 rangeCount,
188 const PushConstantData pushConstantRange[MAX_RANGE_COUNT],
189 const deBool multipleUpdate)
190 : vkt::TestCase (testContext, name, description)
191 , m_rangeCount (rangeCount)
192 , m_multipleUpdate (multipleUpdate)
194 deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
197 PushConstantGraphicsTest::~PushConstantGraphicsTest (void)
201 TestInstance* PushConstantGraphicsTest::createInstance (Context& context) const
203 return new PushConstantGraphicsTestInstance(context, m_rangeCount, m_pushConstantRange, m_multipleUpdate);
206 RangeSizeCase PushConstantGraphicsTest::getRangeSizeCase (deUint32 rangeSize) const
219 return SIZE_CASE_128;
221 DE_FATAL("Range size unsupported yet");
222 return SIZE_CASE_UNSUPPORTED;
226 void PushConstantGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
228 std::ostringstream vertexSrc;
229 std::ostringstream fragmentSrc;
230 std::ostringstream geometrySrc;
231 std::ostringstream tessControlSrc;
232 std::ostringstream tessEvaluationSrc;
234 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
236 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_VERTEX_BIT)
238 vertexSrc << "#version 450\n"
239 << "layout(location = 0) in highp vec4 position;\n"
240 << "layout(location = 1) in highp vec4 color;\n"
241 << "layout(location = 0) out highp vec4 vtxColor;\n"
242 << "layout(push_constant) uniform Material {\n";
244 switch (getRangeSizeCase(m_pushConstantRange[rangeNdx].range.size))
247 vertexSrc << "int kind;\n"
251 vertexSrc << "vec4 color;\n"
253 << "layout(std140, binding = 0) uniform UniformBuf {\n"
255 << "} uniformBuf;\n";
258 vertexSrc << "vec4 color[2];\n"
262 vertexSrc << "int dummy1;\n"
268 vertexSrc << "vec4 color[8];\n"
272 DE_FATAL("Not implemented yet");
276 vertexSrc << "void main()\n"
278 << " gl_Position = position;\n";
280 switch (getRangeSizeCase(m_pushConstantRange[rangeNdx].range.size))
283 vertexSrc << "switch (matInst.kind) {\n"
284 << "case 0: vtxColor = vec4(0.0, 1.0, 0, 1.0); break;\n"
285 << "case 1: vtxColor = vec4(0.0, 0.0, 1.0, 1.0); break;\n"
286 << "case 2: vtxColor = vec4(1.0, 0.0, 0, 1.0); break;\n"
287 << "default: vtxColor = color; break;}\n"
291 vertexSrc << "vtxColor = (matInst.color + uniformBuf.element) * 0.5;\n"
295 vertexSrc << "vtxColor = (matInst.color[0] + matInst.color[1]) * 0.5;\n"
299 vertexSrc << "vtxColor = matInst.color;\n"
303 vertexSrc << "vec4 color = vec4(0.0, 0, 0, 0.0);\n"
304 << "for (int i = 0; i < 8; i++)\n"
306 << " color = color + matInst.color[i];\n"
308 << "vtxColor = color * 0.125;\n"
312 DE_FATAL("Not implemented yet");
316 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(vertexSrc.str());
319 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
321 tessControlSrc << "#version 450\n"
322 << "layout (vertices = 3) out;\n"
323 << "layout(push_constant) uniform TessLevel {\n"
324 << " layout(offset = 24) int level;\n"
326 << "layout(location = 0) in highp vec4 color[];\n"
327 << "layout(location = 0) out highp vec4 vtxColor[];\n"
330 << " gl_TessLevelInner[0] = tessLevel.level;\n"
331 << " gl_TessLevelOuter[0] = tessLevel.level;\n"
332 << " gl_TessLevelOuter[1] = tessLevel.level;\n"
333 << " gl_TessLevelOuter[2] = tessLevel.level;\n"
334 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
335 << " vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
338 sourceCollections.glslSources.add("color_tesc") << glu::TessellationControlSource(tessControlSrc.str());
341 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
343 tessEvaluationSrc << "#version 450\n"
344 << "layout (triangles) in;\n"
345 << "layout(push_constant) uniform Material {\n"
346 << " layout(offset = 32) vec4 color;\n"
348 << "layout(location = 0) in highp vec4 color[];\n"
349 << "layout(location = 0) out highp vec4 vtxColor;\n"
352 << " 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"
353 << " vtxColor = matInst.color;\n"
356 sourceCollections.glslSources.add("color_tese") << glu::TessellationEvaluationSource(tessEvaluationSrc.str());
359 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_GEOMETRY_BIT)
361 geometrySrc << "#version 450\n"
362 << "layout(triangles) in;\n"
363 << "layout(triangle_strip, max_vertices=3) out;\n"
364 << "layout(push_constant) uniform Material {\n"
365 << " layout(offset = 20) int kind;\n"
367 << "layout(location = 0) in highp vec4 color[];\n"
368 << "layout(location = 0) out highp vec4 vtxColor;\n"
371 << " for(int i=0; i<3; i++)\n"
373 << " gl_Position.xyz = gl_in[i].gl_Position.xyz / matInst.kind;\n"
374 << " gl_Position.w = gl_in[i].gl_Position.w;\n"
375 << " vtxColor = color[i];\n"
376 << " EmitVertex();\n"
378 << " EndPrimitive();\n"
381 sourceCollections.glslSources.add("color_geom") << glu::GeometrySource(geometrySrc.str());
384 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_FRAGMENT_BIT)
386 fragmentSrc << "#version 450\n"
387 << "layout(location = 0) in highp vec4 vtxColor;\n"
388 << "layout(location = 0) out highp vec4 fragColor;\n"
389 << "layout(push_constant) uniform Material {\n";
391 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_VERTEX_BIT)
393 fragmentSrc << " layout(offset = 0) int kind;\n"
398 fragmentSrc << " layout(offset = 16) int kind;\n"
402 fragmentSrc << "void main (void)\n"
404 << " switch (matInst.kind) {\n"
405 << " case 0: fragColor = vec4(0, 1.0, 0, 1.0); break;\n"
406 << " case 1: fragColor = vec4(0, 0.0, 1.0, 1.0); break;\n"
407 << " case 2: fragColor = vtxColor; break;\n"
408 << " default: fragColor = vec4(1.0, 1.0, 1.0, 1.0); break;}\n"
411 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSrc.str());
415 // add a pass through fragment shader if it's not activated in push constant ranges
416 if (fragmentSrc.str().empty())
418 fragmentSrc << "#version 450\n"
419 << "layout(location = 0) in highp vec4 vtxColor;\n"
420 << "layout(location = 0) out highp vec4 fragColor;\n"
421 << "void main (void)\n"
423 << " fragColor = vtxColor;\n"
426 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSrc.str());
430 void PushConstantGraphicsTestInstance::createShaderStage (const DeviceInterface& vk,
432 const BinaryCollection& programCollection,
434 VkShaderStageFlagBits stage,
435 Move<VkShaderModule>* module)
437 *module = createShaderModule(vk, device, programCollection.get(name), 0);
439 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
441 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
442 DE_NULL, // const void* pNext;
443 0u, // VkPipelineShaderStageCreateFlags flags;
444 stage, // VkShaderStageFlagBits stage;
445 **module, // VkShaderModule module;
446 "main", // const char* pName;
447 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
450 m_shaderStage.push_back(stageCreateInfo);
453 std::vector<Vertex4RGBA> PushConstantGraphicsTestInstance::createQuad(const float size)
455 std::vector<Vertex4RGBA> vertices;
457 const tcu::Vec4 color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
458 const Vertex4RGBA lowerLeftVertex = {tcu::Vec4(-size, -size, 0.0f, 1.0f), color};
459 const Vertex4RGBA lowerRightVertex = {tcu::Vec4(size, -size, 0.0f, 1.0f), color};
460 const Vertex4RGBA UpperLeftVertex = {tcu::Vec4(-size, size, 0.0f, 1.0f), color};
461 const Vertex4RGBA UpperRightVertex = {tcu::Vec4(size, size, 0.0f, 1.0f), color};
463 vertices.push_back(lowerLeftVertex);
464 vertices.push_back(lowerRightVertex);
465 vertices.push_back(UpperLeftVertex);
466 vertices.push_back(UpperLeftVertex);
467 vertices.push_back(lowerRightVertex);
468 vertices.push_back(UpperRightVertex);
473 PushConstantGraphicsTestInstance::PushConstantGraphicsTestInstance (Context& context,
474 const deUint32 rangeCount,
475 const PushConstantData pushConstantRange[MAX_RANGE_COUNT],
476 deBool multipleUpdate)
477 : vkt::TestInstance (context)
478 , m_renderSize (32, 32)
479 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
480 , m_rangeCount (rangeCount)
481 , m_multipleUpdate (multipleUpdate)
482 , m_shaderFlags (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)
484 const DeviceInterface& vk = context.getDeviceInterface();
485 const VkDevice vkDevice = context.getDevice();
486 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
487 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
488 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
490 deMemcpy(m_pushConstantRange, pushConstantRange, sizeof(PushConstantData) * MAX_RANGE_COUNT);
492 // Create color image
494 const VkImageCreateInfo colorImageParams =
496 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
497 DE_NULL, // const void* pNext;
498 0u, // VkImageCreateFlags flags;
499 VK_IMAGE_TYPE_2D, // VkImageType imageType;
500 m_colorFormat, // VkFormat format;
501 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
502 1u, // deUint32 mipLevels;
503 1u, // deUint32 arrayLayers;
504 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
505 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
506 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
507 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
508 1u, // deUint32 queueFamilyIndexCount;
509 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
510 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
513 m_colorImageCreateInfo = colorImageParams;
514 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo);
516 // Allocate and bind color image memory
517 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
518 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
521 // Create color attachment view
523 const VkImageViewCreateInfo colorAttachmentViewParams =
525 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
526 DE_NULL, // const void* pNext;
527 0u, // VkImageViewCreateFlags flags;
528 *m_colorImage, // VkImage image;
529 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
530 m_colorFormat, // VkFormat format;
531 componentMappingRGBA, // VkChannelMapping channels;
532 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
535 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
538 // Create render pass
540 const VkAttachmentDescription colorAttachmentDescription =
542 0u, // VkAttachmentDescriptionFlags flags;
543 m_colorFormat, // VkFormat format;
544 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
545 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
546 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
547 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
548 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
549 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
550 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
553 const VkAttachmentDescription attachments[1] =
555 colorAttachmentDescription
558 const VkAttachmentReference colorAttachmentReference =
560 0u, // deUint32 attachment;
561 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
564 const VkAttachmentReference depthAttachmentReference =
566 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
567 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
570 const VkSubpassDescription subpassDescription =
572 0u, // VkSubpassDescriptionFlags flags;
573 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
574 0u, // deUint32 inputAttachmentCount;
575 DE_NULL, // const VkAttachmentReference* pInputAttachments;
576 1u, // deUint32 colorAttachmentCount;
577 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
578 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
579 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment;
580 0u, // deUint32 preserveAttachmentCount;
581 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
584 const VkRenderPassCreateInfo renderPassParams =
586 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
587 DE_NULL, // const void* pNext;
588 0u, // VkRenderPassCreateFlags flags;
589 1u, // deUint32 attachmentCount;
590 attachments, // const VkAttachmentDescription* pAttachments;
591 1u, // deUint32 subpassCount;
592 &subpassDescription, // const VkSubpassDescription* pSubpasses;
593 0u, // deUint32 dependencyCount;
594 DE_NULL // const VkSubpassDependency* pDependencies;
597 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
600 // Create framebuffer
602 const VkImageView attachmentBindInfos[1] =
604 *m_colorAttachmentView
607 const VkFramebufferCreateInfo framebufferParams =
609 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
610 DE_NULL, // const void* pNext;
611 0u, // VkFramebufferCreateFlags flags;
612 *m_renderPass, // VkRenderPass renderPass;
613 1u, // deUint32 attachmentCount;
614 attachmentBindInfos, // const VkImageView* pAttachments;
615 (deUint32)m_renderSize.x(), // deUint32 width;
616 (deUint32)m_renderSize.y(), // deUint32 height;
617 1u // deUint32 layers;
620 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
623 // Create pipeline layout
625 // create push constant range
626 VkPushConstantRange pushConstantRanges[MAX_RANGE_COUNT];
627 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
629 pushConstantRanges[rangeNdx].stageFlags = m_pushConstantRange[rangeNdx].range.shaderStage;
630 pushConstantRanges[rangeNdx].offset = m_pushConstantRange[rangeNdx].range.offset;
631 pushConstantRanges[rangeNdx].size = m_pushConstantRange[rangeNdx].range.size;
634 // create descriptor set layout
635 m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT).build(vk, vkDevice);
637 // create descriptor pool
638 m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
640 // create uniform buffer
641 const VkBufferCreateInfo uniformBufferCreateInfo =
643 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
644 DE_NULL, // const void* pNext;
645 0u, // VkBufferCreateFlags flags
646 16u, // VkDeviceSize size;
647 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
648 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
649 1u, // deUint32 queueFamilyCount;
650 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
653 m_uniformBuffer = createBuffer(vk, vkDevice, &uniformBufferCreateInfo);
654 m_uniformBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
655 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferAlloc->getMemory(), m_uniformBufferAlloc->getOffset()));
657 tcu::Vec4 value = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
658 deMemcpy(m_uniformBufferAlloc->getHostPtr(), &value, 16u);
659 flushMappedMemoryRange(vk, vkDevice, m_uniformBufferAlloc->getMemory(), m_uniformBufferAlloc->getOffset(), 16u);
661 // create and update descriptor set
662 const VkDescriptorSetAllocateInfo allocInfo =
664 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
665 DE_NULL, // const void* pNext;
666 *m_descriptorPool, // VkDescriptorPool descriptorPool;
667 1u, // uint32_t setLayoutCount;
668 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
670 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
672 const VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(*m_uniformBuffer, (VkDeviceSize)0u, (VkDeviceSize)16u);
674 DescriptorSetUpdateBuilder()
675 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorInfo)
676 .update(vk, vkDevice);
678 // create pipeline layout
679 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
681 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
682 DE_NULL, // const void* pNext;
683 0u, // VkPipelineLayoutCreateFlags flags;
684 1u, // deUint32 descriptorSetCount;
685 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
686 m_rangeCount, // deUint32 pushConstantRangeCount;
687 pushConstantRanges // const VkPushConstantRange* pPushConstantRanges;
690 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
695 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
697 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_GEOMETRY_BIT)
699 m_shaderFlags |= VK_SHADER_STAGE_GEOMETRY_BIT;
701 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
703 m_shaderFlags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
705 if (m_pushConstantRange[rangeNdx].range.shaderStage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
707 m_shaderFlags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
711 VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
713 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_vert", VK_SHADER_STAGE_VERTEX_BIT , &m_vertexShaderModule);
714 if (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
716 if (features.tessellationShader == VK_FALSE)
718 TCU_THROW(NotSupportedError, "Tessellation Not Supported");
720 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_tesc", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessControlShaderModule);
721 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_tese", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvaluationShaderModule);
723 if (m_shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT)
725 if (features.geometryShader == VK_FALSE)
727 TCU_THROW(NotSupportedError, "Geometry Not Supported");
729 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_geom", VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
731 createShaderStage(vk, vkDevice, m_context.getBinaryCollection(), "color_frag", VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
736 const VkVertexInputBindingDescription vertexInputBindingDescription =
738 0u, // deUint32 binding;
739 sizeof(Vertex4RGBA), // deUint32 strideInBytes;
740 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
743 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
746 0u, // deUint32 location;
747 0u, // deUint32 binding;
748 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
749 0u // deUint32 offsetInBytes;
752 1u, // deUint32 location;
753 0u, // deUint32 binding;
754 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
755 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset;
759 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
761 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
762 DE_NULL, // const void* pNext;
763 0u, // vkPipelineVertexInputStateCreateFlags flags;
764 1u, // deUint32 bindingCount;
765 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
766 2u, // deUint32 attributeCount;
767 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
770 const VkPrimitiveTopology topology = (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
771 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
773 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
774 DE_NULL, // const void* pNext;
775 (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
776 topology, // VkPrimitiveTopology topology;
777 false // VkBool32 primitiveRestartEnable;
780 const VkViewport viewport =
782 0.0f, // float originX;
783 0.0f, // float originY;
784 (float)m_renderSize.x(), // float width;
785 (float)m_renderSize.y(), // float height;
786 0.0f, // float minDepth;
787 1.0f // float maxDepth;
790 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
792 const VkPipelineViewportStateCreateInfo viewportStateParams =
794 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
795 DE_NULL, // const void* pNext;
796 (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags;
797 1u, // deUint32 viewportCount;
798 &viewport, // const VkViewport* pViewports;
799 1u, // deUint32 scissorCount;
800 &scissor, // const VkRect2D* pScissors;
803 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
805 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
806 DE_NULL, // const void* pNext;
807 0u, // VkPipelineRasterizationStateCreateFlags flags;
808 false, // VkBool32 depthClampEnable;
809 false, // VkBool32 rasterizerDiscardEnable;
810 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
811 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
812 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
813 VK_FALSE, // VkBool32 depthBiasEnable;
814 0.0f, // float depthBiasConstantFactor;
815 0.0f, // float depthBiasClamp;
816 0.0f, // float depthBiasSlopeFactor;
817 1.0f, // float lineWidth;
820 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
822 false, // VkBool32 blendEnable;
823 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
824 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
825 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
826 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
827 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
828 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
829 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
830 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
833 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
835 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
836 DE_NULL, // const void* pNext;
837 0, // VkPipelineColorBlendStateCreateFlags flags;
838 false, // VkBool32 logicOpEnable;
839 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
840 1u, // deUint32 attachmentCount;
841 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
842 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
845 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
847 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
848 DE_NULL, // const void* pNext;
849 0u, // VkPipelineMultisampleStateCreateFlags flags;
850 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
851 false, // VkBool32 sampleShadingEnable;
852 0.0f, // float minSampleShading;
853 DE_NULL, // const VkSampleMask* pSampleMask;
854 false, // VkBool32 alphaToCoverageEnable;
855 false // VkBool32 alphaToOneEnable;
858 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
860 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
861 DE_NULL, // const void* pNext;
862 0u, // VkPipelineDynamicStateCreateFlags flags;
863 0u, // deUint32 dynamicStateCount;
864 DE_NULL // const VkDynamicState* pDynamicStates;
867 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
869 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
870 DE_NULL, // const void* pNext;
871 0u, // VkPipelineDepthStencilStateCreateFlags flags;
872 false, // VkBool32 depthTestEnable;
873 false, // VkBool32 depthWriteEnable;
874 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
875 false, // VkBool32 depthBoundsTestEnable;
876 false, // VkBool32 stencilTestEnable;
877 // VkStencilOpState front;
879 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
880 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
881 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
882 VK_COMPARE_OP_NEVER, // VkCompareOp stencilCompareOp;
883 0u, // deUint32 stencilCompareMask;
884 0u, // deUint32 stencilWriteMask;
885 0u, // deUint32 stencilReference;
887 // VkStencilOpState back;
889 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
890 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
891 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
892 VK_COMPARE_OP_NEVER, // VkCompareOp stencilCompareOp;
893 0u, // deUint32 stencilCompareMask;
894 0u, // deUint32 stencilWriteMask;
895 0u, // deUint32 stencilReference;
897 -1.0f, // float minDepthBounds;
898 +1.0f, // float maxDepthBounds;
901 const VkPipelineTessellationStateCreateInfo tessellationStateParams =
903 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
904 DE_NULL, // const void* pNext;
905 0u, // VkPipelineTessellationStateCreateFlags flags;
906 3u, // uint32_t patchControlPoints;
909 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
911 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
912 DE_NULL, // const void* pNext;
913 0u, // VkPipelineCreateFlags flags;
914 (deUint32)m_shaderStage.size(), // deUint32 stageCount;
915 &m_shaderStage[0], // const VkPipelineShaderStageCreateInfo* pStages;
916 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
917 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
918 (m_shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &tessellationStateParams: DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
919 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
920 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
921 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
922 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
923 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
924 &dynamicStateParams, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
925 *m_pipelineLayout, // VkPipelineLayout layout;
926 *m_renderPass, // VkRenderPass renderPass;
927 0u, // deUint32 subpass;
928 0u, // VkPipeline basePipelineHandle;
929 0u // deInt32 basePipelineIndex;
932 m_graphicsPipelines = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
935 // Create vertex buffer
937 m_vertices = createQuad(1.0f);
939 const VkBufferCreateInfo vertexBufferParams =
941 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
942 DE_NULL, // const void* pNext;
943 0u, // VkBufferCreateFlags flags;
944 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size;
945 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
946 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
947 1u, // deUint32 queueFamilyCount;
948 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
951 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
952 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
954 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
956 // Load vertices into vertex buffer
957 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
958 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
961 // Create command pool
963 const VkCommandPoolCreateInfo cmdPoolParams =
965 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
966 DE_NULL, // const void* pNext;
967 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
968 queueFamilyIndex // deUint32 queueFamilyIndex;
970 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
973 // Create command buffer
975 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
977 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
978 DE_NULL, // const void* pNext;
979 *m_cmdPool, // VkCommandPool commandPool;
980 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
981 1u // deUint32 bufferCount;
984 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
986 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
987 DE_NULL, // const void* pNext;
988 0u, // VkCommandBufferUsageFlags flags;
989 (const VkCommandBufferInheritanceInfo*)DE_NULL,
992 const VkClearValue attachmentClearValues[] =
994 defaultClearValue(m_colorFormat)
997 const VkRenderPassBeginInfo renderPassBeginInfo =
999 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1000 DE_NULL, // const void* pNext;
1001 *m_renderPass, // VkRenderPass renderPass;
1002 *m_framebuffer, // VkFramebuffer framebuffer;
1003 { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1004 1, // deUint32 clearValueCount;
1005 attachmentClearValues // const VkClearValue* pClearValues;
1008 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
1010 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1011 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1013 // update push constant
1014 std::vector<tcu::Vec4> color(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1015 std::vector<tcu::Vec4> allOnes(8, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1017 const deUint32 kind = 2u;
1018 const void* value = DE_NULL;
1019 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
1021 value = (m_pushConstantRange[rangeNdx].range.size == 4u) ? (void*)(&kind) : (void*)(&color[0]);
1023 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].range.offset, m_pushConstantRange[rangeNdx].range.size, value);
1025 if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size)
1027 value = (void*)(&allOnes[0]);
1028 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].update.offset, m_pushConstantRange[rangeNdx].update.size, value);
1033 const VkDeviceSize triangleOffset = (m_vertices.size() / TRIANGLE_COUNT) * sizeof(Vertex4RGBA);
1034 for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++)
1036 VkDeviceSize vertexBufferOffset = triangleOffset * triangleNdx;
1038 if (m_multipleUpdate)
1040 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[0].range.shaderStage, m_pushConstantRange[0].range.offset, m_pushConstantRange[0].range.size, &triangleNdx);
1043 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1044 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1045 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
1047 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / TRIANGLE_COUNT), 1, 0, 0);
1050 vk.cmdEndRenderPass(*m_cmdBuffer);
1051 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1056 const VkFenceCreateInfo fenceParams =
1058 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1059 DE_NULL, // const void* pNext;
1060 0u // VkFenceCreateFlags flags;
1063 m_fence = createFence(vk, vkDevice, &fenceParams);
1067 PushConstantGraphicsTestInstance::~PushConstantGraphicsTestInstance (void)
1071 tcu::TestStatus PushConstantGraphicsTestInstance::iterate (void)
1073 const DeviceInterface& vk = m_context.getDeviceInterface();
1074 const VkDevice vkDevice = m_context.getDevice();
1075 const VkQueue queue = m_context.getUniversalQueue();
1076 const VkSubmitInfo submitInfo =
1078 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1079 DE_NULL, // const void* pNext;
1080 0u, // deUint32 waitSemaphoreCount;
1081 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1082 (const VkPipelineStageFlags*)DE_NULL,
1083 1u, // deUint32 commandBufferCount;
1084 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1085 0u, // deUint32 signalSemaphoreCount;
1086 DE_NULL // const VkSemaphore* pSignalSemaphores;
1089 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1090 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1091 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1093 return verifyImage();
1096 tcu::TestStatus PushConstantGraphicsTestInstance::verifyImage (void)
1098 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1099 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
1100 const ColorVertexShader vertexShader;
1101 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat);
1102 const rr::Program program (&vertexShader, &fragmentShader);
1103 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1104 bool compareOk = false;
1106 // Render reference image
1108 if (m_shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT)
1110 m_vertices = createQuad(0.5f);
1113 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
1115 if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size)
1117 for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++)
1119 m_vertices[vertexNdx].color.xyzw() = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1124 if (m_multipleUpdate)
1126 for (size_t vertexNdx = 0; vertexNdx < 3; vertexNdx++)
1128 m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f);
1130 for (size_t vertexNdx = 3; vertexNdx < m_vertices.size(); vertexNdx++)
1132 m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 0.0f, 1.0f);
1136 for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++)
1138 rr::RenderState renderState(refRenderer.getViewportState());
1140 refRenderer.draw(renderState,
1141 rr::PRIMITIVETYPE_TRIANGLES,
1142 std::vector<Vertex4RGBA>(m_vertices.begin() + triangleNdx * 3,
1143 m_vertices.begin() + (triangleNdx + 1) * 3));
1147 // Compare result with reference image
1149 const DeviceInterface& vk = m_context.getDeviceInterface();
1150 const VkDevice vkDevice = m_context.getDevice();
1151 const VkQueue queue = m_context.getUniversalQueue();
1152 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1153 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1154 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
1156 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1159 refRenderer.getAccess(),
1160 result->getAccess(),
1161 tcu::UVec4(2, 2, 2, 2),
1162 tcu::IVec3(1, 1, 0),
1164 tcu::COMPARE_LOG_RESULT);
1168 return tcu::TestStatus::pass("Result image matches reference");
1170 return tcu::TestStatus::fail("Image mismatch");
1173 class PushConstantComputeTest : public vkt::TestCase
1176 PushConstantComputeTest (tcu::TestContext& testContext,
1177 const std::string& name,
1178 const std::string& description,
1179 const PushConstantData pushConstantRange);
1180 virtual ~PushConstantComputeTest (void);
1181 virtual void initPrograms (SourceCollections& sourceCollections) const;
1182 virtual TestInstance* createInstance (Context& context) const;
1185 const PushConstantData m_pushConstantRange;
1188 class PushConstantComputeTestInstance : public vkt::TestInstance
1191 PushConstantComputeTestInstance (Context& context,
1192 const PushConstantData pushConstantRange);
1193 virtual ~PushConstantComputeTestInstance (void);
1194 virtual tcu::TestStatus iterate (void);
1197 const PushConstantData m_pushConstantRange;
1199 Move<VkBuffer> m_outBuffer;
1200 de::MovePtr<Allocation> m_outBufferAlloc;
1201 Move<VkDescriptorPool> m_descriptorPool;
1202 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1203 Move<VkDescriptorSet> m_descriptorSet;
1205 Move<VkPipelineLayout> m_pipelineLayout;
1206 Move<VkPipeline> m_computePipelines;
1208 Move<VkShaderModule> m_computeShaderModule;
1210 Move<VkCommandPool> m_cmdPool;
1211 Move<VkCommandBuffer> m_cmdBuffer;
1213 Move<VkFence> m_fence;
1216 PushConstantComputeTest::PushConstantComputeTest (tcu::TestContext& testContext,
1217 const std::string& name,
1218 const std::string& description,
1219 const PushConstantData pushConstantRange)
1220 : vkt::TestCase (testContext, name, description)
1221 , m_pushConstantRange (pushConstantRange)
1225 PushConstantComputeTest::~PushConstantComputeTest (void)
1229 TestInstance* PushConstantComputeTest::createInstance (Context& context) const
1231 return new PushConstantComputeTestInstance(context, m_pushConstantRange);
1234 void PushConstantComputeTest::initPrograms (SourceCollections& sourceCollections) const
1236 std::ostringstream computeSrc;
1238 computeSrc << "#version 450\n"
1239 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1240 << "layout(std140, set = 0, binding = 0) writeonly buffer Output {\n"
1241 << " vec4 elements[];\n"
1243 << "layout(push_constant) uniform Material{\n"
1244 << " vec4 element;\n"
1246 << "void main (void)\n"
1248 << " outData.elements[gl_GlobalInvocationID.x] = matInst.element;\n"
1251 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc.str());
1254 PushConstantComputeTestInstance::PushConstantComputeTestInstance (Context& context,
1255 const PushConstantData pushConstantRange)
1256 : vkt::TestInstance (context)
1257 , m_pushConstantRange (pushConstantRange)
1259 const DeviceInterface& vk = context.getDeviceInterface();
1260 const VkDevice vkDevice = context.getDevice();
1261 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1262 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1264 // Create pipeline layout
1266 // create push constant range
1267 VkPushConstantRange pushConstantRanges;
1268 pushConstantRanges.stageFlags = m_pushConstantRange.range.shaderStage;
1269 pushConstantRanges.offset = m_pushConstantRange.range.offset;
1270 pushConstantRanges.size = m_pushConstantRange.range.size;
1272 // create descriptor set layout
1273 m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT).build(vk, vkDevice);
1275 // create descriptor pool
1276 m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1278 // create uniform buffer
1279 const VkDeviceSize bufferSize = sizeof(tcu::Vec4) * 8;
1280 const VkBufferCreateInfo bufferCreateInfo =
1282 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1283 DE_NULL, // const void* pNext;
1284 0u, // VkBufferCreateFlags flags
1285 bufferSize, // VkDeviceSize size;
1286 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1287 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1288 1u, // deUint32 queueFamilyCount;
1289 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1292 m_outBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
1293 m_outBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outBuffer), MemoryRequirement::HostVisible);
1294 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outBuffer, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset()));
1296 // create and update descriptor set
1297 const VkDescriptorSetAllocateInfo allocInfo =
1299 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
1300 DE_NULL, // const void* pNext;
1301 *m_descriptorPool, // VkDescriptorPool descriptorPool;
1302 1u, // uint32_t setLayoutCount;
1303 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
1305 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1307 const VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(*m_outBuffer, (VkDeviceSize)0u, bufferSize);
1309 DescriptorSetUpdateBuilder()
1310 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1311 .update(vk, vkDevice);
1313 // create pipeline layout
1314 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1316 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1317 DE_NULL, // const void* pNext;
1318 0u, // VkPipelineLayoutCreateFlags flags;
1319 1u, // deUint32 descriptorSetCount;
1320 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
1321 1u, // deUint32 pushConstantRangeCount;
1322 &pushConstantRanges // const VkPushConstantRange* pPushConstantRanges;
1325 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1330 m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);
1332 const VkPipelineShaderStageCreateInfo stageCreateInfo =
1334 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1335 DE_NULL, // const void* pNext;
1336 0u, // VkPipelineShaderStageCreateFlags flags;
1337 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
1338 *m_computeShaderModule, // VkShaderModule module;
1339 "main", // const char* pName;
1340 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1343 const VkComputePipelineCreateInfo createInfo =
1345 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1346 DE_NULL, // const void* pNext;
1347 0u, // VkPipelineCreateFlags flags;
1348 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
1349 *m_pipelineLayout, // VkPipelineLayout layout;
1350 (VkPipeline)0, // VkPipeline basePipelineHandle;
1351 0u, // int32_t basePipelineIndex;
1354 m_computePipelines = createComputePipeline(vk, vkDevice, (vk::VkPipelineCache)0u, &createInfo);
1357 // Create command pool
1359 const VkCommandPoolCreateInfo cmdPoolParams =
1361 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1362 DE_NULL, // const void* pNext;
1363 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1364 queueFamilyIndex // deUint32 queueFamilyIndex;
1366 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1369 // Create command buffer
1371 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1373 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1374 DE_NULL, // const void* pNext;
1375 *m_cmdPool, // VkCommandPool commandPool;
1376 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
1377 1u // deUint32 bufferCount;
1380 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
1382 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1384 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1385 DE_NULL, // const void* pNext;
1386 0u, // VkCommandBufferUsageFlags flags;
1387 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1390 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1392 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
1393 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
1395 // update push constant
1396 tcu::Vec4 value = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1397 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange.range.shaderStage, m_pushConstantRange.range.offset, m_pushConstantRange.range.size, &value);
1399 vk.cmdDispatch(*m_cmdBuffer, 8, 1, 1);
1401 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1406 const VkFenceCreateInfo fenceParams =
1408 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1409 DE_NULL, // const void* pNext;
1410 0u // VkFenceCreateFlags flags;
1413 m_fence = createFence(vk, vkDevice, &fenceParams);
1417 PushConstantComputeTestInstance::~PushConstantComputeTestInstance (void)
1421 tcu::TestStatus PushConstantComputeTestInstance::iterate (void)
1423 const DeviceInterface& vk = m_context.getDeviceInterface();
1424 const VkDevice vkDevice = m_context.getDevice();
1425 const VkQueue queue = m_context.getUniversalQueue();
1426 const VkSubmitInfo submitInfo =
1428 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1429 DE_NULL, // const void* pNext;
1430 0u, // deUint32 waitSemaphoreCount;
1431 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1432 (const VkPipelineStageFlags*)DE_NULL,
1433 1u, // deUint32 commandBufferCount;
1434 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1435 0u, // deUint32 signalSemaphoreCount;
1436 DE_NULL // const VkSemaphore* pSignalSemaphores;
1439 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1440 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1441 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1444 std::vector<tcu::Vec4> expectValue(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1445 if (deMemCmp((void*)(&expectValue[0]), m_outBufferAlloc->getHostPtr(), (size_t)(sizeof(tcu::Vec4) * 8)))
1447 return tcu::TestStatus::fail("Image mismatch");
1449 return tcu::TestStatus::pass("result image matches with reference");
1454 tcu::TestCaseGroup* createPushConstantTests (tcu::TestContext& testCtx)
1459 const char* description;
1461 PushConstantData range[MAX_RANGE_COUNT];
1462 deBool hasMultipleUpdates;
1463 } graphicsParams[] =
1465 // test range size from minimum valid size to maximum
1468 "test range size is 4 bytes(minimum valid size)",
1470 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 } , { 0, 4 } } },
1475 "test range size is 16 bytes, and together with a normal uniform",
1477 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } } },
1482 "test range size is 128 bytes(maximum valid size)",
1484 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 128 }, { 0, 128 } } },
1487 // test range count, including all valid shader stage in graphics pipeline, and also multiple shader stages share one single range
1489 "count_2_shader_VF",
1490 "test range count is 2, use vertex and fragment shaders",
1493 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
1494 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
1499 "count_3shader_VGF",
1500 "test range count is 3, use vertex, geometry and fragment shaders",
1503 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
1504 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
1505 { { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } },
1510 "count_5_shader_VTGF",
1511 "test range count is 5, use vertex, tessellation, geometry and fragment shaders",
1514 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
1515 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
1516 { { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } },
1517 { { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 24, 4 }, { 24, 4 } },
1518 { { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 32, 16 }, { 32, 16 } },
1523 "count_1_shader_VF",
1524 "test range count is 1, vertex and fragment shaders share one range",
1526 { { { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4 }, { 0, 4 } } },
1529 // test data partial update and multiple times update
1531 "data_update_partial_1",
1532 "test partial update of the values",
1534 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 32 }, { 4, 24 } } },
1538 "data_update_partial_2",
1539 "test partial update of the values",
1541 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 48 }, { 32, 16 } } },
1545 "data_update_multiple",
1546 "test multiple times update of the values",
1548 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 }, { 0, 4 } } },
1556 const char* description;
1557 PushConstantData range;
1562 "test compute pipeline",
1563 { { VK_SHADER_STAGE_COMPUTE_BIT, 0, 16 }, { 0, 16 } },
1567 de::MovePtr<tcu::TestCaseGroup> pushConstantTests (new tcu::TestCaseGroup(testCtx, "push_constant", "PushConstant tests"));
1569 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics_pipeline", "graphics pipeline"));
1570 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(graphicsParams); ndx++)
1572 graphicsTests->addChild(new PushConstantGraphicsTest(testCtx, graphicsParams[ndx].name, graphicsParams[ndx].description, graphicsParams[ndx].count, graphicsParams[ndx].range, graphicsParams[ndx].hasMultipleUpdates));
1574 pushConstantTests->addChild(graphicsTests.release());
1576 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute_pipeline", "compute pipeline"));
1577 computeTests->addChild(new PushConstantComputeTest(testCtx, computeParams[0].name, computeParams[0].description, computeParams[0].range));
1578 pushConstantTests->addChild(computeTests.release());
1580 return pushConstantTests.release();