blob: 9c60c1f2a598791a752e5bde04f4e9949b8bbdf7 [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// FramebufferVk.cpp:
7// Implements the class methods for FramebufferVk.
8//
9
10#include "libANGLE/renderer/vulkan/FramebufferVk.h"
11
Jamie Madill7b57b9d2017-01-13 09:33:38 -050012#include <array>
13#include <vulkan/vulkan.h>
14
Jamie Madill9e54b5a2016-05-25 12:57:39 -040015#include "common/debug.h"
Jamie Madill7b57b9d2017-01-13 09:33:38 -050016#include "image_util/imageformats.h"
17#include "libANGLE/formatutils.h"
18#include "libANGLE/renderer/renderer_utils.h"
19#include "libANGLE/renderer/vulkan/ContextVk.h"
Jamie Madill5deea722017-02-16 10:44:46 -050020#include "libANGLE/renderer/vulkan/DisplayVk.h"
Jamie Madill7b57b9d2017-01-13 09:33:38 -050021#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
22#include "libANGLE/renderer/vulkan/RendererVk.h"
23#include "libANGLE/renderer/vulkan/SurfaceVk.h"
24#include "libANGLE/renderer/vulkan/formatutilsvk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040025
26namespace rx
27{
28
Jamie Madill7b57b9d2017-01-13 09:33:38 -050029namespace
30{
31
32gl::ErrorOrResult<const gl::InternalFormat *> GetReadAttachmentInfo(
33 const gl::FramebufferAttachment *readAttachment)
34{
35 RenderTargetVk *renderTarget = nullptr;
36 ANGLE_TRY(readAttachment->getRenderTarget(&renderTarget));
37
38 GLenum implFormat = renderTarget->format->format().fboImplementationInternalFormat;
39 return &gl::GetInternalFormatInfo(implFormat);
40}
41
Jamie Madillab9f9c32017-01-17 17:47:34 -050042VkSampleCountFlagBits ConvertSamples(GLint sampleCount)
43{
44 switch (sampleCount)
45 {
46 case 0:
47 case 1:
48 return VK_SAMPLE_COUNT_1_BIT;
49 case 2:
50 return VK_SAMPLE_COUNT_2_BIT;
51 case 4:
52 return VK_SAMPLE_COUNT_4_BIT;
53 case 8:
54 return VK_SAMPLE_COUNT_8_BIT;
55 case 16:
56 return VK_SAMPLE_COUNT_16_BIT;
57 case 32:
58 return VK_SAMPLE_COUNT_32_BIT;
59 default:
60 UNREACHABLE();
61 return VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM;
62 }
63}
64
Jamie Madill7b57b9d2017-01-13 09:33:38 -050065} // anonymous namespace
66
67// static
68FramebufferVk *FramebufferVk::CreateUserFBO(const gl::FramebufferState &state)
69{
70 return new FramebufferVk(state);
71}
72
73// static
74FramebufferVk *FramebufferVk::CreateDefaultFBO(const gl::FramebufferState &state,
75 WindowSurfaceVk *backbuffer)
76{
77 return new FramebufferVk(state, backbuffer);
78}
79
Jamie Madillab9f9c32017-01-17 17:47:34 -050080FramebufferVk::FramebufferVk(const gl::FramebufferState &state)
81 : FramebufferImpl(state),
82 mBackbuffer(nullptr),
Jamie Madill5deea722017-02-16 10:44:46 -050083 mRenderPass(),
84 mFramebuffer(),
85 mDirtyRenderPass(true),
86 mDirtyFramebuffer(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040087{
88}
89
Jamie Madill7b57b9d2017-01-13 09:33:38 -050090FramebufferVk::FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer)
Jamie Madillab9f9c32017-01-17 17:47:34 -050091 : FramebufferImpl(state),
92 mBackbuffer(backbuffer),
Jamie Madill5deea722017-02-16 10:44:46 -050093 mRenderPass(),
94 mFramebuffer(),
95 mDirtyRenderPass(true),
96 mDirtyFramebuffer(true)
Jamie Madill7b57b9d2017-01-13 09:33:38 -050097{
98}
99
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400100FramebufferVk::~FramebufferVk()
101{
102}
103
Jamie Madill5deea722017-02-16 10:44:46 -0500104void FramebufferVk::destroy(ContextImpl *contextImpl)
105{
106 VkDevice device = GetAs<ContextVk>(contextImpl)->getDevice();
107
108 mRenderPass.destroy(device);
109 mFramebuffer.destroy(device);
110}
111
112void FramebufferVk::destroyDefault(DisplayImpl *displayImpl)
113{
114 VkDevice device = GetAs<DisplayVk>(displayImpl)->getRenderer()->getDevice();
115
116 mRenderPass.destroy(device);
117 mFramebuffer.destroy(device);
118}
119
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400120gl::Error FramebufferVk::discard(size_t count, const GLenum *attachments)
121{
122 UNIMPLEMENTED();
123 return gl::Error(GL_INVALID_OPERATION);
124}
125
126gl::Error FramebufferVk::invalidate(size_t count, const GLenum *attachments)
127{
128 UNIMPLEMENTED();
129 return gl::Error(GL_INVALID_OPERATION);
130}
131
132gl::Error FramebufferVk::invalidateSub(size_t count,
133 const GLenum *attachments,
134 const gl::Rectangle &area)
135{
136 UNIMPLEMENTED();
137 return gl::Error(GL_INVALID_OPERATION);
138}
139
140gl::Error FramebufferVk::clear(ContextImpl *context, GLbitfield mask)
141{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500142 ContextVk *contextVk = GetAs<ContextVk>(context);
143
144 if (mState.getDepthAttachment() && (mask & GL_DEPTH_BUFFER_BIT) != 0)
145 {
146 // TODO(jmadill): Depth clear
147 UNIMPLEMENTED();
148 }
149
150 if (mState.getStencilAttachment() && (mask & GL_STENCIL_BUFFER_BIT) != 0)
151 {
152 // TODO(jmadill): Stencil clear
153 UNIMPLEMENTED();
154 }
155
156 if ((mask & GL_COLOR_BUFFER_BIT) == 0)
157 {
158 return gl::NoError();
159 }
160
161 const auto &glState = context->getGLState();
162 const auto &clearColor = glState.getColorClearValue();
163 VkClearColorValue clearColorValue;
164 clearColorValue.float32[0] = clearColor.red;
165 clearColorValue.float32[1] = clearColor.green;
166 clearColorValue.float32[2] = clearColor.blue;
167 clearColorValue.float32[3] = clearColor.alpha;
168
169 // TODO(jmadill): Scissored clears.
170 const auto *attachment = mState.getFirstNonNullAttachment();
171 ASSERT(attachment && attachment->isAttached());
172 const auto &size = attachment->getSize();
173 const gl::Rectangle renderArea(0, 0, size.width, size.height);
174
175 vk::CommandBuffer *commandBuffer = contextVk->getCommandBuffer();
Jamie Madill5deea722017-02-16 10:44:46 -0500176 ANGLE_TRY(commandBuffer->begin(contextVk->getDevice()));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500177
178 for (const auto &colorAttachment : mState.getColorAttachments())
179 {
180 if (colorAttachment.isAttached())
181 {
182 RenderTargetVk *renderTarget = nullptr;
183 ANGLE_TRY(colorAttachment.getRenderTarget(&renderTarget));
184 renderTarget->image->changeLayoutTop(
185 VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, commandBuffer);
186 commandBuffer->clearSingleColorImage(*renderTarget->image, clearColorValue);
187 }
188 }
189
190 commandBuffer->end();
191
192 ANGLE_TRY(contextVk->submitCommands(*commandBuffer));
193
194 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400195}
196
197gl::Error FramebufferVk::clearBufferfv(ContextImpl *context,
198 GLenum buffer,
199 GLint drawbuffer,
200 const GLfloat *values)
201{
202 UNIMPLEMENTED();
203 return gl::Error(GL_INVALID_OPERATION);
204}
205
206gl::Error FramebufferVk::clearBufferuiv(ContextImpl *context,
207 GLenum buffer,
208 GLint drawbuffer,
209 const GLuint *values)
210{
211 UNIMPLEMENTED();
212 return gl::Error(GL_INVALID_OPERATION);
213}
214
215gl::Error FramebufferVk::clearBufferiv(ContextImpl *context,
216 GLenum buffer,
217 GLint drawbuffer,
218 const GLint *values)
219{
220 UNIMPLEMENTED();
221 return gl::Error(GL_INVALID_OPERATION);
222}
223
224gl::Error FramebufferVk::clearBufferfi(ContextImpl *context,
225 GLenum buffer,
226 GLint drawbuffer,
227 GLfloat depth,
228 GLint stencil)
229{
230 UNIMPLEMENTED();
231 return gl::Error(GL_INVALID_OPERATION);
232}
233
234GLenum FramebufferVk::getImplementationColorReadFormat() const
235{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500236 auto errOrResult = GetReadAttachmentInfo(mState.getReadAttachment());
237
238 // TODO(jmadill): Handle getRenderTarget error.
239 if (errOrResult.isError())
240 {
Yuly Novikovd73f8522017-01-13 17:48:57 -0500241 ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500242 return GL_NONE;
243 }
244
245 return errOrResult.getResult()->format;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400246}
247
248GLenum FramebufferVk::getImplementationColorReadType() const
249{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500250 auto errOrResult = GetReadAttachmentInfo(mState.getReadAttachment());
251
252 // TODO(jmadill): Handle getRenderTarget error.
253 if (errOrResult.isError())
254 {
Yuly Novikovd73f8522017-01-13 17:48:57 -0500255 ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500256 return GL_NONE;
257 }
258
259 return errOrResult.getResult()->type;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400260}
261
262gl::Error FramebufferVk::readPixels(ContextImpl *context,
263 const gl::Rectangle &area,
264 GLenum format,
265 GLenum type,
266 GLvoid *pixels) const
267{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500268 const auto &glState = context->getGLState();
269 const auto *readFramebuffer = glState.getReadFramebuffer();
270 const auto *readAttachment = readFramebuffer->getReadColorbuffer();
271
272 RenderTargetVk *renderTarget = nullptr;
273 ANGLE_TRY(readAttachment->getRenderTarget(&renderTarget));
274
275 ContextVk *contextVk = GetAs<ContextVk>(context);
276 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill5deea722017-02-16 10:44:46 -0500277 VkDevice device = renderer->getDevice();
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500278
279 vk::Image *readImage = renderTarget->image;
280 vk::StagingImage stagingImage;
Jamie Madill5deea722017-02-16 10:44:46 -0500281 ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, *renderTarget->format,
282 renderTarget->extents, &stagingImage));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500283
284 vk::CommandBuffer *commandBuffer = contextVk->getCommandBuffer();
Jamie Madill5deea722017-02-16 10:44:46 -0500285 commandBuffer->begin(device);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500286 stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
287 commandBuffer);
288
289 gl::Box copyRegion;
290 copyRegion.x = area.x;
291 copyRegion.y = area.y;
292 copyRegion.z = 0;
293 copyRegion.width = area.width;
294 copyRegion.height = area.height;
295 copyRegion.depth = 1;
296
297 readImage->changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
298 commandBuffer);
299 commandBuffer->copySingleImage(*readImage, stagingImage.getImage(), copyRegion,
300 VK_IMAGE_ASPECT_COLOR_BIT);
301 commandBuffer->end();
302
303 ANGLE_TRY(renderer->submitAndFinishCommandBuffer(*commandBuffer));
304
305 // TODO(jmadill): parameters
306 uint8_t *mapPointer = nullptr;
Jamie Madill5deea722017-02-16 10:44:46 -0500307 ANGLE_TRY(
308 stagingImage.getDeviceMemory().map(device, 0, stagingImage.getSize(), 0, &mapPointer));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500309
310 const auto &angleFormat = renderTarget->format->format();
311
312 // TODO(jmadill): Use pixel bytes from the ANGLE format directly.
313 const auto &glFormat = gl::GetInternalFormatInfo(angleFormat.glInternalFormat);
314 int inputPitch = glFormat.pixelBytes * area.width;
315
316 PackPixelsParams params;
317 params.area = area;
318 params.format = format;
319 params.type = type;
320 params.outputPitch = inputPitch;
321 params.pack = glState.getPackState();
322
323 PackPixels(params, angleFormat, inputPitch, mapPointer, reinterpret_cast<uint8_t *>(pixels));
324
Jamie Madill5deea722017-02-16 10:44:46 -0500325 stagingImage.getDeviceMemory().unmap(device);
Jamie Madillf651c772017-02-21 15:03:51 -0500326 renderer->enqueueGarbage(renderer->getCurrentQueueSerial(), std::move(stagingImage));
327
328 stagingImage.getImage().destroy(renderer->getDevice());
Jamie Madill5deea722017-02-16 10:44:46 -0500329
330 stagingImage.destroy(device);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500331
332 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400333}
334
335gl::Error FramebufferVk::blit(ContextImpl *context,
336 const gl::Rectangle &sourceArea,
337 const gl::Rectangle &destArea,
338 GLbitfield mask,
339 GLenum filter)
340{
341 UNIMPLEMENTED();
342 return gl::Error(GL_INVALID_OPERATION);
343}
344
345bool FramebufferVk::checkStatus() const
346{
347 UNIMPLEMENTED();
348 return bool();
349}
350
351void FramebufferVk::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
352{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500353 // TODO(jmadill): Smarter update.
Jamie Madill5deea722017-02-16 10:44:46 -0500354 mDirtyRenderPass = true;
355 mDirtyFramebuffer = true;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500356}
357
358gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(VkDevice device)
359{
Jamie Madill5deea722017-02-16 10:44:46 -0500360 if (mRenderPass.valid() && !mDirtyRenderPass)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500361 {
362 return &mRenderPass;
363 }
364
365 // TODO(jmadill): Can we use stack-only memory?
366 std::vector<VkAttachmentDescription> attachmentDescs;
367 std::vector<VkAttachmentReference> colorAttachmentRefs;
368
369 const auto &colorAttachments = mState.getColorAttachments();
370 for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
371 {
372 const auto &colorAttachment = colorAttachments[attachmentIndex];
373 if (colorAttachment.isAttached())
374 {
375 VkAttachmentDescription colorDesc;
376 VkAttachmentReference colorRef;
377
378 RenderTargetVk *renderTarget = nullptr;
379 ANGLE_TRY(colorAttachment.getRenderTarget(&renderTarget));
380
381 // TODO(jmadill): We would only need this flag for duplicated attachments.
382 colorDesc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
383 colorDesc.format = renderTarget->format->native;
384 colorDesc.samples = ConvertSamples(colorAttachment.getSamples());
385
386 // The load op controls the prior existing depth/color attachment data.
387 // TODO(jmadill): Proper load ops. Should not be hard coded to clear.
388 colorDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
389 colorDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
390 colorDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
391 colorDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
392 colorDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500393
394 // We might want to transition directly to PRESENT_SRC for Surface attachments.
395 colorDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500396
397 colorRef.attachment = static_cast<uint32_t>(colorAttachments.size()) - 1u;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500398 colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500399
400 attachmentDescs.push_back(colorDesc);
401 colorAttachmentRefs.push_back(colorRef);
402 }
403 }
404
405 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
406 VkAttachmentReference depthStencilAttachmentRef;
407 bool useDepth = depthStencilAttachment && depthStencilAttachment->isAttached();
408
409 if (useDepth)
410 {
411 VkAttachmentDescription depthStencilDesc;
412
413 RenderTargetVk *renderTarget = nullptr;
414 ANGLE_TRY(depthStencilAttachment->getRenderTarget(&renderTarget));
415
416 depthStencilDesc.flags = 0;
417 depthStencilDesc.format = renderTarget->format->native;
418 depthStencilDesc.samples = ConvertSamples(depthStencilAttachment->getSamples());
419 depthStencilDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
420 depthStencilDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
421 depthStencilDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
422 depthStencilDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
423 depthStencilDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
424 depthStencilDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
425
426 depthStencilAttachmentRef.attachment = static_cast<uint32_t>(attachmentDescs.size());
427 depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
428
429 attachmentDescs.push_back(depthStencilDesc);
430 }
431
432 ASSERT(!attachmentDescs.empty());
433
434 VkSubpassDescription subpassDesc;
435
436 subpassDesc.flags = 0;
437 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
438 subpassDesc.inputAttachmentCount = 0;
439 subpassDesc.pInputAttachments = nullptr;
440 subpassDesc.colorAttachmentCount = static_cast<uint32_t>(colorAttachmentRefs.size());
441 subpassDesc.pColorAttachments = colorAttachmentRefs.data();
442 subpassDesc.pResolveAttachments = nullptr;
443 subpassDesc.pDepthStencilAttachment = (useDepth ? &depthStencilAttachmentRef : nullptr);
444 subpassDesc.preserveAttachmentCount = 0;
445 subpassDesc.pPreserveAttachments = nullptr;
446
447 VkRenderPassCreateInfo renderPassInfo;
448
449 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
450 renderPassInfo.pNext = nullptr;
451 renderPassInfo.flags = 0;
452 renderPassInfo.attachmentCount = static_cast<uint32_t>(attachmentDescs.size());
453 renderPassInfo.pAttachments = attachmentDescs.data();
454 renderPassInfo.subpassCount = 1;
455 renderPassInfo.pSubpasses = &subpassDesc;
456 renderPassInfo.dependencyCount = 0;
457 renderPassInfo.pDependencies = nullptr;
458
Jamie Madill5deea722017-02-16 10:44:46 -0500459 vk::RenderPass renderPass;
460 ANGLE_TRY(renderPass.init(device, renderPassInfo));
Jamie Madillab9f9c32017-01-17 17:47:34 -0500461
Jamie Madill5deea722017-02-16 10:44:46 -0500462 mRenderPass.retain(device, std::move(renderPass));
463
464 mDirtyRenderPass = false;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500465
466 return &mRenderPass;
467}
468
469gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(VkDevice device)
470{
471 // If we've already created our cached Framebuffer, return it.
Jamie Madill5deea722017-02-16 10:44:46 -0500472 if (mFramebuffer.valid() && !mDirtyFramebuffer)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500473 {
474 return &mFramebuffer;
475 }
476
477 vk::RenderPass *renderPass = nullptr;
478 ANGLE_TRY_RESULT(getRenderPass(device), renderPass);
479
480 // If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
481 if (mBackbuffer)
482 {
483 return mBackbuffer->getCurrentFramebuffer(device, *renderPass);
484 }
485
486 // Gather VkImageViews over all FBO attachments, also size of attached region.
487 std::vector<VkImageView> attachments;
488 gl::Extents attachmentsSize;
489
490 const auto &colorAttachments = mState.getColorAttachments();
491 for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
492 {
493 const auto &colorAttachment = colorAttachments[attachmentIndex];
494 if (colorAttachment.isAttached())
495 {
496 RenderTargetVk *renderTarget = nullptr;
497 ANGLE_TRY(colorAttachment.getRenderTarget<RenderTargetVk>(&renderTarget));
498 attachments.push_back(renderTarget->imageView->getHandle());
499
500 ASSERT(attachmentsSize.empty() || attachmentsSize == colorAttachment.getSize());
501 attachmentsSize = colorAttachment.getSize();
502 }
503 }
504
505 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
506 if (depthStencilAttachment && depthStencilAttachment->isAttached())
507 {
508 RenderTargetVk *renderTarget = nullptr;
509 ANGLE_TRY(depthStencilAttachment->getRenderTarget<RenderTargetVk>(&renderTarget));
510 attachments.push_back(renderTarget->imageView->getHandle());
511
512 ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilAttachment->getSize());
513 attachmentsSize = depthStencilAttachment->getSize();
514 }
515
516 ASSERT(!attachments.empty());
517
518 VkFramebufferCreateInfo framebufferInfo;
519
520 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
521 framebufferInfo.pNext = nullptr;
522 framebufferInfo.flags = 0;
523 framebufferInfo.renderPass = mRenderPass.getHandle();
524 framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
525 framebufferInfo.pAttachments = attachments.data();
526 framebufferInfo.width = static_cast<uint32_t>(attachmentsSize.width);
527 framebufferInfo.height = static_cast<uint32_t>(attachmentsSize.height);
528 framebufferInfo.layers = 1;
529
Jamie Madill5deea722017-02-16 10:44:46 -0500530 vk::Framebuffer framebuffer;
531 ANGLE_TRY(static_cast<gl::Error>(framebuffer.init(device, framebufferInfo)));
Jamie Madillab9f9c32017-01-17 17:47:34 -0500532
Jamie Madill5deea722017-02-16 10:44:46 -0500533 mFramebuffer.retain(device, std::move(framebuffer));
534
535 mDirtyFramebuffer = false;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500536
537 return &mFramebuffer;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400538}
539
JiangYizhoubddc46b2016-12-09 09:50:51 +0800540gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
541{
542 UNIMPLEMENTED();
543 return gl::InternalError() << "getSamplePosition is unimplemented.";
544}
545
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500546gl::Error FramebufferVk::beginRenderPass(VkDevice device,
547 vk::CommandBuffer *commandBuffer,
Jamie Madill4c26fc22017-02-24 11:04:10 -0500548 Serial queueSerial,
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500549 const gl::State &glState)
550{
Jamie Madill4c26fc22017-02-24 11:04:10 -0500551 // TODO(jmadill): Cache render targets.
552 for (const auto &colorAttachment : mState.getColorAttachments())
553 {
554 if (colorAttachment.isAttached())
555 {
556 RenderTargetVk *renderTarget = nullptr;
557 ANGLE_TRY(colorAttachment.getRenderTarget<RenderTargetVk>(&renderTarget));
558 renderTarget->resource->setQueueSerial(queueSerial);
559 }
560 }
561
562 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
563 if (depthStencilAttachment && depthStencilAttachment->isAttached())
564 {
565 RenderTargetVk *renderTarget = nullptr;
566 ANGLE_TRY(depthStencilAttachment->getRenderTarget<RenderTargetVk>(&renderTarget));
567 renderTarget->resource->setQueueSerial(queueSerial);
568 }
569
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500570 vk::Framebuffer *framebuffer = nullptr;
571 ANGLE_TRY_RESULT(getFramebuffer(device), framebuffer);
572 ASSERT(framebuffer && framebuffer->valid());
573
574 vk::RenderPass *renderPass = nullptr;
575 ANGLE_TRY_RESULT(getRenderPass(device), renderPass);
576 ASSERT(renderPass && renderPass->valid());
577
578 // TODO(jmadill): Proper clear value implementation.
579 VkClearColorValue colorClear;
580 memset(&colorClear, 0, sizeof(VkClearColorValue));
581 colorClear.float32[0] = glState.getColorClearValue().red;
582 colorClear.float32[1] = glState.getColorClearValue().green;
583 colorClear.float32[2] = glState.getColorClearValue().blue;
584 colorClear.float32[3] = glState.getColorClearValue().alpha;
585
586 std::vector<VkClearValue> attachmentClearValues;
587 attachmentClearValues.push_back({colorClear});
588
589 // Updated the cached image layout of the attachments in this FBO.
590 // For a default FBO, we need to call through to the WindowSurfaceVk
591 // TODO(jmadill): Iterate over all attachments.
592 ASSERT(mBackbuffer);
593 RenderTargetVk *renderTarget = nullptr;
594 ANGLE_TRY(mState.getFirstColorAttachment()->getRenderTarget(&renderTarget));
595 renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
596
Jamie Madill5deea722017-02-16 10:44:46 -0500597 ANGLE_TRY(commandBuffer->begin(device));
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500598 commandBuffer->beginRenderPass(*renderPass, *framebuffer, glState.getViewport(),
599 attachmentClearValues);
Jamie Madill4c26fc22017-02-24 11:04:10 -0500600
601 setQueueSerial(queueSerial);
602 if (mBackbuffer)
603 {
604 mBackbuffer->setQueueSerial(queueSerial);
605 }
606
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500607 return gl::NoError();
608}
609
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400610} // namespace rx