blob: 97508b2de4cdb44ecbe11d9bb3413499dddc4c47 [file] [log] [blame]
bsalomon18a2f9d2016-05-11 10:09:18 -07001/*
2 * Copyright 2016 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 "VkTestContext.h"
9
10#ifdef SK_VULKAN
11
Greg Daniel02611d92017-07-25 10:05:01 -040012#include "GrContext.h"
Greg Daniel35970ec2017-11-10 10:03:05 -050013#include "VkTestUtils.h"
bsalomonedea94c2016-05-16 14:09:56 -070014#include "vk/GrVkInterface.h"
15#include "vk/GrVkUtil.h"
bsalomonedea94c2016-05-16 14:09:56 -070016
bsalomon18a2f9d2016-05-11 10:09:18 -070017namespace {
Greg Danielc8cd45a2018-07-12 10:02:37 -040018
19#define ACQUIRE_VK_PROC(name, device) \
20 f##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, nullptr, device)); \
21 SkASSERT(f##name);
22
bsalomonedea94c2016-05-16 14:09:56 -070023/**
csmartdalton421a3c12016-10-04 11:08:45 -070024 * Implements sk_gpu_test::FenceSync for Vulkan. It creates a single command
25 * buffer with USAGE_SIMULTANEOUS with no content . On every insertFence request
26 * it submits the command buffer with a new fence.
bsalomonedea94c2016-05-16 14:09:56 -070027 */
csmartdalton421a3c12016-10-04 11:08:45 -070028class VkFenceSync : public sk_gpu_test::FenceSync {
bsalomonedea94c2016-05-16 14:09:56 -070029public:
Greg Danielc8cd45a2018-07-12 10:02:37 -040030 VkFenceSync(GrVkGetProc getProc, VkDevice device, VkQueue queue,
bsalomonedea94c2016-05-16 14:09:56 -070031 uint32_t queueFamilyIndex)
Greg Danielc8cd45a2018-07-12 10:02:37 -040032 : fDevice(device)
bsalomonedea94c2016-05-16 14:09:56 -070033 , fQueue(queue) {
Greg Danielc8cd45a2018-07-12 10:02:37 -040034 ACQUIRE_VK_PROC(CreateCommandPool, device);
35 ACQUIRE_VK_PROC(DestroyCommandPool, device);
36 ACQUIRE_VK_PROC(AllocateCommandBuffers, device);
37 ACQUIRE_VK_PROC(FreeCommandBuffers, device);
38 ACQUIRE_VK_PROC(BeginCommandBuffer, device);
39 ACQUIRE_VK_PROC(EndCommandBuffer, device);
40 ACQUIRE_VK_PROC(CreateFence, device);
41 ACQUIRE_VK_PROC(DestroyFence, device);
42 ACQUIRE_VK_PROC(WaitForFences, device);
43 ACQUIRE_VK_PROC(QueueSubmit, device);
44
45 VkResult result;
bsalomonedea94c2016-05-16 14:09:56 -070046 SkDEBUGCODE(fUnfinishedSyncs = 0;)
47 VkCommandPoolCreateInfo createInfo;
48 createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
49 createInfo.pNext = nullptr;
50 createInfo.flags = 0;
51 createInfo.queueFamilyIndex = queueFamilyIndex;
Greg Danielc8cd45a2018-07-12 10:02:37 -040052 result = fCreateCommandPool(fDevice, &createInfo, nullptr, &fCommandPool);
53 SkASSERT(VK_SUCCESS == result);
bsalomonedea94c2016-05-16 14:09:56 -070054
55 VkCommandBufferAllocateInfo allocateInfo;
56 allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
57 allocateInfo.pNext = nullptr;
58 allocateInfo.commandBufferCount = 1;
59 allocateInfo.commandPool = fCommandPool;
60 allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
Greg Danielc8cd45a2018-07-12 10:02:37 -040061 result = fAllocateCommandBuffers(fDevice, &allocateInfo, &fCommandBuffer);
62 SkASSERT(VK_SUCCESS == result);
bsalomonedea94c2016-05-16 14:09:56 -070063
64 VkCommandBufferBeginInfo beginInfo;
65 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
66 beginInfo.pNext = nullptr;
67 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
68 beginInfo.pInheritanceInfo = nullptr;
Greg Danielc8cd45a2018-07-12 10:02:37 -040069 result = fBeginCommandBuffer(fCommandBuffer, &beginInfo);
70 SkASSERT(VK_SUCCESS == result);
71 result = fEndCommandBuffer(fCommandBuffer);
72 SkASSERT(VK_SUCCESS == result);
73
bsalomonedea94c2016-05-16 14:09:56 -070074 }
75
76 ~VkFenceSync() override {
77 SkASSERT(!fUnfinishedSyncs);
78 // If the above assertion is true then the command buffer should not be in flight.
Greg Danielc8cd45a2018-07-12 10:02:37 -040079 fFreeCommandBuffers(fDevice, fCommandPool, 1, &fCommandBuffer);
80 fDestroyCommandPool(fDevice, fCommandPool, nullptr);
bsalomonedea94c2016-05-16 14:09:56 -070081 }
82
csmartdalton421a3c12016-10-04 11:08:45 -070083 sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const override {
Greg Danielc8cd45a2018-07-12 10:02:37 -040084 VkResult result;
85
bsalomonedea94c2016-05-16 14:09:56 -070086 VkFence fence;
87 VkFenceCreateInfo info;
88 info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
89 info.pNext = nullptr;
90 info.flags = 0;
Greg Danielc8cd45a2018-07-12 10:02:37 -040091 result = fCreateFence(fDevice, &info, nullptr, &fence);
92 SkASSERT(VK_SUCCESS == result);
93
bsalomonedea94c2016-05-16 14:09:56 -070094 VkSubmitInfo submitInfo;
95 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
96 submitInfo.pNext = nullptr;
97 submitInfo.waitSemaphoreCount = 0;
98 submitInfo.pWaitSemaphores = nullptr;
99 submitInfo.pWaitDstStageMask = nullptr;
100 submitInfo.commandBufferCount = 1;
101 submitInfo.pCommandBuffers = &fCommandBuffer;
102 submitInfo.signalSemaphoreCount = 0;
103 submitInfo.pSignalSemaphores = nullptr;
Greg Danielc8cd45a2018-07-12 10:02:37 -0400104 result = fQueueSubmit(fQueue, 1, &submitInfo, fence);
105 SkASSERT(VK_SUCCESS == result);
106
bsalomonedea94c2016-05-16 14:09:56 -0700107 SkDEBUGCODE(++fUnfinishedSyncs;)
Brian Osmanbbdf45e2016-10-10 17:04:52 -0400108 return (sk_gpu_test::PlatformFence)fence;
bsalomonedea94c2016-05-16 14:09:56 -0700109 }
110
csmartdalton421a3c12016-10-04 11:08:45 -0700111 bool waitFence(sk_gpu_test::PlatformFence opaqueFence) const override {
Brian Osmanbbdf45e2016-10-10 17:04:52 -0400112 VkFence fence = (VkFence)opaqueFence;
bsalomonedea94c2016-05-16 14:09:56 -0700113 static constexpr uint64_t kForever = ~((uint64_t)0);
Greg Danielc8cd45a2018-07-12 10:02:37 -0400114 auto result = fWaitForFences(fDevice, 1, &fence, true, kForever);
bsalomonedea94c2016-05-16 14:09:56 -0700115 return result != VK_TIMEOUT;
116 }
117
csmartdalton421a3c12016-10-04 11:08:45 -0700118 void deleteFence(sk_gpu_test::PlatformFence opaqueFence) const override {
Brian Osmanbbdf45e2016-10-10 17:04:52 -0400119 VkFence fence = (VkFence)opaqueFence;
Greg Danielc8cd45a2018-07-12 10:02:37 -0400120 fDestroyFence(fDevice, fence, nullptr);
bsalomonedea94c2016-05-16 14:09:56 -0700121 SkDEBUGCODE(--fUnfinishedSyncs;)
122 }
123
124private:
bsalomonedea94c2016-05-16 14:09:56 -0700125 VkDevice fDevice;
126 VkQueue fQueue;
127 VkCommandPool fCommandPool;
128 VkCommandBuffer fCommandBuffer;
Greg Danielc8cd45a2018-07-12 10:02:37 -0400129
130 PFN_vkCreateCommandPool fCreateCommandPool = nullptr;
131 PFN_vkDestroyCommandPool fDestroyCommandPool = nullptr;
132 PFN_vkAllocateCommandBuffers fAllocateCommandBuffers = nullptr;
133 PFN_vkFreeCommandBuffers fFreeCommandBuffers = nullptr;
134 PFN_vkBeginCommandBuffer fBeginCommandBuffer = nullptr;
135 PFN_vkEndCommandBuffer fEndCommandBuffer = nullptr;
136 PFN_vkCreateFence fCreateFence = nullptr;
137 PFN_vkDestroyFence fDestroyFence = nullptr;
138 PFN_vkWaitForFences fWaitForFences = nullptr;
139 PFN_vkQueueSubmit fQueueSubmit = nullptr;
140
bsalomonedea94c2016-05-16 14:09:56 -0700141 SkDEBUGCODE(mutable int fUnfinishedSyncs;)
csmartdalton421a3c12016-10-04 11:08:45 -0700142 typedef sk_gpu_test::FenceSync INHERITED;
bsalomonedea94c2016-05-16 14:09:56 -0700143};
144
csmartdalton024229a2016-10-04 14:24:23 -0700145GR_STATIC_ASSERT(sizeof(VkFence) <= sizeof(sk_gpu_test::PlatformFence));
146
bsalomonedea94c2016-05-16 14:09:56 -0700147// TODO: Implement swap buffers and finish
bsalomon18a2f9d2016-05-11 10:09:18 -0700148class VkTestContextImpl : public sk_gpu_test::VkTestContext {
149public:
Greg Daniel604b1972017-05-15 13:50:35 -0400150 static VkTestContext* Create(VkTestContext* sharedContext) {
Greg Danielf730c182018-07-02 20:15:37 +0000151 GrVkBackendContext backendContext;
152 bool ownsContext = true;
Greg Daniel37329b32018-07-02 20:16:44 +0000153 VkDebugReportCallbackEXT debugCallback = VK_NULL_HANDLE;
Greg Daniel604b1972017-05-15 13:50:35 -0400154 if (sharedContext) {
155 backendContext = sharedContext->getVkBackendContext();
Greg Danielf730c182018-07-02 20:15:37 +0000156 // We always delete the parent context last so make sure the child does not think they
157 // own the vulkan context.
158 ownsContext = false;
Greg Daniel604b1972017-05-15 13:50:35 -0400159 } else {
Greg Daniel35970ec2017-11-10 10:03:05 -0500160 PFN_vkGetInstanceProcAddr instProc;
161 PFN_vkGetDeviceProcAddr devProc;
162 if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
163 return nullptr;
164 }
Greg Daniel37329b32018-07-02 20:16:44 +0000165 if (!sk_gpu_test::CreateVkBackendContext(instProc, devProc, &backendContext,
166 &debugCallback)) {
Greg Danielf730c182018-07-02 20:15:37 +0000167 return nullptr;
168 }
Greg Daniel604b1972017-05-15 13:50:35 -0400169 }
Greg Daniel37329b32018-07-02 20:16:44 +0000170 return new VkTestContextImpl(backendContext, ownsContext, debugCallback);
bsalomonedea94c2016-05-16 14:09:56 -0700171 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700172
173 ~VkTestContextImpl() override { this->teardown(); }
174
175 void testAbandon() override {}
176
bsalomonedea94c2016-05-16 14:09:56 -0700177 // There is really nothing to here since we don't own any unqueued command buffers here.
bsalomonc8699322016-05-11 11:55:36 -0700178 void submit() override {}
bsalomonedea94c2016-05-16 14:09:56 -0700179
bsalomonc8699322016-05-11 11:55:36 -0700180 void finish() override {}
181
Greg Daniel02611d92017-07-25 10:05:01 -0400182 sk_sp<GrContext> makeGrContext(const GrContextOptions& options) override {
Brian Salomon384fab42017-12-07 12:33:05 -0500183 return GrContext::MakeVulkan(fVk, options);
Greg Daniel02611d92017-07-25 10:05:01 -0400184 }
185
bsalomon18a2f9d2016-05-11 10:09:18 -0700186protected:
Greg Danielc8cd45a2018-07-12 10:02:37 -0400187#define ACQUIRE_VK_PROC_LOCAL(name, inst) \
188 PFN_vk##name grVk##name = \
189 reinterpret_cast<PFN_vk##name>(fVk.fGetProc("vk" #name, inst, nullptr)); \
190 if (grVk##name == nullptr) { \
191 SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
192 return; \
193 }
194
bsalomonedea94c2016-05-16 14:09:56 -0700195 void teardown() override {
196 INHERITED::teardown();
Greg Danielf730c182018-07-02 20:15:37 +0000197 fVk.fMemoryAllocator.reset();
198 if (fOwnsContext) {
Greg Danielc8cd45a2018-07-12 10:02:37 -0400199 ACQUIRE_VK_PROC_LOCAL(DeviceWaitIdle, fVk.fInstance);
200 ACQUIRE_VK_PROC_LOCAL(DestroyDevice, fVk.fInstance);
201 ACQUIRE_VK_PROC_LOCAL(DestroyInstance, fVk.fInstance);
202 grVkDeviceWaitIdle(fVk.fDevice);
203 grVkDestroyDevice(fVk.fDevice, nullptr);
Greg Daniel37329b32018-07-02 20:16:44 +0000204#ifdef SK_ENABLE_VK_LAYERS
205 if (fDebugCallback != VK_NULL_HANDLE) {
Greg Danielc8cd45a2018-07-12 10:02:37 -0400206 ACQUIRE_VK_PROC_LOCAL(DestroyDebugReportCallbackEXT, fVk.fInstance);
207 grVkDestroyDebugReportCallbackEXT(fVk.fInstance, fDebugCallback, nullptr);
Greg Daniel37329b32018-07-02 20:16:44 +0000208 }
209#endif
Greg Danielc8cd45a2018-07-12 10:02:37 -0400210 grVkDestroyInstance(fVk.fInstance, nullptr);
Greg Danielf730c182018-07-02 20:15:37 +0000211 }
bsalomonedea94c2016-05-16 14:09:56 -0700212 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700213
214private:
Greg Daniel37329b32018-07-02 20:16:44 +0000215 VkTestContextImpl(const GrVkBackendContext& backendContext, bool ownsContext,
216 VkDebugReportCallbackEXT debugCallback)
217 : VkTestContext(backendContext, ownsContext, debugCallback) {
Greg Danielc8cd45a2018-07-12 10:02:37 -0400218 fFenceSync.reset(new VkFenceSync(fVk.fGetProc, fVk.fDevice, fVk.fQueue,
Greg Danielf730c182018-07-02 20:15:37 +0000219 fVk.fGraphicsQueueIndex));
bsalomonedea94c2016-05-16 14:09:56 -0700220 }
221
bsalomon18a2f9d2016-05-11 10:09:18 -0700222 void onPlatformMakeCurrent() const override {}
Brian Salomon55ad7742017-11-17 09:25:23 -0500223 std::function<void()> onPlatformGetAutoContextRestore() const override { return nullptr; }
bsalomon18a2f9d2016-05-11 10:09:18 -0700224 void onPlatformSwapBuffers() const override {}
225
226 typedef sk_gpu_test::VkTestContext INHERITED;
227};
csmartdalton421a3c12016-10-04 11:08:45 -0700228} // anonymous namespace
bsalomon18a2f9d2016-05-11 10:09:18 -0700229
230namespace sk_gpu_test {
Greg Daniel604b1972017-05-15 13:50:35 -0400231VkTestContext* CreatePlatformVkTestContext(VkTestContext* sharedContext) {
232 return VkTestContextImpl::Create(sharedContext);
233}
bsalomon18a2f9d2016-05-11 10:09:18 -0700234} // namespace sk_gpu_test
235
236#endif