1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2023 LunarG, Inc.
6 * Copyright (c) 2023 Nintendo
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Shader Object Performance Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktShaderObjectPerformanceTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkShaderObjectUtil.hpp"
30 #include "vktShaderObjectCreateUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include <chrono>
37
38 namespace vkt
39 {
40 namespace ShaderObject
41 {
42
43 namespace
44 {
45
46 enum TestType {
47 DRAW_STATIC_PIPELINE,
48 DRAW_DYNAMIC_PIPELINE,
49 DRAW_LINKED_SHADERS,
50 DRAW_BINARY,
51 DRAW_BINARY_BIND,
52 };
53
54 enum BinaryType {
55 BINARY_SHADER_CREATE,
56 BINARY_MEMCPY,
57 };
58
59 enum DrawType {
60 DRAW,
61 DRAW_INDEXED,
62 DRAW_INDEXED_INDIRECT,
63 DRAW_INDEXED_INDIRECT_COUNT,
64 DRAW_INDIRECT,
65 DRAW_INDIRECT_COUNT,
66 };
67
68 enum DispatchType {
69 DISPATCH,
70 DISPATCH_BASE,
71 DISPATCH_INDIRECT,
72 };
73
74 class ShaderObjectPerformanceInstance : public vkt::TestInstance
75 {
76 public:
ShaderObjectPerformanceInstance(Context& context, const DrawType drawType, const TestType& type)77 ShaderObjectPerformanceInstance (Context& context, const DrawType drawType, const TestType& type)
78 : vkt::TestInstance (context)
79 , m_drawType (drawType)
80 , m_type (type)
81 {}
~ShaderObjectPerformanceInstance(void)82 virtual ~ShaderObjectPerformanceInstance (void) {}
83
84 tcu::TestStatus iterate (void) override;
85 private:
86 std::chrono::nanoseconds draw (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkBuffer indexBuffer, vk::VkBuffer indirectBuffer, vk::VkBuffer countBuffer) const;
87
88 const DrawType m_drawType;
89 const TestType m_type;
90 };
91
extensionEnabled(const std::vector<std::string>& deviceExtensions, const std::string& ext)92 bool extensionEnabled(const std::vector<std::string>& deviceExtensions, const std::string& ext)
93 {
94 return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
95 }
96
getDynamicStates(Context& context)97 std::vector<vk::VkDynamicState> getDynamicStates (Context& context)
98 {
99 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceExtensions());
100 const auto& edsFeatures = context.getExtendedDynamicStateFeaturesEXT();
101 const auto& eds2Features = context.getExtendedDynamicState2FeaturesEXT();
102 const auto& eds3Features = context.getExtendedDynamicState3FeaturesEXT();
103 const auto& viFeatures = context.getVertexInputDynamicStateFeaturesEXT();
104
105 std::vector<vk::VkDynamicState> dynamicStates = {
106 vk::VK_DYNAMIC_STATE_LINE_WIDTH,
107 vk::VK_DYNAMIC_STATE_DEPTH_BIAS,
108 vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS,
109 vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS,
110 vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
111 vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
112 vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE,
113 };
114
115 if (edsFeatures.extendedDynamicState)
116 {
117 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE_EXT);
118 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT);
119 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT);
120 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
121 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
122 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
123 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT);
124 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT);
125 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT);
126 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT);
127 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT);
128 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT);
129 }
130 else
131 {
132 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT);
133 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR);
134 }
135 if (eds2Features.extendedDynamicState2)
136 {
137 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
138 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
139 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE);
140 }
141 if (eds2Features.extendedDynamicState2LogicOp)
142 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
143 if (eds2Features.extendedDynamicState2PatchControlPoints)
144 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
145
146 if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
147 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
148 if (eds3Features.extendedDynamicState3DepthClampEnable)
149 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
150 if (eds3Features.extendedDynamicState3PolygonMode)
151 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
152 if (eds3Features.extendedDynamicState3RasterizationSamples)
153 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
154 if (eds3Features.extendedDynamicState3SampleMask)
155 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
156 if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
157 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
158 if (eds3Features.extendedDynamicState3AlphaToOneEnable)
159 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
160 if (eds3Features.extendedDynamicState3LogicOpEnable)
161 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
162 if (eds3Features.extendedDynamicState3ColorBlendEnable)
163 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
164 if (eds3Features.extendedDynamicState3ColorBlendEquation)
165 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
166 if (eds3Features.extendedDynamicState3ColorWriteMask)
167 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
168 if (viFeatures.vertexInputDynamicState)
169 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
170
171 if (extensionEnabled(deviceExtensions, "VK_EXT_transform_feedback") && eds3Features.extendedDynamicState3RasterizationStream)
172 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
173 if (extensionEnabled(deviceExtensions, "VK_EXT_blend_operation_advanced") && eds3Features.extendedDynamicState3ColorBlendAdvanced)
174 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT);
175 if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") && eds3Features.extendedDynamicState3ConservativeRasterizationMode)
176 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
177 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") && eds3Features.extendedDynamicState3CoverageModulationMode)
178 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV);
179 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") && eds3Features.extendedDynamicState3CoverageModulationTableEnable)
180 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV);
181 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") && eds3Features.extendedDynamicState3CoverageModulationTable)
182 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV);
183 if (extensionEnabled(deviceExtensions, "VK_NV_coverage_reduction_mode") && eds3Features.extendedDynamicState3CoverageReductionMode)
184 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV);
185 if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") && eds3Features.extendedDynamicState3CoverageToColorEnable)
186 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV);
187 if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") && eds3Features.extendedDynamicState3CoverageToColorLocation)
188 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV);
189 if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_enable") && eds3Features.extendedDynamicState3DepthClipEnable)
190 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
191 if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_control") && eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
192 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
193 if (extensionEnabled(deviceExtensions, "VK_EXT_color_write_enable"))
194 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
195 if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") && eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize)
196 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
197 if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization") && eds3Features.extendedDynamicState3LineRasterizationMode)
198 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
199 if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization") && eds3Features.extendedDynamicState3LineStippleEnable)
200 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
201 if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization"))
202 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
203 if (extensionEnabled(deviceExtensions, "VK_EXT_provoking_vertex") && eds3Features.extendedDynamicState3ProvokingVertexMode)
204 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
205 if (extensionEnabled(deviceExtensions, "VK_KHR_fragment_shading_rate"))
206 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR);
207 if (extensionEnabled(deviceExtensions, "VK_NV_representative_fragment_test") && eds3Features.extendedDynamicState3RepresentativeFragmentTestEnable)
208 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV);
209 if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations") && eds3Features.extendedDynamicState3SampleLocationsEnable)
210 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
211 if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations"))
212 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
213 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image") && eds3Features.extendedDynamicState3ShadingRateImageEnable)
214 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV);
215 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
216 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV);
217 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
218 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV);
219 if (extensionEnabled(deviceExtensions, "VK_NV_viewport_swizzle") && eds3Features.extendedDynamicState3ViewportSwizzle)
220 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV);
221 if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling") && eds3Features.extendedDynamicState3ViewportWScalingEnable)
222 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV);
223 if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling"))
224 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
225 if (extensionEnabled(deviceExtensions, "VK_NV_scissor_exclusive"))
226 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV);
227 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
228 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
229 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
230 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
231 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
232 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
233
234 return dynamicStates;
235 }
236
createShaderFromBinary(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::Move<vk::VkShaderEXT>& shader, vk::VkShaderStageFlagBits stage)237 vk::VkShaderEXT createShaderFromBinary (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::Move<vk::VkShaderEXT>& shader, vk::VkShaderStageFlagBits stage)
238 {
239 size_t dataSize = 0;
240 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
241 std::vector<deUint8> data(dataSize);
242 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
243
244 const vk::VkShaderCreateInfoEXT binaryShaderCreateInfo =
245 {
246 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
247 DE_NULL, // const void* pNext;
248 0u, // VkShaderCreateFlagsEXT flags;
249 stage, // VkShaderStageFlagBits stage;
250 0u, // VkShaderStageFlags nextStage;
251 vk::VK_SHADER_CODE_TYPE_BINARY_EXT, // VkShaderCodeTypeEXT codeType;
252 dataSize, // size_t codeSize;
253 data.data(), // const void* pCode;
254 "main", // const char* pName;
255 0u, // uint32_t setLayoutCount;
256 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
257 0u, // uint32_t pushConstantRangeCount;
258 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
259 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
260 };
261
262 vk::VkShaderEXT binaryShader;
263 vk.createShadersEXT(device, 1, &binaryShaderCreateInfo, DE_NULL, &binaryShader);
264 return binaryShader;
265 }
266
draw(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkBuffer indexBuffer, vk::VkBuffer indirectBuffer, vk::VkBuffer countBuffer) const267 std::chrono::nanoseconds ShaderObjectPerformanceInstance::draw (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkBuffer indexBuffer, vk::VkBuffer indirectBuffer, vk::VkBuffer countBuffer) const
268 {
269 if (m_drawType == DRAW)
270 {
271 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
272 vk.cmdDraw(cmdBuffer, 4, 1, 0, 0);
273 return std::chrono::high_resolution_clock::now() - shaderObjectStart;
274 }
275 else if (m_drawType == DRAW_INDEXED)
276 {
277 vk.cmdBindIndexBuffer(cmdBuffer, indexBuffer, 0u, vk::VK_INDEX_TYPE_UINT16);
278 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
279 vk.cmdDrawIndexed(cmdBuffer, 4, 1, 0, 0, 0);
280 return std::chrono::high_resolution_clock::now() - shaderObjectStart;
281 }
282 else if (m_drawType == DRAW_INDEXED_INDIRECT)
283 {
284 vk.cmdBindIndexBuffer(cmdBuffer, indexBuffer, 0u, vk::VK_INDEX_TYPE_UINT16);
285 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
286 vk.cmdDrawIndexedIndirect(cmdBuffer, indirectBuffer, 0u, 1u, sizeof(vk::VkDrawIndexedIndirectCommand));
287 return std::chrono::high_resolution_clock::now() - shaderObjectStart;
288 }
289 else if (m_drawType == DRAW_INDEXED_INDIRECT_COUNT)
290 {
291 vk.cmdBindIndexBuffer(cmdBuffer, indexBuffer, 0u, vk::VK_INDEX_TYPE_UINT16);
292 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
293 vk.cmdDrawIndexedIndirectCount(cmdBuffer, indirectBuffer, 0u, countBuffer, 0u, 1u, sizeof(vk::VkDrawIndexedIndirectCommand));
294 return std::chrono::high_resolution_clock::now() - shaderObjectStart;
295 }
296 else if (m_drawType == DRAW_INDIRECT)
297 {
298 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
299 vk.cmdDrawIndirect(cmdBuffer, indirectBuffer, 0u, 1u, sizeof(vk::VkDrawIndirectCommand));
300 return std::chrono::high_resolution_clock::now() - shaderObjectStart;
301 }
302 else if (m_drawType == DRAW_INDIRECT_COUNT)
303 {
304 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
305 vk.cmdDrawIndirectCount(cmdBuffer, indirectBuffer, 0u, countBuffer, 0u, 1u, sizeof(vk::VkDrawIndirectCommand));
306 return std::chrono::high_resolution_clock::now() - shaderObjectStart;
307 }
308 return std::chrono::nanoseconds(0);
309 }
310
iterate(void)311 tcu::TestStatus ShaderObjectPerformanceInstance::iterate (void)
312 {
313 const vk::VkInstance instance = m_context.getInstance();
314 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
315 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
316 const vk::VkDevice device = m_context.getDevice();
317 const vk::VkQueue queue = m_context.getUniversalQueue();
318 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
319 auto& alloc = m_context.getDefaultAllocator();
320 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
321 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
322 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
323 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
324 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
325
326 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
327 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
328
329 const vk::Move<vk::VkCommandPool> cmdPool (createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
330 const vk::Move<vk::VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
331
332 const vk::VkPrimitiveTopology topology = tessellationSupported ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
333
334 const deUint32 geomIndex = tessellationSupported ? 4u : 2u;
335
336 const vk::VkImageCreateInfo createInfo =
337 {
338 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
339 DE_NULL, // const void* pNext
340 0u, // VkImageCreateFlags flags
341 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
342 colorAttachmentFormat, // VkFormat format
343 { 32, 32, 1 }, // VkExtent3D extent
344 1u, // uint32_t mipLevels
345 1u, // uint32_t arrayLayers
346 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
347 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
348 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
349 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
350 0, // uint32_t queueFamilyIndexCount
351 DE_NULL, // const uint32_t* pQueueFamilyIndices
352 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
353 };
354
355 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
356 const auto imageView = vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
357 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
358
359 const vk::VkDeviceSize colorOutputBufferSize = renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
360 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
361 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
362
363 const auto& binaries = m_context.getBinaryCollection();
364
365 std::vector<vk::VkShaderCreateInfoEXT> createInfos =
366 {
367 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported),
368 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported),
369 };
370
371 if (tessellationSupported)
372 {
373 createInfos.push_back(vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported));
374 createInfos.push_back(vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported));
375 }
376 if (geometrySupported)
377 {
378 createInfos.push_back(vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported, geometrySupported));
379 }
380
381 if (tessellationSupported)
382 {
383 createInfos[0].nextStage = vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
384 createInfos[2].nextStage = vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
385 if (geometrySupported)
386 createInfos[3].nextStage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
387 else
388 createInfos[3].nextStage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
389 }
390 else if (geometrySupported)
391 {
392 createInfos[0].nextStage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
393 createInfos[geomIndex].nextStage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
394 }
395 else
396 {
397 createInfos[0].nextStage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
398 }
399
400 vk::Move<vk::VkShaderEXT> vertShader = vk::createShader(vk, device, createInfos[0]);
401 vk::Move<vk::VkShaderEXT> fragShader = vk::createShader(vk, device, createInfos[1]);
402 vk::Move<vk::VkShaderEXT> tescShader;
403 vk::Move<vk::VkShaderEXT> teseShader;
404 vk::Move<vk::VkShaderEXT> geomShader;
405
406 if (tessellationSupported)
407 {
408 tescShader = vk::createShader(vk, device, createInfos[2]);
409 teseShader = vk::createShader(vk, device, createInfos[3]);
410 }
411 if (geometrySupported)
412 {
413 geomShader = vk::createShader(vk, device, createInfos[geomIndex]);
414 }
415
416 std::vector<vk::VkShaderEXT> refShaders;
417
418 if (m_type == DRAW_LINKED_SHADERS)
419 {
420 refShaders.resize(5, VK_NULL_HANDLE);
421 for (auto& info : createInfos)
422 info.flags = vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT;
423
424 vk.createShadersEXT(device, (deUint32)createInfos.size(), createInfos.data(), DE_NULL, refShaders.data());
425 }
426 else if (m_type == DRAW_BINARY || m_type == DRAW_BINARY_BIND)
427 {
428 refShaders.resize(5, VK_NULL_HANDLE);
429 refShaders[0] = createShaderFromBinary(vk, device, vertShader, vk::VK_SHADER_STAGE_VERTEX_BIT);
430 refShaders[1] = createShaderFromBinary(vk, device, fragShader, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
431 if (tessellationSupported)
432 {
433 refShaders[2] = createShaderFromBinary(vk, device, tescShader, vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
434 refShaders[3] = createShaderFromBinary(vk, device, teseShader, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
435 }
436 if (geometrySupported)
437 {
438 refShaders[geomIndex] = createShaderFromBinary(vk, device, geomShader, vk::VK_SHADER_STAGE_GEOMETRY_BIT);
439 }
440 }
441
442 vk::VkShaderEXT linkedShaders[5];
443 vk.createShadersEXT(device, static_cast<uint32_t>(createInfos.size()), createInfos.data(), nullptr, linkedShaders);
444
445 vk::Move<vk::VkShaderEXT> linkedVertShader = vk::Move<vk::VkShaderEXT>(vk::check<vk::VkShaderEXT>(linkedShaders[0]), vk::Deleter<vk::VkShaderEXT>(vk, device, DE_NULL));
446 vk::Move<vk::VkShaderEXT> linkedFragShader = vk::Move<vk::VkShaderEXT>(vk::check<vk::VkShaderEXT>(linkedShaders[1]), vk::Deleter<vk::VkShaderEXT>(vk, device, DE_NULL));
447 vk::Move<vk::VkShaderEXT> linkedTescShader;
448 vk::Move<vk::VkShaderEXT> linkedTeseShader;
449 vk::Move<vk::VkShaderEXT> linkedGeomShader;
450 if (tessellationSupported)
451 {
452 linkedTescShader = vk::Move<vk::VkShaderEXT>(vk::check<vk::VkShaderEXT>(linkedShaders[2]), vk::Deleter<vk::VkShaderEXT>(vk, device, DE_NULL));
453 linkedTeseShader = vk::Move<vk::VkShaderEXT>(vk::check<vk::VkShaderEXT>(linkedShaders[3]), vk::Deleter<vk::VkShaderEXT>(vk, device, DE_NULL));
454 }
455 if (geometrySupported)
456 {
457 linkedGeomShader = vk::Move<vk::VkShaderEXT>(vk::check<vk::VkShaderEXT>(linkedShaders[geomIndex]), vk::Deleter<vk::VkShaderEXT>(vk, device, DE_NULL));
458 }
459
460 vk::Move<vk::VkShaderModule> vertShaderModule = createShaderModule(vk, device, binaries.get("vert"));
461 vk::Move<vk::VkShaderModule> fragShaderModule = createShaderModule(vk, device, binaries.get("frag"));
462 vk::Move<vk::VkShaderModule> dummyVertShaderModule = createShaderModule(vk, device, binaries.get("dummyVert"));
463 vk::Move<vk::VkShaderModule> dummyFragShaderModule = createShaderModule(vk, device, binaries.get("dummyFrag"));
464 vk::Move<vk::VkShaderModule> tescShaderModule;
465 vk::Move<vk::VkShaderModule> teseShaderModule;
466 vk::Move<vk::VkShaderModule> geomShaderModule;
467 if (tessellationSupported)
468 {
469 tescShaderModule = createShaderModule(vk, device, binaries.get("tesc"));
470 teseShaderModule = createShaderModule(vk, device, binaries.get("tese"));
471 }
472 if (geometrySupported)
473 {
474 geomShaderModule = createShaderModule(vk, device, binaries.get("geom"));
475 }
476
477 const auto emptyPipelineLayout = makePipelineLayout(vk, device);
478
479 const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
480 {
481 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
482 DE_NULL, // const void* pNext;
483 0u, // VkPipelineVertexInputStateCreateFlags flags;
484 0u, // deUint32 vertexBindingDescriptionCount;
485 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
486 0u, // deUint32 vertexAttributeDescriptionCount;
487 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
488 };
489
490 const vk::VkPipelineTessellationStateCreateInfo tessStateCreateInfo =
491 {
492 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
493 DE_NULL, // const void* pNext;
494 0u, // VkPipelineTessellationStateCreateFlags flags;
495 4u, // uint32_t patchControlPoints;
496 };
497
498 vk::VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
499 {
500 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
501 DE_NULL, // const void* pNext;
502 (vk::VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
503 topology, // VkPrimitiveTopology topology;
504 VK_FALSE, // VkBool32 primitiveRestartEnable;
505 };
506
507 vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo =
508 {
509 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType
510 DE_NULL, // const void* pNext
511 0u, // uint32_t viewMask
512 1u, // uint32_t colorAttachmentCount
513 &colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats
514 vk::VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat
515 vk::VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat
516 };
517
518 const vk::VkViewport viewport = vk::makeViewport((float)renderArea.extent.width, 0.0f, (float)renderArea.extent.width, (float)renderArea.extent.height, 0.0f, 1.0f);
519 const vk::VkRect2D scissor = vk::makeRect2D(renderArea.extent);
520
521 vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
522 {
523 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
524 DE_NULL, // const void* pNext
525 (vk::VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags
526 (m_type == DRAW_DYNAMIC_PIPELINE) ? 0u : 1u, // deUint32 viewportCount
527 &viewport, // const VkViewport* pViewports
528 (m_type == DRAW_DYNAMIC_PIPELINE) ? 0u : 1u, // deUint32 scissorCount
529 &scissor // const VkRect2D* pScissors
530 };
531
532 const auto dynamicStates = getDynamicStates(m_context);
533
534 const vk::VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
535 {
536 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
537 DE_NULL, // const void* pNext;
538 (vk::VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags;
539 static_cast<deUint32>(dynamicStates.size()), // deUint32 dynamicStateCount;
540 dynamicStates.data(), // const VkDynamicState* pDynamicStates;
541 };
542
543 const vk::VkPipelineDynamicStateCreateInfo* pDynamicStateCreateInfo = (m_type == DRAW_DYNAMIC_PIPELINE) ? &dynamicStateCreateInfo : DE_NULL;
544
545 const auto pipeline = makeGraphicsPipeline(vk, device, emptyPipelineLayout.get(), vertShaderModule.get(), tescShaderModule.get(), teseShaderModule.get(), geomShaderModule.get(), fragShaderModule.get(), VK_NULL_HANDLE, 0u, &vertexInputStateParams, &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL, DE_NULL, pDynamicStateCreateInfo, &pipelineRenderingCreateInfo);
546 pipelineInputAssemblyStateInfo.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
547 viewportStateCreateInfo.viewportCount = 1u;
548 viewportStateCreateInfo.scissorCount = 1u;
549 const auto dummyPipeline = makeGraphicsPipeline(vk, device, emptyPipelineLayout.get(), dummyVertShaderModule.get(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, dummyFragShaderModule.get(), VK_NULL_HANDLE, 0u, &vertexInputStateParams, &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL, &pipelineRenderingCreateInfo);
550
551 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
552
553 vk::BufferWithMemory indirectBuffer (vk, device, alloc, vk::makeBufferCreateInfo(sizeof(vk::VkDrawIndirectCommand) + sizeof(vk::VkDrawIndexedIndirectCommand), vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
554
555 if (m_drawType == DRAW_INDEXED_INDIRECT || m_drawType == DRAW_INDEXED_INDIRECT_COUNT)
556 {
557 vk::VkDrawIndexedIndirectCommand* indirectDataPtr = reinterpret_cast<vk::VkDrawIndexedIndirectCommand*>(indirectBuffer.getAllocation().getHostPtr());
558 indirectDataPtr->indexCount = 4;
559 indirectDataPtr->instanceCount = 1;
560 indirectDataPtr->firstIndex = 0;
561 indirectDataPtr->vertexOffset = 0;
562 indirectDataPtr->firstInstance = 0;
563 }
564 else
565 {
566 vk::VkDrawIndirectCommand* indirectDataPtr = reinterpret_cast<vk::VkDrawIndirectCommand*>(indirectBuffer.getAllocation().getHostPtr());
567 indirectDataPtr->vertexCount = 4;
568 indirectDataPtr->instanceCount = 1;
569 indirectDataPtr->firstVertex = 0;
570 indirectDataPtr->firstInstance = 0;
571 }
572
573 vk::BufferWithMemory countBuffer (vk, device, alloc, vk::makeBufferCreateInfo(sizeof(deUint32), vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
574 deUint32* countDataPtr = reinterpret_cast<deUint32*>(countBuffer.getAllocation().getHostPtr());
575 countDataPtr[0] = 1u;
576
577 vk::BufferWithMemory indexBuffer (vk, device, alloc, vk::makeBufferCreateInfo(sizeof(deUint32) * 4, vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
578 deUint32* indexDataPtr = reinterpret_cast<deUint32*>(indexBuffer.getAllocation().getHostPtr());
579 indexDataPtr[0] = 0u;
580 indexDataPtr[1] = 1u;
581 indexDataPtr[2] = 2u;
582 indexDataPtr[3] = 3u;
583
584 const vk::VkDeviceSize bufferSize = 64;
585 de::MovePtr<vk::BufferWithMemory> buffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), vk::MemoryRequirement::HostVisible));
586
587 // Do a dummy run, to ensure memory allocations are done with before performance testing
588 {
589 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
590 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *dummyPipeline);
591 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
592 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
593 vk::endRendering(vk, *cmdBuffer);
594 vk::endCommandBuffer(vk, *cmdBuffer);
595 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
596 }
597
598 std::chrono::nanoseconds time = std::chrono::nanoseconds(0);
599 std::chrono::nanoseconds refTime = std::chrono::nanoseconds(0);
600 std::chrono::nanoseconds maxTime = std::chrono::nanoseconds(0);
601 std::chrono::nanoseconds maxRefTime = std::chrono::nanoseconds(0);
602
603 for (deUint32 i = 0; i < 100; ++i)
604 {
605 std::chrono::nanoseconds currentTime;
606 std::chrono::nanoseconds currentRefTime;
607
608 if (m_type == DRAW_BINARY_BIND)
609 {
610 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
611 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
612 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
613 currentTime = std::chrono::high_resolution_clock::now() - shaderObjectStart;
614 vk::endCommandBuffer(vk, *cmdBuffer);
615
616 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
617 const auto refShaderObjectStart = std::chrono::high_resolution_clock::now();
618 vk::bindGraphicsShaders(vk, *cmdBuffer, refShaders[0], refShaders[2], refShaders[3], refShaders[4], refShaders[1], taskSupported, meshSupported);
619 currentRefTime = std::chrono::high_resolution_clock::now() - refShaderObjectStart;
620 vk::endCommandBuffer(vk, *cmdBuffer);
621 }
622 else
623 {
624 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
625 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
626 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, topology, false, !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
627 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
628 currentTime = draw(vk, *cmdBuffer, *indexBuffer, *indirectBuffer, *countBuffer);
629 vk::endRendering(vk, *cmdBuffer);
630 vk::endCommandBuffer(vk, *cmdBuffer);
631 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
632
633 if (m_type == DRAW_LINKED_SHADERS || m_type == DRAW_BINARY)
634 {
635 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
636 vk::bindGraphicsShaders(vk, *cmdBuffer, refShaders[0], refShaders[2], refShaders[3], refShaders[4], refShaders[1], taskSupported, meshSupported);
637 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, topology, false, !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
638 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
639 currentRefTime = draw(vk, *cmdBuffer, *indexBuffer, *indirectBuffer, *countBuffer);
640 vk::endRendering(vk, *cmdBuffer);
641 vk::endCommandBuffer(vk, *cmdBuffer);
642 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
643 }
644 else
645 {
646 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
647 vk::VkDeviceSize offset = 0u;
648 vk::VkDeviceSize stride = 16u;
649 vk.cmdBindVertexBuffers2(*cmdBuffer, 0u, 1u, &**buffer, &offset, &bufferSize, &stride);
650 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, topology, false, !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
651 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
652 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
653 currentRefTime = draw(vk, *cmdBuffer, *indexBuffer, *indirectBuffer, *countBuffer);
654 vk::endRendering(vk, *cmdBuffer);
655 vk::endCommandBuffer(vk, *cmdBuffer);
656 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
657 }
658 }
659
660 time += currentTime;
661 if (currentTime > maxTime)
662 maxTime = currentTime;
663
664 refTime += currentRefTime;
665 if (currentRefTime > maxRefTime)
666 maxRefTime = currentRefTime;
667 }
668
669 for (const auto& shader : refShaders)
670 vk.destroyShaderEXT(device, shader, DE_NULL);
671
672 if (m_type == DRAW_STATIC_PIPELINE)
673 {
674 if (maxTime > maxRefTime * 1.5f)
675 return tcu::TestStatus::fail("Maximum shader object rendering iteration was more than 50% slower than maximum static pipeline iteration rendering");
676 if (time > refTime * 1.25f)
677 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Shader object rendering was more than 25% slower than static pipeline rendering");
678 if (maxTime > maxRefTime * 1.25f)
679 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Maximum shader object iteration rendering was more than 25% slower than maximum static pipeline iteration rendering");
680 }
681 else if (m_type == DRAW_DYNAMIC_PIPELINE)
682 {
683 if (maxTime > maxRefTime * 1.2f)
684 return tcu::TestStatus::fail("Maximum shader object iteration rendering was more than 20% slower than maximum dynamic pipeline iteration rendering");
685 if (time > refTime * 1.1f)
686 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Shader object rendering was more than 10% slower than dynamic pipeline rendering");
687 if (maxTime > maxRefTime * 1.1f)
688 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Maximum shader object iteration rendering was more than 10% slower than maximum dynamic pipeline iteration rendering");
689 }
690 else if (m_type == DRAW_LINKED_SHADERS)
691 {
692 if (maxTime > maxRefTime * 1.05f)
693 return tcu::TestStatus::fail("Maximum unlinked shader object iteration rendering was more than 5% slower than maximum linked shader object iteration rendering");
694 if (time * 1.05f < refTime)
695 return tcu::TestStatus::fail("Linked shader object rendering was more than 5% slower than unlinked shader object rendering");
696 if (maxTime * 1.05f < maxRefTime)
697 return tcu::TestStatus::fail("Maximum linked shader object iteration rendering was more than 5% slower than maximum unlinked shader object iteratino rendering");
698 }
699 else if (m_type == DRAW_BINARY)
700 {
701 if (maxTime > maxRefTime * 1.05f)
702 return tcu::TestStatus::fail("Maximum shader object iteration rendering was more than 5% slower than maximum binary shader object iteration rendering");
703 if (time * 1.05f < refTime)
704 return tcu::TestStatus::fail("Binary shader object rendering was more than 5% slower than shader object rendering");
705 if (maxTime * 1.05f < maxRefTime)
706 return tcu::TestStatus::fail("Maximum binary shader object iteration rendering was more than 5% slower than maximum shader object iteration rendering");
707 }
708 else if (m_type == DRAW_BINARY_BIND)
709 {
710 if (maxTime > maxRefTime * 1.05f)
711 return tcu::TestStatus::fail("Maximum shader object iteration binding was more than 5% slower than maximum binary shader object iteration binding");
712 if (time * 1.05f < refTime)
713 return tcu::TestStatus::fail("Binary shader object binding was more than 5% slower than shader object binding");
714 if (maxTime * 1.05f < maxRefTime)
715 return tcu::TestStatus::fail("Maximum binary shader object iteration binding was more than 5% slower than maximum shader object iteration binding");
716 }
717
718 return tcu::TestStatus::pass("Pass");
719 }
720
721 class ShaderObjectPerformanceCase : public vkt::TestCase
722 {
723 public:
ShaderObjectPerformanceCase(tcu::TestContext& testCtx, const std::string& name, const DrawType drawType, const TestType& type)724 ShaderObjectPerformanceCase(tcu::TestContext& testCtx, const std::string& name, const DrawType drawType, const TestType& type)
725 : vkt::TestCase (testCtx, name)
726 , m_drawType (drawType)
727 , m_type (type)
728 {}
~ShaderObjectPerformanceCase(void)729 virtual ~ShaderObjectPerformanceCase(void) {}
730
731 void checkSupport(vkt::Context& context) const override;
732 virtual void initPrograms(vk::SourceCollections& programCollection) const override;
733 TestInstance* createInstance(Context& context) const override { return new ShaderObjectPerformanceInstance(context, m_drawType, m_type); }
734
735 private:
736 DrawType m_drawType;
737 TestType m_type;
738 };
739
checkSupport(Context& context) const740 void ShaderObjectPerformanceCase::checkSupport(Context& context) const
741 {
742 context.requireDeviceFunctionality("VK_EXT_shader_object");
743 }
744
initPrograms(vk::SourceCollections& programCollection) const745 void ShaderObjectPerformanceCase::initPrograms(vk::SourceCollections& programCollection) const
746 {
747 vk::addBasicShaderObjectShaders(programCollection);
748
749 std::stringstream dummyVert;
750 std::stringstream dummyFrag;
751
752 dummyVert
753 << "#version 450\n"
754 << "layout(location = 0) out vec4 rgba;\n"
755 << "void main() {\n"
756 << " vec2 pos2 = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
757 << " vec3 pos3 = vec3(pos2, 0.0f) * gl_InstanceIndex;\n"
758 << " gl_Position = vec4(pos3, 1.0f);\n"
759 << " rgba = vec4(0.0f, pos3.zyx);\n"
760 << "}\n";
761
762 dummyFrag
763 << "#version 450\n"
764 << "layout(location = 0) in vec4 rgba;\n"
765 << "layout(location = 0) out vec4 color;\n"
766 << "void main() {\n"
767 << " color = rgba * rgba;\n"
768 << "}\n";
769
770 programCollection.glslSources.add("dummyVert") << glu::VertexSource(dummyVert.str());
771 programCollection.glslSources.add("dummyFrag") << glu::FragmentSource(dummyFrag.str());
772 }
773
774
775 class ShaderObjectDispatchPerformanceInstance : public vkt::TestInstance
776 {
777 public:
ShaderObjectDispatchPerformanceInstance(Context& context, const DispatchType dispatchType)778 ShaderObjectDispatchPerformanceInstance (Context& context, const DispatchType dispatchType)
779 : vkt::TestInstance (context)
780 , m_dispatchType (dispatchType)
781 {}
~ShaderObjectDispatchPerformanceInstance(void)782 virtual ~ShaderObjectDispatchPerformanceInstance (void) {}
783
784 tcu::TestStatus iterate (void) override;
785
786 private:
787 const DispatchType m_dispatchType;
788 };
789
iterate(void)790 tcu::TestStatus ShaderObjectDispatchPerformanceInstance::iterate (void)
791 {
792 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
793 const vk::VkDevice device = m_context.getDevice();
794 const vk::VkQueue queue = m_context.getUniversalQueue();
795 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
796 auto& alloc = m_context.getDefaultAllocator();
797
798 const vk::VkDeviceSize bufferSizeBytes = sizeof(deUint32) * 16;
799 const vk::BufferWithMemory outputBuffer (vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
800 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
801 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
802
803 const auto& binaries = m_context.getBinaryCollection();
804
805 const auto& comp = binaries.get("comp");
806 const auto compShaderModule = createShaderModule(vk, device, comp);
807
808 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
809 vk::DescriptorSetLayoutBuilder()
810 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
811 .build(vk, device));
812
813 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
814 vk::DescriptorPoolBuilder()
815 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
816 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
817 const auto pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout.get());
818
819 const vk::Unique<vk::VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
820 const vk::VkDescriptorBufferInfo descriptorInfo = vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
821 vk::DescriptorSetUpdateBuilder()
822 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
823 .update(vk, device);
824
825 const auto compShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_COMPUTE_BIT, binaries.get("comp"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
826 const vk::VkPipelineCreateFlags pipelineFlags = (m_dispatchType == DISPATCH) ? (vk::VkPipelineCreateFlags)0u : (vk::VkPipelineCreateFlags)vk::VK_PIPELINE_CREATE_DISPATCH_BASE_BIT;
827 const auto computePipeline = vk::makeComputePipeline(vk, device, pipelineLayout.get(), pipelineFlags, nullptr, compShaderModule.get(), (vk::VkPipelineShaderStageCreateFlags)0u);
828
829 const vk::Move<vk::VkCommandPool> cmdPool (createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
830 const vk::Move<vk::VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
831
832 vk::BufferWithMemory indirectBuffer (vk, device, alloc, vk::makeBufferCreateInfo(sizeof(vk::VkDispatchIndirectCommand), vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
833
834 vk::VkDispatchIndirectCommand* indirectDataPtr = reinterpret_cast<vk::VkDispatchIndirectCommand*>(indirectBuffer.getAllocation().getHostPtr());
835 indirectDataPtr->x = 1;
836 indirectDataPtr->y = 1;
837 indirectDataPtr->z = 1;
838
839 std::chrono::nanoseconds time = std::chrono::nanoseconds(0);
840 std::chrono::nanoseconds refTime = std::chrono::nanoseconds(0);
841
842 for (deUint32 i = 0; i < 100; ++i)
843 {
844 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
845 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
846 vk::bindComputeShader(vk, *cmdBuffer, *compShader);
847 if (m_dispatchType == DISPATCH)
848 {
849 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
850 vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
851 time += std::chrono::high_resolution_clock::now() - shaderObjectStart;
852 }
853 else if (m_dispatchType == DISPATCH_BASE)
854 {
855 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
856 vk.cmdDispatchBase(*cmdBuffer, 1, 1, 1, 0, 0, 0);
857 time += std::chrono::high_resolution_clock::now() - shaderObjectStart;
858 }
859 else if (m_dispatchType == DISPATCH_INDIRECT)
860 {
861 const auto shaderObjectStart = std::chrono::high_resolution_clock::now();
862 vk.cmdDispatchIndirect(*cmdBuffer, *indirectBuffer, 0u);
863 time += std::chrono::high_resolution_clock::now() - shaderObjectStart;
864 }
865 vk::endCommandBuffer(vk, *cmdBuffer);
866 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
867
868 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
869 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
870 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
871 if (m_dispatchType == DISPATCH)
872 {
873 const auto pipelineStart = std::chrono::high_resolution_clock::now();
874 vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
875 refTime += std::chrono::high_resolution_clock::now() - pipelineStart;
876 }
877 else if (m_dispatchType == DISPATCH_BASE)
878 {
879 const auto pipelineStart = std::chrono::high_resolution_clock::now();
880 vk.cmdDispatchBase(*cmdBuffer, 1, 1, 1, 0, 0, 0);
881 refTime += std::chrono::high_resolution_clock::now() - pipelineStart;
882 }
883 else if (m_dispatchType == DISPATCH_INDIRECT)
884 {
885 const auto pipelineStart = std::chrono::high_resolution_clock::now();
886 vk.cmdDispatchIndirect(*cmdBuffer, *indirectBuffer, 0u);
887 refTime += std::chrono::high_resolution_clock::now() - pipelineStart;
888 }
889 vk::endCommandBuffer(vk, *cmdBuffer);
890 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
891
892 // Ignore first iteration, there is a penalty on the first call
893 if (i == 0)
894 {
895 time = std::chrono::nanoseconds(0);
896 refTime = std::chrono::nanoseconds(0);
897 }
898 }
899
900 if (time > refTime * 1.05f)
901 return tcu::TestStatus::fail("Shader object dispatch was more than 5% slower than compute pipeline dispatch");
902 return tcu::TestStatus::pass("Pass");
903 }
904
905 class ShaderObjectDispatchPerformanceCase : public vkt::TestCase
906 {
907 public:
ShaderObjectDispatchPerformanceCase(tcu::TestContext& testCtx, const std::string& name, const DispatchType dispatchType)908 ShaderObjectDispatchPerformanceCase (tcu::TestContext& testCtx, const std::string& name, const DispatchType dispatchType)
909 : vkt::TestCase (testCtx, name)
910 , m_dispatchType (dispatchType)
911 {}
~ShaderObjectDispatchPerformanceCase(void)912 virtual ~ShaderObjectDispatchPerformanceCase (void) {}
913
914 void checkSupport (vkt::Context& context) const override;
915 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
916 TestInstance* createInstance (Context& context) const override { return new ShaderObjectDispatchPerformanceInstance(context, m_dispatchType); }
917
918 private:
919 const DispatchType m_dispatchType;
920 };
921
checkSupport(Context& context) const922 void ShaderObjectDispatchPerformanceCase::checkSupport (Context& context) const
923 {
924 context.requireDeviceFunctionality("VK_EXT_shader_object");
925 }
926
initPrograms(vk::SourceCollections& programCollection) const927 void ShaderObjectDispatchPerformanceCase::initPrograms (vk::SourceCollections& programCollection) const
928 {
929 vk::addBasicShaderObjectShaders(programCollection);
930 }
931
932
933 class ShaderObjectBinaryPerformanceInstance : public vkt::TestInstance
934 {
935 public:
ShaderObjectBinaryPerformanceInstance(Context& context, BinaryType type)936 ShaderObjectBinaryPerformanceInstance (Context& context, BinaryType type)
937 : vkt::TestInstance (context)
938 , m_type (type)
939 {}
~ShaderObjectBinaryPerformanceInstance(void)940 virtual ~ShaderObjectBinaryPerformanceInstance (void) {}
941
942 tcu::TestStatus iterate (void) override;
943 private:
944 const BinaryType m_type;
945 };
946
iterate(void)947 tcu::TestStatus ShaderObjectBinaryPerformanceInstance::iterate (void)
948 {
949 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
950 const vk::VkDevice device = m_context.getDevice();
951 auto& alloc = m_context.getDefaultAllocator();
952 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
953 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
954
955 const auto& binaries = m_context.getBinaryCollection();
956
957 std::chrono::nanoseconds time = std::chrono::nanoseconds(0);
958 std::chrono::nanoseconds refTime = std::chrono::nanoseconds(0);
959
960 for (deUint32 i = 0; i < 100; ++i)
961 {
962 const auto spirvCreateInfo = vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported);
963 vk::VkShaderEXT spirvShader;
964 const auto spirvStart = std::chrono::high_resolution_clock::now();
965 vk.createShadersEXT(device, 1u, &spirvCreateInfo, DE_NULL, &spirvShader);
966 const auto spirvEnd = std::chrono::high_resolution_clock::now();
967 if (m_type == BINARY_SHADER_CREATE)
968 refTime += spirvEnd - spirvStart;
969
970 size_t dataSize = 0;
971 vk.getShaderBinaryDataEXT(device, spirvShader, &dataSize, DE_NULL);
972 std::vector<deUint8> data(dataSize);
973 vk.getShaderBinaryDataEXT(device, spirvShader, &dataSize, data.data());
974
975 const vk::VkShaderCreateInfoEXT binaryShaderCreateInfo =
976 {
977 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
978 DE_NULL, // const void* pNext;
979 0u, // VkShaderCreateFlagsEXT flags;
980 vk::VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
981 0u, // VkShaderStageFlags nextStage;
982 vk::VK_SHADER_CODE_TYPE_BINARY_EXT, // VkShaderCodeTypeEXT codeType;
983 dataSize, // size_t codeSize;
984 data.data(), // const void* pCode;
985 "main", // const char* pName;
986 0u, // uint32_t setLayoutCount;
987 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
988 0u, // uint32_t pushConstantRangeCount;
989 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
990 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
991 };
992
993 vk::VkShaderEXT binaryShader;
994 const auto binaryStart = std::chrono::high_resolution_clock::now();
995 vk.createShadersEXT(device, 1, &binaryShaderCreateInfo, DE_NULL, &binaryShader);
996 time += std::chrono::high_resolution_clock::now() - binaryStart;
997
998 const auto bufferCreateInfo = vk::makeBufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
999 vk::Move<vk::VkBuffer> buffer = vk::createBuffer(vk, device, &bufferCreateInfo);
1000 const auto bufferMemReqs = vk::getBufferMemoryRequirements(vk, device, *buffer);
1001 const auto memoryProperties = vk::getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
1002 const auto hostCachedDeviceLocal = bufferMemReqs.memoryTypeBits & vk::getCompatibleMemoryTypes(memoryProperties, vk::MemoryRequirement::Cached | vk::MemoryRequirement::Local | vk::MemoryRequirement::HostVisible);
1003
1004 vk::MemoryRequirement memoryRequirements = (hostCachedDeviceLocal != 0) ?
1005 vk::MemoryRequirement::Cached | vk::MemoryRequirement::Local | vk::MemoryRequirement::HostVisible :
1006 vk::MemoryRequirement::Coherent | vk::MemoryRequirement::Local | vk::MemoryRequirement::HostVisible;
1007 vk::BufferWithMemory bufferWithMemory (vk, device, alloc, bufferCreateInfo, memoryRequirements);
1008 const vk::Allocation& bufferAlloc = bufferWithMemory.getAllocation();
1009 const auto memcpyStart = std::chrono::high_resolution_clock::now();
1010 memcpy(bufferAlloc.getHostPtr(), data.data(), dataSize);
1011 flushAlloc(vk, device, bufferAlloc);
1012 const auto memcpyEnd = std::chrono::high_resolution_clock::now();
1013 if (m_type == BINARY_MEMCPY)
1014 refTime += memcpyEnd - memcpyStart;
1015
1016 vk.destroyShaderEXT(device, spirvShader, DE_NULL);
1017 vk.destroyShaderEXT(device, binaryShader, DE_NULL);
1018 }
1019
1020 if (m_type == BINARY_SHADER_CREATE)
1021 {
1022 if (time > refTime * 1.05f)
1023 return tcu::TestStatus::fail("Binary shader object create time is more than 5% slower than spirv shader object create time");
1024 }
1025 else if (m_type == BINARY_MEMCPY)
1026 {
1027 if (time > refTime * 1.5f)
1028 return tcu::TestStatus::fail("Binary shader object create time is more than 50% slower than memcpy of an equal amount of data");
1029 }
1030
1031 return tcu::TestStatus::pass("Pass");
1032 }
1033
1034 class ShaderObjectBinaryPerformanceCase : public vkt::TestCase
1035 {
1036 public:
ShaderObjectBinaryPerformanceCase(tcu::TestContext& testCtx, const std::string& name, BinaryType type)1037 ShaderObjectBinaryPerformanceCase (tcu::TestContext& testCtx, const std::string& name, BinaryType type)
1038 : vkt::TestCase (testCtx, name)
1039 , m_type (type)
1040 {}
~ShaderObjectBinaryPerformanceCase(void)1041 virtual ~ShaderObjectBinaryPerformanceCase (void) {}
1042
1043 void checkSupport (vkt::Context& context) const override;
1044 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
1045 TestInstance* createInstance (Context& context) const override { return new ShaderObjectBinaryPerformanceInstance(context, m_type); }
1046 private:
1047 const BinaryType m_type;
1048 };
1049
checkSupport(Context& context) const1050 void ShaderObjectBinaryPerformanceCase::checkSupport (Context& context) const
1051 {
1052 context.requireDeviceFunctionality("VK_EXT_shader_object");
1053 }
1054
initPrograms(vk::SourceCollections& programCollection) const1055 void ShaderObjectBinaryPerformanceCase::initPrograms (vk::SourceCollections& programCollection) const
1056 {
1057 vk::addBasicShaderObjectShaders(programCollection);
1058 }
1059
1060 }
1061
1062
createShaderObjectPerformanceTests(tcu::TestContext& testCtx)1063 tcu::TestCaseGroup* createShaderObjectPerformanceTests (tcu::TestContext& testCtx)
1064 {
1065 de::MovePtr<tcu::TestCaseGroup> performanceGroup(new tcu::TestCaseGroup(testCtx, "performance"));
1066
1067 const struct
1068 {
1069 DrawType drawType;
1070 const char* name;
1071 } drawTypeTests[] =
1072 {
1073 { DRAW, "draw" },
1074 { DRAW_INDEXED, "draw_indexed" },
1075 { DRAW_INDEXED_INDIRECT, "draw_indexed_indirect" },
1076 { DRAW_INDEXED_INDIRECT_COUNT, "draw_indexed_indirect_count" },
1077 { DRAW_INDIRECT, "draw_indirect" },
1078 { DRAW_INDIRECT_COUNT, "draw_indirect_count" },
1079 };
1080
1081 const struct
1082 {
1083 TestType testTpye;
1084 const char* name;
1085 } typeTests[] =
1086 {
1087 { DRAW_STATIC_PIPELINE, "static_pipeline" },
1088 { DRAW_DYNAMIC_PIPELINE, "dynamic_pipeline" },
1089 { DRAW_LINKED_SHADERS, "linked_shaders" },
1090 { DRAW_BINARY, "binary_shaders" },
1091 };
1092
1093 for (const auto& drawType : drawTypeTests)
1094 {
1095 for (const auto& typeTest : typeTests)
1096 {
1097 performanceGroup->addChild(new ShaderObjectPerformanceCase(testCtx, std::string(drawType.name) + "_" + std::string(typeTest.name), drawType.drawType, typeTest.testTpye));
1098 }
1099 }
1100 performanceGroup->addChild(new ShaderObjectPerformanceCase(testCtx, "binary_bind_shaders", DRAW, DRAW_BINARY_BIND));
1101
1102 performanceGroup->addChild(new ShaderObjectDispatchPerformanceCase(testCtx, "dispatch", DISPATCH));
1103 performanceGroup->addChild(new ShaderObjectDispatchPerformanceCase(testCtx, "dispatch_base", DISPATCH_BASE));
1104 performanceGroup->addChild(new ShaderObjectDispatchPerformanceCase(testCtx, "dispatch_indirect", DISPATCH_INDIRECT));
1105
1106 performanceGroup->addChild(new ShaderObjectBinaryPerformanceCase(testCtx, "binary_shader_create", BINARY_SHADER_CREATE));
1107 performanceGroup->addChild(new ShaderObjectBinaryPerformanceCase(testCtx, "binary_memcpy", BINARY_MEMCPY));
1108
1109 return performanceGroup.release();
1110 }
1111
1112 } // ShaderObject
1113 } // vkt
1114