blob: b6a69f6b996735267f7cd84b84176bcf89e6e6b3 [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"
20#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
21#include "libANGLE/renderer/vulkan/RendererVk.h"
22#include "libANGLE/renderer/vulkan/SurfaceVk.h"
23#include "libANGLE/renderer/vulkan/formatutilsvk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040024
25namespace rx
26{
27
Jamie Madill7b57b9d2017-01-13 09:33:38 -050028namespace
29{
30
31gl::ErrorOrResult<const gl::InternalFormat *> GetReadAttachmentInfo(
32 const gl::FramebufferAttachment *readAttachment)
33{
34 RenderTargetVk *renderTarget = nullptr;
35 ANGLE_TRY(readAttachment->getRenderTarget(&renderTarget));
36
37 GLenum implFormat = renderTarget->format->format().fboImplementationInternalFormat;
38 return &gl::GetInternalFormatInfo(implFormat);
39}
40
Jamie Madillab9f9c32017-01-17 17:47:34 -050041VkSampleCountFlagBits ConvertSamples(GLint sampleCount)
42{
43 switch (sampleCount)
44 {
45 case 0:
46 case 1:
47 return VK_SAMPLE_COUNT_1_BIT;
48 case 2:
49 return VK_SAMPLE_COUNT_2_BIT;
50 case 4:
51 return VK_SAMPLE_COUNT_4_BIT;
52 case 8:
53 return VK_SAMPLE_COUNT_8_BIT;
54 case 16:
55 return VK_SAMPLE_COUNT_16_BIT;
56 case 32:
57 return VK_SAMPLE_COUNT_32_BIT;
58 default:
59 UNREACHABLE();
60 return VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM;
61 }
62}
63
Jamie Madill7b57b9d2017-01-13 09:33:38 -050064} // anonymous namespace
65
66// static
67FramebufferVk *FramebufferVk::CreateUserFBO(const gl::FramebufferState &state)
68{
69 return new FramebufferVk(state);
70}
71
72// static
73FramebufferVk *FramebufferVk::CreateDefaultFBO(const gl::FramebufferState &state,
74 WindowSurfaceVk *backbuffer)
75{
76 return new FramebufferVk(state, backbuffer);
77}
78
Jamie Madillab9f9c32017-01-17 17:47:34 -050079FramebufferVk::FramebufferVk(const gl::FramebufferState &state)
80 : FramebufferImpl(state),
81 mBackbuffer(nullptr),
82 mRenderPass(VK_NULL_HANDLE),
83 mFramebuffer(VK_NULL_HANDLE)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040084{
85}
86
Jamie Madill7b57b9d2017-01-13 09:33:38 -050087FramebufferVk::FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer)
Jamie Madillab9f9c32017-01-17 17:47:34 -050088 : FramebufferImpl(state),
89 mBackbuffer(backbuffer),
90 mRenderPass(VK_NULL_HANDLE),
91 mFramebuffer(VK_NULL_HANDLE)
Jamie Madill7b57b9d2017-01-13 09:33:38 -050092{
93}
94
Jamie Madill9e54b5a2016-05-25 12:57:39 -040095FramebufferVk::~FramebufferVk()
96{
97}
98
99gl::Error FramebufferVk::discard(size_t count, const GLenum *attachments)
100{
101 UNIMPLEMENTED();
102 return gl::Error(GL_INVALID_OPERATION);
103}
104
105gl::Error FramebufferVk::invalidate(size_t count, const GLenum *attachments)
106{
107 UNIMPLEMENTED();
108 return gl::Error(GL_INVALID_OPERATION);
109}
110
111gl::Error FramebufferVk::invalidateSub(size_t count,
112 const GLenum *attachments,
113 const gl::Rectangle &area)
114{
115 UNIMPLEMENTED();
116 return gl::Error(GL_INVALID_OPERATION);
117}
118
119gl::Error FramebufferVk::clear(ContextImpl *context, GLbitfield mask)
120{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500121 ContextVk *contextVk = GetAs<ContextVk>(context);
122
123 if (mState.getDepthAttachment() && (mask & GL_DEPTH_BUFFER_BIT) != 0)
124 {
125 // TODO(jmadill): Depth clear
126 UNIMPLEMENTED();
127 }
128
129 if (mState.getStencilAttachment() && (mask & GL_STENCIL_BUFFER_BIT) != 0)
130 {
131 // TODO(jmadill): Stencil clear
132 UNIMPLEMENTED();
133 }
134
135 if ((mask & GL_COLOR_BUFFER_BIT) == 0)
136 {
137 return gl::NoError();
138 }
139
140 const auto &glState = context->getGLState();
141 const auto &clearColor = glState.getColorClearValue();
142 VkClearColorValue clearColorValue;
143 clearColorValue.float32[0] = clearColor.red;
144 clearColorValue.float32[1] = clearColor.green;
145 clearColorValue.float32[2] = clearColor.blue;
146 clearColorValue.float32[3] = clearColor.alpha;
147
148 // TODO(jmadill): Scissored clears.
149 const auto *attachment = mState.getFirstNonNullAttachment();
150 ASSERT(attachment && attachment->isAttached());
151 const auto &size = attachment->getSize();
152 const gl::Rectangle renderArea(0, 0, size.width, size.height);
153
154 vk::CommandBuffer *commandBuffer = contextVk->getCommandBuffer();
155 ANGLE_TRY(commandBuffer->begin());
156
157 for (const auto &colorAttachment : mState.getColorAttachments())
158 {
159 if (colorAttachment.isAttached())
160 {
161 RenderTargetVk *renderTarget = nullptr;
162 ANGLE_TRY(colorAttachment.getRenderTarget(&renderTarget));
163 renderTarget->image->changeLayoutTop(
164 VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, commandBuffer);
165 commandBuffer->clearSingleColorImage(*renderTarget->image, clearColorValue);
166 }
167 }
168
169 commandBuffer->end();
170
171 ANGLE_TRY(contextVk->submitCommands(*commandBuffer));
172
173 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400174}
175
176gl::Error FramebufferVk::clearBufferfv(ContextImpl *context,
177 GLenum buffer,
178 GLint drawbuffer,
179 const GLfloat *values)
180{
181 UNIMPLEMENTED();
182 return gl::Error(GL_INVALID_OPERATION);
183}
184
185gl::Error FramebufferVk::clearBufferuiv(ContextImpl *context,
186 GLenum buffer,
187 GLint drawbuffer,
188 const GLuint *values)
189{
190 UNIMPLEMENTED();
191 return gl::Error(GL_INVALID_OPERATION);
192}
193
194gl::Error FramebufferVk::clearBufferiv(ContextImpl *context,
195 GLenum buffer,
196 GLint drawbuffer,
197 const GLint *values)
198{
199 UNIMPLEMENTED();
200 return gl::Error(GL_INVALID_OPERATION);
201}
202
203gl::Error FramebufferVk::clearBufferfi(ContextImpl *context,
204 GLenum buffer,
205 GLint drawbuffer,
206 GLfloat depth,
207 GLint stencil)
208{
209 UNIMPLEMENTED();
210 return gl::Error(GL_INVALID_OPERATION);
211}
212
213GLenum FramebufferVk::getImplementationColorReadFormat() const
214{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500215 auto errOrResult = GetReadAttachmentInfo(mState.getReadAttachment());
216
217 // TODO(jmadill): Handle getRenderTarget error.
218 if (errOrResult.isError())
219 {
Yuly Novikovd73f8522017-01-13 17:48:57 -0500220 ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500221 return GL_NONE;
222 }
223
224 return errOrResult.getResult()->format;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400225}
226
227GLenum FramebufferVk::getImplementationColorReadType() const
228{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500229 auto errOrResult = GetReadAttachmentInfo(mState.getReadAttachment());
230
231 // TODO(jmadill): Handle getRenderTarget error.
232 if (errOrResult.isError())
233 {
Yuly Novikovd73f8522017-01-13 17:48:57 -0500234 ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500235 return GL_NONE;
236 }
237
238 return errOrResult.getResult()->type;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400239}
240
241gl::Error FramebufferVk::readPixels(ContextImpl *context,
242 const gl::Rectangle &area,
243 GLenum format,
244 GLenum type,
245 GLvoid *pixels) const
246{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500247 const auto &glState = context->getGLState();
248 const auto *readFramebuffer = glState.getReadFramebuffer();
249 const auto *readAttachment = readFramebuffer->getReadColorbuffer();
250
251 RenderTargetVk *renderTarget = nullptr;
252 ANGLE_TRY(readAttachment->getRenderTarget(&renderTarget));
253
254 ContextVk *contextVk = GetAs<ContextVk>(context);
255 RendererVk *renderer = contextVk->getRenderer();
256
257 vk::Image *readImage = renderTarget->image;
258 vk::StagingImage stagingImage;
259 ANGLE_TRY_RESULT(renderer->createStagingImage(TextureDimension::TEX_2D, *renderTarget->format,
260 renderTarget->extents),
261 stagingImage);
262
263 vk::CommandBuffer *commandBuffer = contextVk->getCommandBuffer();
264 commandBuffer->begin();
265 stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
266 commandBuffer);
267
268 gl::Box copyRegion;
269 copyRegion.x = area.x;
270 copyRegion.y = area.y;
271 copyRegion.z = 0;
272 copyRegion.width = area.width;
273 copyRegion.height = area.height;
274 copyRegion.depth = 1;
275
276 readImage->changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
277 commandBuffer);
278 commandBuffer->copySingleImage(*readImage, stagingImage.getImage(), copyRegion,
279 VK_IMAGE_ASPECT_COLOR_BIT);
280 commandBuffer->end();
281
282 ANGLE_TRY(renderer->submitAndFinishCommandBuffer(*commandBuffer));
283
284 // TODO(jmadill): parameters
285 uint8_t *mapPointer = nullptr;
286 ANGLE_TRY(stagingImage.getDeviceMemory().map(0, stagingImage.getSize(), 0, &mapPointer));
287
288 const auto &angleFormat = renderTarget->format->format();
289
290 // TODO(jmadill): Use pixel bytes from the ANGLE format directly.
291 const auto &glFormat = gl::GetInternalFormatInfo(angleFormat.glInternalFormat);
292 int inputPitch = glFormat.pixelBytes * area.width;
293
294 PackPixelsParams params;
295 params.area = area;
296 params.format = format;
297 params.type = type;
298 params.outputPitch = inputPitch;
299 params.pack = glState.getPackState();
300
301 PackPixels(params, angleFormat, inputPitch, mapPointer, reinterpret_cast<uint8_t *>(pixels));
302
Jamie Madill70ee0f62017-02-06 16:04:20 -0500303 stagingImage.getImage().destroy(renderer->getDevice());
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500304 stagingImage.getDeviceMemory().unmap();
305
306 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400307}
308
309gl::Error FramebufferVk::blit(ContextImpl *context,
310 const gl::Rectangle &sourceArea,
311 const gl::Rectangle &destArea,
312 GLbitfield mask,
313 GLenum filter)
314{
315 UNIMPLEMENTED();
316 return gl::Error(GL_INVALID_OPERATION);
317}
318
319bool FramebufferVk::checkStatus() const
320{
321 UNIMPLEMENTED();
322 return bool();
323}
324
325void FramebufferVk::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
326{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500327 // TODO(jmadill): Smarter update.
Jamie Madillab9f9c32017-01-17 17:47:34 -0500328 mRenderPass = vk::RenderPass();
329 mFramebuffer = vk::Framebuffer();
330}
331
332gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(VkDevice device)
333{
334 if (mRenderPass.valid())
335 {
336 return &mRenderPass;
337 }
338
339 // TODO(jmadill): Can we use stack-only memory?
340 std::vector<VkAttachmentDescription> attachmentDescs;
341 std::vector<VkAttachmentReference> colorAttachmentRefs;
342
343 const auto &colorAttachments = mState.getColorAttachments();
344 for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
345 {
346 const auto &colorAttachment = colorAttachments[attachmentIndex];
347 if (colorAttachment.isAttached())
348 {
349 VkAttachmentDescription colorDesc;
350 VkAttachmentReference colorRef;
351
352 RenderTargetVk *renderTarget = nullptr;
353 ANGLE_TRY(colorAttachment.getRenderTarget(&renderTarget));
354
355 // TODO(jmadill): We would only need this flag for duplicated attachments.
356 colorDesc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
357 colorDesc.format = renderTarget->format->native;
358 colorDesc.samples = ConvertSamples(colorAttachment.getSamples());
359
360 // The load op controls the prior existing depth/color attachment data.
361 // TODO(jmadill): Proper load ops. Should not be hard coded to clear.
362 colorDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
363 colorDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
364 colorDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
365 colorDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
366 colorDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500367
368 // We might want to transition directly to PRESENT_SRC for Surface attachments.
369 colorDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500370
371 colorRef.attachment = static_cast<uint32_t>(colorAttachments.size()) - 1u;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500372 colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500373
374 attachmentDescs.push_back(colorDesc);
375 colorAttachmentRefs.push_back(colorRef);
376 }
377 }
378
379 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
380 VkAttachmentReference depthStencilAttachmentRef;
381 bool useDepth = depthStencilAttachment && depthStencilAttachment->isAttached();
382
383 if (useDepth)
384 {
385 VkAttachmentDescription depthStencilDesc;
386
387 RenderTargetVk *renderTarget = nullptr;
388 ANGLE_TRY(depthStencilAttachment->getRenderTarget(&renderTarget));
389
390 depthStencilDesc.flags = 0;
391 depthStencilDesc.format = renderTarget->format->native;
392 depthStencilDesc.samples = ConvertSamples(depthStencilAttachment->getSamples());
393 depthStencilDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
394 depthStencilDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
395 depthStencilDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
396 depthStencilDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
397 depthStencilDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
398 depthStencilDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
399
400 depthStencilAttachmentRef.attachment = static_cast<uint32_t>(attachmentDescs.size());
401 depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
402
403 attachmentDescs.push_back(depthStencilDesc);
404 }
405
406 ASSERT(!attachmentDescs.empty());
407
408 VkSubpassDescription subpassDesc;
409
410 subpassDesc.flags = 0;
411 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
412 subpassDesc.inputAttachmentCount = 0;
413 subpassDesc.pInputAttachments = nullptr;
414 subpassDesc.colorAttachmentCount = static_cast<uint32_t>(colorAttachmentRefs.size());
415 subpassDesc.pColorAttachments = colorAttachmentRefs.data();
416 subpassDesc.pResolveAttachments = nullptr;
417 subpassDesc.pDepthStencilAttachment = (useDepth ? &depthStencilAttachmentRef : nullptr);
418 subpassDesc.preserveAttachmentCount = 0;
419 subpassDesc.pPreserveAttachments = nullptr;
420
421 VkRenderPassCreateInfo renderPassInfo;
422
423 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
424 renderPassInfo.pNext = nullptr;
425 renderPassInfo.flags = 0;
426 renderPassInfo.attachmentCount = static_cast<uint32_t>(attachmentDescs.size());
427 renderPassInfo.pAttachments = attachmentDescs.data();
428 renderPassInfo.subpassCount = 1;
429 renderPassInfo.pSubpasses = &subpassDesc;
430 renderPassInfo.dependencyCount = 0;
431 renderPassInfo.pDependencies = nullptr;
432
433 vk::RenderPass renderPass(device);
434 ANGLE_TRY(renderPass.init(renderPassInfo));
435
436 mRenderPass = std::move(renderPass);
437
438 return &mRenderPass;
439}
440
441gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(VkDevice device)
442{
443 // If we've already created our cached Framebuffer, return it.
444 if (mFramebuffer.valid())
445 {
446 return &mFramebuffer;
447 }
448
449 vk::RenderPass *renderPass = nullptr;
450 ANGLE_TRY_RESULT(getRenderPass(device), renderPass);
451
452 // If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
453 if (mBackbuffer)
454 {
455 return mBackbuffer->getCurrentFramebuffer(device, *renderPass);
456 }
457
458 // Gather VkImageViews over all FBO attachments, also size of attached region.
459 std::vector<VkImageView> attachments;
460 gl::Extents attachmentsSize;
461
462 const auto &colorAttachments = mState.getColorAttachments();
463 for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
464 {
465 const auto &colorAttachment = colorAttachments[attachmentIndex];
466 if (colorAttachment.isAttached())
467 {
468 RenderTargetVk *renderTarget = nullptr;
469 ANGLE_TRY(colorAttachment.getRenderTarget<RenderTargetVk>(&renderTarget));
470 attachments.push_back(renderTarget->imageView->getHandle());
471
472 ASSERT(attachmentsSize.empty() || attachmentsSize == colorAttachment.getSize());
473 attachmentsSize = colorAttachment.getSize();
474 }
475 }
476
477 const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
478 if (depthStencilAttachment && depthStencilAttachment->isAttached())
479 {
480 RenderTargetVk *renderTarget = nullptr;
481 ANGLE_TRY(depthStencilAttachment->getRenderTarget<RenderTargetVk>(&renderTarget));
482 attachments.push_back(renderTarget->imageView->getHandle());
483
484 ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilAttachment->getSize());
485 attachmentsSize = depthStencilAttachment->getSize();
486 }
487
488 ASSERT(!attachments.empty());
489
490 VkFramebufferCreateInfo framebufferInfo;
491
492 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
493 framebufferInfo.pNext = nullptr;
494 framebufferInfo.flags = 0;
495 framebufferInfo.renderPass = mRenderPass.getHandle();
496 framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
497 framebufferInfo.pAttachments = attachments.data();
498 framebufferInfo.width = static_cast<uint32_t>(attachmentsSize.width);
499 framebufferInfo.height = static_cast<uint32_t>(attachmentsSize.height);
500 framebufferInfo.layers = 1;
501
502 vk::Framebuffer framebuffer(device);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500503 ANGLE_TRY(static_cast<gl::Error>(framebuffer.init(framebufferInfo)));
Jamie Madillab9f9c32017-01-17 17:47:34 -0500504
505 mFramebuffer = std::move(framebuffer);
506
507 return &mFramebuffer;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400508}
509
JiangYizhoubddc46b2016-12-09 09:50:51 +0800510gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
511{
512 UNIMPLEMENTED();
513 return gl::InternalError() << "getSamplePosition is unimplemented.";
514}
515
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500516gl::Error FramebufferVk::beginRenderPass(VkDevice device,
517 vk::CommandBuffer *commandBuffer,
518 const gl::State &glState)
519{
520 vk::Framebuffer *framebuffer = nullptr;
521 ANGLE_TRY_RESULT(getFramebuffer(device), framebuffer);
522 ASSERT(framebuffer && framebuffer->valid());
523
524 vk::RenderPass *renderPass = nullptr;
525 ANGLE_TRY_RESULT(getRenderPass(device), renderPass);
526 ASSERT(renderPass && renderPass->valid());
527
528 // TODO(jmadill): Proper clear value implementation.
529 VkClearColorValue colorClear;
530 memset(&colorClear, 0, sizeof(VkClearColorValue));
531 colorClear.float32[0] = glState.getColorClearValue().red;
532 colorClear.float32[1] = glState.getColorClearValue().green;
533 colorClear.float32[2] = glState.getColorClearValue().blue;
534 colorClear.float32[3] = glState.getColorClearValue().alpha;
535
536 std::vector<VkClearValue> attachmentClearValues;
537 attachmentClearValues.push_back({colorClear});
538
539 // Updated the cached image layout of the attachments in this FBO.
540 // For a default FBO, we need to call through to the WindowSurfaceVk
541 // TODO(jmadill): Iterate over all attachments.
542 ASSERT(mBackbuffer);
543 RenderTargetVk *renderTarget = nullptr;
544 ANGLE_TRY(mState.getFirstColorAttachment()->getRenderTarget(&renderTarget));
545 renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
546
547 ANGLE_TRY(commandBuffer->begin());
548 commandBuffer->beginRenderPass(*renderPass, *framebuffer, glState.getViewport(),
549 attachmentClearValues);
550 return gl::NoError();
551}
552
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400553} // namespace rx