1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "vk/GrVkInterface.h"
9#include "vk/GrVkBackendContext.h"
10#include "vk/GrVkUtil.h"
11
12#define ACQUIRE_PROC(name, instance, device) fFunctions.f##name = \
13    reinterpret_cast<PFN_vk##name>(getProc("vk"#name, instance, device));
14
15GrVkInterface::GetProc make_unified_getter(const GrVkInterface::GetInstanceProc& iproc,
16                                           const GrVkInterface::GetDeviceProc& dproc) {
17    return [&iproc, &dproc](const char* proc_name, VkInstance instance, VkDevice device) {
18        if (device != VK_NULL_HANDLE) {
19            return dproc(device, proc_name);
20        }
21        return iproc(instance, proc_name);
22    };
23}
24
25GrVkInterface::GrVkInterface(const GetInstanceProc& getInstanceProc,
26                             const GetDeviceProc& getDeviceProc,
27                             VkInstance instance,
28                             VkDevice device,
29                             uint32_t extensionFlags)
30        : GrVkInterface(make_unified_getter(getInstanceProc, getDeviceProc),
31                        instance,
32                        device,
33                        extensionFlags) {}
34
35GrVkInterface::GrVkInterface(GetProc getProc,
36                             VkInstance instance,
37                             VkDevice device,
38                             uint32_t extensionFlags) {
39    if (getProc == nullptr) {
40        return;
41    }
42    // Global/Loader Procs.
43    ACQUIRE_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE);
44    ACQUIRE_PROC(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
45    ACQUIRE_PROC(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
46
47    // Instance Procs.
48    ACQUIRE_PROC(EnumeratePhysicalDevices, instance, VK_NULL_HANDLE);
49    ACQUIRE_PROC(GetPhysicalDeviceFeatures, instance, VK_NULL_HANDLE);
50    ACQUIRE_PROC(GetPhysicalDeviceFormatProperties, instance, VK_NULL_HANDLE);
51    ACQUIRE_PROC(GetPhysicalDeviceImageFormatProperties, instance, VK_NULL_HANDLE);
52    ACQUIRE_PROC(GetPhysicalDeviceProperties, instance, VK_NULL_HANDLE);
53    ACQUIRE_PROC(GetPhysicalDeviceQueueFamilyProperties, instance, VK_NULL_HANDLE);
54    ACQUIRE_PROC(GetPhysicalDeviceMemoryProperties, instance, VK_NULL_HANDLE);
55    ACQUIRE_PROC(GetPhysicalDeviceSparseImageFormatProperties, instance, VK_NULL_HANDLE);
56    ACQUIRE_PROC(DestroyInstance, instance, VK_NULL_HANDLE);
57    ACQUIRE_PROC(CreateDevice, instance, VK_NULL_HANDLE);
58    ACQUIRE_PROC(DestroyDevice, instance, VK_NULL_HANDLE);
59    ACQUIRE_PROC(EnumerateDeviceExtensionProperties, instance, VK_NULL_HANDLE);
60    ACQUIRE_PROC(EnumerateDeviceLayerProperties, instance, VK_NULL_HANDLE);
61
62    if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
63        // Also instance Procs.
64        ACQUIRE_PROC(CreateDebugReportCallbackEXT, instance, VK_NULL_HANDLE);
65        ACQUIRE_PROC(DebugReportMessageEXT, instance, VK_NULL_HANDLE);
66        ACQUIRE_PROC(DestroyDebugReportCallbackEXT, instance, VK_NULL_HANDLE);
67    }
68
69    // Device Procs.
70    ACQUIRE_PROC(GetDeviceQueue, VK_NULL_HANDLE, device);
71    ACQUIRE_PROC(QueueSubmit, VK_NULL_HANDLE, device);
72    ACQUIRE_PROC(QueueWaitIdle, VK_NULL_HANDLE, device);
73    ACQUIRE_PROC(DeviceWaitIdle, VK_NULL_HANDLE, device);
74    ACQUIRE_PROC(AllocateMemory, VK_NULL_HANDLE, device);
75    ACQUIRE_PROC(FreeMemory, VK_NULL_HANDLE, device);
76    ACQUIRE_PROC(MapMemory, VK_NULL_HANDLE, device);
77    ACQUIRE_PROC(UnmapMemory, VK_NULL_HANDLE, device);
78    ACQUIRE_PROC(FlushMappedMemoryRanges, VK_NULL_HANDLE, device);
79    ACQUIRE_PROC(InvalidateMappedMemoryRanges, VK_NULL_HANDLE, device);
80    ACQUIRE_PROC(GetDeviceMemoryCommitment, VK_NULL_HANDLE, device);
81    ACQUIRE_PROC(BindBufferMemory, VK_NULL_HANDLE, device);
82    ACQUIRE_PROC(BindImageMemory, VK_NULL_HANDLE, device);
83    ACQUIRE_PROC(GetBufferMemoryRequirements, VK_NULL_HANDLE, device);
84    ACQUIRE_PROC(GetImageMemoryRequirements, VK_NULL_HANDLE, device);
85    ACQUIRE_PROC(GetImageSparseMemoryRequirements, VK_NULL_HANDLE, device);
86    ACQUIRE_PROC(QueueBindSparse, VK_NULL_HANDLE, device);
87    ACQUIRE_PROC(CreateFence, VK_NULL_HANDLE, device);
88    ACQUIRE_PROC(DestroyFence, VK_NULL_HANDLE, device);
89    ACQUIRE_PROC(ResetFences, VK_NULL_HANDLE, device);
90    ACQUIRE_PROC(GetFenceStatus, VK_NULL_HANDLE, device);
91    ACQUIRE_PROC(WaitForFences, VK_NULL_HANDLE, device);
92    ACQUIRE_PROC(CreateSemaphore, VK_NULL_HANDLE, device);
93    ACQUIRE_PROC(DestroySemaphore, VK_NULL_HANDLE, device);
94    ACQUIRE_PROC(CreateEvent, VK_NULL_HANDLE, device);
95    ACQUIRE_PROC(DestroyEvent, VK_NULL_HANDLE, device);
96    ACQUIRE_PROC(GetEventStatus, VK_NULL_HANDLE, device);
97    ACQUIRE_PROC(SetEvent, VK_NULL_HANDLE, device);
98    ACQUIRE_PROC(ResetEvent, VK_NULL_HANDLE, device);
99    ACQUIRE_PROC(CreateQueryPool, VK_NULL_HANDLE, device);
100    ACQUIRE_PROC(DestroyQueryPool, VK_NULL_HANDLE, device);
101    ACQUIRE_PROC(GetQueryPoolResults, VK_NULL_HANDLE, device);
102    ACQUIRE_PROC(CreateBuffer, VK_NULL_HANDLE, device);
103    ACQUIRE_PROC(DestroyBuffer, VK_NULL_HANDLE, device);
104    ACQUIRE_PROC(CreateBufferView, VK_NULL_HANDLE, device);
105    ACQUIRE_PROC(DestroyBufferView, VK_NULL_HANDLE, device);
106    ACQUIRE_PROC(CreateImage, VK_NULL_HANDLE, device);
107    ACQUIRE_PROC(DestroyImage, VK_NULL_HANDLE, device);
108    ACQUIRE_PROC(GetImageSubresourceLayout, VK_NULL_HANDLE, device);
109    ACQUIRE_PROC(CreateImageView, VK_NULL_HANDLE, device);
110    ACQUIRE_PROC(DestroyImageView, VK_NULL_HANDLE, device);
111    ACQUIRE_PROC(CreateShaderModule, VK_NULL_HANDLE, device);
112    ACQUIRE_PROC(DestroyShaderModule, VK_NULL_HANDLE, device);
113    ACQUIRE_PROC(CreatePipelineCache, VK_NULL_HANDLE, device);
114    ACQUIRE_PROC(DestroyPipelineCache, VK_NULL_HANDLE, device);
115    ACQUIRE_PROC(GetPipelineCacheData, VK_NULL_HANDLE, device);
116    ACQUIRE_PROC(MergePipelineCaches, VK_NULL_HANDLE, device);
117    ACQUIRE_PROC(CreateGraphicsPipelines, VK_NULL_HANDLE, device);
118    ACQUIRE_PROC(CreateComputePipelines, VK_NULL_HANDLE, device);
119    ACQUIRE_PROC(DestroyPipeline, VK_NULL_HANDLE, device);
120    ACQUIRE_PROC(CreatePipelineLayout, VK_NULL_HANDLE, device);
121    ACQUIRE_PROC(DestroyPipelineLayout, VK_NULL_HANDLE, device);
122    ACQUIRE_PROC(CreateSampler, VK_NULL_HANDLE, device);
123    ACQUIRE_PROC(DestroySampler, VK_NULL_HANDLE, device);
124    ACQUIRE_PROC(CreateDescriptorSetLayout, VK_NULL_HANDLE, device);
125    ACQUIRE_PROC(DestroyDescriptorSetLayout, VK_NULL_HANDLE, device);
126    ACQUIRE_PROC(CreateDescriptorPool, VK_NULL_HANDLE, device);
127    ACQUIRE_PROC(DestroyDescriptorPool, VK_NULL_HANDLE, device);
128    ACQUIRE_PROC(ResetDescriptorPool, VK_NULL_HANDLE, device);
129    ACQUIRE_PROC(AllocateDescriptorSets, VK_NULL_HANDLE, device);
130    ACQUIRE_PROC(FreeDescriptorSets, VK_NULL_HANDLE, device);
131    ACQUIRE_PROC(UpdateDescriptorSets, VK_NULL_HANDLE, device);
132    ACQUIRE_PROC(CreateFramebuffer, VK_NULL_HANDLE, device);
133    ACQUIRE_PROC(DestroyFramebuffer, VK_NULL_HANDLE, device);
134    ACQUIRE_PROC(CreateRenderPass, VK_NULL_HANDLE, device);
135    ACQUIRE_PROC(DestroyRenderPass, VK_NULL_HANDLE, device);
136    ACQUIRE_PROC(GetRenderAreaGranularity, VK_NULL_HANDLE, device);
137    ACQUIRE_PROC(CreateCommandPool, VK_NULL_HANDLE, device);
138    ACQUIRE_PROC(DestroyCommandPool, VK_NULL_HANDLE, device);
139    ACQUIRE_PROC(ResetCommandPool, VK_NULL_HANDLE, device);
140    ACQUIRE_PROC(AllocateCommandBuffers, VK_NULL_HANDLE, device);
141    ACQUIRE_PROC(FreeCommandBuffers, VK_NULL_HANDLE, device);
142    ACQUIRE_PROC(BeginCommandBuffer, VK_NULL_HANDLE, device);
143    ACQUIRE_PROC(EndCommandBuffer, VK_NULL_HANDLE, device);
144    ACQUIRE_PROC(ResetCommandBuffer, VK_NULL_HANDLE, device);
145    ACQUIRE_PROC(CmdBindPipeline, VK_NULL_HANDLE, device);
146    ACQUIRE_PROC(CmdSetViewport, VK_NULL_HANDLE, device);
147    ACQUIRE_PROC(CmdSetScissor, VK_NULL_HANDLE, device);
148    ACQUIRE_PROC(CmdSetLineWidth, VK_NULL_HANDLE, device);
149    ACQUIRE_PROC(CmdSetDepthBias, VK_NULL_HANDLE, device);
150    ACQUIRE_PROC(CmdSetBlendConstants, VK_NULL_HANDLE, device);
151    ACQUIRE_PROC(CmdSetDepthBounds, VK_NULL_HANDLE, device);
152    ACQUIRE_PROC(CmdSetStencilCompareMask, VK_NULL_HANDLE, device);
153    ACQUIRE_PROC(CmdSetStencilWriteMask, VK_NULL_HANDLE, device);
154    ACQUIRE_PROC(CmdSetStencilReference, VK_NULL_HANDLE, device);
155    ACQUIRE_PROC(CmdBindDescriptorSets, VK_NULL_HANDLE, device);
156    ACQUIRE_PROC(CmdBindIndexBuffer, VK_NULL_HANDLE, device);
157    ACQUIRE_PROC(CmdBindVertexBuffers, VK_NULL_HANDLE, device);
158    ACQUIRE_PROC(CmdDraw, VK_NULL_HANDLE, device);
159    ACQUIRE_PROC(CmdDrawIndexed, VK_NULL_HANDLE, device);
160    ACQUIRE_PROC(CmdDrawIndirect, VK_NULL_HANDLE, device);
161    ACQUIRE_PROC(CmdDrawIndexedIndirect, VK_NULL_HANDLE, device);
162    ACQUIRE_PROC(CmdDispatch, VK_NULL_HANDLE, device);
163    ACQUIRE_PROC(CmdDispatchIndirect, VK_NULL_HANDLE, device);
164    ACQUIRE_PROC(CmdCopyBuffer, VK_NULL_HANDLE, device);
165    ACQUIRE_PROC(CmdCopyImage, VK_NULL_HANDLE, device);
166    ACQUIRE_PROC(CmdBlitImage, VK_NULL_HANDLE, device);
167    ACQUIRE_PROC(CmdCopyBufferToImage, VK_NULL_HANDLE, device);
168    ACQUIRE_PROC(CmdCopyImageToBuffer, VK_NULL_HANDLE, device);
169    ACQUIRE_PROC(CmdUpdateBuffer, VK_NULL_HANDLE, device);
170    ACQUIRE_PROC(CmdFillBuffer, VK_NULL_HANDLE, device);
171    ACQUIRE_PROC(CmdClearColorImage, VK_NULL_HANDLE, device);
172    ACQUIRE_PROC(CmdClearDepthStencilImage, VK_NULL_HANDLE, device);
173    ACQUIRE_PROC(CmdClearAttachments, VK_NULL_HANDLE, device);
174    ACQUIRE_PROC(CmdResolveImage, VK_NULL_HANDLE, device);
175    ACQUIRE_PROC(CmdSetEvent, VK_NULL_HANDLE, device);
176    ACQUIRE_PROC(CmdResetEvent, VK_NULL_HANDLE, device);
177    ACQUIRE_PROC(CmdWaitEvents, VK_NULL_HANDLE, device);
178    ACQUIRE_PROC(CmdPipelineBarrier, VK_NULL_HANDLE, device);
179    ACQUIRE_PROC(CmdBeginQuery, VK_NULL_HANDLE, device);
180    ACQUIRE_PROC(CmdEndQuery, VK_NULL_HANDLE, device);
181    ACQUIRE_PROC(CmdResetQueryPool, VK_NULL_HANDLE, device);
182    ACQUIRE_PROC(CmdWriteTimestamp, VK_NULL_HANDLE, device);
183    ACQUIRE_PROC(CmdCopyQueryPoolResults, VK_NULL_HANDLE, device);
184    ACQUIRE_PROC(CmdPushConstants, VK_NULL_HANDLE, device);
185    ACQUIRE_PROC(CmdBeginRenderPass, VK_NULL_HANDLE, device);
186    ACQUIRE_PROC(CmdNextSubpass, VK_NULL_HANDLE, device);
187    ACQUIRE_PROC(CmdEndRenderPass, VK_NULL_HANDLE, device);
188    ACQUIRE_PROC(CmdExecuteCommands, VK_NULL_HANDLE, device);
189}
190
191#ifdef SK_DEBUG
192    static int kIsDebug = 1;
193#else
194    static int kIsDebug = 0;
195#endif
196
197#define RETURN_FALSE_INTERFACE                                                                   \
198    if (kIsDebug) { SkDebugf("%s:%d GrVkInterface::validate() failed.\n", __FILE__, __LINE__); } \
199    return false;
200
201bool GrVkInterface::validate(uint32_t extensionFlags) const {
202    // functions that are always required
203    if (nullptr == fFunctions.fCreateInstance ||
204        nullptr == fFunctions.fDestroyInstance ||
205        nullptr == fFunctions.fEnumeratePhysicalDevices ||
206        nullptr == fFunctions.fGetPhysicalDeviceFeatures ||
207        nullptr == fFunctions.fGetPhysicalDeviceFormatProperties ||
208        nullptr == fFunctions.fGetPhysicalDeviceImageFormatProperties ||
209        nullptr == fFunctions.fGetPhysicalDeviceProperties ||
210        nullptr == fFunctions.fGetPhysicalDeviceQueueFamilyProperties ||
211        nullptr == fFunctions.fGetPhysicalDeviceMemoryProperties ||
212        nullptr == fFunctions.fCreateDevice ||
213        nullptr == fFunctions.fDestroyDevice ||
214        nullptr == fFunctions.fEnumerateInstanceExtensionProperties ||
215        nullptr == fFunctions.fEnumerateDeviceExtensionProperties ||
216        nullptr == fFunctions.fEnumerateInstanceLayerProperties ||
217        nullptr == fFunctions.fEnumerateDeviceLayerProperties ||
218        nullptr == fFunctions.fGetDeviceQueue ||
219        nullptr == fFunctions.fQueueSubmit ||
220        nullptr == fFunctions.fQueueWaitIdle ||
221        nullptr == fFunctions.fDeviceWaitIdle ||
222        nullptr == fFunctions.fAllocateMemory ||
223        nullptr == fFunctions.fFreeMemory ||
224        nullptr == fFunctions.fMapMemory ||
225        nullptr == fFunctions.fUnmapMemory ||
226        nullptr == fFunctions.fFlushMappedMemoryRanges ||
227        nullptr == fFunctions.fInvalidateMappedMemoryRanges ||
228        nullptr == fFunctions.fGetDeviceMemoryCommitment ||
229        nullptr == fFunctions.fBindBufferMemory ||
230        nullptr == fFunctions.fBindImageMemory ||
231        nullptr == fFunctions.fGetBufferMemoryRequirements ||
232        nullptr == fFunctions.fGetImageMemoryRequirements ||
233        nullptr == fFunctions.fGetImageSparseMemoryRequirements ||
234        nullptr == fFunctions.fGetPhysicalDeviceSparseImageFormatProperties ||
235        nullptr == fFunctions.fQueueBindSparse ||
236        nullptr == fFunctions.fCreateFence ||
237        nullptr == fFunctions.fDestroyFence ||
238        nullptr == fFunctions.fResetFences ||
239        nullptr == fFunctions.fGetFenceStatus ||
240        nullptr == fFunctions.fWaitForFences ||
241        nullptr == fFunctions.fCreateSemaphore ||
242        nullptr == fFunctions.fDestroySemaphore ||
243        nullptr == fFunctions.fCreateEvent ||
244        nullptr == fFunctions.fDestroyEvent ||
245        nullptr == fFunctions.fGetEventStatus ||
246        nullptr == fFunctions.fSetEvent ||
247        nullptr == fFunctions.fResetEvent ||
248        nullptr == fFunctions.fCreateQueryPool ||
249        nullptr == fFunctions.fDestroyQueryPool ||
250        nullptr == fFunctions.fGetQueryPoolResults ||
251        nullptr == fFunctions.fCreateBuffer ||
252        nullptr == fFunctions.fDestroyBuffer ||
253        nullptr == fFunctions.fCreateBufferView ||
254        nullptr == fFunctions.fDestroyBufferView ||
255        nullptr == fFunctions.fCreateImage ||
256        nullptr == fFunctions.fDestroyImage ||
257        nullptr == fFunctions.fGetImageSubresourceLayout ||
258        nullptr == fFunctions.fCreateImageView ||
259        nullptr == fFunctions.fDestroyImageView ||
260        nullptr == fFunctions.fCreateShaderModule ||
261        nullptr == fFunctions.fDestroyShaderModule ||
262        nullptr == fFunctions.fCreatePipelineCache ||
263        nullptr == fFunctions.fDestroyPipelineCache ||
264        nullptr == fFunctions.fGetPipelineCacheData ||
265        nullptr == fFunctions.fMergePipelineCaches ||
266        nullptr == fFunctions.fCreateGraphicsPipelines ||
267        nullptr == fFunctions.fCreateComputePipelines ||
268        nullptr == fFunctions.fDestroyPipeline ||
269        nullptr == fFunctions.fCreatePipelineLayout ||
270        nullptr == fFunctions.fDestroyPipelineLayout ||
271        nullptr == fFunctions.fCreateSampler ||
272        nullptr == fFunctions.fDestroySampler ||
273        nullptr == fFunctions.fCreateDescriptorSetLayout ||
274        nullptr == fFunctions.fDestroyDescriptorSetLayout ||
275        nullptr == fFunctions.fCreateDescriptorPool ||
276        nullptr == fFunctions.fDestroyDescriptorPool ||
277        nullptr == fFunctions.fResetDescriptorPool ||
278        nullptr == fFunctions.fAllocateDescriptorSets ||
279        nullptr == fFunctions.fFreeDescriptorSets ||
280        nullptr == fFunctions.fUpdateDescriptorSets ||
281        nullptr == fFunctions.fCreateFramebuffer ||
282        nullptr == fFunctions.fDestroyFramebuffer ||
283        nullptr == fFunctions.fCreateRenderPass ||
284        nullptr == fFunctions.fDestroyRenderPass ||
285        nullptr == fFunctions.fGetRenderAreaGranularity ||
286        nullptr == fFunctions.fCreateCommandPool ||
287        nullptr == fFunctions.fDestroyCommandPool ||
288        nullptr == fFunctions.fResetCommandPool ||
289        nullptr == fFunctions.fAllocateCommandBuffers ||
290        nullptr == fFunctions.fFreeCommandBuffers ||
291        nullptr == fFunctions.fBeginCommandBuffer ||
292        nullptr == fFunctions.fEndCommandBuffer ||
293        nullptr == fFunctions.fResetCommandBuffer ||
294        nullptr == fFunctions.fCmdBindPipeline ||
295        nullptr == fFunctions.fCmdSetViewport ||
296        nullptr == fFunctions.fCmdSetScissor ||
297        nullptr == fFunctions.fCmdSetLineWidth ||
298        nullptr == fFunctions.fCmdSetDepthBias ||
299        nullptr == fFunctions.fCmdSetBlendConstants ||
300        nullptr == fFunctions.fCmdSetDepthBounds ||
301        nullptr == fFunctions.fCmdSetStencilCompareMask ||
302        nullptr == fFunctions.fCmdSetStencilWriteMask ||
303        nullptr == fFunctions.fCmdSetStencilReference ||
304        nullptr == fFunctions.fCmdBindDescriptorSets ||
305        nullptr == fFunctions.fCmdBindIndexBuffer ||
306        nullptr == fFunctions.fCmdBindVertexBuffers ||
307        nullptr == fFunctions.fCmdDraw ||
308        nullptr == fFunctions.fCmdDrawIndexed ||
309        nullptr == fFunctions.fCmdDrawIndirect ||
310        nullptr == fFunctions.fCmdDrawIndexedIndirect ||
311        nullptr == fFunctions.fCmdDispatch ||
312        nullptr == fFunctions.fCmdDispatchIndirect ||
313        nullptr == fFunctions.fCmdCopyBuffer ||
314        nullptr == fFunctions.fCmdCopyImage ||
315        nullptr == fFunctions.fCmdBlitImage ||
316        nullptr == fFunctions.fCmdCopyBufferToImage ||
317        nullptr == fFunctions.fCmdCopyImageToBuffer ||
318        nullptr == fFunctions.fCmdUpdateBuffer ||
319        nullptr == fFunctions.fCmdFillBuffer ||
320        nullptr == fFunctions.fCmdClearColorImage ||
321        nullptr == fFunctions.fCmdClearDepthStencilImage ||
322        nullptr == fFunctions.fCmdClearAttachments ||
323        nullptr == fFunctions.fCmdResolveImage ||
324        nullptr == fFunctions.fCmdSetEvent ||
325        nullptr == fFunctions.fCmdResetEvent ||
326        nullptr == fFunctions.fCmdWaitEvents ||
327        nullptr == fFunctions.fCmdPipelineBarrier ||
328        nullptr == fFunctions.fCmdBeginQuery ||
329        nullptr == fFunctions.fCmdEndQuery ||
330        nullptr == fFunctions.fCmdResetQueryPool ||
331        nullptr == fFunctions.fCmdWriteTimestamp ||
332        nullptr == fFunctions.fCmdCopyQueryPoolResults ||
333        nullptr == fFunctions.fCmdPushConstants ||
334        nullptr == fFunctions.fCmdBeginRenderPass ||
335        nullptr == fFunctions.fCmdNextSubpass ||
336        nullptr == fFunctions.fCmdEndRenderPass ||
337        nullptr == fFunctions.fCmdExecuteCommands) {
338        RETURN_FALSE_INTERFACE
339    }
340
341    if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
342        if (nullptr == fFunctions.fCreateDebugReportCallbackEXT ||
343            nullptr == fFunctions.fDebugReportMessageEXT ||
344            nullptr == fFunctions.fDestroyDebugReportCallbackEXT) {
345            RETURN_FALSE_INTERFACE
346        }
347    }
348    return true;
349}
350
351