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