1 /*
2  * Copyright (c) 2015-2021 The Khronos Group Inc.
3  * Copyright (c) 2015-2021 Valve Corporation
4  * Copyright (c) 2015-2021 LunarG, Inc.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
19  * Author: Dave Houlton <daveh@lunarg.com>
20  */
21 
22 #ifndef VKRENDERFRAMEWORK_H
23 #define VKRENDERFRAMEWORK_H
24 
25 #include "lvt_function_pointers.h"
26 
27 #ifdef ANDROID
28 #include "vktestframeworkandroid.h"
29 class VkImageObj;
30 #else
31 #include "vktestframework.h"
32 #endif
33 
34 #if defined(ANDROID)
35 #include <android/log.h>
36 #if defined(VALIDATION_APK)
37 #include <android_native_app_glue.h>
38 #endif
39 #endif
40 
41 #include <algorithm>
42 #include <array>
43 #include <memory>
44 #include <vector>
45 #include <unordered_map>
46 #include <unordered_set>
47 
48 using vk_testing::MakeVkHandles;
49 
50 template <class Dst, class Src>
MakeTestbindingHandles(const std::vector<Src * > & v)51 std::vector<Dst *> MakeTestbindingHandles(const std::vector<Src *> &v) {
52     std::vector<Dst *> handles;
53     handles.reserve(v.size());
54     std::transform(v.begin(), v.end(), std::back_inserter(handles), [](const Src *o) { return static_cast<Dst *>(o); });
55     return handles;
56 }
57 
58 typedef vk_testing::Queue VkQueueObj;
59 class VkDeviceObj : public vk_testing::Device {
60   public:
61     VkDeviceObj(uint32_t id, VkPhysicalDevice obj);
62     VkDeviceObj(uint32_t id, VkPhysicalDevice obj, std::vector<const char *> &extension_names,
63                 VkPhysicalDeviceFeatures *features = nullptr, void *create_device_pnext = nullptr);
64 
65     uint32_t QueueFamilyMatching(VkQueueFlags with, VkQueueFlags without, bool all_bits = true);
QueueFamilyWithoutCapabilities(VkQueueFlags capabilities)66     uint32_t QueueFamilyWithoutCapabilities(VkQueueFlags capabilities) {
67         // an all_bits match with 0 matches all
68         return QueueFamilyMatching(VkQueueFlags(0), capabilities, true /* all_bits with */);
69     }
70 
device()71     VkDevice device() { return handle(); }
72     void SetDeviceQueue();
73     VkQueueObj *GetDefaultQueue();
74     VkQueueObj *GetDefaultComputeQueue();
75 
76     uint32_t id;
77     VkPhysicalDeviceProperties props;
78     std::vector<VkQueueFamilyProperties> queue_props;
79 
80     VkQueue m_queue;
81 };
82 
83 // ErrorMonitor Usage:
84 //
85 // Call SetDesiredFailureMsg with a string to be compared against all
86 // encountered log messages, or a validation error enum identifying
87 // desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM
88 // will match all log messages. logMsg will return true for skipCall
89 // only if msg is matched or NULL.
90 //
91 // Call VerifyFound to determine if all desired failure messages
92 // were encountered. Call VerifyNotFound to determine if any unexpected
93 // failure was encountered.
94 class ErrorMonitor {
95   public:
96     enum Behavior {
97         DefaultSuccess = 0,
98         DefaultIgnore,
99     };
100 
101     ErrorMonitor(Behavior = Behavior::DefaultIgnore);
102 
103     ~ErrorMonitor() NOEXCEPT;
104 
105     // Set monitor to pristine state
106     void Reset();
107 
108     // ErrorMonitor will look for an error message containing the specified string(s)
109     void SetDesiredFailureMsg(const VkFlags msgFlags, const std::string msg);
110     void SetDesiredFailureMsg(const VkFlags msgFlags, const char *const msgString);
111 
112     // ErrorMonitor will look for an error message containing the specified string(s)
113     template <typename Iter>
SetDesiredFailureMsg(const VkFlags msgFlags,Iter iter,const Iter end)114     void SetDesiredFailureMsg(const VkFlags msgFlags, Iter iter, const Iter end) {
115         for (; iter != end; ++iter) {
116             SetDesiredFailureMsg(msgFlags, *iter);
117         }
118     }
119 
120     // Set an error that the error monitor will ignore. Do not use this function if you are creating a new test.
121     // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
122     // function and its definition.
123     void SetUnexpectedError(const char *const msg);
124 
125     // Set an error that should not cause a test failure
126     void SetAllowedFailureMsg(const char *const msg);
127 
128     VkBool32 CheckForDesiredMsg(const char *const msgString);
129     VkDebugReportFlagsEXT GetMessageFlags();
130     void SetError(const char *const errorString);
131     void SetBailout(bool *bailout);
132 
133     // Helpers
134 
135     // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags
136     void ExpectSuccess(VkDebugReportFlagsEXT const message_flag_mask = kErrorBit);
ExpectingSuccess()137     bool ExpectingSuccess() const {
138         return (desired_message_strings_.size() == 1) &&
139                (desired_message_strings_.count("") == 1 && ignore_message_strings_.size() == 0);
140     }
NeedCheckSuccess()141     bool NeedCheckSuccess() const {
142         return (behavior_ == Behavior::DefaultSuccess) && ExpectingSuccess();
143     }
144 
145     void VerifyFound();
146     void VerifyNotFound();
147 
148   private:
149     // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
150     // function and its definition.
151     bool IgnoreMessage(std::string const &msg) const;
152     std::vector<std::string> GetOtherFailureMsgs() const;
153     bool AnyDesiredMsgFound() const;
154     bool AllDesiredMsgsFound() const;
155     void DumpFailureMsgs() const;
156     void MonitorReset();
157 
158     VkFlags message_flags_;
159     std::unordered_multiset<std::string> desired_message_strings_;
160     std::unordered_multiset<std::string> failure_message_strings_;
161     std::vector<std::string> ignore_message_strings_;
162     std::vector<std::string> allowed_message_strings_;
163     std::vector<std::string> other_messages_;
164     test_platform_thread_mutex mutex_;
165     bool *bailout_;
166     bool message_found_;
167     Behavior behavior_;
168 };
169 
170 struct DebugReporter {
171     void Create(VkInstance instance) NOEXCEPT;
172     void Destroy(VkInstance instance) NOEXCEPT;
173 
174     ErrorMonitor error_monitor_;
175 
176 #ifdef VK_USE_PLATFORM_ANDROID_KHR
177     static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugReportFlagsEXT message_flags, VkDebugReportObjectTypeEXT, uint64_t,
178                                                         size_t, int32_t, const char *, const char *msg, void *user_data);
179 
180     const char *debug_extension_name = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
181     VkDebugReportCallbackCreateInfoEXT debug_create_info_ = {
182         VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, nullptr,
183         VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
184         &DebugCallback, &error_monitor_};
185     using DebugCreateFnType = PFN_vkCreateDebugReportCallbackEXT;
186     const char *debug_create_fn_name_ = "vkCreateDebugReportCallbackEXT";
187     using DebugDestroyFnType = PFN_vkDestroyDebugReportCallbackEXT;
188     const char *debug_destroy_fn_name_ = "vkDestroyDebugReportCallbackEXT";
189     VkDebugReportCallbackEXT debug_obj_ = VK_NULL_HANDLE;
190 #else
191     static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
192                                                         VkDebugUtilsMessageTypeFlagsEXT message_types,
193                                                         const VkDebugUtilsMessengerCallbackDataEXT *callback_data, void *user_data);
194 
195     const char *debug_extension_name = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
196     VkDebugUtilsMessengerCreateInfoEXT debug_create_info_ = {
197         VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
198         nullptr,
199         0,
200         VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
201             VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT,
202         VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
203         &DebugCallback,
204         &error_monitor_};
205     using DebugCreateFnType = PFN_vkCreateDebugUtilsMessengerEXT;
206     const char *debug_create_fn_name_ = "vkCreateDebugUtilsMessengerEXT";
207     using DebugDestroyFnType = PFN_vkDestroyDebugUtilsMessengerEXT;
208     const char *debug_destroy_fn_name_ = "vkDestroyDebugUtilsMessengerEXT";
209     VkDebugUtilsMessengerEXT debug_obj_ = VK_NULL_HANDLE;
210 #endif
211 };
212 
213 class VkCommandPoolObj;
214 class VkCommandBufferObj;
215 class VkDepthStencilObj;
216 
217 typedef enum {
218     kGalaxyS10,
219     kPixel3,
220     kPixelC,
221     kNexusPlayer,
222     kShieldTV,
223     kShieldTVb,
224     kPixel3aXL,
225     kPixel2XL,
226     kMockICD,
227 } PlatformType;
228 
229 const std::unordered_map<PlatformType, std::string, std::hash<int>> vk_gpu_table = {
230     {kGalaxyS10, "Mali-G76"},
231     {kPixel3, "Adreno (TM) 630"},
232     {kPixelC, "NVIDIA Tegra X1"},
233     {kNexusPlayer, "PowerVR Rogue G6430"},
234     {kShieldTV, "NVIDIA Tegra X1 (nvgpu)"},
235     {kShieldTVb, "NVIDIA Tegra X1 (rev B) (nvgpu)"},
236     {kPixel3aXL, "Adreno (TM) 615"},
237     {kPixel2XL, "Adreno (TM) 540"},
238     {kMockICD, "Vulkan Mock Device"},
239 };
240 
241 class VkRenderFramework : public VkTestFramework {
242   public:
instance()243     VkInstance instance() { return instance_; }
device()244     VkDevice device() { return m_device->device(); }
DeviceObj()245     VkDeviceObj *DeviceObj() const { return m_device; }
246     VkPhysicalDevice gpu();
renderPass()247     VkRenderPass renderPass() { return m_renderPass; }
RenderPassInfo()248     const VkRenderPassCreateInfo &RenderPassInfo() const { return m_renderPass_info; };
framebuffer()249     VkFramebuffer framebuffer() { return m_framebuffer; }
250     ErrorMonitor &Monitor();
251     VkPhysicalDeviceProperties physDevProps();
252 
253     static bool InstanceLayerSupported(const char *layer_name, uint32_t spec_version = 0, uint32_t impl_version = 0);
254     static bool InstanceExtensionSupported(const char *extension_name, uint32_t spec_version = 0);
255 
256     VkInstanceCreateInfo GetInstanceCreateInfo() const;
257     void InitFramework(void * /*unused compatibility parameter*/ = NULL, void *instance_pnext = NULL);
258     void ShutdownFramework();
259 
260     void InitViewport(float width, float height);
261     void InitViewport();
262     bool InitSurface();
263     bool InitSurface(float width, float height);
264     bool InitSurface(float width, float height, VkSurfaceKHR &surface);
265     void InitSwapchainInfo();
266     bool InitSwapchain(VkSurfaceKHR &surface, VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
267                        VkSurfaceTransformFlagBitsKHR preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR);
268     bool InitSwapchain(VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
269                        VkSurfaceTransformFlagBitsKHR preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR);
270     bool InitSwapchain(VkSurfaceKHR &surface, VkImageUsageFlags imageUsage,  VkSurfaceTransformFlagBitsKHR preTransform, VkSwapchainKHR &swapchain, VkSwapchainKHR oldSwapchain = 0);
271     void DestroySwapchain();
272     void InitRenderTarget();
273     void InitRenderTarget(uint32_t targets);
274     void InitRenderTarget(VkImageView *dsBinding);
275     void InitRenderTarget(uint32_t targets, VkImageView *dsBinding);
276     void DestroyRenderTarget();
277     bool InitFrameworkAndRetrieveFeatures(VkPhysicalDeviceFeatures2KHR &features2);
278 
279     bool IsDriver(VkDriverId driver_id);
280     bool IsPlatform(PlatformType platform);
281     void GetPhysicalDeviceFeatures(VkPhysicalDeviceFeatures *features);
282     void GetPhysicalDeviceProperties(VkPhysicalDeviceProperties *props);
283     void InitState(VkPhysicalDeviceFeatures *features = nullptr, void *create_device_pnext = nullptr,
284                    const VkCommandPoolCreateFlags flags = 0);
285 
renderPassBeginInfo()286     const VkRenderPassBeginInfo &renderPassBeginInfo() const { return m_renderPassBeginInfo; }
287 
288     bool EnableDeviceProfileLayer();
289     bool InstanceExtensionEnabled(const char *name);
290     bool DeviceExtensionSupported(const char *extension_name, uint32_t spec_version = 0) const;
291     bool DeviceExtensionSupported(VkPhysicalDevice, const char *, const char *name,
292                                   uint32_t spec_version = 0) const {  // deprecated
293         return DeviceExtensionSupported(name, spec_version);
294     }
295     bool DeviceExtensionEnabled(const char *name);
296     bool DeviceSimulation();
297 
298     // Tracks ext_name to be enabled at device creation time and attempts to enable any required instance extensions.
299     // Returns true if all required instance extensions are supported or there are no required instance extensions, false
300     // otherwise.
301     // `ext_name` can refer to a device or instance extension.
302     bool AddRequiredExtensions(const char *ext_name);
303     // After instance and physical device creation (e.g., after InitFramework), returns true if all required extensions are
304     // available, false otherwise
305     bool AreRequestedExtensionsEnabled() const;
306 
307     // Add ext_name, the names of all instance extensions required by ext_name, and return true if ext_name is supported. If the
308     // extension is not supported, no extension names are added for instance creation. `ext_name` can refer to a device or instance
309     // extension.
310     bool AddRequiredInstanceExtensions(const char *ext_name);
311     // Returns true if the instance extension inst_ext_name is enabled. This call is only valid _after_ previous
312     // `AddRequired*Extensions` calls and InitFramework has been called. `inst_ext_name` must be an instance extension name; false
313     // is returned for all device extension names.
314     bool CanEnableInstanceExtension(const std::string &inst_ext_name) const;
315     // Add dev_ext_name, then names of _device_ extensions required by dev_ext_name, and return true if dev_ext_name is supported.
316     // If the extension is not supported, no extension names are added for device creation. This function has no effect if
317     // dev_ext_name refers to an instance extension.
318     bool AddRequiredDeviceExtensions(const char *dev_ext_name);
319     // Returns true if the device extension is enabled. This call is only valid _after_ previous `AddRequired*Extensions` calls and
320     // InitFramework has been called.
321     // `dev_ext_name` msut be an instance extension name; false is returned for all instance extension names.
322     bool CanEnableDeviceExtension(const std::string &dev_ext_name) const;
323 
324   protected:
325     VkRenderFramework();
326     virtual ~VkRenderFramework() = 0;
327 
328     DebugReporter debug_reporter_;
329     ErrorMonitor *m_errorMonitor = &debug_reporter_.error_monitor_;  // compatibility alias name
330 
331     VkApplicationInfo app_info_;
332     std::vector<const char *> instance_layers_;
333     std::vector<const char *> instance_extensions_;
334     std::vector<const char *> &m_instance_extension_names = instance_extensions_;  // compatibility alias name
335     VkInstance instance_;
336     VkPhysicalDevice gpu_ = VK_NULL_HANDLE;
337     VkPhysicalDeviceProperties physDevProps_;
338 
339     uint32_t m_gpu_index;
340     VkDeviceObj *m_device;
341     VkCommandPoolObj *m_commandPool;
342     VkCommandBufferObj *m_commandBuffer;
343     VkRenderPass m_renderPass;
344     VkRenderPassCreateInfo m_renderPass_info = {};
345     std::vector<VkAttachmentDescription> m_renderPass_attachments;
346     std::vector<VkSubpassDescription> m_renderPass_subpasses;
347     std::vector<VkSubpassDependency> m_renderPass_dependencies;
348 
349     VkFramebuffer m_framebuffer;
350     VkFramebufferCreateInfo m_framebuffer_info;
351     std::vector<VkImageView> m_framebuffer_attachments;
352 
353     // WSI items
354     VkSurfaceKHR m_surface;
355 #if defined(VK_USE_PLATFORM_XLIB_KHR)
356     Display *m_surface_dpy;
357     Window m_surface_window;
358 #endif
359 #if defined(VK_USE_PLATFORM_XCB_KHR)
360     xcb_connection_t *m_surface_xcb_conn;
361 #endif
362     VkSwapchainKHR m_swapchain;
363     VkSurfaceCapabilitiesKHR m_surface_capabilities;
364     std::vector<VkSurfaceFormatKHR> m_surface_formats;
365     std::vector<VkPresentModeKHR> m_surface_present_modes;
366     VkPresentModeKHR m_surface_non_shared_present_mode;
367     VkCompositeAlphaFlagBitsKHR m_surface_composite_alpha;
368 
369     std::vector<VkViewport> m_viewports;
370     std::vector<VkRect2D> m_scissors;
371     float m_lineWidth;
372     float m_depthBiasConstantFactor;
373     float m_depthBiasClamp;
374     float m_depthBiasSlopeFactor;
375     float m_blendConstants[4];
376     float m_minDepthBounds;
377     float m_maxDepthBounds;
378     uint32_t m_compareMask;
379     uint32_t m_writeMask;
380     uint32_t m_reference;
381     bool m_addRenderPassSelfDependency;
382     std::vector<VkSubpassDependency> m_additionalSubpassDependencies;
383     std::vector<VkClearValue> m_renderPassClearValues;
384     VkRenderPassBeginInfo m_renderPassBeginInfo;
385     std::vector<std::unique_ptr<VkImageObj>> m_renderTargets;
386     float m_width, m_height;
387     VkFormat m_render_target_fmt;
388     VkFormat m_depth_stencil_fmt;
389     VkClearColorValue m_clear_color;
390     bool m_clear_via_load_op;
391     float m_depth_clear_color;
392     uint32_t m_stencil_clear_color;
393     VkDepthStencilObj *m_depthStencil;
394 
395     // Requested extensions to enable at device creation time
396     std::vector<const char *> m_requested_extensions;
397     // Device extensions to enable
398     std::vector<const char *> m_device_extension_names;
399 };
400 
401 class VkDescriptorSetObj;
402 class VkConstantBufferObj;
403 class VkPipelineObj;
404 typedef vk_testing::Event VkEventObj;
405 typedef vk_testing::Fence VkFenceObj;
406 typedef vk_testing::Buffer VkBufferObj;
407 typedef vk_testing::AccelerationStructure VkAccelerationStructureObj;
408 typedef vk_testing::AccelerationStructureKHR VkAccelerationStructurekhrObj;
409 class VkCommandPoolObj : public vk_testing::CommandPool {
410   public:
411     VkCommandPoolObj(VkDeviceObj *device, uint32_t queue_family_index, VkCommandPoolCreateFlags flags = 0);
412 };
413 
414 class VkCommandBufferObj : public vk_testing::CommandBuffer {
415   public:
416     VkCommandBufferObj(VkDeviceObj *device, VkCommandPoolObj *pool, VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
417                        VkQueueObj *queue = nullptr);
418     void PipelineBarrier(VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages, VkDependencyFlags dependencyFlags,
419                          uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
420                          const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
421                          const VkImageMemoryBarrier *pImageMemoryBarriers);
422     void PipelineBarrier2KHR(const VkDependencyInfoKHR *pDependencyInfo);
423     void ClearAllBuffers(const std::vector<std::unique_ptr<VkImageObj>> &color_objs, VkClearColorValue clear_color,
424                          VkDepthStencilObj *depth_stencil_obj, float depth_clear_value, uint32_t stencil_clear_value);
425     void PrepareAttachments(const std::vector<std::unique_ptr<VkImageObj>> &color_atts, VkDepthStencilObj *depth_stencil_att);
426     void BindDescriptorSet(VkDescriptorSetObj &descriptorSet);
427     void BindIndexBuffer(VkBufferObj *indexBuffer, VkDeviceSize offset, VkIndexType indexType);
428     void BindVertexBuffer(VkConstantBufferObj *vertexBuffer, VkDeviceSize offset, uint32_t binding);
429     void BeginRenderPass(const VkRenderPassBeginInfo &info, VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE);
430     void EndRenderPass();
431     void BeginRendering(const VkRenderingInfoKHR &renderingInfo);
432     void EndRendering();
433     void FillBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize fill_size, uint32_t data);
434     void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
435     void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
436                      uint32_t firstInstance);
437     void QueueCommandBuffer(bool checkSuccess = true);
438     void QueueCommandBuffer(const VkFenceObj &fence, bool checkSuccess = true);
439     void SetViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports);
440     void SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference);
441     void UpdateBuffer(VkBuffer buffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData);
442     void CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
443                    uint32_t regionCount, const VkImageCopy *pRegions);
444     void ResolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
445                       uint32_t regionCount, const VkImageResolve *pRegions);
446     void ClearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue *pColor, uint32_t rangeCount,
447                          const VkImageSubresourceRange *pRanges);
448     void ClearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pColor,
449                                 uint32_t rangeCount, const VkImageSubresourceRange *pRanges);
450     void BuildAccelerationStructure(VkAccelerationStructureObj *as, VkBuffer scratchBuffer);
451     void BuildAccelerationStructure(VkAccelerationStructureObj *as, VkBuffer scratchBuffer, VkBuffer instanceData);
SetEvent(VkEventObj & event,VkPipelineStageFlags stageMask)452     void SetEvent(VkEventObj &event, VkPipelineStageFlags stageMask) { event.cmd_set(*this, stageMask); }
ResetEvent(VkEventObj & event,VkPipelineStageFlags stageMask)453     void ResetEvent(VkEventObj &event, VkPipelineStageFlags stageMask) { event.cmd_reset(*this, stageMask); }
WaitEvents(uint32_t eventCount,const VkEvent * pEvents,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)454     void WaitEvents(uint32_t eventCount, const VkEvent *pEvents, VkPipelineStageFlags srcStageMask,
455                     VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
456                     uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
457                     uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
458         vk::CmdWaitEvents(handle(), eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers,
459                           bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
460     }
461 
462   protected:
463     VkDeviceObj *m_device;
464     VkQueueObj *m_queue;
465 };
466 
467 class VkConstantBufferObj : public VkBufferObj {
468   public:
469     VkConstantBufferObj(VkDeviceObj *device,
470                         VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
471     VkConstantBufferObj(VkDeviceObj *device, VkDeviceSize size, const void *data,
472                         VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
473 
474     VkDescriptorBufferInfo m_descriptorBufferInfo;
475 
476   protected:
477     VkDeviceObj *m_device;
478 };
479 
480 class VkRenderpassObj : public vk_testing::RenderPass {
481   public:
482     VkRenderpassObj(VkDeviceObj *device, VkFormat format = VK_FORMAT_B8G8R8A8_UNORM);
483     VkRenderpassObj(VkDeviceObj *device, VkFormat format, bool depthStencil);
484 };
485 
486 class VkImageObj : public vk_testing::Image {
487   public:
488     VkImageObj(VkDeviceObj *dev);
489     bool IsCompatible(VkImageUsageFlags usages, VkFormatFeatureFlags features);
490     bool IsCompatibleCheck(const VkImageCreateInfo &create_info);
491 
492   public:
493     static VkImageCreateInfo ImageCreateInfo2D(uint32_t const width, uint32_t const height, uint32_t const mipLevels,
494                                                uint32_t const layers, VkFormat const format, VkFlags const usage,
495                                                VkImageTiling const requested_tiling = VK_IMAGE_TILING_LINEAR,
496                                                const std::vector<uint32_t> *queue_families = nullptr);
497     void Init(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format, VkFlags const usage,
498               VkImageTiling const tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags const reqs = 0,
499               const std::vector<uint32_t> *queue_families = nullptr, bool memory = true);
500     void Init(const VkImageCreateInfo &create_info, VkMemoryPropertyFlags const reqs = 0, bool memory = true);
501 
502     void init(const VkImageCreateInfo *create_info);
503 
504     void InitNoLayout(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
505                       VkFlags const usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags reqs = 0,
506                       const std::vector<uint32_t> *queue_families = nullptr, bool memory = true);
507 
508     void InitNoLayout(const VkImageCreateInfo &create_info, VkMemoryPropertyFlags reqs = 0, bool memory = true);
509 
510     //    void clear( CommandBuffer*, uint32_t[4] );
511 
Layout(VkImageLayout const layout)512     void Layout(VkImageLayout const layout) { m_descriptorImageInfo.imageLayout = layout; }
513 
memory()514     VkDeviceMemory memory() const { return Image::memory().handle(); }
515 
MapMemory()516     void *MapMemory() { return Image::memory().map(); }
517 
UnmapMemory()518     void UnmapMemory() { Image::memory().unmap(); }
519 
520     void ImageMemoryBarrier(VkCommandBufferObj *cmd, VkImageAspectFlags aspect, VkFlags output_mask, VkFlags input_mask,
521                             VkImageLayout image_layout, VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
522                             VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
523                             uint32_t srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
524                             uint32_t dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED);
525 
526     VkResult CopyImage(VkImageObj &src_image);
527 
528     VkResult CopyImageOut(VkImageObj &dst_image);
529 
530     std::array<std::array<uint32_t, 16>, 16> Read();
531 
image()532     VkImage image() const { return handle(); }
533 
534     VkImageView targetView(VkFormat format, VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT, uint32_t baseMipLevel = 0,
535                            uint32_t levelCount = VK_REMAINING_MIP_LEVELS, uint32_t baseArrayLayer = 0,
536                            uint32_t layerCount = VK_REMAINING_ARRAY_LAYERS, VkImageViewType type = VK_IMAGE_VIEW_TYPE_2D) {
537         if (!m_targetView.initialized()) {
538             VkImageViewCreateInfo createView = {};
539             createView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
540             createView.image = handle();
541             createView.viewType = type;
542             createView.format = format;
543             createView.components.r = VK_COMPONENT_SWIZZLE_R;
544             createView.components.g = VK_COMPONENT_SWIZZLE_G;
545             createView.components.b = VK_COMPONENT_SWIZZLE_B;
546             createView.components.a = VK_COMPONENT_SWIZZLE_A;
547             createView.subresourceRange = {aspect, baseMipLevel, levelCount, baseArrayLayer, layerCount};
548             createView.flags = 0;
549             m_targetView.init(*m_device, createView);
550         }
551         return m_targetView.handle();
552     }
553 
554     void SetLayout(VkCommandBufferObj *cmd_buf, VkImageAspectFlags aspect, VkImageLayout image_layout);
555     void SetLayout(VkImageAspectFlags aspect, VkImageLayout image_layout);
556 
Layout()557     VkImageLayout Layout() const { return m_descriptorImageInfo.imageLayout; }
width()558     uint32_t width() const { return extent().width; }
height()559     uint32_t height() const { return extent().height; }
device()560     VkDeviceObj *device() const { return m_device; }
561 
562   protected:
563     VkDeviceObj *m_device;
564 
565     vk_testing::ImageView m_targetView;
566     VkDescriptorImageInfo m_descriptorImageInfo;
567     uint32_t m_mipLevels;
568     uint32_t m_arrayLayers;
569 };
570 
571 class VkTextureObj : public VkImageObj {
572   public:
573     VkTextureObj(VkDeviceObj *device, uint32_t *colors = NULL);
574 
DescriptorImageInfo()575     const VkDescriptorImageInfo &DescriptorImageInfo() const { return m_descriptorImageInfo; }
576 
577   protected:
578     VkDeviceObj *m_device;
579     vk_testing::ImageView m_textureView;
580 };
581 
582 class VkDepthStencilObj : public VkImageObj {
583   public:
584     VkDepthStencilObj(VkDeviceObj *device);
585     void Init(VkDeviceObj *device, int32_t width, int32_t height, VkFormat format,
586               VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VkImageAspectFlags aspect = 0);
587     bool Initialized();
588     VkImageView *BindInfo();
589 
590     VkFormat Format() const;
591 
592   protected:
593     VkDeviceObj *m_device;
594     bool m_initialized;
595     vk_testing::ImageView m_imageView;
596     VkFormat m_depth_stencil_fmt;
597     VkImageView m_attachmentBindInfo;
598 };
599 
600 class VkSamplerObj : public vk_testing::Sampler {
601   public:
602     VkSamplerObj(VkDeviceObj *device);
603 
604   protected:
605     VkDeviceObj *m_device;
606 };
607 
608 class VkDescriptorSetLayoutObj : public vk_testing::DescriptorSetLayout {
609   public:
610     VkDescriptorSetLayoutObj() = default;
611     VkDescriptorSetLayoutObj(const VkDeviceObj *device,
612                              const std::vector<VkDescriptorSetLayoutBinding> &descriptor_set_bindings = {},
613                              VkDescriptorSetLayoutCreateFlags flags = 0, void *pNext = NULL);
614 
615     // Move constructor and move assignment operator for Visual Studio 2013
VkDescriptorSetLayoutObj(VkDescriptorSetLayoutObj && src)616     VkDescriptorSetLayoutObj(VkDescriptorSetLayoutObj &&src) NOEXCEPT : DescriptorSetLayout(std::move(src)){};
617     VkDescriptorSetLayoutObj &operator=(VkDescriptorSetLayoutObj &&src) NOEXCEPT {
618         DescriptorSetLayout::operator=(std::move(src));
619         return *this;
620     }
621 };
622 
623 class VkDescriptorSetObj : public vk_testing::DescriptorPool {
624   public:
625     VkDescriptorSetObj(VkDeviceObj *device);
626     ~VkDescriptorSetObj() NOEXCEPT;
627 
628     int AppendDummy();
629     int AppendBuffer(VkDescriptorType type, VkConstantBufferObj &constantBuffer);
630     int AppendSamplerTexture(VkSamplerObj *sampler, VkTextureObj *texture);
631     void CreateVKDescriptorSet(VkCommandBufferObj *commandBuffer);
632 
633     VkDescriptorSet GetDescriptorSetHandle() const;
634     VkPipelineLayout GetPipelineLayout() const;
635     VkDescriptorSetLayout GetDescriptorSetLayout() const;
636 
637   protected:
638     VkDeviceObj *m_device;
639     std::vector<VkDescriptorSetLayoutBinding> m_layout_bindings;
640     std::map<VkDescriptorType, int> m_type_counts;
641     int m_nextSlot;
642 
643     std::vector<VkDescriptorImageInfo> m_imageSamplerDescriptors;
644     std::vector<VkWriteDescriptorSet> m_writes;
645 
646     vk_testing::DescriptorSetLayout m_layout;
647     vk_testing::PipelineLayout m_pipeline_layout;
648     vk_testing::DescriptorSet *m_set = NULL;
649 };
650 
651 class VkShaderObj : public vk_testing::ShaderModule {
652   public:
653     VkShaderObj(VkDeviceObj &device, VkShaderStageFlagBits stage, char const *name = "main",
654                 const VkSpecializationInfo *specInfo = nullptr);
655     VkShaderObj(VkDeviceObj *device, const char *shaderText, VkShaderStageFlagBits stage, VkRenderFramework *framework,
656                 char const *name = "main", bool debug = false, const VkSpecializationInfo *specInfo = nullptr,
657                 const spv_target_env env = SPV_ENV_VULKAN_1_0);
658     VkShaderObj(VkDeviceObj *device, const std::string spv_source, VkShaderStageFlagBits stage, VkRenderFramework *framework,
659                 char const *name = "main", const VkSpecializationInfo *specInfo = nullptr,
660                 const spv_target_env env = SPV_ENV_VULKAN_1_0);
661     VkPipelineShaderStageCreateInfo const &GetStageCreateInfo() const;
662 
663     bool InitFromGLSL(VkRenderFramework &framework, const char *shader_code, bool debug = false,
664                       const spv_target_env env = SPV_ENV_VULKAN_1_0);
665     VkResult InitFromGLSLTry(VkRenderFramework &framework, const char *shader_code, bool debug = false,
666                              const spv_target_env env = SPV_ENV_VULKAN_1_0);
667     bool InitFromASM(VkRenderFramework &framework, const std::string &spv_source, const spv_target_env env = SPV_ENV_VULKAN_1_0);
668     VkResult InitFromASMTry(VkRenderFramework &framework, const std::string &spv_source, const spv_target_env = SPV_ENV_VULKAN_1_0);
669 
670     // These functions return a pointer to a newly created _and initialized_ VkShaderObj if initialization was successful.
671     // Otherwise, {} is returned.
672     static std::unique_ptr<VkShaderObj> CreateFromGLSL(VkDeviceObj &dev, VkRenderFramework &framework, VkShaderStageFlagBits stage,
673                                                        const std::string &code, const char *entry_point = "main",
674                                                        const VkSpecializationInfo *spec_info = nullptr,
675                                                        const spv_target_env = SPV_ENV_VULKAN_1_0, bool debug = false);
676     static std::unique_ptr<VkShaderObj> CreateFromASM(VkDeviceObj &dev, VkRenderFramework &framework, VkShaderStageFlagBits stage,
677                                                       const std::string &code, const char *entry_point = "main",
678                                                       const VkSpecializationInfo *spec_info = nullptr,
679                                                       const spv_target_env spv_env = SPV_ENV_VULKAN_1_0);
680 
681     // TODO (ncesario) remove ifndef once android build consolidation changes go in
682 #ifndef __ANDROID__
683     struct GlslangTargetEnv {
GlslangTargetEnvGlslangTargetEnv684         GlslangTargetEnv(const spv_target_env env) {
685             switch (env) {
686                 case SPV_ENV_UNIVERSAL_1_0:
687                     language_version = glslang::EShTargetSpv_1_0;
688                     break;
689                 case SPV_ENV_UNIVERSAL_1_1:
690                     language_version = glslang::EShTargetSpv_1_1;
691                     break;
692                 case SPV_ENV_UNIVERSAL_1_2:
693                     language_version = glslang::EShTargetSpv_1_2;
694                     break;
695                 case SPV_ENV_UNIVERSAL_1_3:
696                     language_version = glslang::EShTargetSpv_1_3;
697                     break;
698                 case SPV_ENV_UNIVERSAL_1_4:
699                     language_version = glslang::EShTargetSpv_1_4;
700                     break;
701                 case SPV_ENV_UNIVERSAL_1_5:
702                     language_version = glslang::EShTargetSpv_1_5;
703                     break;
704                 case SPV_ENV_VULKAN_1_0:
705                     client_version = glslang::EShTargetVulkan_1_0;
706                     break;
707                 case SPV_ENV_VULKAN_1_1:
708                     client_version = glslang::EShTargetVulkan_1_1;
709                     language_version = glslang::EShTargetSpv_1_3;
710                     break;
711                 case SPV_ENV_VULKAN_1_2:
712                     client_version = glslang::EShTargetVulkan_1_2;
713                     language_version = glslang::EShTargetSpv_1_5;
714                     break;
715                 default:
716                     break;
717             }
718         }
719 
EShTargetLanguageVersionGlslangTargetEnv720         operator glslang::EShTargetLanguageVersion() const {
721             return language_version;
722         }
723 
EShTargetClientVersionGlslangTargetEnv724         operator glslang::EShTargetClientVersion() const {
725             return client_version;
726         }
727 
728       private:
729         glslang::EShTargetLanguageVersion language_version = glslang::EShTargetSpv_1_0;
730         glslang::EShTargetClientVersion client_version = glslang::EShTargetVulkan_1_0;
731     };
732 #endif
733 
734   protected:
735     VkPipelineShaderStageCreateInfo m_stage_info;
736     VkDeviceObj &m_device;
737 };
738 
739 class VkPipelineLayoutObj : public vk_testing::PipelineLayout {
740   public:
741     VkPipelineLayoutObj() = default;
742     VkPipelineLayoutObj(VkDeviceObj *device, const std::vector<const VkDescriptorSetLayoutObj *> &descriptor_layouts = {},
743                         const std::vector<VkPushConstantRange> &push_constant_ranges = {});
744 
745     // Move constructor and move assignment operator for Visual Studio 2013
VkPipelineLayoutObj(VkPipelineLayoutObj && src)746     VkPipelineLayoutObj(VkPipelineLayoutObj &&src) NOEXCEPT : PipelineLayout(std::move(src)) {}
747     VkPipelineLayoutObj &operator=(VkPipelineLayoutObj &&src) NOEXCEPT {
748         PipelineLayout::operator=(std::move(src));
749         return *this;
750     }
751 
752     void Reset();
753 };
754 
755 class VkPipelineObj : public vk_testing::Pipeline {
756   public:
757     VkPipelineObj(VkDeviceObj *device);
758     void AddShader(VkShaderObj *shaderObj);
759     void AddShader(VkPipelineShaderStageCreateInfo const &createInfo);
760     void AddVertexInputAttribs(VkVertexInputAttributeDescription *vi_attrib, uint32_t count);
761     void AddVertexInputBindings(VkVertexInputBindingDescription *vi_binding, uint32_t count);
762     void AddColorAttachment(uint32_t binding, const VkPipelineColorBlendAttachmentState &att);
763     void MakeDynamic(VkDynamicState state);
764 
765     void AddDefaultColorAttachment(VkColorComponentFlags writeMask = 0xf /*=R|G|B|A*/) {
766         VkPipelineColorBlendAttachmentState att = {};
767         att.blendEnable = VK_FALSE;
768         att.colorWriteMask = writeMask;
769         AddColorAttachment(0, att);
770     }
771 
772     void SetDepthStencil(const VkPipelineDepthStencilStateCreateInfo *);
773     void SetMSAA(const VkPipelineMultisampleStateCreateInfo *ms_state);
774     void SetInputAssembly(const VkPipelineInputAssemblyStateCreateInfo *ia_state);
775     void SetRasterization(const VkPipelineRasterizationStateCreateInfo *rs_state);
776     void SetTessellation(const VkPipelineTessellationStateCreateInfo *te_state);
777     void SetViewport(const std::vector<VkViewport> viewports);
778     void SetScissor(const std::vector<VkRect2D> scissors);
779     void SetLineState(const VkPipelineRasterizationLineStateCreateInfoEXT *line_state);
780 
781     void InitGraphicsPipelineCreateInfo(VkGraphicsPipelineCreateInfo *gp_ci);
782 
783     VkResult CreateVKPipeline(VkPipelineLayout layout, VkRenderPass render_pass, VkGraphicsPipelineCreateInfo *gp_ci = nullptr);
784 
785   protected:
786     VkPipelineVertexInputStateCreateInfo m_vi_state;
787     VkPipelineInputAssemblyStateCreateInfo m_ia_state;
788     VkPipelineRasterizationStateCreateInfo m_rs_state;
789     VkPipelineColorBlendStateCreateInfo m_cb_state;
790     VkPipelineDepthStencilStateCreateInfo const *m_ds_state;
791     VkPipelineViewportStateCreateInfo m_vp_state;
792     VkPipelineMultisampleStateCreateInfo m_ms_state;
793     VkPipelineTessellationStateCreateInfo const *m_te_state;
794     VkPipelineDynamicStateCreateInfo m_pd_state;
795     VkPipelineRasterizationLineStateCreateInfoEXT m_line_state;
796     std::vector<VkDynamicState> m_dynamic_state_enables;
797     std::vector<VkViewport> m_viewports;
798     std::vector<VkRect2D> m_scissors;
799     VkDeviceObj *m_device;
800     std::vector<VkPipelineShaderStageCreateInfo> m_shaderStages;
801     std::vector<VkPipelineColorBlendAttachmentState> m_colorAttachments;
802 };
803 
804 #endif  // VKRENDERFRAMEWORK_H
805