OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 #include "SkSurface.h" | 10 #include "SkSurface.h" |
11 #include "VulkanWindowContext.h" | 11 #include "VulkanWindowContext.h" |
12 | 12 |
13 #include "vk/GrVkInterface.h" | 13 #include "vk/GrVkInterface.h" |
14 #include "vk/GrVkUtil.h" | 14 #include "vk/GrVkUtil.h" |
15 #include "vk/GrVkTypes.h" | 15 #include "vk/GrVkTypes.h" |
16 | 16 |
17 #ifdef VK_USE_PLATFORM_WIN32_KHR | 17 #ifdef VK_USE_PLATFORM_WIN32_KHR |
18 // windows wants to define this as CreateSemaphoreA or CreateSemaphoreW | 18 // windows wants to define this as CreateSemaphoreA or CreateSemaphoreW |
19 #undef CreateSemaphore | 19 #undef CreateSemaphore |
20 #endif | 20 #endif |
21 | 21 |
22 #define GET_PROC(F) f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk"
#F) | 22 #define GET_PROC(F) f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk"
#F) |
23 #define GET_DEV_PROC(F) f ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk"
#F) | 23 #define GET_DEV_PROC(F) f ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk"
#F) |
24 | 24 |
25 namespace sk_app { | 25 namespace sk_app { |
26 | 26 |
27 VulkanWindowContext::VulkanWindowContext(void* platformData, int msaaSampleCount
) | 27 VulkanWindowContext::VulkanWindowContext(void* platformData, int msaaSampleCount
, bool srgb) |
28 : fSurface(VK_NULL_HANDLE) | 28 : fSurface(VK_NULL_HANDLE) |
29 , fSwapchain(VK_NULL_HANDLE) | 29 , fSwapchain(VK_NULL_HANDLE) |
30 , fCommandPool(VK_NULL_HANDLE) | 30 , fCommandPool(VK_NULL_HANDLE) |
31 , fBackbuffers(nullptr) { | 31 , fBackbuffers(nullptr) { |
32 | 32 |
33 // any config code here (particularly for msaa)? | 33 // any config code here (particularly for msaa)? |
34 | 34 |
35 this->initializeContext(platformData); | 35 this->initializeContext(platformData, srgb); |
36 } | 36 } |
37 | 37 |
38 void VulkanWindowContext::initializeContext(void* platformData) { | 38 void VulkanWindowContext::initializeContext(void* platformData, bool srgb) { |
39 | 39 |
40 fBackendContext.reset(GrVkBackendContext::Create(&fPresentQueueIndex, canPre
sent)); | 40 fBackendContext.reset(GrVkBackendContext::Create(&fPresentQueueIndex, canPre
sent)); |
41 if (!(fBackendContext->fExtensions & kKHR_surface_GrVkExtensionFlag) || | 41 if (!(fBackendContext->fExtensions & kKHR_surface_GrVkExtensionFlag) || |
42 !(fBackendContext->fExtensions & kKHR_swapchain_GrVkExtensionFlag)) { | 42 !(fBackendContext->fExtensions & kKHR_swapchain_GrVkExtensionFlag)) { |
43 fBackendContext.reset(nullptr); | 43 fBackendContext.reset(nullptr); |
44 return; | 44 return; |
45 } | 45 } |
46 | 46 |
47 VkInstance instance = fBackendContext->fInstance; | 47 VkInstance instance = fBackendContext->fInstance; |
48 VkDevice device = fBackendContext->fDevice; | 48 VkDevice device = fBackendContext->fDevice; |
(...skipping 18 matching lines...) Expand all Loading... |
67 | 67 |
68 VkBool32 supported; | 68 VkBool32 supported; |
69 VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fBackendContext->fPhysica
lDevice, | 69 VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fBackendContext->fPhysica
lDevice, |
70 fPresentQueueIndex, fSurf
ace, | 70 fPresentQueueIndex, fSurf
ace, |
71 &supported); | 71 &supported); |
72 if (VK_SUCCESS != res) { | 72 if (VK_SUCCESS != res) { |
73 this->destroyContext(); | 73 this->destroyContext(); |
74 return; | 74 return; |
75 } | 75 } |
76 | 76 |
77 if (!this->createSwapchain(-1, -1)) { | 77 if (!this->createSwapchain(-1, -1, srgb)) { |
78 this->destroyContext(); | 78 this->destroyContext(); |
79 return; | 79 return; |
80 } | 80 } |
81 | 81 |
82 // create presentQueue | 82 // create presentQueue |
83 vkGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQ
ueue); | 83 vkGetDeviceQueue(fBackendContext->fDevice, fPresentQueueIndex, 0, &fPresentQ
ueue); |
84 } | 84 } |
85 | 85 |
86 bool VulkanWindowContext::createSwapchain(uint32_t width, uint32_t height) { | 86 bool VulkanWindowContext::createSwapchain(uint32_t width, uint32_t height, bool
srgb) { |
87 // check for capabilities | 87 // check for capabilities |
88 VkSurfaceCapabilitiesKHR caps; | 88 VkSurfaceCapabilitiesKHR caps; |
89 VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fBackendContext->fPh
ysicalDevice, | 89 VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fBackendContext->fPh
ysicalDevice, |
90 fSurface, &caps); | 90 fSurface, &caps); |
91 if (VK_SUCCESS != res) { | 91 if (VK_SUCCESS != res) { |
92 return false; | 92 return false; |
93 } | 93 } |
94 | 94 |
95 uint32_t surfaceFormatCount; | 95 uint32_t surfaceFormatCount; |
96 res = fGetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysicalDevice,
fSurface, | 96 res = fGetPhysicalDeviceSurfaceFormatsKHR(fBackendContext->fPhysicalDevice,
fSurface, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 VK_IMAGE_USAGE_TRANSFER_DST_BIT; | 155 VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
156 SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags); | 156 SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags); |
157 SkASSERT(caps.supportedTransforms & caps.currentTransform); | 157 SkASSERT(caps.supportedTransforms & caps.currentTransform); |
158 SkASSERT(caps.supportedCompositeAlpha & (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR | | 158 SkASSERT(caps.supportedCompositeAlpha & (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR | |
159 VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
); | 159 VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
); |
160 VkCompositeAlphaFlagBitsKHR composite_alpha = | 160 VkCompositeAlphaFlagBitsKHR composite_alpha = |
161 (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ? | 161 (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ? |
162 VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR : | 162 VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR : |
163 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; | 163 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; |
164 | 164 |
165 // Pick our surface format -- for now, the first one | 165 // Pick our surface format. For now, just make sure it matches our sRGB requ
est: |
166 VkFormat surfaceFormat = surfaceFormats[0].format; | 166 VkFormat surfaceFormat = VK_FORMAT_UNDEFINED; |
167 VkColorSpaceKHR colorSpace = surfaceFormats[0].colorSpace; | 167 VkColorSpaceKHR colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; |
| 168 for (uint32_t i = 0; i < surfaceFormatCount; ++i) { |
| 169 GrPixelConfig config; |
| 170 if (GrVkFormatToPixelConfig(surfaceFormats[i].format, &config) && |
| 171 GrPixelConfigIsSRGB(config) == srgb) { |
| 172 surfaceFormat = surfaceFormats[i].format; |
| 173 colorSpace = surfaceFormats[i].colorSpace; |
| 174 break; |
| 175 } |
| 176 } |
| 177 fSRGB = srgb; |
| 178 |
| 179 if (VK_FORMAT_UNDEFINED == surfaceFormat) { |
| 180 return false; |
| 181 } |
168 | 182 |
169 // If mailbox mode is available, use it, as it is the lowest-latency non- | 183 // If mailbox mode is available, use it, as it is the lowest-latency non- |
170 // tearing mode. If not, fall back to FIFO which is always available. | 184 // tearing mode. If not, fall back to FIFO which is always available. |
171 VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR; | 185 VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR; |
172 for (uint32_t i = 0; i < presentModeCount; ++i) { | 186 for (uint32_t i = 0; i < presentModeCount; ++i) { |
173 // use mailbox | 187 // use mailbox |
174 if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) { | 188 if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) { |
175 mode = presentModes[i]; | 189 mode = presentModes[i]; |
176 break; | 190 break; |
177 } | 191 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | 259 info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
246 info.fImageTiling = VK_IMAGE_TILING_OPTIMAL; | 260 info.fImageTiling = VK_IMAGE_TILING_OPTIMAL; |
247 info.fFormat = format; | 261 info.fFormat = format; |
248 desc.fWidth = fWidth; | 262 desc.fWidth = fWidth; |
249 desc.fHeight = fHeight; | 263 desc.fHeight = fHeight; |
250 desc.fConfig = fPixelConfig; | 264 desc.fConfig = fPixelConfig; |
251 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 265 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
252 desc.fSampleCnt = 0; | 266 desc.fSampleCnt = 0; |
253 desc.fStencilBits = 0; | 267 desc.fStencilBits = 0; |
254 desc.fRenderTargetHandle = (GrBackendObject) &info; | 268 desc.fRenderTargetHandle = (GrBackendObject) &info; |
255 SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | 269 SkSurfaceProps props(GrPixelConfigIsSRGB(fPixelConfig) |
| 270 ? SkSurfaceProps::kGammaCorrect_Flag : 0, |
| 271 kUnknown_SkPixelGeometry); |
256 fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc, &p
rops); | 272 fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc, &p
rops); |
257 } | 273 } |
258 | 274 |
259 // create the command pool for the command buffers | 275 // create the command pool for the command buffers |
260 if (VK_NULL_HANDLE == fCommandPool) { | 276 if (VK_NULL_HANDLE == fCommandPool) { |
261 VkCommandPoolCreateInfo commandPoolInfo; | 277 VkCommandPoolCreateInfo commandPoolInfo; |
262 memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo)); | 278 memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo)); |
263 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; | 279 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; |
264 // this needs to be on the render queue | 280 // this needs to be on the render queue |
265 commandPoolInfo.queueFamilyIndex = fBackendContext->fGraphicsQueueIndex; | 281 commandPoolInfo.queueFamilyIndex = fBackendContext->fGraphicsQueueIndex; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 VkResult res = fAcquireNextImageKHR(fBackendContext->fDevice, fSwapchain, UI
NT64_MAX, | 429 VkResult res = fAcquireNextImageKHR(fBackendContext->fDevice, fSwapchain, UI
NT64_MAX, |
414 backbuffer->fAcquireSemaphore, VK_NULL_H
ANDLE, | 430 backbuffer->fAcquireSemaphore, VK_NULL_H
ANDLE, |
415 &backbuffer->fImageIndex); | 431 &backbuffer->fImageIndex); |
416 if (VK_ERROR_SURFACE_LOST_KHR == res) { | 432 if (VK_ERROR_SURFACE_LOST_KHR == res) { |
417 // need to figure out how to create a new vkSurface without the platform
Data* | 433 // need to figure out how to create a new vkSurface without the platform
Data* |
418 // maybe use attach somehow? but need a Window | 434 // maybe use attach somehow? but need a Window |
419 return nullptr; | 435 return nullptr; |
420 } | 436 } |
421 if (VK_ERROR_OUT_OF_DATE_KHR == res) { | 437 if (VK_ERROR_OUT_OF_DATE_KHR == res) { |
422 // tear swapchain down and try again | 438 // tear swapchain down and try again |
423 if (!this->createSwapchain(0, 0)) { | 439 if (!this->createSwapchain(0, 0, fSRGB)) { |
424 return nullptr; | 440 return nullptr; |
425 } | 441 } |
426 | 442 |
427 // acquire the image | 443 // acquire the image |
428 res = fAcquireNextImageKHR(fBackendContext->fDevice, fSwapchain, UINT64_
MAX, | 444 res = fAcquireNextImageKHR(fBackendContext->fDevice, fSwapchain, UINT64_
MAX, |
429 backbuffer->fAcquireSemaphore, VK_NULL_HANDLE
, | 445 backbuffer->fAcquireSemaphore, VK_NULL_HANDLE
, |
430 &backbuffer->fImageIndex); | 446 &backbuffer->fImageIndex); |
431 | 447 |
432 if (VK_SUCCESS != res) { | 448 if (VK_SUCCESS != res) { |
433 return nullptr; | 449 return nullptr; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 &fSwapchain, // pSwapchains | 578 &fSwapchain, // pSwapchains |
563 &backbuffer->fImageIndex, // pImageIndices | 579 &backbuffer->fImageIndex, // pImageIndices |
564 NULL // pResults | 580 NULL // pResults |
565 }; | 581 }; |
566 | 582 |
567 fQueuePresentKHR(fPresentQueue, &presentInfo); | 583 fQueuePresentKHR(fPresentQueue, &presentInfo); |
568 | 584 |
569 } | 585 } |
570 | 586 |
571 } //namespace sk_app | 587 } //namespace sk_app |
OLD | NEW |