blob: 5ef980370eba85d346121433f9cb06439b169614 [file] [log] [blame]
locke-luanrgd1e66ea2019-05-15 22:50:35 -06001/*
2 * Copyright (c) 2015-2019 The Khronos Group Inc.
3 * Copyright (c) 2015-2019 Valve Corporation
4 * Copyright (c) 2015-2019 LunarG, Inc.
5 * Copyright (c) 2015-2019 Google, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Author: Chia-I Wu <olvaffe@gmail.com>
14 * Author: Chris Forbes <chrisf@ijw.co.nz>
15 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
16 * Author: Mark Lobodzinski <mark@lunarg.com>
17 * Author: Mike Stroyan <mike@LunarG.com>
18 * Author: Tobin Ehlis <tobine@google.com>
19 * Author: Tony Barbour <tony@LunarG.com>
20 * Author: Cody Northrop <cnorthrop@google.com>
21 * Author: Dave Houlton <daveh@lunarg.com>
22 * Author: Jeremy Kniager <jeremyk@lunarg.com>
23 * Author: Shannon McPherson <shannon@lunarg.com>
24 * Author: John Zulauf <jzulauf@lunarg.com>
25 */
26
27#ifndef VKLAYERTEST_H
28#define VKLAYERTEST_H
29
30#ifdef ANDROID
31#include "vulkan_wrapper.h"
32#else
33#define NOMINMAX
34#include <vulkan/vulkan.h>
35#endif
36
37#include "layers/vk_device_profile_api_layer.h"
38
39#if defined(ANDROID)
40#include <android/log.h>
41#if defined(VALIDATION_APK)
42#include <android_native_app_glue.h>
43#endif
44#endif
45
46#include "icd-spv.h"
47#include "test_common.h"
48#include "vk_layer_config.h"
49#include "vk_format_utils.h"
50#include "vkrenderframework.h"
51#include "vk_typemap_helper.h"
52#include "convert_to_renderpass2.h"
53
54#include <algorithm>
55#include <cmath>
56#include <functional>
57#include <limits>
58#include <memory>
59#include <unordered_set>
60
61//--------------------------------------------------------------------------------------
62// Mesh and VertexFormat Data
63//--------------------------------------------------------------------------------------
64
65static const char kSkipPrefix[] = " TEST SKIPPED:";
66
67enum BsoFailSelect {
68 BsoFailNone,
69 BsoFailLineWidth,
70 BsoFailDepthBias,
71 BsoFailViewport,
72 BsoFailScissor,
73 BsoFailBlend,
74 BsoFailDepthBounds,
75 BsoFailStencilReadMask,
76 BsoFailStencilWriteMask,
77 BsoFailStencilReference,
78 BsoFailCmdClearAttachments,
79 BsoFailIndexBuffer,
80 BsoFailIndexBufferBadSize,
81 BsoFailIndexBufferBadOffset,
82 BsoFailIndexBufferBadMapSize,
Jeff Bolzf390c6c2019-08-16 16:29:53 -050083 BsoFailIndexBufferBadMapOffset,
84 BsoFailLineStipple,
locke-luanrgd1e66ea2019-05-15 22:50:35 -060085};
86
unknown11b2e802019-06-03 11:47:40 -060087static const char bindStateMinimalShaderText[] = "#version 450\nvoid main() {}\n";
88
locke-luanrgd1e66ea2019-05-15 22:50:35 -060089static const char bindStateVertShaderText[] =
90 "#version 450\n"
locke-luanrgd1e66ea2019-05-15 22:50:35 -060091 "void main() {\n"
unknown11b2e802019-06-03 11:47:40 -060092 " gl_Position = vec4(1);\n"
locke-luanrgd1e66ea2019-05-15 22:50:35 -060093 "}\n";
94
unknown11b2e802019-06-03 11:47:40 -060095static const char bindStateVertPointSizeShaderText[] =
96 "#version 450\n"
97 "out gl_PerVertex {\n"
98 " vec4 gl_Position;\n"
99 " float gl_PointSize;\n"
100 "};\n"
101 "void main() {\n"
102 " gl_Position = vec4(1);\n"
103 " gl_PointSize = 1.0;\n"
104 "}\n";
105
106static char const bindStateGeomShaderText[] =
107 "#version 450\n"
108 "layout(triangles) in;\n"
109 "layout(triangle_strip, max_vertices=3) out;\n"
110 "void main() {\n"
111 " gl_Position = vec4(1);\n"
112 " EmitVertex();\n"
113 "}\n";
114
115static char const bindStateGeomPointSizeShaderText[] =
116 "#version 450\n"
117 "layout (points) in;\n"
118 "layout (points) out;\n"
119 "layout (max_vertices = 1) out;\n"
120 "void main() {\n"
121 " gl_Position = vec4(1);\n"
122 " gl_PointSize = 1.0;\n"
123 " EmitVertex();\n"
124 "}\n";
125
126static const char bindStateTscShaderText[] =
127 "#version 450\n"
128 "layout(vertices=3) out;\n"
129 "void main() {\n"
130 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
131 " gl_TessLevelInner[0] = 1;\n"
132 "}\n";
133
134static const char bindStateTeshaderText[] =
135 "#version 450\n"
136 "layout(triangles, equal_spacing, cw) in;\n"
137 "void main() { gl_Position = vec4(1); }\n";
138
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600139static const char bindStateFragShaderText[] =
140 "#version 450\n"
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600141 "layout(location = 0) out vec4 uFragColor;\n"
142 "void main(){\n"
143 " uFragColor = vec4(0,1,0,1);\n"
144 "}\n";
145
unknown11b2e802019-06-03 11:47:40 -0600146static const char bindStateFragSamplerShaderText[] =
147 "#version 450\n"
148 "layout(set=0, binding=0) uniform sampler2D s;\n"
149 "layout(location=0) out vec4 x;\n"
150 "void main(){\n"
151 " x = texture(s, vec2(1));\n"
152 "}\n";
153
locke-lunarg7301ada2019-06-11 17:52:54 -0600154static const char bindStateFragUniformShaderText[] =
155 "#version 450\n"
156 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
157 "layout(location=0) out vec4 x;\n"
158 "void main(){\n"
159 " x = vec4(bar.y);\n"
160 "}\n";
161
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600162// Static arrays helper
163template <class ElementT, size_t array_size>
164size_t size(ElementT (&)[array_size]) {
165 return array_size;
166}
167
168// Format search helper
169VkFormat FindSupportedDepthStencilFormat(VkPhysicalDevice phy);
170
171// Returns true if *any* requested features are available.
172// Assumption is that the framework can successfully create an image as
173// long as at least one of the feature bits is present (excepting VTX_BUF).
174bool ImageFormatIsSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL,
175 VkFormatFeatureFlags features = ~VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT);
176
177// Returns true if format and *all* requested features are available.
178bool ImageFormatAndFeaturesSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling, VkFormatFeatureFlags features);
179
180// Returns true if format and *all* requested features are available.
181bool ImageFormatAndFeaturesSupported(const VkInstance inst, const VkPhysicalDevice phy, const VkImageCreateInfo info,
182 const VkFormatFeatureFlags features);
183
184// Validation report callback prototype
185VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location,
186 int32_t msgCode, const char *pLayerPrefix, const char *pMsg, void *pUserData);
187
188// Simple sane SamplerCreateInfo boilerplate
189VkSamplerCreateInfo SafeSaneSamplerCreateInfo();
190
191VkImageViewCreateInfo SafeSaneImageViewCreateInfo(VkImage image, VkFormat format, VkImageAspectFlags aspect_mask);
192
193VkImageViewCreateInfo SafeSaneImageViewCreateInfo(const VkImageObj &image, VkFormat format, VkImageAspectFlags aspect_mask);
194
195// Helper for checking createRenderPass2 support and adding related extensions.
196bool CheckCreateRenderPass2Support(VkRenderFramework *renderFramework, std::vector<const char *> &device_extension_names);
197
198// Helper for checking descriptor_indexing support and adding related extensions.
199bool CheckDescriptorIndexingSupportAndInitFramework(VkRenderFramework *renderFramework,
200 std::vector<const char *> &instance_extension_names,
201 std::vector<const char *> &device_extension_names,
202 VkValidationFeaturesEXT *features, void *userData);
203
204// Dependent "false" type for the static assert, as GCC will evaluate
205// non-dependent static_asserts even for non-instantiated templates
206template <typename T>
207struct AlwaysFalse : std::false_type {};
208
209// Helpers to get nearest greater or smaller value (of float) -- useful for testing the boundary cases of Vulkan limits
210template <typename T>
211T NearestGreater(const T from) {
212 using Lim = std::numeric_limits<T>;
213 const auto positive_direction = Lim::has_infinity ? Lim::infinity() : Lim::max();
214
215 return std::nextafter(from, positive_direction);
216}
217
218template <typename T>
219T NearestSmaller(const T from) {
220 using Lim = std::numeric_limits<T>;
221 const auto negative_direction = Lim::has_infinity ? -Lim::infinity() : Lim::lowest();
222
223 return std::nextafter(from, negative_direction);
224}
225
226// ErrorMonitor Usage:
227//
228// Call SetDesiredFailureMsg with a string to be compared against all
229// encountered log messages, or a validation error enum identifying
230// desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM
231// will match all log messages. logMsg will return true for skipCall
232// only if msg is matched or NULL.
233//
234// Call VerifyFound to determine if all desired failure messages
235// were encountered. Call VerifyNotFound to determine if any unexpected
236// failure was encountered.
237class ErrorMonitor {
238 public:
239 ErrorMonitor();
240
241 ~ErrorMonitor();
242
243 // Set monitor to pristine state
244 void Reset();
245
246 // ErrorMonitor will look for an error message containing the specified string(s)
247 void SetDesiredFailureMsg(const VkFlags msgFlags, const std::string msg);
248 void SetDesiredFailureMsg(const VkFlags msgFlags, const char *const msgString);
249
250 // ErrorMonitor will look for an error message containing the specified string(s)
251 template <typename Iter>
252 void SetDesiredFailureMsg(const VkFlags msgFlags, Iter iter, const Iter end) {
253 for (; iter != end; ++iter) {
254 SetDesiredFailureMsg(msgFlags, *iter);
255 }
256 }
257
258 // Set an error that the error monitor will ignore. Do not use this function if you are creating a new test.
259 // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
260 // function and its definition.
261 void SetUnexpectedError(const char *const msg);
262
263 VkBool32 CheckForDesiredMsg(const char *const msgString);
264 vector<string> GetOtherFailureMsgs() const;
265 VkDebugReportFlagsEXT GetMessageFlags() const;
266 bool AnyDesiredMsgFound() const;
267 bool AllDesiredMsgsFound() const;
268 void SetError(const char *const errorString);
269 void SetBailout(bool *bailout);
270 void DumpFailureMsgs() const;
271
272 // Helpers
273
274 // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags
275 void ExpectSuccess(VkDebugReportFlagsEXT const message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT);
276
277 void VerifyFound();
278 void VerifyNotFound();
279
280 private:
281 // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
282 // function and its definition.
283 bool IgnoreMessage(std::string const &msg) const;
284
285 VkFlags message_flags_;
286 std::unordered_multiset<std::string> desired_message_strings_;
287 std::unordered_multiset<std::string> failure_message_strings_;
288 std::vector<std::string> ignore_message_strings_;
289 vector<string> other_messages_;
290 test_platform_thread_mutex mutex_;
291 bool *bailout_;
292 bool message_found_;
293};
294
295class VkLayerTest : public VkRenderFramework {
296 public:
297 void VKTriangleTest(BsoFailSelect failCase);
298
299 void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet,
300 BsoFailSelect failCase);
301
302 void Init(VkPhysicalDeviceFeatures *features = nullptr, VkPhysicalDeviceFeatures2 *features2 = nullptr,
303 const VkCommandPoolCreateFlags flags = 0, void *instance_pnext = nullptr);
unknown015fc342019-06-21 16:49:43 -0600304 bool AddSurfaceInstanceExtension();
305 bool AddSwapchainDeviceExtension();
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600306 ErrorMonitor *Monitor();
307 VkCommandBufferObj *CommandBuffer();
308
309 protected:
310 ErrorMonitor *m_errorMonitor;
311 uint32_t m_instance_api_version = 0;
312 uint32_t m_target_api_version = 0;
313 bool m_enableWSI;
Petr Kraus0ffd7a52019-03-25 01:14:05 +0100314
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600315 uint32_t SetTargetApiVersion(uint32_t target_api_version);
316 uint32_t DeviceValidationVersion();
317 bool LoadDeviceProfileLayer(
318 PFN_vkSetPhysicalDeviceFormatPropertiesEXT &fpvkSetPhysicalDeviceFormatPropertiesEXT,
319 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT &fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT);
Petr Kraus0ffd7a52019-03-25 01:14:05 +0100320
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600321 VkLayerTest();
Petr Kraus0ffd7a52019-03-25 01:14:05 +0100322 ~VkLayerTest();
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600323};
324
325class VkPositiveLayerTest : public VkLayerTest {
326 public:
327 protected:
328};
329
330class VkWsiEnabledLayerTest : public VkLayerTest {
331 public:
332 protected:
333 VkWsiEnabledLayerTest() { m_enableWSI = true; }
334};
335
336class VkBufferTest {
337 public:
338 enum eTestEnFlags {
339 eDoubleDelete,
340 eInvalidDeviceOffset,
341 eInvalidMemoryOffset,
342 eBindNullBuffer,
343 eBindFakeBuffer,
344 eFreeInvalidHandle,
345 eNone,
346 };
347
348 enum eTestConditions { eOffsetAlignment = 1 };
349
350 static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0);
351 // A constructor which performs validation tests within construction.
352 VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone);
353 ~VkBufferTest();
354 bool GetBufferCurrent();
355 const VkBuffer &GetBuffer();
356 void TestDoubleDestroy();
357
358 protected:
359 bool AllocateCurrent;
360 bool BoundCurrent;
361 bool CreateCurrent;
362 bool InvalidDeleteEn;
363
364 VkBuffer VulkanBuffer;
365 VkDevice VulkanDevice;
366 VkDeviceMemory VulkanMemory;
367};
368
unknown11b2e802019-06-03 11:47:40 -0600369struct CreatePipelineHelper;
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600370class VkVerticesObj {
371 public:
372 VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride,
373 VkDeviceSize aVertexCount, const float *aVerticies);
374 ~VkVerticesObj();
375 bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj);
unknown11b2e802019-06-03 11:47:40 -0600376 bool AddVertexInputToPipeHelpr(CreatePipelineHelper *pipelineHelper);
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600377 void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr);
378
379 protected:
380 static uint32_t BindIdGenerator;
381
382 bool BoundCurrent;
383 unsigned AttributeCount;
384 unsigned BindingCount;
385 uint32_t BindId;
386
387 VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo;
388 VkVertexInputAttributeDescription *VertexInputAttributeDescription;
389 VkVertexInputBindingDescription *VertexInputBindingDescription;
390 VkConstantBufferObj VulkanMemoryBuffer;
391};
392
393struct OneOffDescriptorSet {
394 VkDeviceObj *device_;
395 VkDescriptorPool pool_;
396 VkDescriptorSetLayoutObj layout_;
397 VkDescriptorSet set_;
398 typedef std::vector<VkDescriptorSetLayoutBinding> Bindings;
unknown11b2e802019-06-03 11:47:40 -0600399 std::vector<VkDescriptorBufferInfo> buffer_infos;
400 std::vector<VkDescriptorImageInfo> image_infos;
401 std::vector<VkWriteDescriptorSet> descriptor_writes;
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600402
403 OneOffDescriptorSet(VkDeviceObj *device, const Bindings &bindings, VkDescriptorSetLayoutCreateFlags layout_flags = 0,
404 void *layout_pnext = NULL, VkDescriptorPoolCreateFlags poolFlags = 0, void *allocate_pnext = NULL);
405 ~OneOffDescriptorSet();
406 bool Initialized();
locke-lunarg22d73992019-06-13 18:04:56 -0600407 void WriteDescriptorBufferInfo(int blinding, VkBuffer buffer, VkDeviceSize size,
408 VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
unknown11b2e802019-06-03 11:47:40 -0600409 void WriteDescriptorBufferView(int blinding, VkBufferView &buffer_view,
410 VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
locke-lunarg22d73992019-06-13 18:04:56 -0600411 void WriteDescriptorImageInfo(int blinding, VkImageView image_view, VkSampler sampler,
412 VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
unknown11b2e802019-06-03 11:47:40 -0600413 void UpdateDescriptorSets();
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600414};
415
416template <typename T>
417bool IsValidVkStruct(const T &s) {
418 return LvlTypeMap<T>::kSType == s.sType;
419}
420
421// Helper class for tersely creating create pipeline tests
422//
423// Designed with minimal error checking to ensure easy error state creation
424// See OneshotTest for typical usage
425struct CreatePipelineHelper {
426 public:
427 std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_;
428 std::unique_ptr<OneOffDescriptorSet> descriptor_set_;
429 std::vector<VkPipelineShaderStageCreateInfo> shader_stages_;
430 VkPipelineVertexInputStateCreateInfo vi_ci_ = {};
431 VkPipelineInputAssemblyStateCreateInfo ia_ci_ = {};
432 VkPipelineTessellationStateCreateInfo tess_ci_ = {};
433 VkViewport viewport_ = {};
434 VkRect2D scissor_ = {};
435 VkPipelineViewportStateCreateInfo vp_state_ci_ = {};
436 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci_ = {};
437 VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {};
438 VkPipelineLayoutObj pipeline_layout_;
439 VkPipelineDynamicStateCreateInfo dyn_state_ci_ = {};
440 VkPipelineRasterizationStateCreateInfo rs_state_ci_ = {};
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500441 VkPipelineRasterizationLineStateCreateInfoEXT line_state_ci_ = {};
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600442 VkPipelineColorBlendAttachmentState cb_attachments_ = {};
443 VkPipelineColorBlendStateCreateInfo cb_ci_ = {};
444 VkGraphicsPipelineCreateInfo gp_ci_ = {};
445 VkPipelineCacheCreateInfo pc_ci_ = {};
446 VkPipeline pipeline_ = VK_NULL_HANDLE;
447 VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE;
448 std::unique_ptr<VkShaderObj> vs_;
449 std::unique_ptr<VkShaderObj> fs_;
450 VkLayerTest &layer_test_;
451 CreatePipelineHelper(VkLayerTest &test);
452 ~CreatePipelineHelper();
453
454 void InitDescriptorSetInfo();
455 void InitInputAndVertexInfo();
456 void InitMultisampleInfo();
457 void InitPipelineLayoutInfo();
458 void InitViewportInfo();
459 void InitDynamicStateInfo();
460 void InitShaderInfo();
461 void InitRasterizationInfo();
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500462 void InitLineRasterizationInfo();
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600463 void InitBlendStateInfo();
464 void InitGraphicsPipelineInfo();
465 void InitPipelineCacheInfo();
466
467 // Not called by default during init_info
468 void InitTesselationState();
469
470 // TDB -- add control for optional and/or additional initialization
471 void InitInfo();
472 void InitState();
473 void LateBindPipelineInfo();
474 VkResult CreateGraphicsPipeline(bool implicit_destroy = true, bool do_late_bind = true);
475
476 // Helper function to create a simple test case (positive or negative)
477 //
478 // info_override can be any callable that takes a CreatePipelineHeper &
479 // flags, error can be any args accepted by "SetDesiredFailure".
480 template <typename Test, typename OverrideFunc, typename Error>
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500481 static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600482 bool positive_test = false) {
483 CreatePipelineHelper helper(test);
484 helper.InitInfo();
485 info_override(helper);
486 helper.InitState();
487
488 for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error);
489 helper.CreateGraphicsPipeline();
490
491 if (positive_test) {
492 test.Monitor()->VerifyNotFound();
493 } else {
494 test.Monitor()->VerifyFound();
495 }
496 }
497
498 template <typename Test, typename OverrideFunc, typename Error>
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500499 static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, Error error,
500 bool positive_test = false) {
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600501 OneshotTest(test, info_override, flags, std::vector<Error>(1, error), positive_test);
502 }
503};
504
unknown11b2e802019-06-03 11:47:40 -0600505struct CreateComputePipelineHelper {
506 public:
507 std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_;
508 std::unique_ptr<OneOffDescriptorSet> descriptor_set_;
509 VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {};
510 VkPipelineLayoutObj pipeline_layout_;
511 VkComputePipelineCreateInfo cp_ci_ = {};
512 VkPipelineCacheCreateInfo pc_ci_ = {};
513 VkPipeline pipeline_ = VK_NULL_HANDLE;
514 VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE;
515 std::unique_ptr<VkShaderObj> cs_;
516 VkLayerTest &layer_test_;
517 CreateComputePipelineHelper(VkLayerTest &test);
518 ~CreateComputePipelineHelper();
519
520 void InitDescriptorSetInfo();
521 void InitPipelineLayoutInfo();
522 void InitShaderInfo();
523 void InitComputePipelineInfo();
524 void InitPipelineCacheInfo();
525
526 // TDB -- add control for optional and/or additional initialization
527 void InitInfo();
528 void InitState();
529 void LateBindPipelineInfo();
530 VkResult CreateComputePipeline(bool implicit_destroy = true, bool do_late_bind = true);
531
532 // Helper function to create a simple test case (positive or negative)
533 //
534 // info_override can be any callable that takes a CreatePipelineHeper &
535 // flags, error can be any args accepted by "SetDesiredFailure".
536 template <typename Test, typename OverrideFunc, typename Error>
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500537 static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
unknown11b2e802019-06-03 11:47:40 -0600538 bool positive_test = false) {
539 CreateComputePipelineHelper helper(test);
540 helper.InitInfo();
541 info_override(helper);
542 helper.InitState();
543
544 for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error);
545 helper.CreateComputePipeline();
546
547 if (positive_test) {
548 test.Monitor()->VerifyNotFound();
549 } else {
550 test.Monitor()->VerifyFound();
551 }
552 }
553
554 template <typename Test, typename OverrideFunc, typename Error>
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500555 static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, Error error,
556 bool positive_test = false) {
unknown11b2e802019-06-03 11:47:40 -0600557 OneshotTest(test, info_override, flags, std::vector<Error>(1, error), positive_test);
558 }
559};
560
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600561// Helper class for tersely creating create ray tracing pipeline tests
562//
563// Designed with minimal error checking to ensure easy error state creation
564// See OneshotTest for typical usage
565struct CreateNVRayTracingPipelineHelper {
566 public:
567 std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_;
568 std::unique_ptr<OneOffDescriptorSet> descriptor_set_;
569 std::vector<VkPipelineShaderStageCreateInfo> shader_stages_;
570 VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {};
571 VkPipelineLayoutObj pipeline_layout_;
572 VkRayTracingPipelineCreateInfoNV rp_ci_ = {};
573 VkPipelineCacheCreateInfo pc_ci_ = {};
574 VkPipeline pipeline_ = VK_NULL_HANDLE;
575 VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE;
576 std::vector<VkRayTracingShaderGroupCreateInfoNV> groups_;
577 std::unique_ptr<VkShaderObj> rgs_;
578 std::unique_ptr<VkShaderObj> chs_;
579 std::unique_ptr<VkShaderObj> mis_;
580 VkLayerTest &layer_test_;
581 CreateNVRayTracingPipelineHelper(VkLayerTest &test);
582 ~CreateNVRayTracingPipelineHelper();
583
584 static bool InitInstanceExtensions(VkLayerTest &test, std::vector<const char *> &instance_extension_names);
585 static bool InitDeviceExtensions(VkLayerTest &test, std::vector<const char *> &device_extension_names);
586 void InitShaderGroups();
587 void InitDescriptorSetInfo();
588 void InitPipelineLayoutInfo();
589 void InitShaderInfo();
590 void InitNVRayTracingPipelineInfo();
591 void InitPipelineCacheInfo();
592 void InitInfo();
593 void InitState();
594 void LateBindPipelineInfo();
595 VkResult CreateNVRayTracingPipeline(bool implicit_destroy = true, bool do_late_bind = true);
596
597 // Helper function to create a simple test case (positive or negative)
598 //
599 // info_override can be any callable that takes a CreateNVRayTracingPipelineHelper &
600 // flags, error can be any args accepted by "SetDesiredFailure".
601 template <typename Test, typename OverrideFunc, typename Error>
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500602 static void OneshotTest(Test &test, const OverrideFunc &info_override, const std::vector<Error> &errors,
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600603 const VkFlags flags = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
604 CreateNVRayTracingPipelineHelper helper(test);
605 helper.InitInfo();
606 info_override(helper);
607 helper.InitState();
608
609 for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error);
610 helper.CreateNVRayTracingPipeline();
611 test.Monitor()->VerifyFound();
612 }
613
614 template <typename Test, typename OverrideFunc, typename Error>
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500615 static void OneshotTest(Test &test, const OverrideFunc &info_override, Error error,
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600616 const VkFlags flags = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
617 OneshotTest(test, info_override, std::vector<Error>(1, error), flags);
618 }
619
620 template <typename Test, typename OverrideFunc>
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500621 static void OneshotPositiveTest(Test &test, const OverrideFunc &info_override,
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600622 const VkDebugReportFlagsEXT message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
623 CreateNVRayTracingPipelineHelper helper(test);
624 helper.InitInfo();
625 info_override(helper);
626 helper.InitState();
627
628 test.Monitor()->ExpectSuccess(message_flag_mask);
629 ASSERT_VK_SUCCESS(helper.CreateNVRayTracingPipeline());
630 test.Monitor()->VerifyNotFound();
631 }
632};
633
634namespace chain_util {
635template <typename T>
636T Init(const void *pnext_in = nullptr) {
637 T pnext_obj = {};
638 pnext_obj.sType = LvlTypeMap<T>::kSType;
639 pnext_obj.pNext = pnext_in;
640 return pnext_obj;
641}
642
643class ExtensionChain {
644 const void *head_ = nullptr;
645 typedef std::function<bool(const char *)> AddIfFunction;
646 AddIfFunction add_if_;
647 typedef std::vector<const char *> List;
648 List *list_;
649
650 public:
651 template <typename F>
652 ExtensionChain(F &add_if, List *list) : add_if_(add_if), list_(list) {}
653
654 template <typename T>
655 void Add(const char *name, T &obj) {
656 if (add_if_(name)) {
657 if (list_) {
658 list_->push_back(name);
659 }
660 obj.pNext = head_;
661 head_ = &obj;
662 }
663 }
664
665 const void *Head() const;
666};
667} // namespace chain_util
668
669// PushDescriptorProperties helper
670VkPhysicalDevicePushDescriptorPropertiesKHR GetPushDescriptorProperties(VkInstance instance, VkPhysicalDevice gpu);
671
Jeff Bolz14b005f2019-06-20 22:24:45 -0500672// Subgroup properties helper
673VkPhysicalDeviceSubgroupProperties GetSubgroupProperties(VkInstance instance, VkPhysicalDevice gpu);
674
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600675class BarrierQueueFamilyTestHelper {
676 public:
677 struct QueueFamilyObjs {
678 uint32_t index;
679 // We would use std::unique_ptr, but this triggers a compiler error on older compilers
680 VkQueueObj *queue = nullptr;
681 VkCommandPoolObj *command_pool = nullptr;
682 VkCommandBufferObj *command_buffer = nullptr;
683 VkCommandBufferObj *command_buffer2 = nullptr;
684 ~QueueFamilyObjs();
685 void Init(VkDeviceObj *device, uint32_t qf_index, VkQueue qf_queue, VkCommandPoolCreateFlags cp_flags);
686 };
687
688 struct Context {
689 VkLayerTest *layer_test;
690 uint32_t default_index;
691 std::unordered_map<uint32_t, QueueFamilyObjs> queue_families;
692 Context(VkLayerTest *test, const std::vector<uint32_t> &queue_family_indices);
693 void Reset();
694 };
695
696 BarrierQueueFamilyTestHelper(Context *context);
697 // Init with queue families non-null for CONCURRENT sharing mode (which requires them)
unknown11b2e802019-06-03 11:47:40 -0600698 void Init(std::vector<uint32_t> *families, bool image_memory = true, bool buffer_memory = true);
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600699
700 QueueFamilyObjs *GetQueueFamilyInfo(Context *context, uint32_t qfi);
701
702 enum Modifier {
703 NONE,
704 DOUBLE_RECORD,
705 DOUBLE_COMMAND_BUFFER,
706 };
707
unknown11b2e802019-06-03 11:47:40 -0600708 void operator()(std::string img_err, std::string buf_err = "", uint32_t src = VK_QUEUE_FAMILY_IGNORED,
709 uint32_t dst = VK_QUEUE_FAMILY_IGNORED, bool positive = false,
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600710 uint32_t queue_family_index = kInvalidQueueFamily, Modifier mod = Modifier::NONE);
711
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600712 static const uint32_t kInvalidQueueFamily = UINT32_MAX;
713 Context *context_;
714 VkImageObj image_;
715 VkImageMemoryBarrier image_barrier_;
716 VkBufferObj buffer_;
717 VkBufferMemoryBarrier buffer_barrier_;
718};
719
720struct DebugUtilsLabelCheckData {
721 std::function<void(const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, DebugUtilsLabelCheckData *)> callback;
722 size_t count;
723};
724
725bool operator==(const VkDebugUtilsLabelEXT &rhs, const VkDebugUtilsLabelEXT &lhs);
726
727VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
728 VkDebugUtilsMessageTypeFlagsEXT messageTypes,
729 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData);
730
731#if GTEST_IS_THREADSAFE
732struct thread_data_struct {
733 VkCommandBuffer commandBuffer;
734 VkDevice device;
735 VkEvent event;
736 bool bailout;
737};
738
739extern "C" void *AddToCommandBuffer(void *arg);
740#endif // GTEST_IS_THREADSAFE
741
742extern "C" void *ReleaseNullFence(void *arg);
743
744void TestRenderPassCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo *create_info,
Petr Kraus8780ed32019-07-10 02:39:58 +0200745 bool rp2_supported, const char *rp1_vuid, const char *rp2_vuid);
746void PositiveTestRenderPassCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo *create_info,
747 bool rp2_supported);
locke-lunarg7301ada2019-06-11 17:52:54 -0600748void TestRenderPass2KHRCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo2KHR *create_info,
749 const char *rp2_vuid);
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600750void TestRenderPassBegin(ErrorMonitor *error_monitor, const VkDevice device, const VkCommandBuffer command_buffer,
751 const VkRenderPassBeginInfo *begin_info, bool rp2Supported, const char *rp1_vuid, const char *rp2_vuid);
752
753// Helpers for the tests below
754void ValidOwnershipTransferOp(ErrorMonitor *monitor, VkCommandBufferObj *cb, VkPipelineStageFlags src_stages,
755 VkPipelineStageFlags dst_stages, const VkBufferMemoryBarrier *buf_barrier,
756 const VkImageMemoryBarrier *img_barrier);
757
758void ValidOwnershipTransfer(ErrorMonitor *monitor, VkCommandBufferObj *cb_from, VkCommandBufferObj *cb_to,
759 VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages,
760 const VkBufferMemoryBarrier *buf_barrier, const VkImageMemoryBarrier *img_barrier);
761
762VkResult GPDIFPHelper(VkPhysicalDevice dev, const VkImageCreateInfo *ci, VkImageFormatProperties *limits = nullptr);
763
764VkFormat FindFormatLinearWithoutMips(VkPhysicalDevice gpu, VkImageCreateInfo image_ci);
765
766bool FindFormatWithoutSamples(VkPhysicalDevice gpu, VkImageCreateInfo &image_ci);
767
768bool FindUnsupportedImage(VkPhysicalDevice gpu, VkImageCreateInfo &image_ci);
769
770VkFormat FindFormatWithoutFeatures(VkPhysicalDevice gpu, VkImageTiling tiling,
771 VkFormatFeatureFlags undesired_features = UINT32_MAX);
772
773void NegHeightViewportTests(VkDeviceObj *m_device, VkCommandBufferObj *m_commandBuffer, ErrorMonitor *m_errorMonitor);
774
unknown11b2e802019-06-03 11:47:40 -0600775void CreateSamplerTest(VkLayerTest &test, const VkSamplerCreateInfo *pCreateInfo, std::string code = "");
776
777void CreateBufferTest(VkLayerTest &test, const VkBufferCreateInfo *pCreateInfo, std::string code = "");
778
779void CreateImageTest(VkLayerTest &test, const VkImageCreateInfo *pCreateInfo, std::string code = "");
780
Jeff Bolz83166712019-07-19 13:24:03 -0500781void CreateBufferViewTest(VkLayerTest &test, const VkBufferViewCreateInfo *pCreateInfo, const std::vector<std::string> &codes);
unknown11b2e802019-06-03 11:47:40 -0600782
783void CreateImageViewTest(VkLayerTest &test, const VkImageViewCreateInfo *pCreateInfo, std::string code = "");
784
林昆毅 Kunyi(Locke) Lin7fa7d062019-06-10 20:36:29 -0600785void print_android(const char *c);
locke-luanrgd1e66ea2019-05-15 22:50:35 -0600786#endif // VKLAYERTEST_H