blob: c0f8fc695f2567ca0892c8aad1be1968e3aa2315 [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// SurfaceVk.cpp:
7// Implements the class methods for SurfaceVk.
8//
9
10#include "libANGLE/renderer/vulkan/SurfaceVk.h"
11
12#include "common/debug.h"
Jamie Madill4d0bf552016-12-28 15:45:24 -050013#include "libANGLE/Surface.h"
14#include "libANGLE/renderer/vulkan/DisplayVk.h"
Jamie Madille09bd5d2016-11-29 16:20:35 -050015#include "libANGLE/renderer/vulkan/FramebufferVk.h"
16#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madillabaab232017-01-10 12:37:37 -050017#include "libANGLE/renderer/vulkan/formatutilsvk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040018
19namespace rx
20{
21
Jamie Madill4d0bf552016-12-28 15:45:24 -050022namespace
23{
24
Jamie Madillabaab232017-01-10 12:37:37 -050025const vk::Format &GetVkFormatFromConfig(const egl::Config &config)
Jamie Madill4d0bf552016-12-28 15:45:24 -050026{
27 // TODO(jmadill): Properly handle format interpretation.
Jamie Madillabaab232017-01-10 12:37:37 -050028 return vk::Format::Get(GL_BGRA8_EXT);
Jamie Madill4d0bf552016-12-28 15:45:24 -050029}
30
31} // namespace
32
Jamie Madille09bd5d2016-11-29 16:20:35 -050033OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState,
34 EGLint width,
35 EGLint height)
36 : SurfaceImpl(surfaceState), mWidth(width), mHeight(height)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040037{
38}
39
Jamie Madille09bd5d2016-11-29 16:20:35 -050040OffscreenSurfaceVk::~OffscreenSurfaceVk()
Jamie Madill9e54b5a2016-05-25 12:57:39 -040041{
42}
43
Jamie Madille09bd5d2016-11-29 16:20:35 -050044egl::Error OffscreenSurfaceVk::initialize(const DisplayImpl *displayImpl)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040045{
Jamie Madille09bd5d2016-11-29 16:20:35 -050046 return egl::Error(EGL_SUCCESS);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040047}
48
Jamie Madille09bd5d2016-11-29 16:20:35 -050049FramebufferImpl *OffscreenSurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040050{
Jamie Madill7b57b9d2017-01-13 09:33:38 -050051 // Use a user FBO for an offscreen RT.
52 return FramebufferVk::CreateUserFBO(state);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040053}
54
Jamie Madille09bd5d2016-11-29 16:20:35 -050055egl::Error OffscreenSurfaceVk::swap(const DisplayImpl *displayImpl)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040056{
Jamie Madille09bd5d2016-11-29 16:20:35 -050057 return egl::Error(EGL_SUCCESS);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040058}
59
Jamie Madille09bd5d2016-11-29 16:20:35 -050060egl::Error OffscreenSurfaceVk::postSubBuffer(EGLint /*x*/,
61 EGLint /*y*/,
62 EGLint /*width*/,
63 EGLint /*height*/)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040064{
Jamie Madille09bd5d2016-11-29 16:20:35 -050065 return egl::Error(EGL_SUCCESS);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040066}
67
Jamie Madille09bd5d2016-11-29 16:20:35 -050068egl::Error OffscreenSurfaceVk::querySurfacePointerANGLE(EGLint /*attribute*/, void ** /*value*/)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040069{
Jamie Madille09bd5d2016-11-29 16:20:35 -050070 UNREACHABLE();
71 return egl::Error(EGL_BAD_CURRENT_SURFACE);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040072}
73
Jamie Madille09bd5d2016-11-29 16:20:35 -050074egl::Error OffscreenSurfaceVk::bindTexImage(gl::Texture * /*texture*/, EGLint /*buffer*/)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040075{
Jamie Madille09bd5d2016-11-29 16:20:35 -050076 return egl::Error(EGL_SUCCESS);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040077}
78
Jamie Madille09bd5d2016-11-29 16:20:35 -050079egl::Error OffscreenSurfaceVk::releaseTexImage(EGLint /*buffer*/)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040080{
Jamie Madille09bd5d2016-11-29 16:20:35 -050081 return egl::Error(EGL_SUCCESS);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040082}
83
Jamie Madille09bd5d2016-11-29 16:20:35 -050084void OffscreenSurfaceVk::setSwapInterval(EGLint /*interval*/)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040085{
Jamie Madill9e54b5a2016-05-25 12:57:39 -040086}
87
Jamie Madille09bd5d2016-11-29 16:20:35 -050088EGLint OffscreenSurfaceVk::getWidth() const
Jamie Madill9e54b5a2016-05-25 12:57:39 -040089{
Jamie Madille09bd5d2016-11-29 16:20:35 -050090 return mWidth;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040091}
92
Jamie Madille09bd5d2016-11-29 16:20:35 -050093EGLint OffscreenSurfaceVk::getHeight() const
Jamie Madill9e54b5a2016-05-25 12:57:39 -040094{
Jamie Madille09bd5d2016-11-29 16:20:35 -050095 return mHeight;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040096}
97
Jamie Madille09bd5d2016-11-29 16:20:35 -050098EGLint OffscreenSurfaceVk::isPostSubBufferSupported() const
Jamie Madill9e54b5a2016-05-25 12:57:39 -040099{
Jamie Madille09bd5d2016-11-29 16:20:35 -0500100 return EGL_FALSE;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400101}
102
Jamie Madille09bd5d2016-11-29 16:20:35 -0500103EGLint OffscreenSurfaceVk::getSwapBehavior() const
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400104{
Jamie Madille09bd5d2016-11-29 16:20:35 -0500105 return EGL_BUFFER_PRESERVED;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400106}
107
Jamie Madille09bd5d2016-11-29 16:20:35 -0500108gl::Error OffscreenSurfaceVk::getAttachmentRenderTarget(
109 const gl::FramebufferAttachment::Target & /*target*/,
110 FramebufferAttachmentRenderTarget ** /*rtOut*/)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400111{
Jamie Madille09bd5d2016-11-29 16:20:35 -0500112 UNREACHABLE();
113 return gl::Error(GL_INVALID_OPERATION);
114}
115
Jamie Madill4d0bf552016-12-28 15:45:24 -0500116WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
117 EGLNativeWindowType window,
118 EGLint width,
119 EGLint height)
120 : SurfaceImpl(surfaceState),
121 mNativeWindowType(window),
Jamie Madill4d0bf552016-12-28 15:45:24 -0500122 mSurface(VK_NULL_HANDLE),
123 mSwapchain(VK_NULL_HANDLE),
124 mDevice(VK_NULL_HANDLE),
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500125 mInstance(VK_NULL_HANDLE),
126 mRenderTarget(),
127 mCurrentSwapchainImageIndex(0)
Jamie Madille09bd5d2016-11-29 16:20:35 -0500128{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500129 mRenderTarget.extents.width = static_cast<GLint>(width);
130 mRenderTarget.extents.height = static_cast<GLint>(height);
131 mRenderTarget.extents.depth = 1;
Jamie Madille09bd5d2016-11-29 16:20:35 -0500132}
133
134WindowSurfaceVk::~WindowSurfaceVk()
135{
Jamie Madill4d0bf552016-12-28 15:45:24 -0500136 mSwapchainImages.clear();
137
138 if (mSwapchain)
139 {
140 vkDestroySwapchainKHR(mDevice, mSwapchain, nullptr);
141 mSwapchain = VK_NULL_HANDLE;
142 }
143
144 if (mSurface)
145 {
146 vkDestroySurfaceKHR(mInstance, mSurface, nullptr);
147 mSurface = VK_NULL_HANDLE;
148 }
Jamie Madille09bd5d2016-11-29 16:20:35 -0500149}
150
151egl::Error WindowSurfaceVk::initialize(const DisplayImpl *displayImpl)
152{
Jamie Madill4d0bf552016-12-28 15:45:24 -0500153 const DisplayVk *displayVk = GetAs<DisplayVk>(displayImpl);
154 return initializeImpl(displayVk->getRenderer()).toEGL(EGL_BAD_SURFACE);
155}
156
157vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
158{
159 // These are needed for resource deallocation.
160 // TODO(jmadill): Don't cache these.
161 mDevice = renderer->getDevice();
162 mInstance = renderer->getInstance();
163
164 // TODO(jmadill): Make this platform-specific.
165 VkWin32SurfaceCreateInfoKHR createInfo;
166
167 createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
168 createInfo.pNext = nullptr;
169 createInfo.flags = 0;
170 createInfo.hinstance = GetModuleHandle(nullptr);
171 createInfo.hwnd = mNativeWindowType;
172 ANGLE_VK_TRY(vkCreateWin32SurfaceKHR(renderer->getInstance(), &createInfo, nullptr, &mSurface));
173
174 uint32_t presentQueue = 0;
175 ANGLE_TRY_RESULT(renderer->selectPresentQueueForSurface(mSurface), presentQueue);
176
177 const auto &physicalDevice = renderer->getPhysicalDevice();
178
179 VkSurfaceCapabilitiesKHR surfaceCaps;
180 ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, &surfaceCaps));
181
182 // Adjust width and height to the swapchain if necessary.
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500183 uint32_t width = surfaceCaps.currentExtent.width;
184 uint32_t height = surfaceCaps.currentExtent.height;
185
186 // TODO(jmadill): Support devices which don't support copy. We use this for ReadPixels.
187 ANGLE_VK_CHECK((surfaceCaps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0,
188 VK_ERROR_INITIALIZATION_FAILED);
189
190 if (surfaceCaps.currentExtent.width == 0xFFFFFFFFu)
Jamie Madill4d0bf552016-12-28 15:45:24 -0500191 {
192 ASSERT(surfaceCaps.currentExtent.height == 0xFFFFFFFFu);
193
194 RECT rect;
195 ANGLE_VK_CHECK(GetClientRect(mNativeWindowType, &rect) == TRUE,
196 VK_ERROR_INITIALIZATION_FAILED);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500197 if (mRenderTarget.extents.width == 0)
Jamie Madill4d0bf552016-12-28 15:45:24 -0500198 {
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500199 width = static_cast<uint32_t>(rect.right - rect.left);
Jamie Madill4d0bf552016-12-28 15:45:24 -0500200 }
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500201 if (mRenderTarget.extents.height == 0)
Jamie Madill4d0bf552016-12-28 15:45:24 -0500202 {
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500203 height = static_cast<uint32_t>(rect.bottom - rect.top);
Jamie Madill4d0bf552016-12-28 15:45:24 -0500204 }
205 }
206
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500207 mRenderTarget.extents.width = static_cast<int>(width);
208 mRenderTarget.extents.height = static_cast<int>(height);
209
Jamie Madill4d0bf552016-12-28 15:45:24 -0500210 uint32_t presentModeCount = 0;
211 ANGLE_VK_TRY(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, mSurface,
212 &presentModeCount, nullptr));
213 ASSERT(presentModeCount > 0);
214
215 std::vector<VkPresentModeKHR> presentModes(presentModeCount);
216 ANGLE_VK_TRY(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, mSurface,
217 &presentModeCount, presentModes.data()));
218
219 // Use FIFO mode if available, since it throttles you to the display rate. Mailbox can lead
220 // to rendering frames which are never seen by the user, wasting power.
221 VkPresentModeKHR swapchainPresentMode = presentModes[0];
222 for (auto presentMode : presentModes)
223 {
224 if (presentMode == VK_PRESENT_MODE_FIFO_KHR)
225 {
226 swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
227 break;
228 }
229
230 // Fallback to immediate mode if FIFO is unavailable.
231 if (presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR)
232 {
233 swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
234 }
235 }
236
237 // Determine number of swapchain images. Aim for one more than the minimum.
238 uint32_t minImageCount = surfaceCaps.minImageCount + 1;
239 if (surfaceCaps.maxImageCount > 0 && minImageCount > surfaceCaps.maxImageCount)
240 {
241 minImageCount = surfaceCaps.maxImageCount;
242 }
243
244 // Default to identity transform.
245 VkSurfaceTransformFlagBitsKHR preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
246 if ((surfaceCaps.supportedTransforms & preTransform) == 0)
247 {
248 preTransform = surfaceCaps.currentTransform;
249 }
250
Jamie Madill4d0bf552016-12-28 15:45:24 -0500251 uint32_t surfaceFormatCount = 0;
252 ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, mSurface, &surfaceFormatCount,
253 nullptr));
254
255 std::vector<VkSurfaceFormatKHR> surfaceFormats(surfaceFormatCount);
256 ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, mSurface, &surfaceFormatCount,
257 surfaceFormats.data()));
258
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500259 mRenderTarget.format = &GetVkFormatFromConfig(*mState.config);
260 auto nativeFormat = mRenderTarget.format->native;
261
Jamie Madill4d0bf552016-12-28 15:45:24 -0500262 if (surfaceFormatCount == 1u && surfaceFormats[0].format == VK_FORMAT_UNDEFINED)
263 {
264 // This is fine.
265 }
266 else
267 {
268 bool foundFormat = false;
269 for (const auto &surfaceFormat : surfaceFormats)
270 {
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500271 if (surfaceFormat.format == nativeFormat)
Jamie Madill4d0bf552016-12-28 15:45:24 -0500272 {
273 foundFormat = true;
274 break;
275 }
276 }
277
278 ANGLE_VK_CHECK(foundFormat, VK_ERROR_INITIALIZATION_FAILED);
279 }
280
281 VkSwapchainCreateInfoKHR swapchainInfo;
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500282 swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
283 swapchainInfo.pNext = nullptr;
284 swapchainInfo.flags = 0;
285 swapchainInfo.surface = mSurface;
286 swapchainInfo.minImageCount = minImageCount;
287 swapchainInfo.imageFormat = nativeFormat;
288 swapchainInfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
289 swapchainInfo.imageExtent.width = width;
290 swapchainInfo.imageExtent.height = height;
291 swapchainInfo.imageArrayLayers = 1;
292 swapchainInfo.imageUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
293 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
Jamie Madill4d0bf552016-12-28 15:45:24 -0500294 swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
295 swapchainInfo.queueFamilyIndexCount = 0;
296 swapchainInfo.pQueueFamilyIndices = nullptr;
297 swapchainInfo.preTransform = preTransform;
298 swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
299 swapchainInfo.presentMode = swapchainPresentMode;
300 swapchainInfo.clipped = VK_TRUE;
301 swapchainInfo.oldSwapchain = VK_NULL_HANDLE;
302
303 const auto &device = renderer->getDevice();
304 ANGLE_VK_TRY(vkCreateSwapchainKHR(device, &swapchainInfo, nullptr, &mSwapchain));
305
306 // Intialize the swapchain image views.
307 uint32_t imageCount = 0;
308 ANGLE_VK_TRY(vkGetSwapchainImagesKHR(device, mSwapchain, &imageCount, nullptr));
309
310 std::vector<VkImage> swapchainImages(imageCount);
311 ANGLE_VK_TRY(vkGetSwapchainImagesKHR(device, mSwapchain, &imageCount, swapchainImages.data()));
312
313 // CommandBuffer is a singleton in the Renderer.
314 vk::CommandBuffer *commandBuffer = renderer->getCommandBuffer();
315 ANGLE_TRY(commandBuffer->begin());
316
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500317 VkClearColorValue transparentBlack;
318 transparentBlack.float32[0] = 0.0f;
319 transparentBlack.float32[1] = 0.0f;
320 transparentBlack.float32[2] = 0.0f;
321 transparentBlack.float32[3] = 0.0f;
322
Jamie Madill4d0bf552016-12-28 15:45:24 -0500323 for (auto swapchainImage : swapchainImages)
324 {
325 VkImageViewCreateInfo imageViewInfo;
326 imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
327 imageViewInfo.pNext = nullptr;
328 imageViewInfo.flags = 0;
329 imageViewInfo.image = swapchainImage;
330 imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500331 imageViewInfo.format = nativeFormat;
Jamie Madill4d0bf552016-12-28 15:45:24 -0500332 imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
333 imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
334 imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
335 imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
336 imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
337 imageViewInfo.subresourceRange.baseMipLevel = 0;
338 imageViewInfo.subresourceRange.levelCount = 1;
339 imageViewInfo.subresourceRange.baseArrayLayer = 0;
340 imageViewInfo.subresourceRange.layerCount = 1;
341
342 vk::Image image(swapchainImage);
343 vk::ImageView imageView(device);
344 ANGLE_TRY(imageView.init(imageViewInfo));
345
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500346 // Set transfer dest layout, and clear the image to black.
347 image.changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
348 commandBuffer);
349 commandBuffer->clearSingleColorImage(image, transparentBlack);
Jamie Madill4d0bf552016-12-28 15:45:24 -0500350
351 mSwapchainImages.push_back(std::move(image));
352 mSwapchainImageViews.push_back(std::move(imageView));
353 }
354
355 ANGLE_TRY(commandBuffer->end());
356 ANGLE_TRY(renderer->submitAndFinishCommandBuffer(*commandBuffer));
357
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500358 // Start by getting the next available swapchain image.
359 ANGLE_TRY(nextSwapchainImage(renderer));
360
Jamie Madill4d0bf552016-12-28 15:45:24 -0500361 return vk::NoError();
Jamie Madille09bd5d2016-11-29 16:20:35 -0500362}
363
364FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state)
365{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500366 return FramebufferVk::CreateDefaultFBO(state, this);
Jamie Madille09bd5d2016-11-29 16:20:35 -0500367}
368
369egl::Error WindowSurfaceVk::swap(const DisplayImpl *displayImpl)
370{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500371 const DisplayVk *displayVk = GetAs<DisplayVk>(displayImpl);
372 return swapImpl(displayVk->getRenderer()).toEGL(EGL_BAD_ALLOC);
373}
374
375vk::Error WindowSurfaceVk::swapImpl(RendererVk *renderer)
376{
377 vk::CommandBuffer *currentCB = renderer->getCommandBuffer();
378
379 auto *image = &mSwapchainImages[mCurrentSwapchainImageIndex];
380
381 currentCB->begin();
382 image->changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
383 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
384 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, currentCB);
385 currentCB->end();
386
387 ANGLE_TRY(renderer->waitThenFinishCommandBuffer(*currentCB, mPresentCompleteSemaphore));
388
389 VkPresentInfoKHR presentInfo;
390 presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
391 presentInfo.pNext = nullptr;
392 presentInfo.waitSemaphoreCount = 0;
393 presentInfo.pWaitSemaphores = nullptr;
394 presentInfo.swapchainCount = 1;
395 presentInfo.pSwapchains = &mSwapchain;
396 presentInfo.pImageIndices = &mCurrentSwapchainImageIndex;
397 presentInfo.pResults = nullptr;
398
399 ANGLE_VK_TRY(vkQueuePresentKHR(renderer->getQueue(), &presentInfo));
400
401 // Get the next available swapchain iamge.
402 ANGLE_TRY(nextSwapchainImage(renderer));
403
404 return vk::NoError();
405}
406
407vk::Error WindowSurfaceVk::nextSwapchainImage(RendererVk *renderer)
408{
409 VkDevice device = renderer->getDevice();
410
411 vk::Semaphore presentComplete(device);
412 ANGLE_TRY(presentComplete.init());
413
414 ANGLE_VK_TRY(vkAcquireNextImageKHR(device, mSwapchain, std::numeric_limits<uint64_t>::max(),
415 presentComplete.getHandle(), VK_NULL_HANDLE,
416 &mCurrentSwapchainImageIndex));
417
418 mPresentCompleteSemaphore = std::move(presentComplete);
419
420 // Update RenderTarget pointers.
421 mRenderTarget.image = &mSwapchainImages[mCurrentSwapchainImageIndex];
422 mRenderTarget.imageView = &mSwapchainImageViews[mCurrentSwapchainImageIndex];
423
424 return vk::NoError();
Jamie Madille09bd5d2016-11-29 16:20:35 -0500425}
426
427egl::Error WindowSurfaceVk::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
428{
429 // TODO(jmadill)
430 return egl::Error(EGL_SUCCESS);
431}
432
433egl::Error WindowSurfaceVk::querySurfacePointerANGLE(EGLint attribute, void **value)
434{
435 UNREACHABLE();
436 return egl::Error(EGL_BAD_CURRENT_SURFACE);
437}
438
439egl::Error WindowSurfaceVk::bindTexImage(gl::Texture *texture, EGLint buffer)
440{
441 return egl::Error(EGL_SUCCESS);
442}
443
444egl::Error WindowSurfaceVk::releaseTexImage(EGLint buffer)
445{
446 return egl::Error(EGL_SUCCESS);
447}
448
449void WindowSurfaceVk::setSwapInterval(EGLint interval)
450{
451}
452
453EGLint WindowSurfaceVk::getWidth() const
454{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500455 return static_cast<EGLint>(mRenderTarget.extents.width);
Jamie Madille09bd5d2016-11-29 16:20:35 -0500456}
457
458EGLint WindowSurfaceVk::getHeight() const
459{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500460 return static_cast<EGLint>(mRenderTarget.extents.height);
Jamie Madille09bd5d2016-11-29 16:20:35 -0500461}
462
463EGLint WindowSurfaceVk::isPostSubBufferSupported() const
464{
465 // TODO(jmadill)
466 return EGL_FALSE;
467}
468
469EGLint WindowSurfaceVk::getSwapBehavior() const
470{
471 // TODO(jmadill)
472 return EGL_BUFFER_DESTROYED;
473}
474
475gl::Error WindowSurfaceVk::getAttachmentRenderTarget(
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500476 const gl::FramebufferAttachment::Target & /*target*/,
Jamie Madille09bd5d2016-11-29 16:20:35 -0500477 FramebufferAttachmentRenderTarget **rtOut)
478{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500479 *rtOut = &mRenderTarget;
480 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400481}
482
Jamie Madillab9f9c32017-01-17 17:47:34 -0500483gl::ErrorOrResult<vk::Framebuffer *> WindowSurfaceVk::getCurrentFramebuffer(
484 VkDevice device,
485 const vk::RenderPass &compatibleRenderPass)
486{
487 if (!mSwapchainFramebuffers.empty())
488 {
489 // Validation layers should detect if the render pass is really compatible.
490 return &mSwapchainFramebuffers[mCurrentSwapchainImageIndex];
491 }
492
493 VkFramebufferCreateInfo framebufferInfo;
494
495 // TODO(jmadill): Depth/Stencil attachments.
496 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
497 framebufferInfo.pNext = nullptr;
498 framebufferInfo.flags = 0;
499 framebufferInfo.renderPass = compatibleRenderPass.getHandle();
500 framebufferInfo.attachmentCount = 1u;
501 framebufferInfo.pAttachments = nullptr;
502 framebufferInfo.width = static_cast<uint32_t>(mRenderTarget.extents.width);
503 framebufferInfo.height = static_cast<uint32_t>(mRenderTarget.extents.height);
504 framebufferInfo.layers = 1;
505
506 for (const auto &imageView : mSwapchainImageViews)
507 {
508 VkImageView imageViewHandle = imageView.getHandle();
509 framebufferInfo.pAttachments = &imageViewHandle;
510
511 vk::Framebuffer framebuffer(device);
512 ANGLE_TRY(framebuffer.init(framebufferInfo));
513
514 mSwapchainFramebuffers.push_back(std::move(framebuffer));
515 }
516
517 // We should only initialize framebuffers on the first swap.
518 ASSERT(mCurrentSwapchainImageIndex == 0u);
519 return &mSwapchainFramebuffers[mCurrentSwapchainImageIndex];
520}
521
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400522} // namespace rx