blob: 2db9c7a4b5e56c65be709d9e91466892c9240dfd [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 Madill70ee0f62017-02-06 16:04:20 -0500325 stagingImage.getImage().destroy(renderer->getDevice());
Jamie Madill5deea722017-02-16 10:44:46 -0500326 stagingImage.getDeviceMemory().unmap(device);
327
328 stagingImage.destroy(device);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500329
330 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400331}
332
333gl::Error FramebufferVk::blit(ContextImpl *context,
334 const gl::Rectangle &sourceArea,
335 const gl::Rectangle &destArea,
336 GLbitfield mask,
337 GLenum filter)
338{
339 UNIMPLEMENTED();
340 return gl::Error(GL_INVALID_OPERATION);
341}
342
343bool FramebufferVk::checkStatus() const
344{
345 UNIMPLEMENTED();
346 return bool();
347}
348
349void FramebufferVk::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
350{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500351 // TODO(jmadill): Smarter update.
Jamie Madill5deea722017-02-16 10:44:46 -0500352 mDirtyRenderPass = true;
353 mDirtyFramebuffer = true;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500354}
355
356gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(VkDevice device)
357{
Jamie Madill5deea722017-02-16 10:44:46 -0500358 if (mRenderPass.valid() && !mDirtyRenderPass)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500359 {
360 return &mRenderPass;
361 }
362
363 // TODO(jmadill): Can we use stack-only memory?
364 std::vector<VkAttachmentDescription> attachmentDescs;
365 std::vector<VkAttachmentReference> colorAttachmentRefs;
366
367 const auto &colorAttachments = mState.getColorAttachments();
368 for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
369 {
370 const auto &colorAttachment = colorAttachments[attachmentIndex];
371 if (colorAttachment.isAttached())
372 {
373 VkAttachmentDescription colorDesc;
374 VkAttachmentReference colorRef;
375
376 RenderTargetVk *renderTarget = nullptr;
377 ANGLE_TRY(colorAttachment.getRenderTarget(&renderTarget));
378
379 // TODO(jmadill): We would only need this flag for duplicated attachments.
380 colorDesc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
381 colorDesc.format = renderTarget->format->native;
382 colorDesc.samples = ConvertSamples(colorAttachment.getSamples());
383
384 // The load op controls the prior existing depth/color attachment data.
385 // TODO(jmadill): Proper load ops. Should not be hard coded to clear.
386 colorDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
387 colorDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
388 colorDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
389 colorDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
390 colorDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500391
392 // We might want to transition directly to PRESENT_SRC for Surface attachments.
393 colorDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500394
395 colorRef.attachment = static_cast<uint32_t>(colorAttachments.size()) - 1u;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500396 colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500397
398 attachmentDescs.push_back(colorDesc);
399 colorAttachmentRefs.push_back(colorRef);
400 }
401 }
402
403 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
404 VkAttachmentReference depthStencilAttachmentRef;
405 bool useDepth = depthStencilAttachment && depthStencilAttachment->isAttached();
406
407 if (useDepth)
408 {
409 VkAttachmentDescription depthStencilDesc;
410
411 RenderTargetVk *renderTarget = nullptr;
412 ANGLE_TRY(depthStencilAttachment->getRenderTarget(&renderTarget));
413
414 depthStencilDesc.flags = 0;
415 depthStencilDesc.format = renderTarget->format->native;
416 depthStencilDesc.samples = ConvertSamples(depthStencilAttachment->getSamples());
417 depthStencilDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
418 depthStencilDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
419 depthStencilDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
420 depthStencilDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
421 depthStencilDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
422 depthStencilDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
423
424 depthStencilAttachmentRef.attachment = static_cast<uint32_t>(attachmentDescs.size());
425 depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
426
427 attachmentDescs.push_back(depthStencilDesc);
428 }
429
430 ASSERT(!attachmentDescs.empty());
431
432 VkSubpassDescription subpassDesc;
433
434 subpassDesc.flags = 0;
435 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
436 subpassDesc.inputAttachmentCount = 0;
437 subpassDesc.pInputAttachments = nullptr;
438 subpassDesc.colorAttachmentCount = static_cast<uint32_t>(colorAttachmentRefs.size());
439 subpassDesc.pColorAttachments = colorAttachmentRefs.data();
440 subpassDesc.pResolveAttachments = nullptr;
441 subpassDesc.pDepthStencilAttachment = (useDepth ? &depthStencilAttachmentRef : nullptr);
442 subpassDesc.preserveAttachmentCount = 0;
443 subpassDesc.pPreserveAttachments = nullptr;
444
445 VkRenderPassCreateInfo renderPassInfo;
446
447 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
448 renderPassInfo.pNext = nullptr;
449 renderPassInfo.flags = 0;
450 renderPassInfo.attachmentCount = static_cast<uint32_t>(attachmentDescs.size());
451 renderPassInfo.pAttachments = attachmentDescs.data();
452 renderPassInfo.subpassCount = 1;
453 renderPassInfo.pSubpasses = &subpassDesc;
454 renderPassInfo.dependencyCount = 0;
455 renderPassInfo.pDependencies = nullptr;
456
Jamie Madill5deea722017-02-16 10:44:46 -0500457 vk::RenderPass renderPass;
458 ANGLE_TRY(renderPass.init(device, renderPassInfo));
Jamie Madillab9f9c32017-01-17 17:47:34 -0500459
Jamie Madill5deea722017-02-16 10:44:46 -0500460 mRenderPass.retain(device, std::move(renderPass));
461
462 mDirtyRenderPass = false;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500463
464 return &mRenderPass;
465}
466
467gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(VkDevice device)
468{
469 // If we've already created our cached Framebuffer, return it.
Jamie Madill5deea722017-02-16 10:44:46 -0500470 if (mFramebuffer.valid() && !mDirtyFramebuffer)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500471 {
472 return &mFramebuffer;
473 }
474
475 vk::RenderPass *renderPass = nullptr;
476 ANGLE_TRY_RESULT(getRenderPass(device), renderPass);
477
478 // If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
479 if (mBackbuffer)
480 {
481 return mBackbuffer->getCurrentFramebuffer(device, *renderPass);
482 }
483
484 // Gather VkImageViews over all FBO attachments, also size of attached region.
485 std::vector<VkImageView> attachments;
486 gl::Extents attachmentsSize;
487
488 const auto &colorAttachments = mState.getColorAttachments();
489 for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
490 {
491 const auto &colorAttachment = colorAttachments[attachmentIndex];
492 if (colorAttachment.isAttached())
493 {
494 RenderTargetVk *renderTarget = nullptr;
495 ANGLE_TRY(colorAttachment.getRenderTarget<RenderTargetVk>(&renderTarget));
496 attachments.push_back(renderTarget->imageView->getHandle());
497
498 ASSERT(attachmentsSize.empty() || attachmentsSize == colorAttachment.getSize());
499 attachmentsSize = colorAttachment.getSize();
500 }
501 }
502
503 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
504 if (depthStencilAttachment && depthStencilAttachment->isAttached())
505 {
506 RenderTargetVk *renderTarget = nullptr;
507 ANGLE_TRY(depthStencilAttachment->getRenderTarget<RenderTargetVk>(&renderTarget));
508 attachments.push_back(renderTarget->imageView->getHandle());
509
510 ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilAttachment->getSize());
511 attachmentsSize = depthStencilAttachment->getSize();
512 }
513
514 ASSERT(!attachments.empty());
515
516 VkFramebufferCreateInfo framebufferInfo;
517
518 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
519 framebufferInfo.pNext = nullptr;
520 framebufferInfo.flags = 0;
521 framebufferInfo.renderPass = mRenderPass.getHandle();
522 framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
523 framebufferInfo.pAttachments = attachments.data();
524 framebufferInfo.width = static_cast<uint32_t>(attachmentsSize.width);
525 framebufferInfo.height = static_cast<uint32_t>(attachmentsSize.height);
526 framebufferInfo.layers = 1;
527
Jamie Madill5deea722017-02-16 10:44:46 -0500528 vk::Framebuffer framebuffer;
529 ANGLE_TRY(static_cast<gl::Error>(framebuffer.init(device, framebufferInfo)));
Jamie Madillab9f9c32017-01-17 17:47:34 -0500530
Jamie Madill5deea722017-02-16 10:44:46 -0500531 mFramebuffer.retain(device, std::move(framebuffer));
532
533 mDirtyFramebuffer = false;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500534
535 return &mFramebuffer;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400536}
537
JiangYizhoubddc46b2016-12-09 09:50:51 +0800538gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
539{
540 UNIMPLEMENTED();
541 return gl::InternalError() << "getSamplePosition is unimplemented.";
542}
543
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500544gl::Error FramebufferVk::beginRenderPass(VkDevice device,
545 vk::CommandBuffer *commandBuffer,
Jamie Madill4c26fc22017-02-24 11:04:10 -0500546 Serial queueSerial,
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500547 const gl::State &glState)
548{
Jamie Madill4c26fc22017-02-24 11:04:10 -0500549 // TODO(jmadill): Cache render targets.
550 for (const auto &colorAttachment : mState.getColorAttachments())
551 {
552 if (colorAttachment.isAttached())
553 {
554 RenderTargetVk *renderTarget = nullptr;
555 ANGLE_TRY(colorAttachment.getRenderTarget<RenderTargetVk>(&renderTarget));
556 renderTarget->resource->setQueueSerial(queueSerial);
557 }
558 }
559
560 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
561 if (depthStencilAttachment && depthStencilAttachment->isAttached())
562 {
563 RenderTargetVk *renderTarget = nullptr;
564 ANGLE_TRY(depthStencilAttachment->getRenderTarget<RenderTargetVk>(&renderTarget));
565 renderTarget->resource->setQueueSerial(queueSerial);
566 }
567
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500568 vk::Framebuffer *framebuffer = nullptr;
569 ANGLE_TRY_RESULT(getFramebuffer(device), framebuffer);
570 ASSERT(framebuffer && framebuffer->valid());
571
572 vk::RenderPass *renderPass = nullptr;
573 ANGLE_TRY_RESULT(getRenderPass(device), renderPass);
574 ASSERT(renderPass && renderPass->valid());
575
576 // TODO(jmadill): Proper clear value implementation.
577 VkClearColorValue colorClear;
578 memset(&colorClear, 0, sizeof(VkClearColorValue));
579 colorClear.float32[0] = glState.getColorClearValue().red;
580 colorClear.float32[1] = glState.getColorClearValue().green;
581 colorClear.float32[2] = glState.getColorClearValue().blue;
582 colorClear.float32[3] = glState.getColorClearValue().alpha;
583
584 std::vector<VkClearValue> attachmentClearValues;
585 attachmentClearValues.push_back({colorClear});
586
587 // Updated the cached image layout of the attachments in this FBO.
588 // For a default FBO, we need to call through to the WindowSurfaceVk
589 // TODO(jmadill): Iterate over all attachments.
590 ASSERT(mBackbuffer);
591 RenderTargetVk *renderTarget = nullptr;
592 ANGLE_TRY(mState.getFirstColorAttachment()->getRenderTarget(&renderTarget));
593 renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
594
Jamie Madill5deea722017-02-16 10:44:46 -0500595 ANGLE_TRY(commandBuffer->begin(device));
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500596 commandBuffer->beginRenderPass(*renderPass, *framebuffer, glState.getViewport(),
597 attachmentClearValues);
Jamie Madill4c26fc22017-02-24 11:04:10 -0500598
599 setQueueSerial(queueSerial);
600 if (mBackbuffer)
601 {
602 mBackbuffer->setQueueSerial(queueSerial);
603 }
604
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500605 return gl::NoError();
606}
607
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400608} // namespace rx