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