1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Instanced Draw Tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktDrawInstancedTests.hpp"
29 #include "deSharedPtr.hpp"
30 #include "rrRenderer.hpp"
31 #include "tcuImageCompare.hpp"
32 #include "tcuRGBA.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkCmdUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vktDrawBufferObjectUtil.hpp"
40 #include "vktDrawCreateInfoUtil.hpp"
41 #include "vktDrawImageObjectUtil.hpp"
42 #include "vktDrawTestCaseUtil.hpp"
51 static const int QUAD_GRID_SIZE = 8;
52 static const int WIDTH = 128;
53 static const int HEIGHT = 128;
60 FUNCTION_DRAW_INDEXED,
61 FUNCTION_DRAW_INDIRECT,
62 FUNCTION_DRAW_INDEXED_INDIRECT,
67 DrawFunction function;
68 vk::VkPrimitiveTopology topology;
69 const SharedGroupParams groupParams;
71 deBool testAttribDivisor;
72 deUint32 attribDivisor;
79 struct VertexPositionAndColor
81 VertexPositionAndColor (tcu::Vec4 position_, tcu::Vec4 color_)
82 : position (position_)
91 std::ostream & operator<<(std::ostream & str, TestParams const & v)
93 std::ostringstream string;
96 string << "dynamic_state_";
100 case TestParams::FUNCTION_DRAW:
103 case TestParams::FUNCTION_DRAW_INDEXED:
104 string << "draw_indexed";
106 case TestParams::FUNCTION_DRAW_INDIRECT:
107 string << "draw_indirect";
109 case TestParams::FUNCTION_DRAW_INDEXED_INDIRECT:
110 string << "draw_indexed_indirect";
116 string << "_" << de::toString(v.topology);
118 if (v.testAttribDivisor)
119 string << "_attrib_divisor_" << v.attribDivisor;
122 string << "_multiview";
124 return str << string.str();
127 rr::PrimitiveType mapVkPrimitiveTopology (vk::VkPrimitiveTopology primitiveTopology)
129 switch (primitiveTopology)
131 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST: return rr::PRIMITIVETYPE_POINTS;
132 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST: return rr::PRIMITIVETYPE_LINES;
133 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: return rr::PRIMITIVETYPE_LINE_STRIP;
134 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return rr::PRIMITIVETYPE_TRIANGLES;
135 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: return rr::PRIMITIVETYPE_TRIANGLE_FAN;
136 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return rr::PRIMITIVETYPE_TRIANGLE_STRIP;
137 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: return rr::PRIMITIVETYPE_LINES_ADJACENCY;
138 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: return rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY;
139 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: return rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY;
140 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: return rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY;
144 return rr::PRIMITIVETYPE_LAST;
148 de::SharedPtr<Buffer> createAndUploadBuffer(const std::vector<T> data, const vk::DeviceInterface& vk, const Context& context, vk::VkBufferUsageFlags usage)
150 const vk::VkDeviceSize dataSize = data.size() * sizeof(T);
151 de::SharedPtr<Buffer> buffer = Buffer::createAndAlloc(vk, context.getDevice(),
152 BufferCreateInfo(dataSize, usage),
153 context.getDefaultAllocator(),
154 vk::MemoryRequirement::HostVisible);
156 deUint8* ptr = reinterpret_cast<deUint8*>(buffer->getBoundMemory().getHostPtr());
158 deMemcpy(ptr, &data[0], static_cast<size_t>(dataSize));
160 vk::flushAlloc(vk, context.getDevice(), buffer->getBoundMemory());
164 class TestVertShader : public rr::VertexShader
167 TestVertShader (int numInstances, int firstInstance)
168 : rr::VertexShader (3, 1)
169 , m_numInstances (numInstances)
170 , m_firstInstance (firstInstance)
172 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
173 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
174 m_inputs[2].type = rr::GENERICVECTYPE_FLOAT;
175 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
178 void shadeVertices (const rr::VertexAttrib* inputs,
179 rr::VertexPacket* const* packets,
180 const int numPackets) const
182 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
184 const int instanceNdx = packets[packetNdx]->instanceNdx + m_firstInstance;
185 const tcu::Vec4 position = rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx, m_firstInstance);
186 const tcu::Vec4 color = rr::readVertexAttribFloat(inputs[1], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx, m_firstInstance);
187 const tcu::Vec4 color2 = rr::readVertexAttribFloat(inputs[2], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx, m_firstInstance);
188 packets[packetNdx]->position = position + tcu::Vec4((float)(packets[packetNdx]->instanceNdx * 2.0 / m_numInstances), 0.0, 0.0, 0.0);
189 packets[packetNdx]->outputs[0] = color + tcu::Vec4((float)instanceNdx / (float)m_numInstances, 0.0, 0.0, 1.0) + color2;
194 const int m_numInstances;
195 const int m_firstInstance;
198 class TestFragShader : public rr::FragmentShader
201 TestFragShader (void)
202 : rr::FragmentShader(1, 1)
204 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
205 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
208 void shadeFragments (rr::FragmentPacket* packets,
209 const int numPackets,
210 const rr::FragmentShadingContext& context) const
212 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
214 rr::FragmentPacket& packet = packets[packetNdx];
215 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
217 const tcu::Vec4 color = rr::readVarying<float>(packet, context, 0, fragNdx);
218 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
224 class InstancedDrawInstance : public TestInstance
227 InstancedDrawInstance (Context& context, TestParams params);
228 virtual tcu::TestStatus iterate (void);
231 void prepareVertexData (int instanceCount, int firstInstance, int instanceDivisor);
232 void preRenderCommands (const vk::VkClearValue& clearColor, deUint32 numLayers);
233 void draw (vk::VkCommandBuffer cmdBuffer,
234 vk::VkBuffer vertexBuffer, vk::VkBuffer instancedVertexBuffer,
235 de::SharedPtr<Buffer> indexBuffer, de::SharedPtr<Buffer> indirectBuffer,
236 deUint32 firstInstance, deUint32 instanceCount);
238 #ifndef CTS_USES_VULKANSC
239 void beginSecondaryCmdBuffer (vk::VkRenderingFlagsKHR renderingFlags = 0u);
240 #endif // CTS_USES_VULKANSC
244 const TestParams m_params;
245 const vk::DeviceInterface& m_vk;
247 vk::VkFormat m_colorAttachmentFormat;
249 vk::Move<vk::VkPipeline> m_pipeline;
250 vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
252 de::SharedPtr<Image> m_colorTargetImage;
253 vk::Move<vk::VkImageView> m_colorTargetView;
255 PipelineCreateInfo::VertexInputState m_vertexInputState;
257 vk::Move<vk::VkCommandPool> m_cmdPool;
258 vk::Move<vk::VkCommandBuffer> m_cmdBuffer;
259 vk::Move<vk::VkCommandBuffer> m_secCmdBuffer;
261 vk::Move<vk::VkFramebuffer> m_framebuffer;
262 vk::Move<vk::VkRenderPass> m_renderPass;
265 std::vector<VertexPositionAndColor> m_data;
266 std::vector<deUint32> m_indexes;
267 std::vector<tcu::Vec4> m_instancedColor;
270 class InstancedDrawCase : public TestCase
273 InstancedDrawCase (tcu::TestContext& testCtx,
274 const std::string& name,
275 const std::string& desc,
277 : TestCase (testCtx, name, desc)
280 m_vertexShader = "#version 430\n"
281 "layout(location = 0) in vec4 in_position;\n"
282 "layout(location = 1) in vec4 in_color;\n"
283 "layout(location = 2) in vec4 in_color_2;\n"
284 "layout(push_constant) uniform TestParams {\n"
285 " float firstInstance;\n"
286 " float instanceCount;\n"
288 "layout(location = 0) out vec4 out_color;\n"
289 "out gl_PerVertex {\n"
290 " vec4 gl_Position;\n"
291 " float gl_PointSize;\n"
294 " gl_PointSize = 1.0;\n"
295 " gl_Position = in_position + vec4(float(gl_InstanceIndex - params.firstInstance) * 2.0 / params.instanceCount, 0.0, 0.0, 0.0);\n"
296 " out_color = in_color + vec4(float(gl_InstanceIndex) / params.instanceCount, 0.0, 0.0, 1.0) + in_color_2;\n"
299 m_fragmentShader = "#version 430\n"
300 "layout(location = 0) in vec4 in_color;\n"
301 "layout(location = 0) out vec4 out_color;\n"
304 " out_color = in_color;\n"
308 virtual void checkSupport (Context& context) const
310 if (m_params.dynamicState)
312 const auto physicalVertexInputDynamicState = context.getVertexInputDynamicStateFeaturesEXT();
313 if (!physicalVertexInputDynamicState.vertexInputDynamicState)
314 TCU_THROW(NotSupportedError, "Implementation does not support vertexInputDynamicState");
316 if (m_params.testAttribDivisor)
318 context.requireDeviceFunctionality("VK_EXT_vertex_attribute_divisor");
320 const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT& vertexAttributeDivisorFeatures = context.getVertexAttributeDivisorFeaturesEXT();
322 if (m_params.attribDivisor != 1 && !vertexAttributeDivisorFeatures.vertexAttributeInstanceRateDivisor)
323 TCU_THROW(NotSupportedError, "Implementation does not support vertexAttributeInstanceRateDivisor");
325 if (m_params.attribDivisor == 0 && !vertexAttributeDivisorFeatures.vertexAttributeInstanceRateZeroDivisor)
326 TCU_THROW(NotSupportedError, "Implementation does not support vertexAttributeInstanceRateDivisorZero");
328 if (m_params.testMultiview)
330 context.requireDeviceFunctionality("VK_KHR_multiview");
332 const vk::VkPhysicalDeviceMultiviewFeatures& multiviewFeatures = context.getMultiviewFeatures();
334 if (!multiviewFeatures.multiview)
335 TCU_THROW(NotSupportedError, "Implementation does not support multiview feature");
339 #ifndef CTS_USES_VULKANSC
340 if (m_params.groupParams->useDynamicRendering)
341 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
343 if (m_params.topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
344 context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
345 !context.getPortabilitySubsetFeatures().triangleFans)
347 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
349 #endif // CTS_USES_VULKANSC
352 TestInstance* createInstance (Context& context) const
354 return new InstancedDrawInstance(context, m_params);
357 virtual void initPrograms (vk::SourceCollections& programCollection) const
359 programCollection.glslSources.add("InstancedDrawVert") << glu::VertexSource(m_vertexShader);
360 programCollection.glslSources.add("InstancedDrawFrag") << glu::FragmentSource(m_fragmentShader);
364 const TestParams m_params;
365 std::string m_vertexShader;
366 std::string m_fragmentShader;
369 InstancedDrawInstance::InstancedDrawInstance(Context &context, TestParams params)
370 : TestInstance (context)
372 , m_vk (context.getDeviceInterface())
373 , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
375 const vk::VkDevice device = m_context.getDevice();
376 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
378 const vk::VkPushConstantRange pushConstantRange = {
379 vk::VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlags stageFlags;
380 0u, // uint32_t offset;
381 (deUint32)sizeof(float) * 2, // uint32_t size;
384 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo(0, DE_NULL, 1, &pushConstantRange);
385 m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
387 deUint32 arrayLayers = m_params.testMultiview ? 2 : 1;
388 const vk::VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
389 const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1, arrayLayers, vk::VK_SAMPLE_COUNT_1_BIT,
390 vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
392 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
394 const enum vk::VkImageViewType imageViewType = m_params.testMultiview ? vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY : vk::VK_IMAGE_VIEW_TYPE_2D;
395 ImageSubresourceRange subresourceRange = ImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
397 if (m_params.testMultiview)
398 subresourceRange.layerCount = 2;
400 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), imageViewType, m_colorAttachmentFormat, subresourceRange);
401 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
403 if (!m_params.groupParams->useDynamicRendering)
405 RenderPassCreateInfo renderPassCreateInfo;
406 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
407 vk::VK_SAMPLE_COUNT_1_BIT,
408 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
409 vk::VK_ATTACHMENT_STORE_OP_STORE,
410 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
411 vk::VK_ATTACHMENT_STORE_OP_STORE,
412 vk::VK_IMAGE_LAYOUT_GENERAL,
413 vk::VK_IMAGE_LAYOUT_GENERAL));
415 const vk::VkAttachmentReference colorAttachmentReference =
418 vk::VK_IMAGE_LAYOUT_GENERAL
421 renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
426 &colorAttachmentReference,
428 AttachmentReference(),
432 vk::VkRenderPassMultiviewCreateInfo renderPassMultiviewCreateInfo;
433 // Bit mask that specifies which view rendering is broadcast to
434 // 0011 = Broadcast to first and second view (layer)
435 const deUint32 viewMask = 0x3;
436 // Bit mask that specifices correlation between views
437 // An implementation may use this for optimizations (concurrent render)
438 const deUint32 correlationMask = 0x3;
440 if (m_params.testMultiview)
442 DE_ASSERT(renderPassCreateInfo.subpassCount == 1);
444 renderPassMultiviewCreateInfo.sType = vk::VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
445 renderPassMultiviewCreateInfo.pNext = DE_NULL;
446 renderPassMultiviewCreateInfo.subpassCount = renderPassCreateInfo.subpassCount;
447 renderPassMultiviewCreateInfo.pViewMasks = &viewMask;
448 renderPassMultiviewCreateInfo.correlationMaskCount = 1u;
449 renderPassMultiviewCreateInfo.pCorrelationMasks = &correlationMask;
450 renderPassMultiviewCreateInfo.pViewOffsets = DE_NULL;
451 renderPassMultiviewCreateInfo.dependencyCount = 0u;
453 renderPassCreateInfo.pNext = &renderPassMultiviewCreateInfo;
456 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
458 // create framebuffer
459 std::vector<vk::VkImageView> colorAttachments { *m_colorTargetView };
460 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
461 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
464 const vk::VkVertexInputBindingDescription vertexInputBindingDescription[2] =
468 (deUint32)sizeof(VertexPositionAndColor),
469 vk::VK_VERTEX_INPUT_RATE_VERTEX,
473 (deUint32)sizeof(tcu::Vec4),
474 vk::VK_VERTEX_INPUT_RATE_INSTANCE,
478 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
483 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
489 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
490 (deUint32)sizeof(tcu::Vec4),
495 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
500 m_vertexInputState = PipelineCreateInfo::VertexInputState(2,
501 vertexInputBindingDescription,
502 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),
503 vertexInputAttributeDescriptions);
505 const vk::VkVertexInputBindingDivisorDescriptionEXT vertexInputBindingDivisorDescription =
508 m_params.attribDivisor,
511 if (m_params.testAttribDivisor)
512 m_vertexInputState.addDivisors(1, &vertexInputBindingDivisorDescription);
514 const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
515 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
516 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
517 if (m_params.groupParams->useSecondaryCmdBuffer)
518 m_secCmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY);
520 const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("InstancedDrawVert"), 0));
521 const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("InstancedDrawFrag"), 0));
523 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
525 vk::VkViewport viewport = vk::makeViewport(WIDTH, HEIGHT);
526 vk::VkRect2D scissor = vk::makeRect2D(WIDTH, HEIGHT);
528 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
529 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
530 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
531 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_params.topology));
532 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
533 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<vk::VkViewport>(1, viewport), std::vector<vk::VkRect2D>(1, scissor)));
534 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
535 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
536 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
538 if (m_params.dynamicState)
540 vk::VkDynamicState dynStates[] =
542 vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
545 vk::VkPipelineDynamicStateCreateInfo dynamicState
547 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
553 pipelineCreateInfo.addState(dynamicState);
557 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
560 #ifndef CTS_USES_VULKANSC
561 vk::VkPipelineRenderingCreateInfoKHR renderingFormatCreateInfo
563 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
567 &m_colorAttachmentFormat,
568 vk::VK_FORMAT_UNDEFINED,
569 vk::VK_FORMAT_UNDEFINED
572 if (m_params.groupParams->useDynamicRendering)
574 pipelineCreateInfo.pNext = &renderingFormatCreateInfo;
576 if (m_params.testMultiview)
577 renderingFormatCreateInfo.viewMask = 3u;
579 #endif // CTS_USES_VULKANSC
581 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
584 tcu::TestStatus InstancedDrawInstance::iterate()
586 const vk::VkQueue queue = m_context.getUniversalQueue();
587 const vk::VkDevice device = m_context.getDevice();
588 static const deUint32 instanceCounts[] = { 0, 1, 2, 4, 20 };
589 static const deUint32 firstInstanceIndices[] = { 0, 1, 3, 4, 20 };
590 const deUint32 numLayers = m_params.testMultiview ? 2 : 1;
591 const vk::VkRect2D renderArea = vk::makeRect2D(WIDTH, HEIGHT);
593 qpTestResult res = QP_TEST_RESULT_PASS;
595 const vk::VkClearValue clearColor = { { { 0.0f, 0.0f, 0.0f, 1.0f } } };
596 int firstInstanceIndicesCount = DE_LENGTH_OF_ARRAY(firstInstanceIndices);
598 // Require 'drawIndirectFirstInstance' feature to run non-zero firstInstance indirect draw tests.
599 if (m_params.function == TestParams::FUNCTION_DRAW_INDIRECT && !m_context.getDeviceFeatures().drawIndirectFirstInstance)
601 firstInstanceIndicesCount = 1;
604 for (int instanceCountNdx = 0; instanceCountNdx < DE_LENGTH_OF_ARRAY(instanceCounts); instanceCountNdx++)
606 const deUint32 instanceCount = instanceCounts[instanceCountNdx];
607 for (int firstInstanceIndexNdx = 0; firstInstanceIndexNdx < firstInstanceIndicesCount; firstInstanceIndexNdx++)
609 // Prepare vertex data for at least one instance
610 const deUint32 prepareCount = de::max(instanceCount, 1u);
611 const deUint32 firstInstance = firstInstanceIndices[firstInstanceIndexNdx];
613 prepareVertexData(prepareCount, firstInstance, m_params.testAttribDivisor ? m_params.attribDivisor : 1);
614 const de::SharedPtr<Buffer> vertexBuffer = createAndUploadBuffer(m_data, m_vk, m_context, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
615 const de::SharedPtr<Buffer> instancedVertexBuffer = createAndUploadBuffer(m_instancedColor, m_vk, m_context, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
617 de::SharedPtr<Buffer> indexBuffer;
618 if (m_params.function == TestParams::FUNCTION_DRAW_INDEXED || m_params.function == TestParams::FUNCTION_DRAW_INDEXED_INDIRECT)
619 indexBuffer = createAndUploadBuffer(m_indexes, m_vk, m_context, vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
621 de::SharedPtr<Buffer> indirectBuffer;
622 if (m_params.function == TestParams::FUNCTION_DRAW_INDIRECT)
624 std::vector<vk::VkDrawIndirectCommand> drawCommands;
625 drawCommands.push_back({
626 (deUint32)m_data.size(), // uint32_t vertexCount;
627 instanceCount, // uint32_t instanceCount;
628 0u, // uint32_t firstVertex;
629 firstInstance // uint32_t firstInstance;
631 indirectBuffer = createAndUploadBuffer(drawCommands, m_vk, m_context, vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
633 if (m_params.function == TestParams::FUNCTION_DRAW_INDEXED_INDIRECT)
635 std::vector<vk::VkDrawIndexedIndirectCommand> drawCommands;
636 drawCommands.push_back({
637 (deUint32)m_indexes.size(), // uint32_t indexCount;
638 instanceCount, // uint32_t instanceCount;
639 0u, // uint32_t firstIndex;
640 0, // int32_t vertexOffset;
641 firstInstance // uint32_t firstInstance;
643 indirectBuffer = createAndUploadBuffer(drawCommands, m_vk, m_context, vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
646 #ifndef CTS_USES_VULKANSC
647 const deUint32 layerCount = (m_params.testMultiview) ? 2u : 1u;
648 const deUint32 viewMask = (m_params.testMultiview) ? 3u : 0u;
649 if (m_params.groupParams->useSecondaryCmdBuffer)
651 // record secondary command buffer
652 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
654 beginSecondaryCmdBuffer(vk::VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
655 beginRendering(m_vk, *m_secCmdBuffer, *m_colorTargetView, renderArea, clearColor, vk::VK_IMAGE_LAYOUT_GENERAL,
656 vk::VK_ATTACHMENT_LOAD_OP_LOAD, 0u, layerCount, viewMask);
659 beginSecondaryCmdBuffer();
661 draw(*m_secCmdBuffer, vertexBuffer->object(), instancedVertexBuffer->object(), indexBuffer, indirectBuffer, firstInstance, instanceCount);
663 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
664 endRendering(m_vk, *m_secCmdBuffer);
666 endCommandBuffer(m_vk, *m_secCmdBuffer);
668 // record primary command buffer
669 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
671 preRenderCommands(clearColor, numLayers);
673 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
675 beginRendering(m_vk, *m_cmdBuffer, *m_colorTargetView, renderArea, clearColor, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_LOAD,
676 vk::VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR, layerCount, viewMask);
679 m_vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
681 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
682 endRendering(m_vk, *m_cmdBuffer);
684 endCommandBuffer(m_vk, *m_cmdBuffer);
686 else if (m_params.groupParams->useDynamicRendering)
688 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
689 preRenderCommands(clearColor, numLayers);
691 beginRendering(m_vk, *m_cmdBuffer, *m_colorTargetView, renderArea, clearColor, vk::VK_IMAGE_LAYOUT_GENERAL,
692 vk::VK_ATTACHMENT_LOAD_OP_LOAD, 0u, layerCount, viewMask);
693 draw(*m_cmdBuffer, vertexBuffer->object(), instancedVertexBuffer->object(), indexBuffer, indirectBuffer, firstInstance, instanceCount);
694 endRendering(m_vk, *m_cmdBuffer);
696 endCommandBuffer(m_vk, *m_cmdBuffer);
698 #endif // CTS_USES_VULKANSC
700 if (!m_params.groupParams->useDynamicRendering)
702 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
703 preRenderCommands(clearColor, numLayers);
705 beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
706 draw(*m_cmdBuffer, vertexBuffer->object(), instancedVertexBuffer->object(), indexBuffer, indirectBuffer, firstInstance, instanceCount);
707 endRenderPass(m_vk, *m_cmdBuffer);
709 endCommandBuffer(m_vk, *m_cmdBuffer);
714 void InstancedDrawInstance::beginRender(vk::VkCommandBuffer cmdBuffer, const vk::VkClearValue& clearColor, vk::VkRenderingFlagsKHR renderingFlags)
717 if (m_params.groupParams->useDynamicRendering)
721 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
722 m_context.resetCommandPoolForVKSC(device, *m_cmdPool);
724 // Reference rendering
725 std::vector<tcu::Vec4> vetrices;
726 std::vector<tcu::Vec4> colors;
728 for (std::vector<VertexPositionAndColor>::const_iterator it = m_data.begin(); it != m_data.end(); ++it)
730 vetrices.push_back(it->position);
731 colors.push_back(it->color);
734 tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
736 tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
738 const TestVertShader vertShader(instanceCount, firstInstance);
739 const TestFragShader fragShader;
740 const rr::Program program (&vertShader, &fragShader);
741 const rr::MultisamplePixelBufferAccess colorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(refImage.getAccess());
742 const rr::RenderTarget renderTarget (colorBuffer);
743 const rr::RenderState renderState ((rr::ViewportState(colorBuffer)), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
744 const rr::Renderer renderer;
746 const rr::VertexAttrib vertexAttribs[] =
748 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vetrices[0]),
749 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &colors[0]),
750 // The reference renderer treats a divisor of 0 as meaning per-vertex. Use INT_MAX instead; it should work just as well.
751 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), m_params.testAttribDivisor ? (m_params.attribDivisor == 0 ? INT_MAX : m_params.attribDivisor) : 1, &m_instancedColor[0])
754 if (m_params.function == TestParams::FUNCTION_DRAW || m_params.function == TestParams::FUNCTION_DRAW_INDIRECT)
756 const rr::PrimitiveList primitives = rr::PrimitiveList(mapVkPrimitiveTopology(m_params.topology), (int)vetrices.size(), 0);
757 const rr::DrawCommand command(renderState, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), &vertexAttribs[0],
759 renderer.drawInstanced(command, instanceCount);
763 const rr::DrawIndices indicies(m_indexes.data());
765 const rr::PrimitiveList primitives = rr::PrimitiveList(mapVkPrimitiveTopology(m_params.topology), (int)m_indexes.size(), indicies);
766 const rr::DrawCommand command(renderState, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), &vertexAttribs[0],
768 renderer.drawInstanced(command, instanceCount);
771 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
772 for (deUint32 i = 0; i < numLayers; i++)
774 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
775 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT, 0, i);
777 tcu::TestLog &log = m_context.getTestContext().getLog();
779 std::ostringstream resultDesc;
780 resultDesc << "Image layer " << i << " comparison result. Instance count: " << instanceCount << " first instance index: " << firstInstance;
782 if (m_params.topology == vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
784 const bool ok = tcu::intThresholdPositionDeviationCompare(
785 log, "Result", resultDesc.str().c_str(), refImage.getAccess(), renderedFrame,
786 tcu::UVec4(4u), // color threshold
787 tcu::IVec3(1, 1, 0), // position deviation tolerance
788 true, // don't check the pixels at the boundary
789 tcu::COMPARE_LOG_RESULT);
792 res = QP_TEST_RESULT_FAIL;
796 if (!tcu::fuzzyCompare(log, "Result", resultDesc.str().c_str(), refImage.getAccess(), renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT))
797 res = QP_TEST_RESULT_FAIL;
802 return tcu::TestStatus(res, qpGetTestResultName(res));
805 void InstancedDrawInstance::prepareVertexData(int instanceCount, int firstInstance, int instanceDivisor)
809 m_instancedColor.clear();
811 if (m_params.function == TestParams::FUNCTION_DRAW || m_params.function == TestParams::FUNCTION_DRAW_INDIRECT)
813 for (int y = 0; y < QUAD_GRID_SIZE; y++)
815 for (int x = 0; x < QUAD_GRID_SIZE; x++)
817 const float fx0 = -1.0f + (float)(x+0) / (float)QUAD_GRID_SIZE * 2.0f / (float)instanceCount;
818 const float fx1 = -1.0f + (float)(x+1) / (float)QUAD_GRID_SIZE * 2.0f / (float)instanceCount;
819 const float fy0 = -1.0f + (float)(y+0) / (float)QUAD_GRID_SIZE * 2.0f;
820 const float fy1 = -1.0f + (float)(y+1) / (float)QUAD_GRID_SIZE * 2.0f;
822 // Vertices of a quad's lower-left triangle: (fx0, fy0), (fx1, fy0) and (fx0, fy1)
823 m_data.push_back(VertexPositionAndColor(tcu::Vec4(fx0, fy0, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
824 m_data.push_back(VertexPositionAndColor(tcu::Vec4(fx1, fy0, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
825 m_data.push_back(VertexPositionAndColor(tcu::Vec4(fx0, fy1, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
827 // Vertices of a quad's upper-right triangle: (fx1, fy1), (fx0, fy1) and (fx1, fy0)
828 m_data.push_back(VertexPositionAndColor(tcu::Vec4(fx1, fy1, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
829 m_data.push_back(VertexPositionAndColor(tcu::Vec4(fx0, fy1, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
830 m_data.push_back(VertexPositionAndColor(tcu::Vec4(fx1, fy0, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
836 for (int y = 0; y < QUAD_GRID_SIZE + 1; y++)
838 for (int x = 0; x < QUAD_GRID_SIZE + 1; x++)
840 const float fx = -1.0f + (float)x / (float)QUAD_GRID_SIZE * 2.0f / (float)instanceCount;
841 const float fy = -1.0f + (float)y / (float)QUAD_GRID_SIZE * 2.0f;
843 m_data.push_back(VertexPositionAndColor(tcu::Vec4(fx, fy, 1.0f, 1.0f),
844 (y % 2 ? tcu::RGBA::blue().toVec() : tcu::RGBA::green().toVec())));
848 for (int y = 0; y < QUAD_GRID_SIZE; y++)
850 for (int x = 0; x < QUAD_GRID_SIZE; x++)
852 const int ndx00 = y*(QUAD_GRID_SIZE + 1) + x;
853 const int ndx10 = y*(QUAD_GRID_SIZE + 1) + x + 1;
854 const int ndx01 = (y + 1)*(QUAD_GRID_SIZE + 1) + x;
855 const int ndx11 = (y + 1)*(QUAD_GRID_SIZE + 1) + x + 1;
857 // Lower-left triangle of a quad.
858 m_indexes.push_back((deUint16)ndx00);
859 m_indexes.push_back((deUint16)ndx10);
860 m_indexes.push_back((deUint16)ndx01);
862 // Upper-right triangle of a quad.
863 m_indexes.push_back((deUint16)ndx11);
864 m_indexes.push_back((deUint16)ndx01);
865 m_indexes.push_back((deUint16)ndx10);
870 const int colorCount = instanceDivisor == 0 ? 1 : (instanceCount + firstInstance + instanceDivisor - 1) / instanceDivisor;
871 for (int i = 0; i < instanceCount + firstInstance; i++)
873 m_instancedColor.push_back(tcu::Vec4(0.0, (float)(1.0 - i * 1.0 / colorCount) / 2, 0.0, 1.0));
877 void InstancedDrawInstance::preRenderCommands(const vk::VkClearValue& clearColor, deUint32 numLayers)
879 const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, numLayers);
881 if (m_params.testMultiview)
883 vk::VkImageMemoryBarrier barrier
885 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
886 DE_NULL, // const void* pNext;
887 0u, // VkAccessFlags srcAccessMask;
888 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
889 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
890 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
891 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
892 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
893 m_colorTargetImage->object(), // VkImage image;
894 subresourceRange // VkImageSubresourceRange subresourceRange;
897 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL,
898 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &barrier);
902 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
903 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
906 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
907 vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &subresourceRange);
909 const vk::VkMemoryBarrier memBarrier
911 vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
913 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
914 vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
917 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
918 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
919 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
922 void InstancedDrawInstance::draw(vk::VkCommandBuffer cmdBuffer,
923 vk::VkBuffer vertexBuffer, vk::VkBuffer instancedVertexBuffer,
924 de::SharedPtr<Buffer> indexBuffer, de::SharedPtr<Buffer> indirectBuffer,
925 deUint32 firstInstance, deUint32 instanceCount)
927 if (m_params.function == TestParams::FUNCTION_DRAW_INDEXED || m_params.function == TestParams::FUNCTION_DRAW_INDEXED_INDIRECT)
928 m_vk.cmdBindIndexBuffer(cmdBuffer, indexBuffer->object(), 0, vk::VK_INDEX_TYPE_UINT32);
930 const vk::VkBuffer vertexBuffers[] { vertexBuffer, instancedVertexBuffer };
931 const vk::VkDeviceSize vertexBufferOffsets[] { 0, 0 };
933 m_vk.cmdBindVertexBuffers(cmdBuffer, 0, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
935 const float pushConstants[] = { (float)firstInstance, (float)instanceCount };
936 m_vk.cmdPushConstants(cmdBuffer, *m_pipelineLayout, vk::VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(pushConstants), pushConstants);
937 m_vk.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
939 if (m_params.dynamicState)
941 vk::VkVertexInputBindingDescription2EXT vertexBindingDescription[2]
944 vk::VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
947 (deUint32)sizeof(VertexPositionAndColor),
948 vk::VK_VERTEX_INPUT_RATE_VERTEX,
952 vk::VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
955 (deUint32)sizeof(tcu::Vec4),
956 vk::VK_VERTEX_INPUT_RATE_INSTANCE,
957 m_params.attribDivisor
961 vk::VkVertexInputAttributeDescription2EXT vertexAttributeDescription[3]
964 vk::VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
968 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
972 vk::VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
976 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
977 (deUint32)sizeof(tcu::Vec4),
980 vk::VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
984 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
989 m_vk.cmdSetVertexInputEXT(cmdBuffer, 2, vertexBindingDescription, 3, vertexAttributeDescription);
992 switch (m_params.function)
994 case TestParams::FUNCTION_DRAW:
995 m_vk.cmdDraw(cmdBuffer, (deUint32)m_data.size(), instanceCount, 0u, firstInstance);
998 case TestParams::FUNCTION_DRAW_INDEXED:
999 m_vk.cmdDrawIndexed(cmdBuffer, (deUint32)m_indexes.size(), instanceCount, 0u, 0u, firstInstance);
1002 case TestParams::FUNCTION_DRAW_INDIRECT:
1003 m_vk.cmdDrawIndirect(cmdBuffer, indirectBuffer->object(), 0, 1u, 0u);
1006 case TestParams::FUNCTION_DRAW_INDEXED_INDIRECT:
1007 m_vk.cmdDrawIndexedIndirect(cmdBuffer, indirectBuffer->object(), 0, 1u, 0u);
1015 #ifndef CTS_USES_VULKANSC
1016 void InstancedDrawInstance::beginSecondaryCmdBuffer(vk::VkRenderingFlagsKHR renderingFlags)
1018 const vk::VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
1020 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
1021 DE_NULL, // const void* pNext;
1022 renderingFlags, // VkRenderingFlagsKHR flags;
1023 (m_params.testMultiview) ? 3u : 0u, // uint32_t viewMask;
1024 1u, // uint32_t colorAttachmentCount;
1025 &m_colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats;
1026 vk::VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
1027 vk::VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
1028 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1031 const vk::VkCommandBufferInheritanceInfo bufferInheritanceInfo
1033 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
1034 &inheritanceRenderingInfo, // const void* pNext;
1035 DE_NULL, // VkRenderPass renderPass;
1036 0u, // deUint32 subpass;
1037 DE_NULL, // VkFramebuffer framebuffer;
1038 VK_FALSE, // VkBool32 occlusionQueryEnable;
1039 (vk::VkQueryControlFlags)0u, // VkQueryControlFlags queryFlags;
1040 (vk::VkQueryPipelineStatisticFlags)0u // VkQueryPipelineStatisticFlags pipelineStatistics;
1043 vk::VkCommandBufferUsageFlags usageFlags = vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1044 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1045 usageFlags |= vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1047 const vk::VkCommandBufferBeginInfo commandBufBeginParams
1049 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1050 DE_NULL, // const void* pNext;
1051 usageFlags, // VkCommandBufferUsageFlags flags;
1052 &bufferInheritanceInfo
1055 VK_CHECK(m_vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams));
1057 #endif // CTS_USES_VULKANSC
1061 InstancedTests::InstancedTests(tcu::TestContext& testCtx, const SharedGroupParams groupParams)
1062 : TestCaseGroup (testCtx, "instanced", "Instanced drawing tests")
1063 , m_groupParams (groupParams)
1065 static const vk::VkPrimitiveTopology topologies[] =
1067 vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
1068 vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
1069 vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
1070 vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1071 vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1072 vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
1074 static const TestParams::DrawFunction functions[] =
1076 TestParams::FUNCTION_DRAW,
1077 TestParams::FUNCTION_DRAW_INDEXED,
1078 TestParams::FUNCTION_DRAW_INDIRECT,
1079 TestParams::FUNCTION_DRAW_INDEXED_INDIRECT,
1082 static const deBool multiviews[] = { DE_FALSE, DE_TRUE };
1084 static const deUint32 divisors[] = { 0, 1, 2, 4, 20 };
1085 for (int dynState = 0; dynState < 2; dynState++)
1087 for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(topologies); topologyNdx++)
1089 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
1090 if (groupParams->useSecondaryCmdBuffer && (topologyNdx % 2u))
1093 for (int functionNdx = 0; functionNdx < DE_LENGTH_OF_ARRAY(functions); functionNdx++)
1095 for (int testAttribDivisor = 0; testAttribDivisor < 2; testAttribDivisor++)
1097 for (int divisorNdx = 0; divisorNdx < DE_LENGTH_OF_ARRAY(divisors); divisorNdx++)
1099 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
1100 if (groupParams->useSecondaryCmdBuffer && (divisorNdx % 2u))
1103 for (int multiviewNdx = 0; multiviewNdx < DE_LENGTH_OF_ARRAY(multiviews); multiviewNdx++)
1105 // If we don't have VK_EXT_vertex_attribute_divisor, we only get a divisor or 1.
1106 if (!testAttribDivisor && divisors[divisorNdx] != 1)
1111 functions[functionNdx], // DrawFunction function;
1112 topologies[topologyNdx], // vk::VkPrimitiveTopology topology;
1113 groupParams, // const SharedGroupParams groupParams;
1114 testAttribDivisor ? DE_TRUE : DE_FALSE, // deBool testAttribDivisor;
1115 divisors[divisorNdx], // deUint32 attribDivisor;
1116 multiviews[multiviewNdx], // deBool testMultiview;
1117 dynState == 0 ? false : true // deBool dynamicState;
1120 // Add multiview tests only when vertex attribute divisor is enabled.
1121 if (param.testMultiview && !testAttribDivisor)
1124 std::string testName = de::toString(param);
1126 addChild(new InstancedDrawCase(m_testCtx, de::toLower(testName), "Instanced drawing test", param));
1135 InstancedTests::~InstancedTests() {}