Skip to content

Commit 4b60b83

Browse files
committed
Vulkan: test external context callbacks
1 parent 396421a commit 4b60b83

1 file changed

Lines changed: 107 additions & 4 deletions

File tree

test/generator/acquire_release_aottest.cpp

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,109 @@ extern "C" int halide_webgpu_release_context(void *user_context) {
143143
}
144144

145145
#define HAS_MULTIPLE_CONTEXTS true
146+
#elif defined(TEST_VULKAN)
147+
148+
#include "HalideRuntimeVulkan.h"
149+
150+
struct gpu_context {
151+
halide_vulkan_memory_allocator *allocator = nullptr;
152+
VkInstance instance = nullptr;
153+
VkDevice device = nullptr;
154+
VkPhysicalDevice physical_device = nullptr;
155+
VkQueue queue = nullptr;
156+
uint32_t queue_family_index = 0;
157+
VkDebugUtilsMessengerEXT messenger = nullptr;
158+
halide_vulkan_acquire_context_t previous_acquire = nullptr;
159+
halide_vulkan_release_context_t previous_release = nullptr;
160+
int acquires = 0;
161+
int releases = 0;
162+
} vulkan_context;
163+
164+
extern "C" int custom_vulkan_acquire_context(void *user_context,
165+
halide_vulkan_memory_allocator **allocator,
166+
VkInstance *instance,
167+
VkDevice *device,
168+
VkPhysicalDevice *physical_device,
169+
VkQueue *queue,
170+
uint32_t *queue_family_index,
171+
VkDebugUtilsMessengerEXT *messenger,
172+
bool create) {
173+
if (vulkan_context.allocator == nullptr || vulkan_context.instance == nullptr) {
174+
return halide_error_code_device_interface_no_device;
175+
}
176+
*allocator = vulkan_context.allocator;
177+
*instance = vulkan_context.instance;
178+
*device = vulkan_context.device;
179+
*physical_device = vulkan_context.physical_device;
180+
*queue = vulkan_context.queue;
181+
*queue_family_index = vulkan_context.queue_family_index;
182+
*messenger = vulkan_context.messenger;
183+
vulkan_context.acquires++;
184+
return halide_error_code_success;
185+
}
186+
187+
extern "C" int custom_vulkan_release_context(void *user_context,
188+
VkInstance instance,
189+
VkDevice device,
190+
VkQueue queue,
191+
VkDebugUtilsMessengerEXT messenger) {
192+
vulkan_context.releases++;
193+
return halide_error_code_success;
194+
}
195+
196+
bool init_context() {
197+
halide_vulkan_memory_allocator *default_allocator = nullptr;
198+
// Use Halide's built-in Vulkan setup to get real handles, then exercise the
199+
// same callback and allocator path an embedder would use for its own context.
200+
int result = halide_vulkan_acquire_context(nullptr,
201+
&default_allocator,
202+
&vulkan_context.instance,
203+
&vulkan_context.device,
204+
&vulkan_context.physical_device,
205+
&vulkan_context.queue,
206+
&vulkan_context.queue_family_index,
207+
&vulkan_context.messenger,
208+
true);
209+
if (result != halide_error_code_success) {
210+
printf("[SKIP] Failed to create Vulkan context: %d\n", result);
211+
return false;
212+
}
213+
halide_vulkan_release_context(nullptr, vulkan_context.instance, vulkan_context.device,
214+
vulkan_context.queue, vulkan_context.messenger);
215+
216+
result = halide_vulkan_acquire_memory_allocator(nullptr,
217+
&vulkan_context.allocator,
218+
vulkan_context.instance,
219+
vulkan_context.device,
220+
vulkan_context.physical_device);
221+
if (result != halide_error_code_success) {
222+
printf("Failed to create external Vulkan allocator: %d\n", result);
223+
return false;
224+
}
225+
226+
vulkan_context.previous_acquire = halide_set_vulkan_acquire_context(custom_vulkan_acquire_context);
227+
vulkan_context.previous_release = halide_set_vulkan_release_context(custom_vulkan_release_context);
228+
return true;
229+
}
230+
231+
void destroy_context() {
232+
int result = halide_vulkan_release_memory_allocator(nullptr,
233+
vulkan_context.allocator,
234+
vulkan_context.instance,
235+
vulkan_context.device,
236+
vulkan_context.physical_device);
237+
if (result != halide_error_code_success) {
238+
printf("Failed to release external Vulkan allocator: %d\n", result);
239+
}
240+
assert(vulkan_context.acquires == vulkan_context.releases);
241+
vulkan_context.allocator = nullptr;
242+
243+
halide_set_vulkan_acquire_context(vulkan_context.previous_acquire);
244+
halide_set_vulkan_release_context(vulkan_context.previous_release);
245+
halide_device_release(nullptr, halide_vulkan_device_interface());
246+
247+
vulkan_context = gpu_context{};
248+
}
146249
#else
147250
// Just use the default implementation of acquire/release.
148251
bool init_context() {
@@ -194,10 +297,14 @@ bool run_test() {
194297
output.device_free();
195298

196299
if (interface != nullptr) {
300+
#if defined(TEST_VULKAN)
301+
destroy_context();
302+
#else
197303
halide_device_release(nullptr, interface);
198304

199305
// Free the context we created.
200306
destroy_context();
307+
#endif
201308
} else {
202309
printf("Device interface is nullptr.\n");
203310
}
@@ -207,17 +314,13 @@ bool run_test() {
207314
}
208315

209316
int main(int argc, char **argv) {
210-
#if defined(TEST_VULKAN)
211-
printf("[SKIP] Vulkan doesn't implement a custom context for this test.\n");
212-
#else
213317
if (!run_test()) {
214318
return 1;
215319
}
216320

217321
if (!run_test()) {
218322
return 1;
219323
}
220-
#endif
221324
return 0;
222325
}
223326

0 commit comments

Comments
 (0)