blob: f5557e6798a666e2279b44f15b698472d1be05a2 [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 <vulkan/vulkan.h>
Jamie Madill231c7f52017-04-26 13:45:37 -040013#include <array>
Jamie Madill7b57b9d2017-01-13 09:33:38 -050014
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"
Jamie Madillc564c072017-06-01 12:45:42 -040017#include "libANGLE/Context.h"
18#include "libANGLE/Display.h"
Jamie Madill7b57b9d2017-01-13 09:33:38 -050019#include "libANGLE/formatutils.h"
20#include "libANGLE/renderer/renderer_utils.h"
Jamie Madill1f46bc12018-02-20 16:09:43 -050021#include "libANGLE/renderer/vulkan/CommandGraph.h"
Jamie Madill7b57b9d2017-01-13 09:33:38 -050022#include "libANGLE/renderer/vulkan/ContextVk.h"
Jamie Madill5deea722017-02-16 10:44:46 -050023#include "libANGLE/renderer/vulkan/DisplayVk.h"
Jamie Madill7b57b9d2017-01-13 09:33:38 -050024#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
25#include "libANGLE/renderer/vulkan/RendererVk.h"
26#include "libANGLE/renderer/vulkan/SurfaceVk.h"
Jamie Madill3c424b42018-01-19 12:35:09 -050027#include "libANGLE/renderer/vulkan/vk_format_utils.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040028
29namespace rx
30{
31
Jamie Madill7b57b9d2017-01-13 09:33:38 -050032namespace
33{
Jamie Madill66546be2018-03-08 09:47:20 -050034const gl::InternalFormat &GetReadAttachmentInfo(const gl::Context *context,
35 RenderTargetVk *renderTarget)
Jamie Madill7b57b9d2017-01-13 09:33:38 -050036{
Jamie Madillbc543422018-03-30 10:43:19 -040037 GLenum implFormat =
38 renderTarget->image->getFormat().textureFormat().fboImplementationInternalFormat;
Jamie Madill66546be2018-03-08 09:47:20 -050039 return gl::GetSizedInternalFormatInfo(implFormat);
Jamie Madill7b57b9d2017-01-13 09:33:38 -050040}
Jamie Madill7b57b9d2017-01-13 09:33:38 -050041} // anonymous namespace
42
43// static
44FramebufferVk *FramebufferVk::CreateUserFBO(const gl::FramebufferState &state)
45{
46 return new FramebufferVk(state);
47}
48
49// static
50FramebufferVk *FramebufferVk::CreateDefaultFBO(const gl::FramebufferState &state,
51 WindowSurfaceVk *backbuffer)
52{
53 return new FramebufferVk(state, backbuffer);
54}
55
Jamie Madillab9f9c32017-01-17 17:47:34 -050056FramebufferVk::FramebufferVk(const gl::FramebufferState &state)
Jamie Madill9aef3672018-04-27 11:45:06 -040057 : FramebufferImpl(state),
58 mBackbuffer(nullptr),
59 mRenderPassDesc(),
60 mFramebuffer(),
61 mActiveColorComponents(0),
62 mMaskedClearDescriptorSet(VK_NULL_HANDLE)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040063{
64}
65
Jamie Madill7b57b9d2017-01-13 09:33:38 -050066FramebufferVk::FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer)
Jamie Madill9aef3672018-04-27 11:45:06 -040067 : FramebufferImpl(state),
68 mBackbuffer(backbuffer),
69 mRenderPassDesc(),
70 mFramebuffer(),
71 mActiveColorComponents(0),
72 mMaskedClearDescriptorSet(VK_NULL_HANDLE)
Jamie Madill7b57b9d2017-01-13 09:33:38 -050073{
74}
75
Jamie Madill9e54b5a2016-05-25 12:57:39 -040076FramebufferVk::~FramebufferVk()
77{
78}
79
Jamie Madillc564c072017-06-01 12:45:42 -040080void FramebufferVk::destroy(const gl::Context *context)
Jamie Madill5deea722017-02-16 10:44:46 -050081{
Jamie Madille1f3ad42017-10-28 23:00:42 -040082 RendererVk *renderer = vk::GetImpl(context)->getRenderer();
Jamie Madill526543c2017-10-28 10:59:16 -040083 renderer->releaseResource(*this, &mFramebuffer);
Jamie Madill9aef3672018-04-27 11:45:06 -040084 renderer->releaseResource(*this, &mMaskedClearUniformBuffer.buffer);
85 renderer->releaseResource(*this, &mMaskedClearUniformBuffer.memory);
Jamie Madill5deea722017-02-16 10:44:46 -050086}
87
Jamie Madillc564c072017-06-01 12:45:42 -040088void FramebufferVk::destroyDefault(const egl::Display *display)
Jamie Madill5deea722017-02-16 10:44:46 -050089{
Jamie Madille1f3ad42017-10-28 23:00:42 -040090 VkDevice device = vk::GetImpl(display)->getRenderer()->getDevice();
Jamie Madill5deea722017-02-16 10:44:46 -050091
Jamie Madill5deea722017-02-16 10:44:46 -050092 mFramebuffer.destroy(device);
93}
94
Jamie Madill4928b7c2017-06-20 12:57:39 -040095gl::Error FramebufferVk::discard(const gl::Context *context,
96 size_t count,
97 const GLenum *attachments)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040098{
99 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500100 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400101}
102
Jamie Madill4928b7c2017-06-20 12:57:39 -0400103gl::Error FramebufferVk::invalidate(const gl::Context *context,
104 size_t count,
105 const GLenum *attachments)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400106{
107 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500108 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400109}
110
Jamie Madill4928b7c2017-06-20 12:57:39 -0400111gl::Error FramebufferVk::invalidateSub(const gl::Context *context,
112 size_t count,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400113 const GLenum *attachments,
114 const gl::Rectangle &area)
115{
116 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500117 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400118}
119
Jamie Madillc564c072017-06-01 12:45:42 -0400120gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400121{
Jamie Madill0cec82a2018-03-14 09:21:07 -0400122 ContextVk *contextVk = vk::GetImpl(context);
123 RendererVk *renderer = contextVk->getRenderer();
124 Serial currentSerial = renderer->getCurrentQueueSerial();
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500125
Jamie Madill0cec82a2018-03-14 09:21:07 -0400126 // This command buffer is only started once.
127 vk::CommandBuffer *commandBuffer = nullptr;
128 vk::CommandGraphNode *writingNode = nullptr;
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500129
Jamie Madill0cec82a2018-03-14 09:21:07 -0400130 const gl::FramebufferAttachment *depthAttachment = mState.getDepthAttachment();
131 bool clearDepth = (depthAttachment && (mask & GL_DEPTH_BUFFER_BIT) != 0);
132 ASSERT(!clearDepth || depthAttachment->isAttached());
133
134 const gl::FramebufferAttachment *stencilAttachment = mState.getStencilAttachment();
135 bool clearStencil = (stencilAttachment && (mask & GL_STENCIL_BUFFER_BIT) != 0);
136 ASSERT(!clearStencil || stencilAttachment->isAttached());
137
Luc Ferrona8af3a62018-03-29 14:44:24 -0400138 bool clearColor = IsMaskFlagSet(static_cast<int>(mask), GL_COLOR_BUFFER_BIT);
139
Luc Ferron8836f632018-04-05 07:26:53 -0400140 const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthStencilAttachment();
Jamie Madilld47044a2018-04-27 11:45:03 -0400141 const gl::State &glState = context->getGLState();
Luc Ferron8836f632018-04-05 07:26:53 -0400142
Jamie Madill9aef3672018-04-27 11:45:06 -0400143 // The most costly clear mode is when we need to mask out specific color channels. This can
144 // only be done with a draw call. The scissor region however can easily be integrated with
145 // this method. Similarly for depth/stencil clear.
146 VkColorComponentFlags colorMaskFlags = contextVk->getClearColorMask();
147 if (clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents)
148 {
149 return clearWithDraw(contextVk, colorMaskFlags);
150 }
151
Luc Ferron8836f632018-04-05 07:26:53 -0400152 // If we clear the depth OR the stencil but not both, and we have a packed depth stencil
153 // attachment, we need to use clearAttachment instead of clearDepthStencil since Vulkan won't
154 // allow us to clear one or the other separately.
155 bool isSingleClearOnPackedDepthStencilAttachment =
156 depthStencilAttachment && (clearDepth != clearStencil);
Jamie Madilld47044a2018-04-27 11:45:03 -0400157 if (glState.isScissorTestEnabled() || isSingleClearOnPackedDepthStencilAttachment)
Luc Ferrona8af3a62018-03-29 14:44:24 -0400158 {
159 // With scissor test enabled, we clear very differently and we don't need to access
160 // the image inside each attachment we can just use clearCmdAttachments with our
161 // scissor region instead.
Jamie Madillb90779e2018-04-27 11:45:01 -0400162 ANGLE_TRY(clearWithClearAttachments(contextVk, clearColor, clearDepth, clearStencil));
Luc Ferrona8af3a62018-03-29 14:44:24 -0400163 return gl::NoError();
164 }
165
166 // Standard Depth/stencil clear without scissor.
Jamie Madill0cec82a2018-03-14 09:21:07 -0400167 if (clearDepth || clearStencil)
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500168 {
Jamie Madill0cec82a2018-03-14 09:21:07 -0400169 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
Jamie Madill9cceac42018-03-31 14:19:16 -0400170 writingNode = getCurrentWritingNode();
Jamie Madill0cec82a2018-03-14 09:21:07 -0400171
172 const VkClearDepthStencilValue &clearDepthStencilValue =
173 contextVk->getClearDepthStencilValue().depthStencil;
174
175 // We only support packed depth/stencil, not separate.
Luc Ferron8836f632018-04-05 07:26:53 -0400176 ASSERT(!(clearDepth && clearStencil) || depthStencilAttachment);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400177
Luc Ferrone6a40d02018-03-22 10:30:57 -0400178 const VkImageAspectFlags aspectFlags =
179 (depthAttachment ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
180 (stencilAttachment ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400181
182 RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
183 renderTarget->resource->onWriteResource(writingNode, currentSerial);
Jamie Madill858c1cc2018-03-31 14:19:13 -0400184 renderTarget->image->clearDepthStencil(aspectFlags, clearDepthStencilValue, commandBuffer);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400185
Luc Ferrona8af3a62018-03-29 14:44:24 -0400186 if (!clearColor)
Jamie Madill0cec82a2018-03-14 09:21:07 -0400187 {
188 return gl::NoError();
189 }
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500190 }
191
Luc Ferrona8af3a62018-03-29 14:44:24 -0400192 ASSERT(clearColor);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500193 const auto *attachment = mState.getFirstNonNullAttachment();
194 ASSERT(attachment && attachment->isAttached());
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500195
Jamie Madill0cec82a2018-03-14 09:21:07 -0400196 if (!commandBuffer)
197 {
198 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
Jamie Madill9cceac42018-03-31 14:19:16 -0400199 writingNode = getCurrentWritingNode();
Jamie Madill0cec82a2018-03-14 09:21:07 -0400200 }
Jamie Madillefb5a5c2018-01-29 15:56:59 -0500201
Jamie Madill66546be2018-03-08 09:47:20 -0500202 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
203 const auto &colorRenderTargets = mRenderTargetCache.getColors();
Jamie Madill9aef3672018-04-27 11:45:06 -0400204 const VkClearColorValue &clearColorValue = contextVk->getClearColorValue().color;
Jamie Madill66546be2018-03-08 09:47:20 -0500205 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500206 {
Jamie Madill66546be2018-03-08 09:47:20 -0500207 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
208 ASSERT(colorRenderTarget);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400209 colorRenderTarget->resource->onWriteResource(writingNode, currentSerial);
Jamie Madill9aef3672018-04-27 11:45:06 -0400210 colorRenderTarget->image->clearColor(clearColorValue, commandBuffer);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500211 }
212
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500213 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400214}
215
Jamie Madillc564c072017-06-01 12:45:42 -0400216gl::Error FramebufferVk::clearBufferfv(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400217 GLenum buffer,
218 GLint drawbuffer,
219 const GLfloat *values)
220{
221 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500222 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400223}
224
Jamie Madillc564c072017-06-01 12:45:42 -0400225gl::Error FramebufferVk::clearBufferuiv(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400226 GLenum buffer,
227 GLint drawbuffer,
228 const GLuint *values)
229{
230 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500231 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400232}
233
Jamie Madillc564c072017-06-01 12:45:42 -0400234gl::Error FramebufferVk::clearBufferiv(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400235 GLenum buffer,
236 GLint drawbuffer,
237 const GLint *values)
238{
239 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500240 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400241}
242
Jamie Madillc564c072017-06-01 12:45:42 -0400243gl::Error FramebufferVk::clearBufferfi(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400244 GLenum buffer,
245 GLint drawbuffer,
246 GLfloat depth,
247 GLint stencil)
248{
249 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500250 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400251}
252
Jamie Madill4928b7c2017-06-20 12:57:39 -0400253GLenum FramebufferVk::getImplementationColorReadFormat(const gl::Context *context) const
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400254{
Jamie Madill66546be2018-03-08 09:47:20 -0500255 return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).format;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400256}
257
Jamie Madill4928b7c2017-06-20 12:57:39 -0400258GLenum FramebufferVk::getImplementationColorReadType(const gl::Context *context) const
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400259{
Jamie Madill66546be2018-03-08 09:47:20 -0500260 return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).type;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400261}
262
Jamie Madillc564c072017-06-01 12:45:42 -0400263gl::Error FramebufferVk::readPixels(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400264 const gl::Rectangle &area,
265 GLenum format,
266 GLenum type,
Jamie Madilld4826152017-09-21 11:18:59 -0400267 void *pixels)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400268{
Jamie Madill66546be2018-03-08 09:47:20 -0500269 const gl::State &glState = context->getGLState();
Jamie Madille1f3ad42017-10-28 23:00:42 -0400270 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500271 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill5deea722017-02-16 10:44:46 -0500272 VkDevice device = renderer->getDevice();
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500273
Jamie Madill66546be2018-03-08 09:47:20 -0500274 RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
275 ASSERT(renderTarget);
276
Jamie Madill93edca12018-03-30 10:43:18 -0400277 vk::ImageHelper stagingImage;
278 ANGLE_TRY(stagingImage.init2DStaging(
Jamie Madillbc543422018-03-30 10:43:19 -0400279 device, renderer->getMemoryProperties(), renderTarget->image->getFormat(),
Jamie Madill93edca12018-03-30 10:43:18 -0400280 gl::Extents(area.width, area.height, 1), vk::StagingUsage::Read));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500281
Jamie Madill49ac74b2017-12-21 14:42:33 -0500282 vk::CommandBuffer *commandBuffer = nullptr;
Jamie Madill1f46bc12018-02-20 16:09:43 -0500283 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
Jamie Madilld4826152017-09-21 11:18:59 -0400284
Jamie Madill858c1cc2018-03-31 14:19:13 -0400285 stagingImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
286 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
287 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500288
Jamie Madill858c1cc2018-03-31 14:19:13 -0400289 vk::ImageHelper::Copy(renderTarget->image, &stagingImage, gl::Offset(area.x, area.y, 0),
290 gl::Offset(), gl::Extents(area.width, area.height, 1),
291 VK_IMAGE_ASPECT_COLOR_BIT, commandBuffer);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500292
Jamie Madill49ac74b2017-12-21 14:42:33 -0500293 // Triggers a full finish.
294 // TODO(jmadill): Don't block on asynchronous readback.
295 ANGLE_TRY(renderer->finish(context));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500296
297 // TODO(jmadill): parameters
298 uint8_t *mapPointer = nullptr;
Jamie Madill93edca12018-03-30 10:43:18 -0400299 ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, stagingImage.getAllocatedMemorySize(),
300 0, &mapPointer));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500301
Jamie Madillbc543422018-03-30 10:43:19 -0400302 const angle::Format &angleFormat = renderTarget->image->getFormat().textureFormat();
Jamie Madill6816d842018-03-31 14:19:17 -0400303 GLuint outputPitch = angleFormat.pixelBytes * area.width;
Luc Ferron60284222018-03-20 16:01:44 -0400304
305 // Get the staging image pitch and use it to pack the pixels later.
306 VkSubresourceLayout subresourceLayout;
307 stagingImage.getImage().getSubresourceLayout(device, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0,
308 &subresourceLayout);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500309
310 PackPixelsParams params;
311 params.area = area;
312 params.format = format;
313 params.type = type;
Luc Ferron60284222018-03-20 16:01:44 -0400314 params.outputPitch = outputPitch;
Corentin Wallez336129f2017-10-17 15:55:40 -0400315 params.packBuffer = glState.getTargetBuffer(gl::BufferBinding::PixelPack);
Corentin Wallezcda6af12017-10-30 19:20:37 -0400316 params.pack = glState.getPackState();
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500317
Luc Ferron60284222018-03-20 16:01:44 -0400318 PackPixels(params, angleFormat, static_cast<int>(subresourceLayout.rowPitch), mapPointer,
319 reinterpret_cast<uint8_t *>(pixels));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500320
Jamie Madill5deea722017-02-16 10:44:46 -0500321 stagingImage.getDeviceMemory().unmap(device);
Jamie Madille88ec8e2017-10-31 17:18:14 -0400322 renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
Jamie Madillf651c772017-02-21 15:03:51 -0500323
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500324 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400325}
326
Jamie Madillc564c072017-06-01 12:45:42 -0400327gl::Error FramebufferVk::blit(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400328 const gl::Rectangle &sourceArea,
329 const gl::Rectangle &destArea,
330 GLbitfield mask,
331 GLenum filter)
332{
333 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500334 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400335}
336
Kenneth Russellce8602a2017-10-03 18:23:08 -0700337bool FramebufferVk::checkStatus(const gl::Context *context) const
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400338{
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400339 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400340}
341
Jamie Madill19fa1c62018-03-08 09:47:21 -0500342gl::Error FramebufferVk::syncState(const gl::Context *context,
343 const gl::Framebuffer::DirtyBits &dirtyBits)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400344{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400345 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill7bd16662017-10-28 19:40:50 -0400346 RendererVk *renderer = contextVk->getRenderer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400347
348 ASSERT(dirtyBits.any());
Jamie Madill57d9cbb2018-04-27 11:45:04 -0400349 for (size_t dirtyBit : dirtyBits)
350 {
351 switch (dirtyBit)
352 {
353 case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
354 case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
355 ANGLE_TRY(mRenderTargetCache.updateDepthStencilRenderTarget(context, mState));
356 break;
357 case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
358 case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
359 case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
360 case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
361 case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
362 case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
363 break;
364 default:
365 {
366 ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
367 dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
368 size_t colorIndex =
369 static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
370 ANGLE_TRY(mRenderTargetCache.updateColorRenderTarget(context, mState, colorIndex));
Jamie Madill9aef3672018-04-27 11:45:06 -0400371
372 // Update cached masks for masked clears.
373 RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndex];
374 if (renderTarget)
375 {
376 const angle::Format &format = renderTarget->image->getFormat().textureFormat();
377 updateActiveColorMasks(colorIndex, format.redBits > 0, format.greenBits > 0,
378 format.blueBits > 0, format.alphaBits > 0);
379 }
380 else
381 {
382 updateActiveColorMasks(colorIndex, 0, 0, 0, 0);
383 }
Jamie Madill57d9cbb2018-04-27 11:45:04 -0400384 break;
385 }
386 }
387 }
Jamie Madill66546be2018-03-08 09:47:20 -0500388
Jamie Madill9aef3672018-04-27 11:45:06 -0400389 mActiveColorComponents = gl_vk::GetColorComponentFlags(
390 mActiveColorComponentMasks[0].any(), mActiveColorComponentMasks[1].any(),
391 mActiveColorComponentMasks[2].any(), mActiveColorComponentMasks[3].any());
392
Jamie Madill9f2a8612017-11-30 12:43:09 -0500393 mRenderPassDesc.reset();
Jamie Madill7bd16662017-10-28 19:40:50 -0400394 renderer->releaseResource(*this, &mFramebuffer);
Jamie Madill49ac74b2017-12-21 14:42:33 -0500395
Jamie Madill9cceac42018-03-31 14:19:16 -0400396 // Trigger a new set of secondary commands next time we render to this FBO.
397 getNewWritingNode(renderer);
Jamie Madill72106562017-03-24 14:18:50 -0400398
Jamie Madill72106562017-03-24 14:18:50 -0400399 contextVk->invalidateCurrentPipeline();
Jamie Madill19fa1c62018-03-08 09:47:21 -0500400
401 return gl::NoError();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500402}
403
Jamie Madillb90779e2018-04-27 11:45:01 -0400404const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc()
Jamie Madillab9f9c32017-01-17 17:47:34 -0500405{
Jamie Madill9f2a8612017-11-30 12:43:09 -0500406 if (mRenderPassDesc.valid())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500407 {
Jamie Madill9f2a8612017-11-30 12:43:09 -0500408 return mRenderPassDesc.value();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500409 }
410
Jamie Madill0b684ce2017-11-23 12:57:39 -0500411 vk::RenderPassDesc desc;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500412
Jamie Madill66546be2018-03-08 09:47:20 -0500413 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
414 const auto &colorRenderTargets = mRenderTargetCache.getColors();
415 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500416 {
Jamie Madill66546be2018-03-08 09:47:20 -0500417 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
418 ASSERT(colorRenderTarget);
Jamie Madillbc543422018-03-30 10:43:19 -0400419 desc.packColorAttachment(*colorRenderTarget->image);
Jamie Madillab9f9c32017-01-17 17:47:34 -0500420 }
421
Jamie Madill66546be2018-03-08 09:47:20 -0500422 RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
423 if (depthStencilRenderTarget)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500424 {
Jamie Madillbc543422018-03-30 10:43:19 -0400425 desc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
Jamie Madillab9f9c32017-01-17 17:47:34 -0500426 }
427
Jamie Madill9f2a8612017-11-30 12:43:09 -0500428 mRenderPassDesc = desc;
429 return mRenderPassDesc.value();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500430}
431
Jamie Madillb90779e2018-04-27 11:45:01 -0400432gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(RendererVk *rendererVk)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500433{
434 // If we've already created our cached Framebuffer, return it.
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400435 if (mFramebuffer.valid())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500436 {
437 return &mFramebuffer;
438 }
439
Jamie Madillb90779e2018-04-27 11:45:01 -0400440 const vk::RenderPassDesc &desc = getRenderPassDesc();
Jamie Madill9f2a8612017-11-30 12:43:09 -0500441
Jamie Madillab9f9c32017-01-17 17:47:34 -0500442 vk::RenderPass *renderPass = nullptr;
Jamie Madill9f2a8612017-11-30 12:43:09 -0500443 ANGLE_TRY(rendererVk->getCompatibleRenderPass(desc, &renderPass));
Jamie Madillab9f9c32017-01-17 17:47:34 -0500444
445 // If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
Jamie Madill9f2a8612017-11-30 12:43:09 -0500446 VkDevice device = rendererVk->getDevice();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500447 if (mBackbuffer)
448 {
449 return mBackbuffer->getCurrentFramebuffer(device, *renderPass);
450 }
451
452 // Gather VkImageViews over all FBO attachments, also size of attached region.
453 std::vector<VkImageView> attachments;
454 gl::Extents attachmentsSize;
455
Jamie Madill66546be2018-03-08 09:47:20 -0500456 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
457 const auto &colorRenderTargets = mRenderTargetCache.getColors();
458 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500459 {
Jamie Madill66546be2018-03-08 09:47:20 -0500460 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
461 ASSERT(colorRenderTarget);
462 attachments.push_back(colorRenderTarget->imageView->getHandle());
Jamie Madillab9f9c32017-01-17 17:47:34 -0500463
Jamie Madillbc543422018-03-30 10:43:19 -0400464 ASSERT(attachmentsSize.empty() ||
465 attachmentsSize == colorRenderTarget->image->getExtents());
466 attachmentsSize = colorRenderTarget->image->getExtents();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500467 }
468
Jamie Madill66546be2018-03-08 09:47:20 -0500469 RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
470 if (depthStencilRenderTarget)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500471 {
Jamie Madill66546be2018-03-08 09:47:20 -0500472 attachments.push_back(depthStencilRenderTarget->imageView->getHandle());
Jamie Madillab9f9c32017-01-17 17:47:34 -0500473
Jamie Madillbc543422018-03-30 10:43:19 -0400474 ASSERT(attachmentsSize.empty() ||
475 attachmentsSize == depthStencilRenderTarget->image->getExtents());
476 attachmentsSize = depthStencilRenderTarget->image->getExtents();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500477 }
478
479 ASSERT(!attachments.empty());
480
481 VkFramebufferCreateInfo framebufferInfo;
482
483 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
484 framebufferInfo.pNext = nullptr;
485 framebufferInfo.flags = 0;
Jamie Madill9f2a8612017-11-30 12:43:09 -0500486 framebufferInfo.renderPass = renderPass->getHandle();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500487 framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
488 framebufferInfo.pAttachments = attachments.data();
489 framebufferInfo.width = static_cast<uint32_t>(attachmentsSize.width);
490 framebufferInfo.height = static_cast<uint32_t>(attachmentsSize.height);
491 framebufferInfo.layers = 1;
492
Jamie Madill25301b62017-10-28 20:59:31 -0400493 ANGLE_TRY(mFramebuffer.init(device, framebufferInfo));
Jamie Madill5deea722017-02-16 10:44:46 -0500494
Jamie Madillab9f9c32017-01-17 17:47:34 -0500495 return &mFramebuffer;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400496}
497
Jamie Madillb90779e2018-04-27 11:45:01 -0400498gl::Error FramebufferVk::clearWithClearAttachments(ContextVk *contextVk,
499 bool clearColor,
500 bool clearDepth,
501 bool clearStencil)
Luc Ferron5242d5b2018-02-15 07:14:35 -0500502{
Luc Ferron5242d5b2018-02-15 07:14:35 -0500503 RendererVk *renderer = contextVk->getRenderer();
504
Jamie Madill9aef3672018-04-27 11:45:06 -0400505 getNewWritingNode(renderer);
506
Luc Ferron5242d5b2018-02-15 07:14:35 -0500507 // This command can only happen inside a render pass, so obtain one if its already happening
508 // or create a new one if not.
509 vk::CommandGraphNode *node = nullptr;
510 vk::CommandBuffer *commandBuffer = nullptr;
Jamie Madillb90779e2018-04-27 11:45:01 -0400511 ANGLE_TRY(getCommandGraphNodeForDraw(contextVk, &node));
Luc Ferron5242d5b2018-02-15 07:14:35 -0500512 if (node->getInsideRenderPassCommands()->valid())
513 {
514 commandBuffer = node->getInsideRenderPassCommands();
515 }
516 else
517 {
518 ANGLE_TRY(node->beginInsideRenderPassRecording(renderer, &commandBuffer));
519 }
520
Luc Ferrone4c38be2018-04-17 11:09:16 -0400521 // TODO(jmadill): Cube map attachments. http://anglebug.com/2470
522 // We assume for now that we always need to clear only 1 layer starting at the
523 // baseArrayLayer 0, this might need to change depending how we'll implement
524 // cube maps, 3d textures and array textures.
525 VkClearRect clearRect;
526 clearRect.baseArrayLayer = 0;
527 clearRect.layerCount = 1;
528
529 // When clearing, the scissor region must be clipped to the renderArea per the validation rules
530 // in Vulkan.
531 gl::Rectangle intersection;
Jamie Madill9aef3672018-04-27 11:45:06 -0400532 if (!gl::ClipRectangle(contextVk->getGLState().getScissor(), node->getRenderPassRenderArea(),
533 &intersection))
Luc Ferrone4c38be2018-04-17 11:09:16 -0400534 {
535 // There is nothing to clear since the scissor is outside of the render area.
536 return gl::NoError();
537 }
Luc Ferrone4c38be2018-04-17 11:09:16 -0400538 clearRect.rect = gl_vk::GetRect(intersection);
539
Luc Ferron5242d5b2018-02-15 07:14:35 -0500540 gl::AttachmentArray<VkClearAttachment> clearAttachments;
541 int clearAttachmentIndex = 0;
Luc Ferrona8af3a62018-03-29 14:44:24 -0400542
543 if (clearColor)
Luc Ferron5242d5b2018-02-15 07:14:35 -0500544 {
Luc Ferrona8af3a62018-03-29 14:44:24 -0400545 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
546 for (size_t colorIndex : mState.getEnabledDrawBuffers())
547 {
548 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
549 clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
550 clearAttachment.colorAttachment = static_cast<uint32_t>(colorIndex);
551 clearAttachment.clearValue = contextVk->getClearColorValue();
552 ++clearAttachmentIndex;
553 }
554 }
555
556 if (clearDepth && clearStencil && mState.getDepthStencilAttachment() != nullptr)
557 {
558 // When we have a packed depth/stencil attachment we can do 1 clear for both when it
559 // applies.
Luc Ferron5242d5b2018-02-15 07:14:35 -0500560 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
Luc Ferrona8af3a62018-03-29 14:44:24 -0400561 clearAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
562 clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
563 clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
Luc Ferron5242d5b2018-02-15 07:14:35 -0500564 ++clearAttachmentIndex;
565 }
Luc Ferrona8af3a62018-03-29 14:44:24 -0400566 else
567 {
568 if (clearDepth)
569 {
570 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
571 clearAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
572 clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
573 clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
574 ++clearAttachmentIndex;
575 }
576
577 if (clearStencil)
578 {
579 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
580 clearAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
581 clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
582 clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
583 ++clearAttachmentIndex;
584 }
585 }
Luc Ferron5242d5b2018-02-15 07:14:35 -0500586
Luc Ferrona8af3a62018-03-29 14:44:24 -0400587 commandBuffer->clearAttachments(static_cast<uint32_t>(clearAttachmentIndex),
Luc Ferron5242d5b2018-02-15 07:14:35 -0500588 clearAttachments.data(), 1, &clearRect);
589 return gl::NoError();
590}
591
Jamie Madill9aef3672018-04-27 11:45:06 -0400592gl::Error FramebufferVk::clearWithDraw(ContextVk *contextVk, VkColorComponentFlags colorMaskFlags)
593{
594 RendererVk *renderer = contextVk->getRenderer();
595 vk::ShaderLibrary *shaderLibrary = renderer->getShaderLibrary();
596
597 const vk::ShaderAndSerial *fullScreenQuad = nullptr;
598 ANGLE_TRY(shaderLibrary->getShader(renderer, vk::InternalShaderID::FullScreenQuad_vert,
599 &fullScreenQuad));
600
601 const vk::ShaderAndSerial *uniformColor = nullptr;
602 ANGLE_TRY(
603 shaderLibrary->getShader(renderer, vk::InternalShaderID::UniformColor_frag, &uniformColor));
604
605 const vk::PipelineLayout *pipelineLayout = nullptr;
606 ANGLE_TRY(renderer->getInternalUniformPipelineLayout(&pipelineLayout));
607
608 vk::CommandBuffer *commandBuffer = nullptr;
609 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
610
611 vk::CommandGraphNode *node = nullptr;
612 ANGLE_TRY(getCommandGraphNodeForDraw(contextVk, &node));
613
614 // This pipeline desc could be cached.
615 vk::PipelineDesc pipelineDesc;
616 pipelineDesc.initDefaults();
617 pipelineDesc.updateColorWriteMask(colorMaskFlags);
618 pipelineDesc.updateRenderPassDesc(getRenderPassDesc());
619 pipelineDesc.updateShaders(fullScreenQuad->queueSerial(), uniformColor->queueSerial());
620 pipelineDesc.updateViewport(node->getRenderPassRenderArea(), 0.0f, 1.0f);
621
622 const gl::State &glState = contextVk->getGLState();
623 if (glState.isScissorTestEnabled())
624 {
625 gl::Rectangle intersection;
626 if (!gl::ClipRectangle(glState.getScissor(), node->getRenderPassRenderArea(),
627 &intersection))
628 {
629 return gl::NoError();
630 }
631
632 pipelineDesc.updateScissor(intersection);
633 }
634 else
635 {
636 pipelineDesc.updateScissor(node->getRenderPassRenderArea());
637 }
638
639 vk::PipelineAndSerial *pipeline = nullptr;
640 ANGLE_TRY(renderer->getInternalPipeline(*fullScreenQuad, *uniformColor, *pipelineLayout,
641 pipelineDesc, gl::AttributesMask(), &pipeline));
642 pipeline->updateSerial(renderer->getCurrentQueueSerial());
643
644 VkDevice device = renderer->getDevice();
645
646 if (!mMaskedClearUniformBuffer.buffer.valid())
647 {
648 ASSERT(mMaskedClearDescriptorSet == VK_NULL_HANDLE);
649
650 VkBufferUsageFlags bufferUsage =
651 (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
652
653 VkBufferCreateInfo uniformBufferInfo;
654 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
655 uniformBufferInfo.pNext = nullptr;
656 uniformBufferInfo.flags = 0;
657 uniformBufferInfo.size = sizeof(VkClearColorValue);
658 uniformBufferInfo.usage = bufferUsage;
659 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
660 uniformBufferInfo.queueFamilyIndexCount = 0;
661 uniformBufferInfo.pQueueFamilyIndices = nullptr;
662
663 ANGLE_TRY(mMaskedClearUniformBuffer.buffer.init(device, uniformBufferInfo));
664
665 VkMemoryPropertyFlags memoryFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
666 size_t requiredSize = 0;
667 ANGLE_TRY(vk::AllocateBufferMemory(renderer, memoryFlags, &mMaskedClearUniformBuffer.buffer,
668 &mMaskedClearUniformBuffer.memory, &requiredSize));
669
670 const vk::DescriptorSetLayout &descriptorSetLayout =
671 renderer->getInternalUniformDescriptorSetLayout();
672
673 // This might confuse the dynamic descriptor pool's counting, but it shouldn't cause
674 // overflow.
675 vk::DynamicDescriptorPool *descriptorPool = contextVk->getDynamicDescriptorPool();
676 descriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout.ptr(), 1,
677 &mMaskedClearDescriptorSet);
678
679 VkDescriptorBufferInfo bufferInfo;
680 bufferInfo.buffer = mMaskedClearUniformBuffer.buffer.getHandle();
681 bufferInfo.offset = 0;
682 bufferInfo.range = VK_WHOLE_SIZE;
683
684 VkWriteDescriptorSet writeSet;
685 writeSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
686 writeSet.pNext = nullptr;
687 writeSet.dstSet = mMaskedClearDescriptorSet;
688 writeSet.dstBinding = 1;
689 writeSet.dstArrayElement = 0;
690 writeSet.descriptorCount = 1;
691 writeSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
692 writeSet.pImageInfo = nullptr;
693 writeSet.pBufferInfo = &bufferInfo;
694 writeSet.pTexelBufferView = nullptr;
695
696 vkUpdateDescriptorSets(device, 1, &writeSet, 0, nullptr);
697 }
698
699 VkClearColorValue clearColorValue = contextVk->getClearColorValue().color;
700 commandBuffer->updateBuffer(mMaskedClearUniformBuffer.buffer, 0, sizeof(VkClearColorValue),
701 clearColorValue.float32);
702
703 vk::CommandBuffer *drawCommandBuffer = nullptr;
704 ANGLE_TRY(node->beginInsideRenderPassRecording(renderer, &drawCommandBuffer));
705
706 std::array<uint32_t, 2> dynamicOffsets = {{0, 0}};
707 drawCommandBuffer->bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1,
708 &mMaskedClearDescriptorSet, 2, dynamicOffsets.data());
709
710 // TODO(jmadill): Masked combined color and depth/stencil clear. http://anglebug.com/2455
711 // Any active queries submitted by the user should also be paused here.
712 drawCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->get());
713 drawCommandBuffer->draw(6, 1, 0, 0);
714
715 return gl::NoError();
716}
717
JiangYizhoubddc46b2016-12-09 09:50:51 +0800718gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
719{
720 UNIMPLEMENTED();
721 return gl::InternalError() << "getSamplePosition is unimplemented.";
722}
723
Jamie Madillb90779e2018-04-27 11:45:01 -0400724gl::Error FramebufferVk::getCommandGraphNodeForDraw(ContextVk *contextVk,
Jamie Madille4c5a232018-03-02 21:00:31 -0500725 vk::CommandGraphNode **nodeOut)
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500726{
Jamie Madill49ac74b2017-12-21 14:42:33 -0500727 RendererVk *renderer = contextVk->getRenderer();
728 Serial currentSerial = renderer->getCurrentQueueSerial();
Jamie Madillbef918c2017-12-13 13:11:30 -0500729
Jamie Madill9cceac42018-03-31 14:19:16 -0400730 // This will reset the current writing node if it has been completed.
731 updateQueueSerial(currentSerial);
732
733 if (hasChildlessWritingNode())
Jamie Madill4c26fc22017-02-24 11:04:10 -0500734 {
Jamie Madill9cceac42018-03-31 14:19:16 -0400735 *nodeOut = getCurrentWritingNode();
736 }
737 else
738 {
739 *nodeOut = getNewWritingNode(renderer);
Jamie Madill4c26fc22017-02-24 11:04:10 -0500740 }
741
Jamie Madill9cceac42018-03-31 14:19:16 -0400742 if ((*nodeOut)->getInsideRenderPassCommands()->valid())
743 {
744 return gl::NoError();
745 }
Jamie Madill4c26fc22017-02-24 11:04:10 -0500746
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500747 vk::Framebuffer *framebuffer = nullptr;
Jamie Madillb90779e2018-04-27 11:45:01 -0400748 ANGLE_TRY_RESULT(getFramebuffer(renderer), framebuffer);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500749
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500750 std::vector<VkClearValue> attachmentClearValues;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500751
Jamie Madille4c5a232018-03-02 21:00:31 -0500752 vk::CommandBuffer *commandBuffer = nullptr;
Jamie Madill9cceac42018-03-31 14:19:16 -0400753 if (!(*nodeOut)->getOutsideRenderPassCommands()->valid())
754 {
755 ANGLE_TRY((*nodeOut)->beginOutsideRenderPassRecording(
756 renderer->getDevice(), renderer->getCommandPool(), &commandBuffer));
757 }
758 else
759 {
760 commandBuffer = (*nodeOut)->getOutsideRenderPassCommands();
761 }
Jamie Madille4c5a232018-03-02 21:00:31 -0500762
Jamie Madill49ac74b2017-12-21 14:42:33 -0500763 // Initialize RenderPass info.
Jamie Madill66546be2018-03-08 09:47:20 -0500764 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
765 const auto &colorRenderTargets = mRenderTargetCache.getColors();
766 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madill4c26fc22017-02-24 11:04:10 -0500767 {
Jamie Madill66546be2018-03-08 09:47:20 -0500768 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
769 ASSERT(colorRenderTarget);
Jamie Madill49ac74b2017-12-21 14:42:33 -0500770
Jamie Madill9cceac42018-03-31 14:19:16 -0400771 (*nodeOut)->appendColorRenderTarget(currentSerial, colorRenderTarget);
Jamie Madill66546be2018-03-08 09:47:20 -0500772 attachmentClearValues.emplace_back(contextVk->getClearColorValue());
773 }
774
775 RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
776 if (depthStencilRenderTarget)
777 {
Jamie Madill9cceac42018-03-31 14:19:16 -0400778 (*nodeOut)->appendDepthStencilRenderTarget(currentSerial, depthStencilRenderTarget);
Jamie Madillf4d693c2018-02-14 16:38:16 -0500779 attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
Jamie Madill49ac74b2017-12-21 14:42:33 -0500780 }
781
Luc Ferrond17bdfe2018-04-05 13:50:10 -0400782 gl::Rectangle renderArea =
783 gl::Rectangle(0, 0, mState.getDimensions().width, mState.getDimensions().height);
Jamie Madillf4d693c2018-02-14 16:38:16 -0500784 // Hard-code RenderPass to clear the first render target to the current clear value.
785 // TODO(jmadill): Proper clear value implementation. http://anglebug.com/2361
Luc Ferrond17bdfe2018-04-05 13:50:10 -0400786 (*nodeOut)->storeRenderPassInfo(*framebuffer, renderArea, attachmentClearValues);
Jamie Madill49ac74b2017-12-21 14:42:33 -0500787
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500788 return gl::NoError();
789}
790
Jamie Madill9aef3672018-04-27 11:45:06 -0400791void FramebufferVk::updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a)
792{
793 mActiveColorComponentMasks[0].set(colorIndex, r);
794 mActiveColorComponentMasks[1].set(colorIndex, g);
795 mActiveColorComponentMasks[2].set(colorIndex, b);
796 mActiveColorComponentMasks[3].set(colorIndex, a);
797}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400798} // namespace rx