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::IVec2 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(location = 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, // VkPipelineTesselationStateCreateFlags 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 DE_NULL, // VkRenderPass renderPass;
990 0u, // deUint32 subpass;
991 DE_NULL, // VkFramebuffer framebuffer;
992 false, // VkBool32 occlusionQueryEnable;
993 0u, // VkQueryControlFlags queryFlags;
994 0u // VkQueryPipelineStatisticFlags pipelineStatistics;
997 const VkClearValue attachmentClearValues[] =
999 defaultClearValue(m_colorFormat)
1002 const VkRenderPassBeginInfo renderPassBeginInfo =
1004 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1005 DE_NULL, // const void* pNext;
1006 *m_renderPass, // VkRenderPass renderPass;
1007 *m_framebuffer, // VkFramebuffer framebuffer;
1008 { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1009 1, // deUint32 clearValueCount;
1010 attachmentClearValues // const VkClearValue* pClearValues;
1013 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
1015 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1016 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1018 // update push constant
1019 std::vector<tcu::Vec4> color(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1020 std::vector<tcu::Vec4> allOnes(8, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1022 const deUint32 kind = 2u;
1023 const void* value = DE_NULL;
1024 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
1026 value = (m_pushConstantRange[rangeNdx].range.size == 4u) ? (void*)(&kind) : (void*)(&color[0]);
1028 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].range.offset, m_pushConstantRange[rangeNdx].range.size, value);
1030 if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size)
1032 value = (void*)(&allOnes[0]);
1033 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[rangeNdx].range.shaderStage, m_pushConstantRange[rangeNdx].update.offset, m_pushConstantRange[rangeNdx].update.size, value);
1038 const VkDeviceSize triangleOffset = (m_vertices.size() / TRIANGLE_COUNT) * sizeof(Vertex4RGBA);
1039 for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++)
1041 VkDeviceSize vertexBufferOffset = triangleOffset * triangleNdx;
1043 if (m_multipleUpdate)
1045 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange[0].range.shaderStage, m_pushConstantRange[0].range.offset, m_pushConstantRange[0].range.size, &triangleNdx);
1048 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1049 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1050 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
1052 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / TRIANGLE_COUNT), 1, 0, 0);
1055 vk.cmdEndRenderPass(*m_cmdBuffer);
1056 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1061 const VkFenceCreateInfo fenceParams =
1063 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1064 DE_NULL, // const void* pNext;
1065 0u // VkFenceCreateFlags flags;
1068 m_fence = createFence(vk, vkDevice, &fenceParams);
1072 PushConstantGraphicsTestInstance::~PushConstantGraphicsTestInstance (void)
1076 tcu::TestStatus PushConstantGraphicsTestInstance::iterate (void)
1078 const DeviceInterface& vk = m_context.getDeviceInterface();
1079 const VkDevice vkDevice = m_context.getDevice();
1080 const VkQueue queue = m_context.getUniversalQueue();
1081 const VkSubmitInfo submitInfo =
1083 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1084 DE_NULL, // const void* pNext;
1085 0u, // deUint32 waitSemaphoreCount;
1086 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1087 1u, // deUint32 commandBufferCount;
1088 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1089 0u, // deUint32 signalSemaphoreCount;
1090 DE_NULL // const VkSemaphore* pSignalSemaphores;
1093 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1094 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1095 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1097 return verifyImage();
1100 tcu::TestStatus PushConstantGraphicsTestInstance::verifyImage (void)
1102 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1103 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
1104 const ColorVertexShader vertexShader;
1105 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat);
1106 const rr::Program program (&vertexShader, &fragmentShader);
1107 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1108 bool compareOk = false;
1110 // Render reference image
1112 if (m_shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT)
1114 m_vertices = createQuad(0.5f);
1117 for (size_t rangeNdx = 0; rangeNdx < m_rangeCount; rangeNdx++)
1119 if (m_pushConstantRange[rangeNdx].update.size < m_pushConstantRange[rangeNdx].range.size)
1121 for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++)
1123 m_vertices[vertexNdx].color.xyzw() = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1128 if (m_multipleUpdate)
1130 for (size_t vertexNdx = 0; vertexNdx < 3; vertexNdx++)
1132 m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f);
1134 for (size_t vertexNdx = 3; vertexNdx < m_vertices.size(); vertexNdx++)
1136 m_vertices[vertexNdx].color.xyz() = tcu::Vec3(0.0f, 0.0f, 1.0f);
1140 for (int triangleNdx = 0; triangleNdx < TRIANGLE_COUNT; triangleNdx++)
1142 rr::RenderState renderState(refRenderer.getViewportState());
1144 refRenderer.draw(renderState,
1145 rr::PRIMITIVETYPE_TRIANGLES,
1146 std::vector<Vertex4RGBA>(m_vertices.begin() + triangleNdx * 3,
1147 m_vertices.begin() + (triangleNdx + 1) * 3));
1151 // Compare result with reference image
1153 const DeviceInterface& vk = m_context.getDeviceInterface();
1154 const VkDevice vkDevice = m_context.getDevice();
1155 const VkQueue queue = m_context.getUniversalQueue();
1156 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1157 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1158 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
1160 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1163 refRenderer.getAccess(),
1164 result->getAccess(),
1165 tcu::UVec4(2, 2, 2, 2),
1166 tcu::IVec3(1, 1, 0),
1168 tcu::COMPARE_LOG_RESULT);
1172 return tcu::TestStatus::pass("Result image matches reference");
1174 return tcu::TestStatus::fail("Image mismatch");
1177 class PushConstantComputeTest : public vkt::TestCase
1180 PushConstantComputeTest (tcu::TestContext& testContext,
1181 const std::string& name,
1182 const std::string& description,
1183 const PushConstantData pushConstantRange);
1184 virtual ~PushConstantComputeTest (void);
1185 virtual void initPrograms (SourceCollections& sourceCollections) const;
1186 virtual TestInstance* createInstance (Context& context) const;
1189 const PushConstantData m_pushConstantRange;
1192 class PushConstantComputeTestInstance : public vkt::TestInstance
1195 PushConstantComputeTestInstance (Context& context,
1196 const PushConstantData pushConstantRange);
1197 virtual ~PushConstantComputeTestInstance (void);
1198 virtual tcu::TestStatus iterate (void);
1201 const PushConstantData m_pushConstantRange;
1203 Move<VkBuffer> m_outBuffer;
1204 de::MovePtr<Allocation> m_outBufferAlloc;
1205 Move<VkDescriptorPool> m_descriptorPool;
1206 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1207 Move<VkDescriptorSet> m_descriptorSet;
1209 Move<VkPipelineLayout> m_pipelineLayout;
1210 Move<VkPipeline> m_computePipelines;
1212 Move<VkShaderModule> m_computeShaderModule;
1214 Move<VkCommandPool> m_cmdPool;
1215 Move<VkCommandBuffer> m_cmdBuffer;
1217 Move<VkFence> m_fence;
1220 PushConstantComputeTest::PushConstantComputeTest (tcu::TestContext& testContext,
1221 const std::string& name,
1222 const std::string& description,
1223 const PushConstantData pushConstantRange)
1224 : vkt::TestCase (testContext, name, description)
1225 , m_pushConstantRange (pushConstantRange)
1229 PushConstantComputeTest::~PushConstantComputeTest (void)
1233 TestInstance* PushConstantComputeTest::createInstance (Context& context) const
1235 return new PushConstantComputeTestInstance(context, m_pushConstantRange);
1238 void PushConstantComputeTest::initPrograms (SourceCollections& sourceCollections) const
1240 std::ostringstream computeSrc;
1242 computeSrc << "#version 450\n"
1243 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1244 << "layout(std140, set = 0, binding = 0) writeonly buffer Output {\n"
1245 << " vec4 elements[];\n"
1247 << "layout(push_constant) uniform Material{\n"
1248 << " vec4 element;\n"
1250 << "void main (void)\n"
1252 << " outData.elements[gl_GlobalInvocationID.x] = matInst.element;\n"
1255 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc.str());
1258 PushConstantComputeTestInstance::PushConstantComputeTestInstance (Context& context,
1259 const PushConstantData pushConstantRange)
1260 : vkt::TestInstance (context)
1261 , m_pushConstantRange (pushConstantRange)
1263 const DeviceInterface& vk = context.getDeviceInterface();
1264 const VkDevice vkDevice = context.getDevice();
1265 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1266 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1268 // Create pipeline layout
1270 // create push constant range
1271 VkPushConstantRange pushConstantRanges;
1272 pushConstantRanges.stageFlags = m_pushConstantRange.range.shaderStage;
1273 pushConstantRanges.offset = m_pushConstantRange.range.offset;
1274 pushConstantRanges.size = m_pushConstantRange.range.size;
1276 // create descriptor set layout
1277 m_descriptorSetLayout = DescriptorSetLayoutBuilder().addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT).build(vk, vkDevice);
1279 // create descriptor pool
1280 m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1282 // create uniform buffer
1283 const VkDeviceSize bufferSize = sizeof(tcu::Vec4) * 8;
1284 const VkBufferCreateInfo bufferCreateInfo =
1286 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1287 DE_NULL, // const void* pNext;
1288 0u, // VkBufferCreateFlags flags
1289 bufferSize, // VkDeviceSize size;
1290 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1291 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1292 1u, // deUint32 queueFamilyCount;
1293 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1296 m_outBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
1297 m_outBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outBuffer), MemoryRequirement::HostVisible);
1298 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outBuffer, m_outBufferAlloc->getMemory(), m_outBufferAlloc->getOffset()));
1300 // create and update descriptor set
1301 const VkDescriptorSetAllocateInfo allocInfo =
1303 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
1304 DE_NULL, // const void* pNext;
1305 *m_descriptorPool, // VkDescriptorPool descriptorPool;
1306 1u, // uint32_t setLayoutCount;
1307 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
1309 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1311 const VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(*m_outBuffer, (VkDeviceSize)0u, bufferSize);
1313 DescriptorSetUpdateBuilder()
1314 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1315 .update(vk, vkDevice);
1317 // create pipeline layout
1318 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1320 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1321 DE_NULL, // const void* pNext;
1322 0u, // VkPipelineLayoutCreateFlags flags;
1323 1u, // deUint32 descriptorSetCount;
1324 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
1325 1u, // deUint32 pushConstantRangeCount;
1326 &pushConstantRanges // const VkPushConstantRange* pPushConstantRanges;
1329 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1334 m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);
1336 const VkPipelineShaderStageCreateInfo stageCreateInfo =
1338 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1339 DE_NULL, // const void* pNext;
1340 0u, // VkPipelineShaderStageCreateFlags flags;
1341 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
1342 *m_computeShaderModule, // VkShaderModule module;
1343 "main", // const char* pName;
1344 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1347 const VkComputePipelineCreateInfo createInfo =
1349 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1350 DE_NULL, // const void* pNext;
1351 0u, // VkPipelineCreateFlags flags;
1352 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
1353 *m_pipelineLayout, // VkPipelineLayout layout;
1354 (VkPipeline)0, // VkPipeline basePipelineHandle;
1355 0u, // int32_t basePipelineIndex;
1358 m_computePipelines = createComputePipeline(vk, vkDevice, (vk::VkPipelineCache)0u, &createInfo);
1361 // Create command pool
1363 const VkCommandPoolCreateInfo cmdPoolParams =
1365 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1366 DE_NULL, // const void* pNext;
1367 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1368 queueFamilyIndex // deUint32 queueFamilyIndex;
1370 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1373 // Create command buffer
1375 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1377 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1378 DE_NULL, // const void* pNext;
1379 *m_cmdPool, // VkCommandPool commandPool;
1380 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
1381 1u // deUint32 bufferCount;
1384 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
1386 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1388 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1389 DE_NULL, // const void* pNext;
1390 0u, // VkCommandBufferUsageFlags flags;
1391 DE_NULL, // VkRenderPass renderPass;
1392 0u, // deUint32 subpass;
1393 DE_NULL, // VkFramebuffer framebuffer;
1394 false, // VkBool32 occlusionQueryEnable;
1395 0u, // VkQueryControlFlags queryFlags;
1396 0u // VkQueryPipelineStatisticFlags pipelineStatistics;
1399 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1401 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
1402 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
1404 // update push constant
1405 tcu::Vec4 value = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1406 vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, m_pushConstantRange.range.shaderStage, m_pushConstantRange.range.offset, m_pushConstantRange.range.size, &value);
1408 vk.cmdDispatch(*m_cmdBuffer, 8, 1, 1);
1410 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1415 const VkFenceCreateInfo fenceParams =
1417 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1418 DE_NULL, // const void* pNext;
1419 0u // VkFenceCreateFlags flags;
1422 m_fence = createFence(vk, vkDevice, &fenceParams);
1426 PushConstantComputeTestInstance::~PushConstantComputeTestInstance (void)
1430 tcu::TestStatus PushConstantComputeTestInstance::iterate (void)
1432 const DeviceInterface& vk = m_context.getDeviceInterface();
1433 const VkDevice vkDevice = m_context.getDevice();
1434 const VkQueue queue = m_context.getUniversalQueue();
1435 const VkSubmitInfo submitInfo =
1437 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1438 DE_NULL, // const void* pNext;
1439 0u, // deUint32 waitSemaphoreCount;
1440 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1441 1u, // deUint32 commandBufferCount;
1442 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1443 0u, // deUint32 signalSemaphoreCount;
1444 DE_NULL // const VkSemaphore* pSignalSemaphores;
1447 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1448 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1449 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1452 std::vector<tcu::Vec4> expectValue(8, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1453 if (deMemCmp((void*)(&expectValue[0]), m_outBufferAlloc->getHostPtr(), (size_t)(sizeof(tcu::Vec4) * 8)))
1455 return tcu::TestStatus::fail("Image mismatch");
1457 return tcu::TestStatus::pass("result image matches with reference");
1462 tcu::TestCaseGroup* createPushConstantTests (tcu::TestContext& testCtx)
1467 const char* description;
1469 PushConstantData range[MAX_RANGE_COUNT];
1470 deBool hasMultipleUpdates;
1471 } graphicsParams[] =
1473 // test range size from minimum valid size to maximum
1476 "test range size is 4 bytes(minimum valid size)",
1478 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 } , { 0, 4 } } },
1483 "test range size is 16 bytes, and together with a normal uniform",
1485 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } } },
1490 "test range size is 128 bytes(maximum valid size)",
1492 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 128 }, { 0, 128 } } },
1495 // test range count, including all valid shader stage in graphics pipeline, and also multiple shader stages share one single range
1497 "count_2_shader_VF",
1498 "test range count is 2, use vertex and fragment shaders",
1501 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
1502 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
1507 "count_3shader_VGF",
1508 "test range count is 3, use vertex, geometry and fragment shaders",
1511 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
1512 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
1513 { { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } },
1518 "count_5_shader_VTGF",
1519 "test range count is 5, use vertex, tessellation, geometry and fragment shaders",
1522 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, { 0, 16 } },
1523 { { VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4 }, { 16, 4 } },
1524 { { VK_SHADER_STAGE_GEOMETRY_BIT, 20, 4 }, { 20, 4 } },
1525 { { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 24, 4 }, { 24, 4 } },
1526 { { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 32, 16 }, { 32, 16 } },
1531 "count_1_shader_VF",
1532 "test range count is 1, vertex and fragment shaders share one range",
1534 { { { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4 }, { 0, 4 } } },
1537 // test data partial update and multiple times update
1539 "data_update_partial_1",
1540 "test partial update of the values",
1542 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 32 }, { 4, 24 } } },
1546 "data_update_partial_2",
1547 "test partial update of the values",
1549 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 48 }, { 32, 16 } } },
1553 "data_update_multiple",
1554 "test multiple times update of the values",
1556 { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 }, { 0, 4 } } },
1564 const char* description;
1565 PushConstantData range;
1570 "test compute pipeline",
1571 { { VK_SHADER_STAGE_COMPUTE_BIT, 0, 16 }, { 0, 16 } },
1575 de::MovePtr<tcu::TestCaseGroup> pushConstantTests (new tcu::TestCaseGroup(testCtx, "push_constant", "PushConstant tests"));
1577 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics_pipeline", "graphics pipeline"));
1578 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(graphicsParams); ndx++)
1580 graphicsTests->addChild(new PushConstantGraphicsTest(testCtx, graphicsParams[ndx].name, graphicsParams[ndx].description, graphicsParams[ndx].count, graphicsParams[ndx].range, graphicsParams[ndx].hasMultipleUpdates));
1582 pushConstantTests->addChild(graphicsTests.release());
1584 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute_pipeline", "compute pipeline"));
1585 computeTests->addChild(new PushConstantComputeTest(testCtx, computeParams[0].name, computeParams[0].description, computeParams[0].range));
1586 pushConstantTests->addChild(computeTests.release());
1588 return pushConstantTests.release();