/* * Copyright (c) 2015-2019 The Khronos Group Inc. * Copyright (c) 2015-2019 Valve Corporation * Copyright (c) 2015-2019 LunarG, Inc. * Copyright (c) 2015-2019 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Author: Chia-I Wu * Author: Chris Forbes * Author: Courtney Goeltzenleuchter * Author: Mark Lobodzinski * Author: Mike Stroyan * Author: Tobin Ehlis * Author: Tony Barbour * Author: Cody Northrop * Author: Dave Houlton * Author: Jeremy Kniager * Author: Shannon McPherson * Author: John Zulauf */ #ifndef VKLAYERTEST_H #define VKLAYERTEST_H #ifdef ANDROID #include "vulkan_wrapper.h" #else #define NOMINMAX #include #endif #include "layers/vk_device_profile_api_layer.h" #if defined(ANDROID) #include #if defined(VALIDATION_APK) #include #endif #endif #include "icd-spv.h" #include "test_common.h" #include "vk_layer_config.h" #include "vk_format_utils.h" #include "vkrenderframework.h" #include "vk_typemap_helper.h" #include "convert_to_renderpass2.h" #include #include #include #include #include #include //-------------------------------------------------------------------------------------- // Mesh and VertexFormat Data //-------------------------------------------------------------------------------------- static const char kSkipPrefix[] = " TEST SKIPPED:"; enum BsoFailSelect { BsoFailNone, BsoFailLineWidth, BsoFailDepthBias, BsoFailViewport, BsoFailScissor, BsoFailBlend, BsoFailDepthBounds, BsoFailStencilReadMask, BsoFailStencilWriteMask, BsoFailStencilReference, BsoFailCmdClearAttachments, BsoFailIndexBuffer, BsoFailIndexBufferBadSize, BsoFailIndexBufferBadOffset, BsoFailIndexBufferBadMapSize, BsoFailIndexBufferBadMapOffset, BsoFailLineStipple, }; static const char bindStateMinimalShaderText[] = "#version 450\nvoid main() {}\n"; static const char bindStateVertShaderText[] = "#version 450\n" "void main() {\n" " gl_Position = vec4(1);\n" "}\n"; static const char bindStateVertPointSizeShaderText[] = "#version 450\n" "out gl_PerVertex {\n" " vec4 gl_Position;\n" " float gl_PointSize;\n" "};\n" "void main() {\n" " gl_Position = vec4(1);\n" " gl_PointSize = 1.0;\n" "}\n"; static char const bindStateGeomShaderText[] = "#version 450\n" "layout(triangles) in;\n" "layout(triangle_strip, max_vertices=3) out;\n" "void main() {\n" " gl_Position = vec4(1);\n" " EmitVertex();\n" "}\n"; static char const bindStateGeomPointSizeShaderText[] = "#version 450\n" "layout (points) in;\n" "layout (points) out;\n" "layout (max_vertices = 1) out;\n" "void main() {\n" " gl_Position = vec4(1);\n" " gl_PointSize = 1.0;\n" " EmitVertex();\n" "}\n"; static const char bindStateTscShaderText[] = "#version 450\n" "layout(vertices=3) out;\n" "void main() {\n" " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n" " gl_TessLevelInner[0] = 1;\n" "}\n"; static const char bindStateTeshaderText[] = "#version 450\n" "layout(triangles, equal_spacing, cw) in;\n" "void main() { gl_Position = vec4(1); }\n"; static const char bindStateFragShaderText[] = "#version 450\n" "layout(location = 0) out vec4 uFragColor;\n" "void main(){\n" " uFragColor = vec4(0,1,0,1);\n" "}\n"; static const char bindStateFragSamplerShaderText[] = "#version 450\n" "layout(set=0, binding=0) uniform sampler2D s;\n" "layout(location=0) out vec4 x;\n" "void main(){\n" " x = texture(s, vec2(1));\n" "}\n"; static const char bindStateFragUniformShaderText[] = "#version 450\n" "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" "layout(location=0) out vec4 x;\n" "void main(){\n" " x = vec4(bar.y);\n" "}\n"; // Static arrays helper template size_t size(ElementT (&)[array_size]) { return array_size; } // Format search helper VkFormat FindSupportedDepthStencilFormat(VkPhysicalDevice phy); // Returns true if *any* requested features are available. // Assumption is that the framework can successfully create an image as // long as at least one of the feature bits is present (excepting VTX_BUF). bool ImageFormatIsSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL, VkFormatFeatureFlags features = ~VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT); // Returns true if format and *all* requested features are available. bool ImageFormatAndFeaturesSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling, VkFormatFeatureFlags features); // Returns true if format and *all* requested features are available. bool ImageFormatAndFeaturesSupported(const VkInstance inst, const VkPhysicalDevice phy, const VkImageCreateInfo info, const VkFormatFeatureFlags features); // Validation report callback prototype VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, void *pUserData); // Simple sane SamplerCreateInfo boilerplate VkSamplerCreateInfo SafeSaneSamplerCreateInfo(); VkImageViewCreateInfo SafeSaneImageViewCreateInfo(VkImage image, VkFormat format, VkImageAspectFlags aspect_mask); VkImageViewCreateInfo SafeSaneImageViewCreateInfo(const VkImageObj &image, VkFormat format, VkImageAspectFlags aspect_mask); // Helper for checking createRenderPass2 support and adding related extensions. bool CheckCreateRenderPass2Support(VkRenderFramework *renderFramework, std::vector &device_extension_names); // Helper for checking descriptor_indexing support and adding related extensions. bool CheckDescriptorIndexingSupportAndInitFramework(VkRenderFramework *renderFramework, std::vector &instance_extension_names, std::vector &device_extension_names, VkValidationFeaturesEXT *features, void *userData); // Dependent "false" type for the static assert, as GCC will evaluate // non-dependent static_asserts even for non-instantiated templates template struct AlwaysFalse : std::false_type {}; // Helpers to get nearest greater or smaller value (of float) -- useful for testing the boundary cases of Vulkan limits template T NearestGreater(const T from) { using Lim = std::numeric_limits; const auto positive_direction = Lim::has_infinity ? Lim::infinity() : Lim::max(); return std::nextafter(from, positive_direction); } template T NearestSmaller(const T from) { using Lim = std::numeric_limits; const auto negative_direction = Lim::has_infinity ? -Lim::infinity() : Lim::lowest(); return std::nextafter(from, negative_direction); } // ErrorMonitor Usage: // // Call SetDesiredFailureMsg with a string to be compared against all // encountered log messages, or a validation error enum identifying // desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM // will match all log messages. logMsg will return true for skipCall // only if msg is matched or NULL. // // Call VerifyFound to determine if all desired failure messages // were encountered. Call VerifyNotFound to determine if any unexpected // failure was encountered. class ErrorMonitor { public: ErrorMonitor(); ~ErrorMonitor(); // Set monitor to pristine state void Reset(); // ErrorMonitor will look for an error message containing the specified string(s) void SetDesiredFailureMsg(const VkFlags msgFlags, const std::string msg); void SetDesiredFailureMsg(const VkFlags msgFlags, const char *const msgString); // ErrorMonitor will look for an error message containing the specified string(s) template void SetDesiredFailureMsg(const VkFlags msgFlags, Iter iter, const Iter end) { for (; iter != end; ++iter) { SetDesiredFailureMsg(msgFlags, *iter); } } // Set an error that the error monitor will ignore. Do not use this function if you are creating a new test. // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this // function and its definition. void SetUnexpectedError(const char *const msg); VkBool32 CheckForDesiredMsg(const char *const msgString); vector GetOtherFailureMsgs() const; VkDebugReportFlagsEXT GetMessageFlags() const; bool AnyDesiredMsgFound() const; bool AllDesiredMsgsFound() const; void SetError(const char *const errorString); void SetBailout(bool *bailout); void DumpFailureMsgs() const; // Helpers // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags void ExpectSuccess(VkDebugReportFlagsEXT const message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT); void VerifyFound(); void VerifyNotFound(); private: // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this // function and its definition. bool IgnoreMessage(std::string const &msg) const; VkFlags message_flags_; std::unordered_multiset desired_message_strings_; std::unordered_multiset failure_message_strings_; std::vector ignore_message_strings_; vector other_messages_; test_platform_thread_mutex mutex_; bool *bailout_; bool message_found_; }; class VkLayerTest : public VkRenderFramework { public: void VKTriangleTest(BsoFailSelect failCase); void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failCase); void Init(VkPhysicalDeviceFeatures *features = nullptr, VkPhysicalDeviceFeatures2 *features2 = nullptr, const VkCommandPoolCreateFlags flags = 0, void *instance_pnext = nullptr); bool AddSurfaceInstanceExtension(); bool AddSwapchainDeviceExtension(); ErrorMonitor *Monitor(); VkCommandBufferObj *CommandBuffer(); protected: ErrorMonitor *m_errorMonitor; uint32_t m_instance_api_version = 0; uint32_t m_target_api_version = 0; bool m_enableWSI; uint32_t SetTargetApiVersion(uint32_t target_api_version); uint32_t DeviceValidationVersion(); bool LoadDeviceProfileLayer( PFN_vkSetPhysicalDeviceFormatPropertiesEXT &fpvkSetPhysicalDeviceFormatPropertiesEXT, PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT &fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT); VkLayerTest(); ~VkLayerTest(); }; class VkPositiveLayerTest : public VkLayerTest { public: protected: }; class VkWsiEnabledLayerTest : public VkLayerTest { public: protected: VkWsiEnabledLayerTest() { m_enableWSI = true; } }; class VkBufferTest { public: enum eTestEnFlags { eDoubleDelete, eInvalidDeviceOffset, eInvalidMemoryOffset, eBindNullBuffer, eBindFakeBuffer, eFreeInvalidHandle, eNone, }; enum eTestConditions { eOffsetAlignment = 1 }; static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0); // A constructor which performs validation tests within construction. VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone); ~VkBufferTest(); bool GetBufferCurrent(); const VkBuffer &GetBuffer(); void TestDoubleDestroy(); protected: bool AllocateCurrent; bool BoundCurrent; bool CreateCurrent; bool InvalidDeleteEn; VkBuffer VulkanBuffer; VkDevice VulkanDevice; VkDeviceMemory VulkanMemory; }; struct CreatePipelineHelper; class VkVerticesObj { public: VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride, VkDeviceSize aVertexCount, const float *aVerticies); ~VkVerticesObj(); bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj); bool AddVertexInputToPipeHelpr(CreatePipelineHelper *pipelineHelper); void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr); protected: static uint32_t BindIdGenerator; bool BoundCurrent; unsigned AttributeCount; unsigned BindingCount; uint32_t BindId; VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo; VkVertexInputAttributeDescription *VertexInputAttributeDescription; VkVertexInputBindingDescription *VertexInputBindingDescription; VkConstantBufferObj VulkanMemoryBuffer; }; struct OneOffDescriptorSet { VkDeviceObj *device_; VkDescriptorPool pool_; VkDescriptorSetLayoutObj layout_; VkDescriptorSet set_; typedef std::vector Bindings; std::vector buffer_infos; std::vector image_infos; std::vector descriptor_writes; OneOffDescriptorSet(VkDeviceObj *device, const Bindings &bindings, VkDescriptorSetLayoutCreateFlags layout_flags = 0, void *layout_pnext = NULL, VkDescriptorPoolCreateFlags poolFlags = 0, void *allocate_pnext = NULL); ~OneOffDescriptorSet(); bool Initialized(); void WriteDescriptorBufferInfo(int blinding, VkBuffer buffer, VkDeviceSize size, VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); void WriteDescriptorBufferView(int blinding, VkBufferView &buffer_view, VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER); void WriteDescriptorImageInfo(int blinding, VkImageView image_view, VkSampler sampler, VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); void UpdateDescriptorSets(); }; template bool IsValidVkStruct(const T &s) { return LvlTypeMap::kSType == s.sType; } // Helper class for tersely creating create pipeline tests // // Designed with minimal error checking to ensure easy error state creation // See OneshotTest for typical usage struct CreatePipelineHelper { public: std::vector dsl_bindings_; std::unique_ptr descriptor_set_; std::vector shader_stages_; VkPipelineVertexInputStateCreateInfo vi_ci_ = {}; VkPipelineInputAssemblyStateCreateInfo ia_ci_ = {}; VkPipelineTessellationStateCreateInfo tess_ci_ = {}; VkViewport viewport_ = {}; VkRect2D scissor_ = {}; VkPipelineViewportStateCreateInfo vp_state_ci_ = {}; VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci_ = {}; VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {}; VkPipelineLayoutObj pipeline_layout_; VkPipelineDynamicStateCreateInfo dyn_state_ci_ = {}; VkPipelineRasterizationStateCreateInfo rs_state_ci_ = {}; VkPipelineRasterizationLineStateCreateInfoEXT line_state_ci_ = {}; VkPipelineColorBlendAttachmentState cb_attachments_ = {}; VkPipelineColorBlendStateCreateInfo cb_ci_ = {}; VkGraphicsPipelineCreateInfo gp_ci_ = {}; VkPipelineCacheCreateInfo pc_ci_ = {}; VkPipeline pipeline_ = VK_NULL_HANDLE; VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE; std::unique_ptr vs_; std::unique_ptr fs_; VkLayerTest &layer_test_; CreatePipelineHelper(VkLayerTest &test); ~CreatePipelineHelper(); void InitDescriptorSetInfo(); void InitInputAndVertexInfo(); void InitMultisampleInfo(); void InitPipelineLayoutInfo(); void InitViewportInfo(); void InitDynamicStateInfo(); void InitShaderInfo(); void InitRasterizationInfo(); void InitLineRasterizationInfo(); void InitBlendStateInfo(); void InitGraphicsPipelineInfo(); void InitPipelineCacheInfo(); // Not called by default during init_info void InitTesselationState(); // TDB -- add control for optional and/or additional initialization void InitInfo(); void InitState(); void LateBindPipelineInfo(); VkResult CreateGraphicsPipeline(bool implicit_destroy = true, bool do_late_bind = true); // Helper function to create a simple test case (positive or negative) // // info_override can be any callable that takes a CreatePipelineHeper & // flags, error can be any args accepted by "SetDesiredFailure". template static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, const std::vector &errors, bool positive_test = false) { CreatePipelineHelper helper(test); helper.InitInfo(); info_override(helper); helper.InitState(); for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error); helper.CreateGraphicsPipeline(); if (positive_test) { test.Monitor()->VerifyNotFound(); } else { test.Monitor()->VerifyFound(); } } template static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) { OneshotTest(test, info_override, flags, std::vector(1, error), positive_test); } }; struct CreateComputePipelineHelper { public: std::vector dsl_bindings_; std::unique_ptr descriptor_set_; VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {}; VkPipelineLayoutObj pipeline_layout_; VkComputePipelineCreateInfo cp_ci_ = {}; VkPipelineCacheCreateInfo pc_ci_ = {}; VkPipeline pipeline_ = VK_NULL_HANDLE; VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE; std::unique_ptr cs_; VkLayerTest &layer_test_; CreateComputePipelineHelper(VkLayerTest &test); ~CreateComputePipelineHelper(); void InitDescriptorSetInfo(); void InitPipelineLayoutInfo(); void InitShaderInfo(); void InitComputePipelineInfo(); void InitPipelineCacheInfo(); // TDB -- add control for optional and/or additional initialization void InitInfo(); void InitState(); void LateBindPipelineInfo(); VkResult CreateComputePipeline(bool implicit_destroy = true, bool do_late_bind = true); // Helper function to create a simple test case (positive or negative) // // info_override can be any callable that takes a CreatePipelineHeper & // flags, error can be any args accepted by "SetDesiredFailure". template static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, const std::vector &errors, bool positive_test = false) { CreateComputePipelineHelper helper(test); helper.InitInfo(); info_override(helper); helper.InitState(); for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error); helper.CreateComputePipeline(); if (positive_test) { test.Monitor()->VerifyNotFound(); } else { test.Monitor()->VerifyFound(); } } template static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) { OneshotTest(test, info_override, flags, std::vector(1, error), positive_test); } }; // Helper class for tersely creating create ray tracing pipeline tests // // Designed with minimal error checking to ensure easy error state creation // See OneshotTest for typical usage struct CreateNVRayTracingPipelineHelper { public: std::vector dsl_bindings_; std::unique_ptr descriptor_set_; std::vector shader_stages_; VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {}; VkPipelineLayoutObj pipeline_layout_; VkRayTracingPipelineCreateInfoNV rp_ci_ = {}; VkPipelineCacheCreateInfo pc_ci_ = {}; VkPipeline pipeline_ = VK_NULL_HANDLE; VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE; std::vector groups_; std::unique_ptr rgs_; std::unique_ptr chs_; std::unique_ptr mis_; VkLayerTest &layer_test_; CreateNVRayTracingPipelineHelper(VkLayerTest &test); ~CreateNVRayTracingPipelineHelper(); static bool InitInstanceExtensions(VkLayerTest &test, std::vector &instance_extension_names); static bool InitDeviceExtensions(VkLayerTest &test, std::vector &device_extension_names); void InitShaderGroups(); void InitDescriptorSetInfo(); void InitPipelineLayoutInfo(); void InitShaderInfo(); void InitNVRayTracingPipelineInfo(); void InitPipelineCacheInfo(); void InitInfo(); void InitState(); void LateBindPipelineInfo(); VkResult CreateNVRayTracingPipeline(bool implicit_destroy = true, bool do_late_bind = true); // Helper function to create a simple test case (positive or negative) // // info_override can be any callable that takes a CreateNVRayTracingPipelineHelper & // flags, error can be any args accepted by "SetDesiredFailure". template static void OneshotTest(Test &test, const OverrideFunc &info_override, const std::vector &errors, const VkFlags flags = VK_DEBUG_REPORT_ERROR_BIT_EXT) { CreateNVRayTracingPipelineHelper helper(test); helper.InitInfo(); info_override(helper); helper.InitState(); for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error); helper.CreateNVRayTracingPipeline(); test.Monitor()->VerifyFound(); } template static void OneshotTest(Test &test, const OverrideFunc &info_override, Error error, const VkFlags flags = VK_DEBUG_REPORT_ERROR_BIT_EXT) { OneshotTest(test, info_override, std::vector(1, error), flags); } template static void OneshotPositiveTest(Test &test, const OverrideFunc &info_override, const VkDebugReportFlagsEXT message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) { CreateNVRayTracingPipelineHelper helper(test); helper.InitInfo(); info_override(helper); helper.InitState(); test.Monitor()->ExpectSuccess(message_flag_mask); ASSERT_VK_SUCCESS(helper.CreateNVRayTracingPipeline()); test.Monitor()->VerifyNotFound(); } }; namespace chain_util { template T Init(const void *pnext_in = nullptr) { T pnext_obj = {}; pnext_obj.sType = LvlTypeMap::kSType; pnext_obj.pNext = pnext_in; return pnext_obj; } class ExtensionChain { const void *head_ = nullptr; typedef std::function AddIfFunction; AddIfFunction add_if_; typedef std::vector List; List *list_; public: template ExtensionChain(F &add_if, List *list) : add_if_(add_if), list_(list) {} template void Add(const char *name, T &obj) { if (add_if_(name)) { if (list_) { list_->push_back(name); } obj.pNext = head_; head_ = &obj; } } const void *Head() const; }; } // namespace chain_util // PushDescriptorProperties helper VkPhysicalDevicePushDescriptorPropertiesKHR GetPushDescriptorProperties(VkInstance instance, VkPhysicalDevice gpu); // Subgroup properties helper VkPhysicalDeviceSubgroupProperties GetSubgroupProperties(VkInstance instance, VkPhysicalDevice gpu); class BarrierQueueFamilyTestHelper { public: struct QueueFamilyObjs { uint32_t index; // We would use std::unique_ptr, but this triggers a compiler error on older compilers VkQueueObj *queue = nullptr; VkCommandPoolObj *command_pool = nullptr; VkCommandBufferObj *command_buffer = nullptr; VkCommandBufferObj *command_buffer2 = nullptr; ~QueueFamilyObjs(); void Init(VkDeviceObj *device, uint32_t qf_index, VkQueue qf_queue, VkCommandPoolCreateFlags cp_flags); }; struct Context { VkLayerTest *layer_test; uint32_t default_index; std::unordered_map queue_families; Context(VkLayerTest *test, const std::vector &queue_family_indices); void Reset(); }; BarrierQueueFamilyTestHelper(Context *context); // Init with queue families non-null for CONCURRENT sharing mode (which requires them) void Init(std::vector *families, bool image_memory = true, bool buffer_memory = true); QueueFamilyObjs *GetQueueFamilyInfo(Context *context, uint32_t qfi); enum Modifier { NONE, DOUBLE_RECORD, DOUBLE_COMMAND_BUFFER, }; void operator()(std::string img_err, std::string buf_err = "", uint32_t src = VK_QUEUE_FAMILY_IGNORED, uint32_t dst = VK_QUEUE_FAMILY_IGNORED, bool positive = false, uint32_t queue_family_index = kInvalidQueueFamily, Modifier mod = Modifier::NONE); static const uint32_t kInvalidQueueFamily = UINT32_MAX; Context *context_; VkImageObj image_; VkImageMemoryBarrier image_barrier_; VkBufferObj buffer_; VkBufferMemoryBarrier buffer_barrier_; }; struct DebugUtilsLabelCheckData { std::function callback; size_t count; }; bool operator==(const VkDebugUtilsLabelEXT &rhs, const VkDebugUtilsLabelEXT &lhs); VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData); #if GTEST_IS_THREADSAFE struct thread_data_struct { VkCommandBuffer commandBuffer; VkDevice device; VkEvent event; bool bailout; }; extern "C" void *AddToCommandBuffer(void *arg); #endif // GTEST_IS_THREADSAFE extern "C" void *ReleaseNullFence(void *arg); void TestRenderPassCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo *create_info, bool rp2_supported, const char *rp1_vuid, const char *rp2_vuid); void PositiveTestRenderPassCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo *create_info, bool rp2_supported); void TestRenderPass2KHRCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo2KHR *create_info, const char *rp2_vuid); void TestRenderPassBegin(ErrorMonitor *error_monitor, const VkDevice device, const VkCommandBuffer command_buffer, const VkRenderPassBeginInfo *begin_info, bool rp2Supported, const char *rp1_vuid, const char *rp2_vuid); // Helpers for the tests below void ValidOwnershipTransferOp(ErrorMonitor *monitor, VkCommandBufferObj *cb, VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages, const VkBufferMemoryBarrier *buf_barrier, const VkImageMemoryBarrier *img_barrier); void ValidOwnershipTransfer(ErrorMonitor *monitor, VkCommandBufferObj *cb_from, VkCommandBufferObj *cb_to, VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages, const VkBufferMemoryBarrier *buf_barrier, const VkImageMemoryBarrier *img_barrier); VkResult GPDIFPHelper(VkPhysicalDevice dev, const VkImageCreateInfo *ci, VkImageFormatProperties *limits = nullptr); VkFormat FindFormatLinearWithoutMips(VkPhysicalDevice gpu, VkImageCreateInfo image_ci); bool FindFormatWithoutSamples(VkPhysicalDevice gpu, VkImageCreateInfo &image_ci); bool FindUnsupportedImage(VkPhysicalDevice gpu, VkImageCreateInfo &image_ci); VkFormat FindFormatWithoutFeatures(VkPhysicalDevice gpu, VkImageTiling tiling, VkFormatFeatureFlags undesired_features = UINT32_MAX); void NegHeightViewportTests(VkDeviceObj *m_device, VkCommandBufferObj *m_commandBuffer, ErrorMonitor *m_errorMonitor); void CreateSamplerTest(VkLayerTest &test, const VkSamplerCreateInfo *pCreateInfo, std::string code = ""); void CreateBufferTest(VkLayerTest &test, const VkBufferCreateInfo *pCreateInfo, std::string code = ""); void CreateImageTest(VkLayerTest &test, const VkImageCreateInfo *pCreateInfo, std::string code = ""); void CreateBufferViewTest(VkLayerTest &test, const VkBufferViewCreateInfo *pCreateInfo, const std::vector &codes); void CreateImageViewTest(VkLayerTest &test, const VkImageViewCreateInfo *pCreateInfo, std::string code = ""); void print_android(const char *c); #endif // VKLAYERTEST_H