Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: tools/vulkan/VulkanTestContext.cpp

Issue 1848833005: First pass at VulkanViewer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments, plus add GM rendering Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1
2 /*
3 * Copyright 2015 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "GrContext.h"
10 #include "SkSurface.h"
11 #include "VulkanTestContext.h"
12
13 #include "vk/GrVkInterface.h"
14 #include "vk/GrVkUtil.h"
15 #include "vk/GrVkTypes.h"
16
17 #ifdef VK_USE_PLATFORM_WIN32_KHR
18 // windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
19 #undef CreateSemaphore
20 #endif
21
22 VulkanTestContext::VulkanTestContext(void* platformData, int msaaSampleCount)
23 : fSurface(VK_NULL_HANDLE)
24 , fSwapchain(VK_NULL_HANDLE)
25 , fCommandPool(VK_NULL_HANDLE)
26 , fBackbuffers(nullptr) {
27
28 // any config code here (particularly for msaa)?
29
30 this->initializeContext(platformData);
31 }
32
33 void VulkanTestContext::initializeContext(void* platformData) {
34
35 fBackendContext.reset(GrVkBackendContext::Create());
36 fBackendContext->ref();
37
38 fContext = GrContext::Create(kVulkan_GrBackend, (GrBackendContext)fBackendCo ntext.get());
39
40 fSurface = createVkSurface(platformData);
41 if (VK_NULL_HANDLE == fSurface) {
42 fBackendContext.reset(nullptr);
43 return;
44 }
45
46 // query to get the initial queue props size
47 uint32_t queueCount;
48 GR_VK_CALL(fBackendContext->fInterface,
49 GetPhysicalDeviceQueueFamilyProperties(fBackendContext->fPhysical Device, &queueCount,
50 nullptr));
51 SkASSERT(queueCount >= 1);
52
53 SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties));
54 // now get the actual queue props
55 VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAl loc.get();
56
57 GR_VK_CALL(fBackendContext->fInterface,
58 GetPhysicalDeviceQueueFamilyProperties(fBackendContext->fPhysical Device, &queueCount,
59 queueProps));
60
61 // iterate to find the present queue
62 fPresentQueueIndex = -1;
63 for (uint32_t i = 0; i < queueCount; i++) {
64 if ((queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && canPresent(i)) {
65 fPresentQueueIndex = i;
66 break;
67 }
68 }
69 SkASSERT(0 <= fPresentQueueIndex && fPresentQueueIndex < queueCount);
70
71 VkBool32 supported;
72 VkResult res = GR_VK_CALL(fBackendContext->fInterface,
73 GetPhysicalDeviceSurfaceSupportKHR(fBackendContext ->fPhysicalDevice,
74 fPresentQueueIn dex,
75 fSurface,
76 &supported));
77 if (VK_SUCCESS != res) {
78 this->destroyContext();
79 return;
80 }
81
82 // get this info from somewhere?
83 if (!this->createSwapchain(1024, 768)) {
84 this->destroyContext();
85 return;
86 }
87
88 // create presentQueue
89 vkGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQ ueue);
90
91
92 }
93
94 bool VulkanTestContext::createSwapchain(uint32_t width, uint32_t height)
95 {
96 // check for capabilities
97 VkSurfaceCapabilitiesKHR caps;
98 VkResult res = GR_VK_CALL(fBackendContext->fInterface,
99 GetPhysicalDeviceSurfaceCapabilitiesKHR(fBackendConte xt->fPhysicalDevice,
100 fSurface,
101 &caps));
102 if (VK_SUCCESS != res) {
103 return false;
104 }
105
106 uint32_t surfaceFormatCount;
107 res = GR_VK_CALL(fBackendContext->fInterface,
108 GetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysic alDevice,
109 fSurface,
110 &surfaceFormatCount,
111 nullptr));
112 if (VK_SUCCESS != res) {
113 return false;
114 }
115
116 SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatK HR));
117 VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc .get();
118 res = GR_VK_CALL(fBackendContext->fInterface,
119 GetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysic alDevice,
120 fSurface,
121 &surfaceFormatCount,
122 surfaceFormats));
123 if (VK_SUCCESS != res) {
124 return false;
125 }
126
127 uint32_t presentModeCount;
128 res = GR_VK_CALL(fBackendContext->fInterface,
129 GetPhysicalDeviceSurfacePresentModesKHR(fBackendContext->fP hysicalDevice,
130 fSurface,
131 &presentModeCount,
132 nullptr));
133 if (VK_SUCCESS != res) {
134 return false;
135 }
136
137 SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
138 VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
139 res = GR_VK_CALL(fBackendContext->fInterface,
140 GetPhysicalDeviceSurfacePresentModesKHR(fBackendContext->fP hysicalDevice,
141 fSurface,
142 &presentModeCount,
143 presentModes));
144 if (VK_SUCCESS != res) {
145 return false;
146 }
147
148 VkExtent2D extent = caps.currentExtent;
149 // use the hints
150 if (extent.width == (uint32_t)-1) {
151 extent.width = width;
152 extent.height = height;
153 }
154
155 // clamp width; to protect us from broken hints?
156 if (extent.width < caps.minImageExtent.width) {
157 extent.width = caps.minImageExtent.width;
158 } else if (extent.width > caps.maxImageExtent.width) {
159 extent.width = caps.maxImageExtent.width;
160 }
161 // clamp height
162 if (extent.height < caps.minImageExtent.height) {
163 extent.height = caps.minImageExtent.height;
164 } else if (extent.height > caps.maxImageExtent.height) {
165 extent.height = caps.maxImageExtent.height;
166 }
167 fWidth = (int)extent.width;
168 fHeight = (int)extent.height;
169
170 uint32_t imageCount = caps.minImageCount + 2;
171 if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
172 // Application must settle for fewer images than desired:
173 imageCount = caps.maxImageCount;
174 }
175
176 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
177 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
178 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
179 SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags);
180 SkASSERT(caps.supportedTransforms & caps.currentTransform);
181 SkASSERT(caps.supportedCompositeAlpha & (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
182 VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) );
183 VkCompositeAlphaFlagBitsKHR composite_alpha =
184 (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ?
185 VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR :
186 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
187
188 // FIFO is the only mode universally supported
189 VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
190 bool vsync = false;
191 for (uint32_t i = 0; i < presentModeCount; ++i) {
192 if ((vsync && VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) ||
193 (!vsync && VK_PRESENT_MODE_IMMEDIATE_KHR == presentModes[i])) {
194 mode = presentModes[i];
195 }
196 }
197
198 VkSwapchainCreateInfoKHR swapchainCreateInfo;
199 memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
200 swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
201 swapchainCreateInfo.surface = fSurface;
202 swapchainCreateInfo.minImageCount = imageCount;
203 swapchainCreateInfo.imageFormat = surfaceFormats[0].format; // for now , use the first one
204 swapchainCreateInfo.imageColorSpace = surfaceFormats[0].colorSpace;
205 swapchainCreateInfo.imageExtent = extent;
206 swapchainCreateInfo.imageArrayLayers = 1;
207 swapchainCreateInfo.imageUsage = usageFlags;
208
209 uint32_t queueFamilies[] = { fBackendContext->fQueueFamilyIndex, fPresentQue ueIndex };
210 if (fBackendContext->fQueueFamilyIndex != fPresentQueueIndex) {
211 swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
212 swapchainCreateInfo.queueFamilyIndexCount = 2;
213 swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
214 } else {
215 swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
216 swapchainCreateInfo.queueFamilyIndexCount = 0;
217 swapchainCreateInfo.pQueueFamilyIndices = nullptr;
218 }
219
220 swapchainCreateInfo.preTransform = caps.currentTransform;;
221 swapchainCreateInfo.compositeAlpha = composite_alpha;
222 swapchainCreateInfo.presentMode = mode;
223 swapchainCreateInfo.clipped = true;
224 swapchainCreateInfo.oldSwapchain = fSwapchain;
225
226 res = GR_VK_CALL(fBackendContext->fInterface,
227 CreateSwapchainKHR(fBackendContext->fDevice,
228 &swapchainCreateInfo, nullptr, &fSwapcha in));
229 if (VK_SUCCESS != res) {
230 return false;
231 }
232
233 // destroy the old swapchain
234 if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
235 GR_VK_CALL(fBackendContext->fInterface, DeviceWaitIdle(fBackendContext-> fDevice));
236
237 this->destroyBuffers();
238
239 GR_VK_CALL(fBackendContext->fInterface, DestroySwapchainKHR(fBackendCont ext->fDevice,
240 swapchainCrea teInfo.oldSwapchain,
241 nullptr));
242 }
243
244 GrVkFormatToPixelConfig(swapchainCreateInfo.imageFormat, &fPixelConfig);
245
246 this->createBuffers();
247
248 return true;
249 }
250
251 void VulkanTestContext::createBuffers() {
252 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface, GetSwapchainImagesKHR(fBack endContext->fDevice,
253 fSwap chain,
254 &fIma geCount,
255 nullp tr));
256 SkASSERT(fImageCount);
257 fImages = new VkImage[fImageCount];
258 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface, GetSwapchainImagesKHR(fBack endContext->fDevice,
259 fSwap chain,
260 &fIma geCount,
261 fImag es));
262
263 // set up initial image layouts and create surfaces
264 fImageLayouts = new VkImageLayout[fImageCount];
265 fSurfaces = new sk_sp<SkSurface>[fImageCount];
266 for (uint32_t i = 0; i < fImageCount; ++i) {
267 fImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
268
269 GrBackendRenderTargetDesc desc;
270 GrVkTextureInfo info;
271 info.fImage = fImages[i];
272 info.fAlloc = nullptr;
273 info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
274 info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
275 desc.fWidth = fWidth;
276 desc.fHeight = fHeight;
277 desc.fConfig = fPixelConfig;
278 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
279 desc.fSampleCnt = 0;
280 desc.fStencilBits = 0;
281 desc.fRenderTargetHandle = (GrBackendObject) &info;
282 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
283 fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc, &p rops);
284 }
285
286 // create the command pool for the command buffers
287 if (VK_NULL_HANDLE == fCommandPool) {
288 VkCommandPoolCreateInfo commandPoolInfo;
289 memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo));
290 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
291 // this needs to be on the render queue
292 commandPoolInfo.queueFamilyIndex = fBackendContext->fQueueFamilyIndex;
293 commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
294 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
295 CreateCommandPool(fBackendContext->fDevice, &command PoolInfo,
296 nullptr, &fCommandPool));
297 }
298
299 // set up the backbuffers
300 VkSemaphoreCreateInfo semaphoreInfo;
301 memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
302 semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
303 semaphoreInfo.pNext = nullptr;
304 semaphoreInfo.flags = 0;
305 VkCommandBufferAllocateInfo commandBuffersInfo;
306 memset(&commandBuffersInfo, 0, sizeof(VkCommandBufferAllocateInfo));
307 commandBuffersInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
308 commandBuffersInfo.pNext = nullptr;
309 commandBuffersInfo.commandPool = fCommandPool;
310 commandBuffersInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
311 commandBuffersInfo.commandBufferCount = 2;
312 VkFenceCreateInfo fenceInfo;
313 memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
314 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
315 fenceInfo.pNext = nullptr;
316 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
317
318 // we create one additional backbuffer structure here, because we want to
319 // give the command buffers they contain a chance to finish before we cycle back
320 fBackbuffers = new BackbufferInfo[fImageCount + 1];
321 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
322 fBackbuffers[i].fImageIndex = -1;
323 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
324 CreateSemaphore(fBackendContext->fDevice, &semaphore Info,
325 nullptr, &fBackbuffers[i].fAcquireSe maphore));
326 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
327 CreateSemaphore(fBackendContext->fDevice, &semaphore Info,
328 nullptr, &fBackbuffers[i].fRenderSem aphore));
329 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
330 AllocateCommandBuffers(fBackendContext->fDevice, &co mmandBuffersInfo,
331 fBackbuffers[i].fTransitionCm dBuffers));
332 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
333 CreateFence(fBackendContext->fDevice, &fenceInfo, nu llptr,
334 &fBackbuffers[i].fUsageFences[0]));
335 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
336 CreateFence(fBackendContext->fDevice, &fenceInfo, nu llptr,
337 &fBackbuffers[i].fUsageFences[1]));
338 }
339 fCurrentBackbufferIndex = fImageCount;
340 }
341
342 void VulkanTestContext::destroyBuffers() {
343
344 if (fBackbuffers) {
345 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
346 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
347 WaitForFences(fBackendContext->fDevice, 2,
348 fBackbuffers[i].fUsageFences,
349 true, UINT64_MAX));
350 fBackbuffers[i].fImageIndex = -1;
351 GR_VK_CALL(fBackendContext->fInterface,
352 DestroySemaphore(fBackendContext->fDevice,
353 fBackbuffers[i].fAcquireSemaphore,
354 nullptr));
355 GR_VK_CALL(fBackendContext->fInterface,
356 DestroySemaphore(fBackendContext->fDevice,
357 fBackbuffers[i].fRenderSemaphore,
358 nullptr));
359 GR_VK_CALL(fBackendContext->fInterface,
360 FreeCommandBuffers(fBackendContext->fDevice, fCommandPool , 2,
361 fBackbuffers[i].fTransitionCmdBuffers) );
362 GR_VK_CALL(fBackendContext->fInterface,
363 DestroyFence(fBackendContext->fDevice, fBackbuffers[i].fU sageFences[0], 0));
364 GR_VK_CALL(fBackendContext->fInterface,
365 DestroyFence(fBackendContext->fDevice, fBackbuffers[i].fU sageFences[1], 0));
366 }
367 }
368
369 delete[] fBackbuffers;
370 fBackbuffers = nullptr;
371
372 delete[] fSurfaces;
373 fSurfaces = nullptr;
374 delete[] fImageLayouts;
375 fImageLayouts = nullptr;
376 delete[] fImages;
377 fImages = nullptr;
378 }
379
380 VulkanTestContext::~VulkanTestContext() {
381 this->destroyContext();
382 }
383
384 void VulkanTestContext::destroyContext() {
385 if (!fBackendContext.get()) {
386 return;
387 }
388
389 GR_VK_CALL(fBackendContext->fInterface, DeviceWaitIdle(fBackendContext->fDev ice));
390
391 this->destroyBuffers();
392
393 if (VK_NULL_HANDLE != fCommandPool) {
394 GR_VK_CALL(fBackendContext->fInterface, DestroyCommandPool(fBackendConte xt->fDevice,
395 fCommandPool, nullptr));
396 fCommandPool = VK_NULL_HANDLE;
397 }
398
399 if (VK_NULL_HANDLE != fSwapchain) {
400 GR_VK_CALL(fBackendContext->fInterface, DestroySwapchainKHR(fBackendCont ext->fDevice,
401 fSwapchain, nullptr));
402 fSwapchain = VK_NULL_HANDLE;
403 }
404
405 if (VK_NULL_HANDLE != fSurface) {
406 GR_VK_CALL(fBackendContext->fInterface, DestroySurfaceKHR(fBackendContex t->fInstance,
407 fSurface, null ptr));
408 fSurface = VK_NULL_HANDLE;
409 }
410
411 delete fContext;
412
413 fBackendContext.reset(nullptr);
414 }
415
416 VulkanTestContext::BackbufferInfo* VulkanTestContext::getAvailableBackbuffer() {
417 SkASSERT(fBackbuffers);
418
419 ++fCurrentBackbufferIndex;
420 if (fCurrentBackbufferIndex > fImageCount) {
421 fCurrentBackbufferIndex = 0;
422 }
423
424 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
425
426 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
427 WaitForFences(fBackendContext->fDevice, 2, backbuffer->f UsageFences,
428 true, UINT64_MAX));
429 return backbuffer;
430 }
431
432 SkSurface* VulkanTestContext::getBackbufferSurface() {
433 BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
434 SkASSERT(backbuffer);
435
436 // reset the fence
437 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
438 ResetFences(fBackendContext->fDevice, 2, backbuffer->fUs ageFences));
439 // semaphores should be in unsignaled state
440
441 // acquire the image
442 VkResult res = GR_VK_CALL(fBackendContext->fInterface,
443 AcquireNextImageKHR(fBackendContext->fDevice,
444 fSwapchain,
445 UINT64_MAX,
446 backbuffer->fAcquireSemaphore,
447 VK_NULL_HANDLE,
448 &backbuffer->fImageIndex));
449 if (VK_ERROR_SURFACE_LOST_KHR == res) {
450 // need to figure out how to create a new vkSurface without the platform Data*
451 return nullptr;
452 }
453 if (VK_ERROR_OUT_OF_DATE_KHR == res || VK_ERROR_SURFACE_LOST_KHR == res) {
454 // tear swapchain down and try again
455 if (!this->createSwapchain(0, 0)) {
456 return nullptr;
457 }
458
459 // acquire the image
460 res = GR_VK_CALL(fBackendContext->fInterface,
461 AcquireNextImageKHR(fBackendContext->fDevice,
462 fSwapchain,
463 UINT64_MAX,
464 backbuffer->fAcquireSemaphore,
465 VK_NULL_HANDLE,
466 &backbuffer->fImageIndex));
467
468 if (VK_SUCCESS != res) {
469 return nullptr;
470 }
471 }
472
473 // set up layout transfer from initial to color attachment
474 VkImageLayout layout = fImageLayouts[backbuffer->fImageIndex];
475 VkPipelineStageFlags srcStageMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ?
476 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT :
477 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPU T_BIT;
478 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPU T_BIT;
479 VkAccessFlags srcAccessMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ?
480 0 : VK_ACCESS_MEMORY_READ_BIT;
481 VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
482
483 VkImageMemoryBarrier imageMemoryBarrier = {
484 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
485 NULL, // pNext
486 srcAccessMask, // outputMask
487 dstAccessMask, // inputMask
488 layout, // oldLayout
489 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
490 fPresentQueueIndex, // srcQueueFamilyIndex
491 fBackendContext->fQueueFamilyIndex, // dstQueueFamilyIndex
492 fImages[backbuffer->fImageIndex], // image
493 { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange
494 };
495 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
496 ResetCommandBuffer(backbuffer->fTransitionCmdBuffers[0], 0));
497 VkCommandBufferBeginInfo info;
498 memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
499 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
500 info.flags = 0;
501 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
502 BeginCommandBuffer(backbuffer->fTransitionCmdBuffers[0], &info));
503
504 GR_VK_CALL(fBackendContext->fInterface,
505 CmdPipelineBarrier(backbuffer->fTransitionCmdBuffers[0],
506 srcStageMask, dstStageMask, 0,
507 0, nullptr,
508 0, nullptr,
509 1, &imageMemoryBarrier));
510
511 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
512 EndCommandBuffer(backbuffer->fTransitionCmdBuffers[0]));
513
514 // insert the layout transfer into the queue and wait on the acquire
515 VkSubmitInfo submitInfo;
516 memset(&submitInfo, 0, sizeof(VkSubmitInfo));
517 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
518 submitInfo.waitSemaphoreCount = 1;
519 submitInfo.pWaitSemaphores = &backbuffer->fAcquireSemaphore;
520 submitInfo.pWaitDstStageMask = 0;
521 submitInfo.commandBufferCount = 1;
522 submitInfo.pCommandBuffers = &backbuffer->fTransitionCmdBuffers[0];
523 submitInfo.signalSemaphoreCount = 0;
524
525 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
526 QueueSubmit(fBackendContext->fQueue, 1, &submitInfo,
527 backbuffer->fUsageFences[0]));
528
529 return fSurfaces[backbuffer->fImageIndex].get();
530 }
531
532
533 void VulkanTestContext::swapBuffers() {
534
535 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
536
537 VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
538 VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPU T_BIT;
539 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
540 VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
541 VkAccessFlags dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
542
543 VkImageMemoryBarrier imageMemoryBarrier = {
544 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
545 NULL, // pNext
546 srcAccessMask, // outputMask
547 dstAccessMask, // inputMask
548 layout, // oldLayout
549 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // newLayout
550 fBackendContext->fQueueFamilyIndex, // srcQueueFamilyIndex
551 fPresentQueueIndex, // dstQueueFamilyIndex
552 fImages[backbuffer->fImageIndex], // image
553 { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange
554 };
555 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
556 ResetCommandBuffer(backbuffer->fTransitionCmdBuffers[1], 0));
557 VkCommandBufferBeginInfo info;
558 memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
559 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
560 info.flags = 0;
561 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
562 BeginCommandBuffer(backbuffer->fTransitionCmdBuffers[1], &info));
563 GR_VK_CALL(fBackendContext->fInterface,
564 CmdPipelineBarrier(backbuffer->fTransitionCmdBuffers[1],
565 srcStageMask, dstStageMask, 0,
566 0, nullptr,
567 0, nullptr,
568 1, &imageMemoryBarrier));
569 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
570 EndCommandBuffer(backbuffer->fTransitionCmdBuffers[1]));
571
572 fImageLayouts[backbuffer->fImageIndex] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
573
574 // insert the layout transfer into the queue and wait on the acquire
575 VkSubmitInfo submitInfo;
576 memset(&submitInfo, 0, sizeof(VkSubmitInfo));
577 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
578 submitInfo.waitSemaphoreCount = 0;
579 submitInfo.pWaitDstStageMask = 0;
580 submitInfo.commandBufferCount = 1;
581 submitInfo.pCommandBuffers = &backbuffer->fTransitionCmdBuffers[1];
582 submitInfo.signalSemaphoreCount = 1;
583 submitInfo.pSignalSemaphores = &backbuffer->fRenderSemaphore;
584
585 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
586 QueueSubmit(fBackendContext->fQueue, 1, &submitInfo,
587 backbuffer->fUsageFences[1]));
588
589 // Submit present operation to present queue
590 const VkPresentInfoKHR presentInfo =
591 {
592 VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType
593 NULL, // pNext
594 1, // waitSemaphoreCount
595 &backbuffer->fRenderSemaphore, // pWaitSemaphores
596 1, // swapchainCount
597 &fSwapchain, // pSwapchains
598 &backbuffer->fImageIndex, // pImageIndices
599 NULL // pResults
600 };
601
602 GR_VK_CALL_ERRCHECK(fBackendContext->fInterface,
603 QueuePresentKHR(fPresentQueue, &presentInfo));
604
605 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698