dEQP-VK.draw.indirect_draw.indexed.indirect_draw_instanced.no_first_instance.triangle_strip
dEQP-VK.draw.indirect_draw.indexed.indirect_draw_instanced.first_instance.triangle_list
dEQP-VK.draw.indirect_draw.indexed.indirect_draw_instanced.first_instance.triangle_strip
+dEQP-VK.draw.basic_draw.draw.point_list.1
+dEQP-VK.draw.basic_draw.draw.point_list.3
+dEQP-VK.draw.basic_draw.draw.point_list.17
+dEQP-VK.draw.basic_draw.draw.point_list.45
+dEQP-VK.draw.basic_draw.draw.line_list.1
+dEQP-VK.draw.basic_draw.draw.line_list.3
+dEQP-VK.draw.basic_draw.draw.line_list.17
+dEQP-VK.draw.basic_draw.draw.line_list.45
+dEQP-VK.draw.basic_draw.draw.line_strip.1
+dEQP-VK.draw.basic_draw.draw.line_strip.3
+dEQP-VK.draw.basic_draw.draw.line_strip.17
+dEQP-VK.draw.basic_draw.draw.line_strip.45
+dEQP-VK.draw.basic_draw.draw.triangle_list.1
+dEQP-VK.draw.basic_draw.draw.triangle_list.3
+dEQP-VK.draw.basic_draw.draw.triangle_list.17
+dEQP-VK.draw.basic_draw.draw.triangle_list.45
+dEQP-VK.draw.basic_draw.draw.triangle_strip.1
+dEQP-VK.draw.basic_draw.draw.triangle_strip.3
+dEQP-VK.draw.basic_draw.draw.triangle_strip.17
+dEQP-VK.draw.basic_draw.draw.triangle_strip.45
+dEQP-VK.draw.basic_draw.draw.triangle_fan.1
+dEQP-VK.draw.basic_draw.draw.triangle_fan.3
+dEQP-VK.draw.basic_draw.draw.triangle_fan.17
+dEQP-VK.draw.basic_draw.draw.triangle_fan.45
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.1
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.3
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.17
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.45_multi_command
dEQP-VK.compute.basic.empty_shader
dEQP-VK.compute.basic.ubo_to_ssbo_single_invocation
dEQP-VK.compute.basic.ubo_to_ssbo_single_group
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Simple Draw Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktBasicDrawTests.hpp"
+
+#include "vktDrawBaseClass.hpp"
+#include "vkQueryUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+
+#include "deDefs.h"
+#include "deRandom.hpp"
+#include "deString.h"
+
+#include "tcuTestCase.hpp"
+#include "tcuRGBA.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuImageCompare.hpp"
+
+#include "rrRenderer.hpp"
+
+#include <string>
+#include <sstream>
+
+namespace vkt
+{
+namespace Draw
+{
+namespace
+{
+static const deUint32 SEED = 0xc2a39fu;
+static const deUint32 INDEX_LIMIT = 10000;
+// To avoid too big and mostly empty structures
+static const deUint32 OFFSET_LIMIT = 1000;
+// Number of primitives to draw
+static const deUint32 PRIMITIVE_COUNT[] = {1, 3, 17, 45};
+
+enum DrawCommandType
+{
+ DRAW_COMMAND_TYPE_DRAW,
+ DRAW_COMMAND_TYPE_DRAW_INDEXED,
+ DRAW_COMMAND_TYPE_DRAW_INDIRECT,
+ DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT,
+
+ DRAW_COMMAND_TYPE_DRAW_LAST
+};
+
+const char* getDrawCommandTypeName (DrawCommandType command)
+{
+ switch (command)
+ {
+ case DRAW_COMMAND_TYPE_DRAW: return "draw";
+ case DRAW_COMMAND_TYPE_DRAW_INDEXED: return "draw_indexed";
+ case DRAW_COMMAND_TYPE_DRAW_INDIRECT: return "draw_indirect";
+ case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT: return "draw_indexed_indirect";
+ default: DE_ASSERT(false);
+ }
+ return "";
+}
+
+rr::PrimitiveType mapVkPrimitiveTopology (vk::VkPrimitiveTopology primitiveTopology)
+{
+ switch (primitiveTopology)
+ {
+ case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST: return rr::PRIMITIVETYPE_POINTS;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST: return rr::PRIMITIVETYPE_LINES;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: return rr::PRIMITIVETYPE_LINE_STRIP;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return rr::PRIMITIVETYPE_TRIANGLES;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: return rr::PRIMITIVETYPE_TRIANGLE_FAN;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return rr::PRIMITIVETYPE_TRIANGLE_STRIP;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: return rr::PRIMITIVETYPE_LINES_ADJACENCY;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: return rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: return rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: return rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY;
+ default:
+ DE_ASSERT(false);
+ }
+ return rr::PRIMITIVETYPE_LAST;
+}
+
+struct DrawParamsBase
+{
+ std::vector<PositionColorVertex> vertices;
+ vk::VkPrimitiveTopology topology;
+
+ DrawParamsBase ()
+ {}
+
+ DrawParamsBase (const vk::VkPrimitiveTopology top)
+ : topology (top)
+ {}
+};
+
+struct IndexedParamsBase
+{
+ std::vector<deUint32> indexes;
+ const vk::VkIndexType indexType;
+
+ IndexedParamsBase (const vk::VkIndexType indexT)
+ : indexType (indexT)
+ {}
+};
+
+// Structs to store draw parameters
+struct DrawParams : DrawParamsBase
+{
+ // vkCmdDraw parameters is like a single VkDrawIndirectCommand
+ vk::VkDrawIndirectCommand params;
+
+ DrawParams (const vk::VkPrimitiveTopology top, const deUint32 vertexC, const deUint32 instanceC, const deUint32 firstV, const deUint32 firstI)
+ : DrawParamsBase (top)
+ {
+ params.vertexCount = vertexC;
+ params.instanceCount = instanceC;
+ params.firstVertex = firstV;
+ params.firstInstance = firstI;
+ }
+};
+
+struct DrawIndexedParams : DrawParamsBase, IndexedParamsBase
+{
+ // vkCmdDrawIndexed parameters is like a single VkDrawIndexedIndirectCommand
+ vk::VkDrawIndexedIndirectCommand params;
+
+ DrawIndexedParams (const vk::VkPrimitiveTopology top, const vk::VkIndexType indexT, const deUint32 indexC, const deUint32 instanceC, const deUint32 firstIdx, const deInt32 vertexO, const deUint32 firstIns)
+ : DrawParamsBase (top)
+ , IndexedParamsBase (indexT)
+ {
+ params.indexCount = indexC;
+ params.instanceCount = instanceC;
+ params.firstIndex = firstIdx;
+ params.vertexOffset = vertexO;
+ params.firstInstance = firstIns;
+ }
+};
+
+struct DrawIndirectParams : DrawParamsBase
+{
+ std::vector<vk::VkDrawIndirectCommand> commands;
+
+ DrawIndirectParams (const vk::VkPrimitiveTopology top)
+ : DrawParamsBase (top)
+ {}
+
+ void addCommand (const deUint32 vertexC, const deUint32 instanceC, const deUint32 firstV, const deUint32 firstI)
+ {
+ vk::VkDrawIndirectCommand cmd;
+ cmd.vertexCount = vertexC;
+ cmd.instanceCount = instanceC;
+ cmd.firstVertex = firstV;
+ cmd.firstInstance = firstI;
+
+ commands.push_back(cmd);
+ }
+};
+
+struct DrawIndexedIndirectParams : DrawParamsBase, IndexedParamsBase
+{
+ std::vector<vk::VkDrawIndexedIndirectCommand> commands;
+
+ DrawIndexedIndirectParams (const vk::VkPrimitiveTopology top, const vk::VkIndexType indexT)
+ : DrawParamsBase (top)
+ , IndexedParamsBase (indexT)
+ {}
+
+ void addCommand (const deUint32 indexC, const deUint32 instanceC, const deUint32 firstIdx, const deInt32 vertexO, const deUint32 firstIns)
+ {
+ vk::VkDrawIndexedIndirectCommand cmd;
+ cmd.indexCount = indexC;
+ cmd.instanceCount = instanceC;
+ cmd.firstIndex = firstIdx;
+ cmd.vertexOffset = vertexO;
+ cmd.firstInstance = firstIns;
+
+ commands.push_back(cmd);
+ }
+};
+
+// Reference renderer shaders
+class PassthruVertShader : public rr::VertexShader
+{
+public:
+ PassthruVertShader (void)
+ : rr::VertexShader (2, 1)
+ {
+ m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
+ m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
+ m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
+ }
+
+ void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
+ {
+ for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+ {
+ packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
+ packets[packetNdx]->instanceNdx,
+ packets[packetNdx]->vertexNdx);
+
+ tcu::Vec4 color = rr::readVertexAttribFloat(inputs[1],
+ packets[packetNdx]->instanceNdx,
+ packets[packetNdx]->vertexNdx);
+
+ packets[packetNdx]->outputs[0] = color;
+ }
+ }
+};
+
+class PassthruFragShader : public rr::FragmentShader
+{
+public:
+ PassthruFragShader (void)
+ : rr::FragmentShader(1, 1)
+ {
+ m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
+ m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
+ }
+
+ void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
+ {
+ for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+ {
+ rr::FragmentPacket& packet = packets[packetNdx];
+ for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
+ {
+ tcu::Vec4 color = rr::readVarying<float>(packet, context, 0, fragNdx);
+ rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
+ }
+ }
+ }
+};
+
+class DrawTestInstanceBase : public TestInstance
+{
+public:
+ DrawTestInstanceBase (Context& context);
+ virtual ~DrawTestInstanceBase (void) = 0;
+ void initialize (const DrawParamsBase& data);
+ void initPipeline (const vk::VkDevice device);
+ void beginRenderPass (void);
+
+ // Specialize this function for each type
+ virtual tcu::TestStatus iterate (void) = 0;
+protected:
+ // Specialize this function for each type
+ virtual void generateDrawData (void) = 0;
+ void generateRefImage (const tcu::PixelBufferAccess& access, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
+
+ DrawParamsBase m_data;
+ const vk::DeviceInterface& m_vk;
+ vk::Move<vk::VkPipeline> m_pipeline;
+ vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
+ vk::VkFormat m_colorAttachmentFormat;
+ de::SharedPtr<Image> m_colorTargetImage;
+ vk::Move<vk::VkImageView> m_colorTargetView;
+ vk::Move<vk::VkRenderPass> m_renderPass;
+ vk::Move<vk::VkFramebuffer> m_framebuffer;
+ PipelineCreateInfo::VertexInputState m_vertexInputState;
+ de::SharedPtr<Buffer> m_vertexBuffer;
+ vk::Move<vk::VkCommandPool> m_cmdPool;
+ vk::Move<vk::VkCommandBuffer> m_cmdBuffer;
+
+ enum
+ {
+ WIDTH = 256,
+ HEIGHT = 256
+ };
+};
+
+DrawTestInstanceBase::DrawTestInstanceBase (Context& context)
+ : vkt::TestInstance (context)
+ , m_vk (context.getDeviceInterface())
+ , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
+{
+}
+
+DrawTestInstanceBase::~DrawTestInstanceBase (void)
+{
+}
+
+void DrawTestInstanceBase::initialize (const DrawParamsBase& data)
+{
+ m_data = data;
+
+ const vk::VkDevice device = m_context.getDevice();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+
+ const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
+ m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
+
+ const vk::VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
+ const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
+ 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);
+
+ m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
+
+ const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
+ m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
+
+ RenderPassCreateInfo renderPassCreateInfo;
+ renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
+ vk::VK_SAMPLE_COUNT_1_BIT,
+ vk::VK_ATTACHMENT_LOAD_OP_LOAD,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_IMAGE_LAYOUT_GENERAL,
+ vk::VK_IMAGE_LAYOUT_GENERAL));
+
+ const vk::VkAttachmentReference colorAttachmentReference =
+ {
+ 0,
+ vk::VK_IMAGE_LAYOUT_GENERAL
+ };
+
+ renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
+ 0,
+ 0,
+ DE_NULL,
+ 1,
+ &colorAttachmentReference,
+ DE_NULL,
+ AttachmentReference(),
+ 0,
+ DE_NULL));
+
+ m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
+
+ std::vector<vk::VkImageView> colorAttachments(1);
+ colorAttachments[0] = *m_colorTargetView;
+
+ const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
+
+ m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
+
+ const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
+ {
+ 0,
+ (deUint32)sizeof(tcu::Vec4) * 2,
+ vk::VK_VERTEX_INPUT_RATE_VERTEX,
+ };
+
+ const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
+ {
+ {
+ 0u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ 0u
+ },
+ {
+ 1u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ (deUint32)(sizeof(float)* 4),
+ }
+ };
+
+ m_vertexInputState = PipelineCreateInfo::VertexInputState(1,
+ &vertexInputBindingDescription,
+ 2,
+ vertexInputAttributeDescriptions);
+
+ const vk::VkDeviceSize dataSize = m_data.vertices.size() * sizeof(PositionColorVertex);
+ m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize,
+ vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
+
+ deUint8* ptr = reinterpret_cast<deUint8*>(m_vertexBuffer->getBoundMemory().getHostPtr());
+ deMemcpy(ptr, &(m_data.vertices[0]), static_cast<size_t>(dataSize));
+
+ vk::flushMappedMemoryRange(m_vk,
+ device,
+ m_vertexBuffer->getBoundMemory().getMemory(),
+ m_vertexBuffer->getBoundMemory().getOffset(),
+ dataSize);
+
+ const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
+ m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
+
+ const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ *m_cmdPool, // VkCommandPool commandPool;
+ vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
+ 1u, // deUint32 bufferCount;
+ };
+ m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, &cmdBufferAllocateInfo);
+
+ initPipeline(device);
+}
+
+void DrawTestInstanceBase::initPipeline (const vk::VkDevice device)
+{
+ const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("vert"), 0));
+ const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("frag"), 0));
+
+ const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
+
+ vk::VkViewport viewport;
+ viewport.x = 0;
+ viewport.y = 0;
+ viewport.width = static_cast<float>(WIDTH);
+ viewport.height = static_cast<float>(HEIGHT);
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+
+ vk::VkRect2D scissor;
+ scissor.offset.x = 0;
+ scissor.offset.y = 0;
+ scissor.extent.width = WIDTH;
+ scissor.extent.height = HEIGHT;
+
+ PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
+ pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_data.topology));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<vk::VkViewport>(1, viewport), std::vector<vk::VkRect2D>(1, scissor)));
+ pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
+
+ m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
+}
+
+void DrawTestInstanceBase::beginRenderPass (void)
+{
+ const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
+ const CmdBufferBeginInfo beginInfo;
+
+ m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
+
+ initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
+
+ const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
+ m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
+
+ const vk::VkMemoryBarrier memBarrier =
+ {
+ vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+ DE_NULL,
+ vk::VK_ACCESS_TRANSFER_WRITE_BIT,
+ vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
+ };
+
+ m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
+ vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+
+ const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
+ const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
+
+ m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE);
+}
+
+void DrawTestInstanceBase::generateRefImage (const tcu::PixelBufferAccess& access, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
+{
+ const PassthruVertShader vertShader;
+ const PassthruFragShader fragShader;
+ const rr::Program program (&vertShader, &fragShader);
+ const rr::MultisamplePixelBufferAccess colorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(access);
+ const rr::RenderTarget renderTarget (colorBuffer);
+ const rr::RenderState renderState ((rr::ViewportState(colorBuffer)));
+ const rr::Renderer renderer;
+
+ const rr::VertexAttrib vertexAttribs[] =
+ {
+ rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertices[0]),
+ rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &colors[0])
+ };
+
+ renderer.draw(rr::DrawCommand(renderState,
+ renderTarget,
+ program,
+ DE_LENGTH_OF_ARRAY(vertexAttribs),
+ &vertexAttribs[0],
+ rr::PrimitiveList(mapVkPrimitiveTopology(m_data.topology), (deUint32)vertices.size(), 0)));
+}
+
+template<typename T>
+class DrawTestInstance : public DrawTestInstanceBase
+{
+public:
+ DrawTestInstance (Context& context, const T& data);
+ virtual ~DrawTestInstance (void);
+ virtual void generateDrawData (void);
+ virtual tcu::TestStatus iterate (void);
+private:
+ T m_data;
+};
+
+template<typename T>
+DrawTestInstance<T>::DrawTestInstance (Context& context, const T& data)
+ : DrawTestInstanceBase (context)
+ , m_data (data)
+{
+ generateDrawData();
+ initialize(m_data);
+}
+
+template<typename T>
+DrawTestInstance<T>::~DrawTestInstance (void)
+{
+}
+
+template<typename T>
+void DrawTestInstance<T>::generateDrawData (void)
+{
+ DE_FATAL("Using the general case of this function is forbidden!");
+}
+
+template<typename T>
+tcu::TestStatus DrawTestInstance<T>::iterate (void)
+{
+ DE_FATAL("Using the general case of this function is forbidden!");
+ return tcu::TestStatus::fail("");
+}
+
+template<typename T>
+class DrawTestCase : public TestCase
+{
+ public:
+ DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const T data);
+ ~DrawTestCase (void);
+ virtual void initPrograms (vk::SourceCollections& programCollection) const;
+ virtual void initShaderSources (void);
+ virtual TestInstance* createInstance (Context& context) const;
+
+private:
+ T m_data;
+ std::string m_vertShaderSource;
+ std::string m_fragShaderSource;
+};
+
+template<typename T>
+DrawTestCase<T>::DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const T data)
+ : vkt::TestCase (context, name, desc)
+ , m_data (data)
+{
+ initShaderSources();
+}
+
+template<typename T>
+DrawTestCase<T>::~DrawTestCase (void)
+{
+}
+
+template<typename T>
+void DrawTestCase<T>::initPrograms (vk::SourceCollections& programCollection) const
+{
+ programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
+ programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
+}
+
+template<typename T>
+void DrawTestCase<T>::initShaderSources (void)
+{
+ std::stringstream vertShader;
+ vertShader << "#version 430\n"
+ << "layout(location = 0) in vec4 in_position;\n"
+ << "layout(location = 1) in vec4 in_color;\n"
+ << "layout(location = 0) out vec4 out_color;\n"
+
+ << "out gl_PerVertex {\n"
+ << " vec4 gl_Position;\n"
+ << "};\n"
+ << "void main() {\n"
+ << " gl_Position = in_position;\n"
+ << " out_color = in_color;\n"
+ << "}\n";
+
+ m_vertShaderSource = vertShader.str();
+
+ std::stringstream fragShader;
+ fragShader << "#version 430\n"
+ << "layout(location = 0) in vec4 in_color;\n"
+ << "layout(location = 0) out vec4 out_color;\n"
+ << "void main()\n"
+ << "{\n"
+ << " out_color = in_color;\n"
+ << "}\n";
+
+ m_fragShaderSource = fragShader.str();
+}
+
+template<typename T>
+TestInstance* DrawTestCase<T>::createInstance (Context& context) const
+{
+ return new DrawTestInstance<T>(context, m_data);
+}
+
+// Specialized cases
+template<>
+void DrawTestInstance<DrawParams>::generateDrawData (void)
+{
+ de::Random rnd (SEED ^ m_data.params.firstVertex ^ m_data.params.vertexCount);
+
+ const deUint32 vectorSize = m_data.params.firstVertex + m_data.params.vertexCount;
+
+ // Initialize the vector
+ m_data.vertices = std::vector<PositionColorVertex>(vectorSize, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
+
+ // Fill only the used indexes
+ for (deUint32 vertexIdx = m_data.params.firstVertex; vertexIdx < vectorSize; ++vertexIdx)
+ {
+ m_data.vertices[vertexIdx] = PositionColorVertex(
+ tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0), // Coord
+ tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0))); // Color
+ }
+}
+
+template<>
+tcu::TestStatus DrawTestInstance<DrawParams>::iterate (void)
+{
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+ m_vk.cmdDraw(*m_cmdBuffer, m_data.params.vertexCount, m_data.params.instanceCount, m_data.params.firstVertex, m_data.params.firstInstance);
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ vk::VkSubmitInfo submitInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0, // deUint32 waitSemaphoreCount;
+ DE_NULL, // const VkSemaphore* pWaitSemaphores;
+ (const vk::VkPipelineStageFlags*)DE_NULL,
+ 1, // deUint32 commandBufferCount;
+ &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
+ 0, // deUint32 signalSemaphoreCount;
+ DE_NULL // const VkSemaphore* pSignalSemaphores;
+ };
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
+
+ // Validation
+ tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ std::vector<tcu::Vec4> vertices;
+ std::vector<tcu::Vec4> colors;
+
+ for (std::vector<PositionColorVertex>::const_iterator vertex = m_data.vertices.begin() + m_data.params.firstVertex; vertex != m_data.vertices.end(); ++vertex)
+ {
+ vertices.push_back(vertex->position);
+ colors.push_back(vertex->color);
+ }
+ generateRefImage(refImage.getAccess(), vertices, colors);
+
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ refImage.getAccess(),
+ renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT)) {
+ res = QP_TEST_RESULT_FAIL;
+ }
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+}
+
+template<>
+void DrawTestInstance<DrawIndexedParams>::generateDrawData (void)
+{
+ de::Random rnd (SEED ^ m_data.params.firstIndex ^ m_data.params.indexCount);
+ const deUint32 indexSize = m_data.params.firstIndex + m_data.params.indexCount;
+
+ // Initialize the vector with zeros
+ m_data.indexes = std::vector<deUint32>(indexSize, 0);
+
+ deUint32 highestIndex = 0; // Store to highest index to calculate the vertices size
+ // Fill the indexes from firstIndex
+ for (deUint32 idx = 0; idx < m_data.params.indexCount; ++idx)
+ {
+ deUint32 vertexIdx = rnd.getInt(m_data.params.vertexOffset, INDEX_LIMIT);
+ highestIndex = (vertexIdx > highestIndex) ? vertexIdx : highestIndex;
+
+ m_data.indexes[m_data.params.firstIndex + idx] = vertexIdx;
+ }
+
+ // Fill up the vertex coordinates with zeros until the highestIndex including the vertexOffset
+ m_data.vertices = std::vector<PositionColorVertex>(m_data.params.vertexOffset + highestIndex + 1, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
+
+ // Generate random vertex only where you have index pointing at
+ for (std::vector<deUint32>::const_iterator indexIt = m_data.indexes.begin() + m_data.params.firstIndex; indexIt != m_data.indexes.end(); ++indexIt)
+ {
+ // Get iterator to the vertex position with the vertexOffset
+ std::vector<PositionColorVertex>::iterator vertexIt = m_data.vertices.begin() + m_data.params.vertexOffset + *indexIt;
+
+ tcu::VecAccess<float, 4, 4> positionAccess = vertexIt->position.xyzw();
+ positionAccess = tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0);
+
+ tcu::VecAccess<float, 4, 4> colorAccess = vertexIt->color.xyzw();
+ colorAccess = tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0));
+ }
+}
+
+template<>
+tcu::TestStatus DrawTestInstance<DrawIndexedParams>::iterate (void)
+{
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::DeviceInterface& vk = m_context.getDeviceInterface();
+ const vk::VkDevice vkDevice = m_context.getDevice();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+ vk::Allocator& allocator = m_context.getDefaultAllocator();
+
+ beginRenderPass();
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ const deUint32 bufferSize = (deUint32)(m_data.indexes.size() * sizeof(deUint32));
+
+ vk::Move<vk::VkBuffer> indexBuffer;
+
+ const vk::VkBufferCreateInfo bufferCreateInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkBufferCreateFlags flags;
+ bufferSize, // VkDeviceSize size;
+ vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
+ vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ };
+
+ indexBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
+
+ de::MovePtr<vk::Allocation> indexAlloc;
+
+ indexAlloc = allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), vk::MemoryRequirement::HostVisible);
+ VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexAlloc->getMemory(), indexAlloc->getOffset()));
+
+ deMemcpy(indexAlloc->getHostPtr(), &(m_data.indexes[0]), bufferSize);
+
+ m_vk.cmdBindIndexBuffer(*m_cmdBuffer, *indexBuffer, 0u, m_data.indexType);
+ m_vk.cmdDrawIndexed(*m_cmdBuffer, m_data.params.indexCount, m_data.params.instanceCount, m_data.params.firstIndex, m_data.params.vertexOffset, m_data.params.firstInstance);
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ vk::VkSubmitInfo submitInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0, // deUint32 waitSemaphoreCount;
+ DE_NULL, // const VkSemaphore* pWaitSemaphores;
+ (const vk::VkPipelineStageFlags*)DE_NULL,
+ 1, // deUint32 commandBufferCount;
+ &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
+ 0, // deUint32 signalSemaphoreCount;
+ DE_NULL // const VkSemaphore* pSignalSemaphores;
+ };
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
+
+ // Validation
+ tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ std::vector<tcu::Vec4> vertices;
+ std::vector<tcu::Vec4> colors;
+
+ for (std::vector<deUint32>::const_iterator it = m_data.indexes.begin() + m_data.params.firstIndex; it != m_data.indexes.end(); ++it)
+ {
+ deUint32 idx = m_data.params.vertexOffset + *it;
+ vertices.push_back(m_data.vertices[idx].position);
+ colors.push_back(m_data.vertices[idx].color);
+ }
+ generateRefImage(refImage.getAccess(), vertices, colors);
+
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ refImage.getAccess(),
+ renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT)) {
+ res = QP_TEST_RESULT_FAIL;
+ }
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+}
+
+template<>
+void DrawTestInstance<DrawIndirectParams>::generateDrawData (void)
+{
+ de::Random rnd(SEED ^ m_data.commands[0].vertexCount ^ m_data.commands[0].firstVertex);
+
+ deUint32 lastIndex = 0;
+
+ // Find the interval which will be used
+ for (std::vector<vk::VkDrawIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
+ {
+ const deUint32 index = it->firstVertex + it->vertexCount;
+ lastIndex = (index > lastIndex) ? index : lastIndex;
+ }
+
+ // Initialize with zeros
+ m_data.vertices = std::vector<PositionColorVertex>(lastIndex, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
+
+ // Generate random vertices only where necessary
+ for (std::vector<vk::VkDrawIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
+ {
+ std::vector<PositionColorVertex>::iterator vertexStart = m_data.vertices.begin() + it->firstVertex;
+
+ for (deUint32 idx = 0; idx < it->vertexCount; ++idx)
+ {
+ std::vector<PositionColorVertex>::iterator vertexIt = vertexStart + idx;
+
+ tcu::VecAccess<float, 4, 4> positionAccess = vertexIt->position.xyzw();
+ positionAccess = tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0);
+
+ tcu::VecAccess<float, 4, 4> colorAccess = vertexIt->color.xyzw();
+ colorAccess = tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0));
+ }
+ }
+}
+
+template<>
+tcu::TestStatus DrawTestInstance<DrawIndirectParams>::iterate (void)
+{
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::DeviceInterface& vk = m_context.getDeviceInterface();
+ const vk::VkDevice vkDevice = m_context.getDevice();
+ vk::Allocator& allocator = m_context.getDefaultAllocator();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ const vk::VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
+
+ beginRenderPass();
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ vk::Move<vk::VkBuffer> indirectBuffer;
+ de::MovePtr<vk::Allocation> indirectAlloc;
+
+ {
+ const vk::VkDeviceSize indirectInfoSize = m_data.commands.size() * sizeof(vk::VkDrawIndirectCommand);
+
+ const vk::VkBufferCreateInfo indirectCreateInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkBufferCreateFlags flags;
+ indirectInfoSize, // VkDeviceSize size;
+ vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, // VkBufferUsageFlags usage;
+ vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ };
+
+ indirectBuffer = createBuffer(vk, vkDevice, &indirectCreateInfo);
+ indirectAlloc = allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indirectBuffer), vk::MemoryRequirement::HostVisible);
+ VK_CHECK(vk.bindBufferMemory(vkDevice, *indirectBuffer, indirectAlloc->getMemory(), indirectAlloc->getOffset()));
+
+ deMemcpy(indirectAlloc->getHostPtr(), &(m_data.commands[0]), (size_t)indirectInfoSize);
+ }
+
+ // If multiDrawIndirect not supported execute single calls
+ if (m_data.commands.size() > 1 && !(features.multiDrawIndirect))
+ {
+ for (deUint32 cmdIdx = 0; cmdIdx < m_data.commands.size(); ++cmdIdx)
+ {
+ const deUint32 offset = (deUint32)(indirectAlloc->getOffset() + cmdIdx * sizeof(vk::VkDrawIndirectCommand));
+ m_vk.cmdDrawIndirect(*m_cmdBuffer, *indirectBuffer, offset, 1, sizeof(vk::VkDrawIndirectCommand));
+ }
+ }
+ else
+ {
+ m_vk.cmdDrawIndirect(*m_cmdBuffer, *indirectBuffer, indirectAlloc->getOffset(), (deUint32)m_data.commands.size(), sizeof(vk::VkDrawIndirectCommand));
+ }
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ vk::VkSubmitInfo submitInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0, // deUint32 waitSemaphoreCount;
+ DE_NULL, // const VkSemaphore* pWaitSemaphores;
+ (const vk::VkPipelineStageFlags*)DE_NULL,
+ 1, // deUint32 commandBufferCount;
+ &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
+ 0, // deUint32 signalSemaphoreCount;
+ DE_NULL // const VkSemaphore* pSignalSemaphores;
+ };
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
+
+ // Validation
+ tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (std::vector<vk::VkDrawIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
+ {
+ std::vector<tcu::Vec4> vertices;
+ std::vector<tcu::Vec4> colors;
+
+ std::vector<PositionColorVertex>::const_iterator firstIt = m_data.vertices.begin() + it->firstVertex;
+ std::vector<PositionColorVertex>::const_iterator lastIt = firstIt + it->vertexCount;
+
+ for (std::vector<PositionColorVertex>::const_iterator vertex = firstIt; vertex != lastIt; ++vertex)
+ {
+ vertices.push_back(vertex->position);
+ colors.push_back(vertex->color);
+ }
+ generateRefImage(refImage.getAccess(), vertices, colors);
+ }
+
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ refImage.getAccess(),
+ renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT)) {
+ res = QP_TEST_RESULT_FAIL;
+ }
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+}
+
+template<>
+void DrawTestInstance<DrawIndexedIndirectParams>::generateDrawData (void)
+{
+ de::Random rnd (SEED ^ m_data.commands[0].firstIndex ^ m_data.commands[0].indexCount);
+
+ deUint32 lastIndex = 0;
+
+ // Get the maximum range of indexes
+ for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
+ {
+ const deUint32 index = it->firstIndex + it->indexCount;
+ lastIndex = (index > lastIndex) ? index : lastIndex;
+ }
+
+ // Initialize the vector with zeros
+ m_data.indexes = std::vector<deUint32>(lastIndex, 0);
+
+ deUint32 highestIndex = 0;
+
+ // Generate random indexes for the ranges
+ for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator it = m_data.commands.begin(); it != m_data.commands.end(); ++it)
+ {
+ for (deUint32 idx = 0; idx < it->indexCount; ++idx)
+ {
+ const deUint32 vertexIdx = rnd.getInt(it->vertexOffset, INDEX_LIMIT);
+ const deUint32 maxIndex = vertexIdx + it->vertexOffset;
+
+ highestIndex = (maxIndex > highestIndex) ? maxIndex : highestIndex;
+ m_data.indexes[it->firstIndex + idx] = vertexIdx;
+ }
+ }
+
+ // Initialize the vertex vector
+ m_data.vertices = std::vector<PositionColorVertex>(highestIndex + 1, PositionColorVertex(tcu::Vec4(0.0, 0.0, 0.0, 0.0), tcu::Vec4(0.0, 0.0, 0.0, 0.0)));
+
+ // Generate random vertices in the used locations
+ for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator cmdIt = m_data.commands.begin(); cmdIt != m_data.commands.end(); ++cmdIt)
+ {
+ deUint32 firstIdx = cmdIt->firstIndex;
+ deUint32 lastIdx = firstIdx + cmdIt->indexCount;
+
+ for (deUint32 idx = firstIdx; idx < lastIdx; ++idx)
+ {
+ std::vector<PositionColorVertex>::iterator vertexIt = m_data.vertices.begin() + cmdIt->vertexOffset + m_data.indexes[idx];
+
+ tcu::VecAccess<float, 4, 4> positionAccess = vertexIt->position.xyzw();
+ positionAccess = tcu::Vec4(rnd.getFloat(-1.0, 1.0), rnd.getFloat(-1.0, 1.0), 1.0, 1.0);
+
+ tcu::VecAccess<float, 4, 4> colorAccess = vertexIt->color.xyzw();
+ colorAccess = tcu::Vec4(rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0), rnd.getFloat(0.0, 1.0));
+ }
+ }
+}
+
+template<>
+tcu::TestStatus DrawTestInstance<DrawIndexedIndirectParams>::iterate (void)
+{
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::DeviceInterface& vk = m_context.getDeviceInterface();
+ const vk::VkDevice vkDevice = m_context.getDevice();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+ vk::Allocator& allocator = m_context.getDefaultAllocator();
+ const vk::VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
+
+ beginRenderPass();
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ vk::Move<vk::VkBuffer> indirectBuffer;
+ de::MovePtr<vk::Allocation> indirectAlloc;
+
+ {
+ const vk::VkDeviceSize indirectInfoSize = m_data.commands.size() * sizeof(vk::VkDrawIndexedIndirectCommand);
+
+ const vk::VkBufferCreateInfo indirectCreateInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkBufferCreateFlags flags;
+ indirectInfoSize, // VkDeviceSize size;
+ vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, // VkBufferUsageFlags usage;
+ vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ };
+
+ indirectBuffer = createBuffer(vk, vkDevice, &indirectCreateInfo);
+ indirectAlloc = allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indirectBuffer), vk::MemoryRequirement::HostVisible);
+ VK_CHECK(vk.bindBufferMemory(vkDevice, *indirectBuffer, indirectAlloc->getMemory(), indirectAlloc->getOffset()));
+
+ deMemcpy(indirectAlloc->getHostPtr(), &(m_data.commands[0]), (size_t)indirectInfoSize);
+ }
+
+ const deUint32 bufferSize = (deUint32)(m_data.indexes.size() * sizeof(deUint32));
+
+ vk::Move<vk::VkBuffer> indexBuffer;
+
+ const vk::VkBufferCreateInfo bufferCreateInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkBufferCreateFlags flags;
+ bufferSize, // VkDeviceSize size;
+ vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
+ vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ };
+
+ indexBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
+
+ de::MovePtr<vk::Allocation> indexAlloc;
+
+ indexAlloc = allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), vk::MemoryRequirement::HostVisible);
+ VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexAlloc->getMemory(), indexAlloc->getOffset()));
+
+ deMemcpy(indexAlloc->getHostPtr(), &(m_data.indexes[0]), bufferSize);
+
+ m_vk.cmdBindIndexBuffer(*m_cmdBuffer, *indexBuffer, 0u, m_data.indexType);
+
+ // If multiDrawIndirect not supported execute single calls
+ if (m_data.commands.size() > 1 && !(features.multiDrawIndirect))
+ {
+ for (deUint32 cmdIdx = 0; cmdIdx < m_data.commands.size(); ++cmdIdx)
+ {
+ const deUint32 offset = (deUint32)(indirectAlloc->getOffset() + cmdIdx * sizeof(vk::VkDrawIndexedIndirectCommand));
+ m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, *indirectBuffer, offset, 1, sizeof(vk::VkDrawIndexedIndirectCommand));
+ }
+ }
+ else
+ {
+ m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, *indirectBuffer, indirectAlloc->getOffset(), (deUint32)m_data.commands.size(), sizeof(vk::VkDrawIndexedIndirectCommand));
+ }
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ vk::VkSubmitInfo submitInfo =
+ {
+ vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0, // deUint32 waitSemaphoreCount;
+ DE_NULL, // const VkSemaphore* pWaitSemaphores;
+ (const vk::VkPipelineStageFlags*)DE_NULL,
+ 1, // deUint32 commandBufferCount;
+ &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
+ 0, // deUint32 signalSemaphoreCount;
+ DE_NULL // const VkSemaphore* pSignalSemaphores;
+ };
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
+
+ // Validation
+ tcu::TextureLevel refImage (vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (std::vector<vk::VkDrawIndexedIndirectCommand>::const_iterator cmd = m_data.commands.begin(); cmd != m_data.commands.end(); ++cmd)
+ {
+ std::vector<tcu::Vec4> vertices;
+ std::vector<tcu::Vec4> colors;
+
+ for (deUint32 idx = 0; idx < cmd->indexCount; ++idx)
+ {
+ const deUint32 vertexIndex = cmd->vertexOffset + m_data.indexes[cmd->firstIndex + idx];
+ vertices.push_back(m_data.vertices[vertexIndex].position);
+ colors.push_back(m_data.vertices[vertexIndex].color);
+ }
+ generateRefImage(refImage.getAccess(), vertices, colors);
+ }
+
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ refImage.getAccess(),
+ renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT)) {
+ res = QP_TEST_RESULT_FAIL;
+ }
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+}
+
+typedef DrawTestCase<DrawParams> DrawCase;
+typedef DrawTestCase<DrawIndexedParams> IndexedCase;
+typedef DrawTestCase<DrawIndirectParams> IndirectCase;
+typedef DrawTestCase<DrawIndexedIndirectParams> IndexedIndirectCase;
+
+struct TestCaseParams
+{
+ const DrawCommandType command;
+ const vk::VkPrimitiveTopology topology;
+
+ TestCaseParams (const DrawCommandType cmd, const vk::VkPrimitiveTopology top)
+ : command (cmd)
+ , topology (top)
+ {}
+};
+
+} // anonymous
+
+void populateSubGroup (tcu::TestCaseGroup* testGroup, const TestCaseParams caseParams)
+{
+ de::Random rnd (SEED ^ deStringHash(testGroup->getName()));
+ tcu::TestContext& testCtx = testGroup->getTestContext();
+ const DrawCommandType command = caseParams.command;
+ const vk::VkPrimitiveTopology topology = caseParams.topology;
+
+ for (deUint32 primitiveCountIdx = 0; primitiveCountIdx < DE_LENGTH_OF_ARRAY(PRIMITIVE_COUNT); ++primitiveCountIdx)
+ {
+ const deUint32 primitives = PRIMITIVE_COUNT[primitiveCountIdx];
+
+ deUint32 multiplier = 1;
+ deUint32 offset = 0;
+ // Calculated by Vulkan 23.1
+ switch (topology)
+ {
+ case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST: break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST: multiplier = 2; break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: multiplier = 3; break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: offset = 1; break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: multiplier = 4; offset = 1; break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: offset = 1; break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: multiplier = 6; break;
+ case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: multiplier = 2; break;
+ default: DE_FATAL("Unsupported topology.");
+ }
+
+ const deUint32 vertexCount = multiplier * primitives + offset;
+ std::string name = de::toString(primitives);
+
+ switch (command)
+ {
+ case DRAW_COMMAND_TYPE_DRAW:
+ {
+ deUint32 firstPrimitive = rnd.getInt(0, primitives);
+ deUint32 firstVertex = multiplier * firstPrimitive;
+ testGroup->addChild(new DrawCase(testCtx, name.c_str(), "vkCmdDraw testcase.",
+ DrawParams(topology, vertexCount, 1, firstVertex, 0))
+ );
+ break;
+ }
+ case DRAW_COMMAND_TYPE_DRAW_INDEXED:
+ {
+ deUint32 firstIndex = rnd.getInt(0, OFFSET_LIMIT);
+ deUint32 vertexOffset = rnd.getInt(0, OFFSET_LIMIT);
+ testGroup->addChild(new IndexedCase(testCtx, name.c_str(), "vkCmdDrawIndexed testcase.",
+ DrawIndexedParams(topology, vk::VK_INDEX_TYPE_UINT32, vertexCount, 1, firstIndex, vertexOffset, 0))
+ );
+ break;
+ }
+ case DRAW_COMMAND_TYPE_DRAW_INDIRECT:
+ {
+ deUint32 firstVertex = rnd.getInt(0, OFFSET_LIMIT);
+
+ DrawIndirectParams params = DrawIndirectParams(topology);
+
+ params.addCommand(vertexCount, 1, 0, 0);
+ testGroup->addChild(new IndirectCase(testCtx, (name + "_single_command").c_str(), "vkCmdDrawIndirect testcase.", params));
+
+ params.addCommand(vertexCount, 1, firstVertex, 0);
+ testGroup->addChild(new IndirectCase(testCtx, (name + "_multi_command").c_str(), "vkCmdDrawIndirect testcase.", params));
+ break;
+ }
+ case DRAW_COMMAND_TYPE_DRAW_INDEXED_INDIRECT:
+ {
+ deUint32 firstIndex = rnd.getInt(vertexCount, OFFSET_LIMIT);
+ deUint32 vertexOffset = rnd.getInt(vertexCount, OFFSET_LIMIT);
+
+ DrawIndexedIndirectParams params = DrawIndexedIndirectParams(topology, vk::VK_INDEX_TYPE_UINT32);
+ params.addCommand(vertexCount, 1, 0, 0, 0);
+ testGroup->addChild(new IndexedIndirectCase(testCtx, (name + "_single_command").c_str(), "vkCmdDrawIndexedIndirect testcase.", params));
+
+ params.addCommand(vertexCount, 1, firstIndex, vertexOffset, 0);
+ testGroup->addChild(new IndexedIndirectCase(testCtx, (name + "_multi_command").c_str(), "vkCmdDrawIndexedIndirect testcase.", params));
+ break;
+ }
+ default:
+ DE_FATAL("Unsupported draw command.");
+ }
+ }
+}
+
+void createTopologyGroups (tcu::TestCaseGroup* testGroup, const DrawCommandType cmdType)
+{
+ for (deUint32 idx = 0; idx != vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; ++idx)
+ {
+ const vk::VkPrimitiveTopology topology = vk::VkPrimitiveTopology(idx);
+ const std::string groupName = de::toLower(getPrimitiveTopologyName(topology)).substr(22);
+ addTestGroup(testGroup, groupName, "Testcases with a specific topology.", populateSubGroup, TestCaseParams(cmdType, topology));
+ }
+}
+
+void createDrawTests (tcu::TestCaseGroup* testGroup)
+{
+ for (deUint32 idx = 0; idx < DRAW_COMMAND_TYPE_DRAW_LAST; ++idx)
+ {
+ const DrawCommandType command = DrawCommandType(idx);
+ addTestGroup(testGroup, getDrawCommandTypeName(command), "Group for testing a specific draw command.", createTopologyGroups, command);
+ }
+}
+
+tcu::TestCaseGroup* createBasicDrawTests (tcu::TestContext& testCtx)
+{
+ return createTestGroup(testCtx, "basic_draw", "Basic drawing tests", createDrawTests);
+}
+
+} // DrawTests
+} // vkt
dEQP-VK.draw.indirect_draw.indexed.indirect_draw_instanced.no_first_instance.triangle_strip
dEQP-VK.draw.indirect_draw.indexed.indirect_draw_instanced.first_instance.triangle_list
dEQP-VK.draw.indirect_draw.indexed.indirect_draw_instanced.first_instance.triangle_strip
+dEQP-VK.draw.basic_draw.draw.point_list.1
+dEQP-VK.draw.basic_draw.draw.point_list.3
+dEQP-VK.draw.basic_draw.draw.point_list.17
+dEQP-VK.draw.basic_draw.draw.point_list.45
+dEQP-VK.draw.basic_draw.draw.line_list.1
+dEQP-VK.draw.basic_draw.draw.line_list.3
+dEQP-VK.draw.basic_draw.draw.line_list.17
+dEQP-VK.draw.basic_draw.draw.line_list.45
+dEQP-VK.draw.basic_draw.draw.line_strip.1
+dEQP-VK.draw.basic_draw.draw.line_strip.3
+dEQP-VK.draw.basic_draw.draw.line_strip.17
+dEQP-VK.draw.basic_draw.draw.line_strip.45
+dEQP-VK.draw.basic_draw.draw.triangle_list.1
+dEQP-VK.draw.basic_draw.draw.triangle_list.3
+dEQP-VK.draw.basic_draw.draw.triangle_list.17
+dEQP-VK.draw.basic_draw.draw.triangle_list.45
+dEQP-VK.draw.basic_draw.draw.triangle_strip.1
+dEQP-VK.draw.basic_draw.draw.triangle_strip.3
+dEQP-VK.draw.basic_draw.draw.triangle_strip.17
+dEQP-VK.draw.basic_draw.draw.triangle_strip.45
+dEQP-VK.draw.basic_draw.draw.triangle_fan.1
+dEQP-VK.draw.basic_draw.draw.triangle_fan.3
+dEQP-VK.draw.basic_draw.draw.triangle_fan.17
+dEQP-VK.draw.basic_draw.draw.triangle_fan.45
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.line_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.line_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.triangle_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw.triangle_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.1
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.3
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.17
+dEQP-VK.draw.basic_draw.draw_indexed.point_list.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_list.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_fan.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.line_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_list_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.1
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.3
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.17
+dEQP-VK.draw.basic_draw.draw_indexed.triangle_strip_with_adjacency.45
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.point_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_fan.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.line_strip_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indirect.triangle_strip_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.point_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_fan.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.line_strip_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_list_with_adjacency.45_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.1_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.1_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.3_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.3_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.17_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.17_multi_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.45_single_command
+dEQP-VK.draw.basic_draw.draw_indexed_indirect.triangle_strip_with_adjacency.45_multi_command
dEQP-VK.compute.basic.empty_shader
dEQP-VK.compute.basic.ubo_to_ssbo_single_invocation
dEQP-VK.compute.basic.ubo_to_ssbo_single_group