blob: d69b64d71b981c67874e41122853954633f34417 [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 Madill4928b7c2017-06-20 12:57:39 -040088gl::Error FramebufferVk::discard(const gl::Context *context,
89 size_t count,
90 const GLenum *attachments)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040091{
92 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050093 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -040094}
95
Jamie Madill4928b7c2017-06-20 12:57:39 -040096gl::Error FramebufferVk::invalidate(const gl::Context *context,
97 size_t count,
98 const GLenum *attachments)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040099{
100 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500101 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400102}
103
Jamie Madill4928b7c2017-06-20 12:57:39 -0400104gl::Error FramebufferVk::invalidateSub(const gl::Context *context,
105 size_t count,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400106 const GLenum *attachments,
107 const gl::Rectangle &area)
108{
109 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500110 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400111}
112
Jamie Madillc564c072017-06-01 12:45:42 -0400113gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400114{
Jamie Madill0cec82a2018-03-14 09:21:07 -0400115 ContextVk *contextVk = vk::GetImpl(context);
116 RendererVk *renderer = contextVk->getRenderer();
117 Serial currentSerial = renderer->getCurrentQueueSerial();
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500118
Jamie Madill0cec82a2018-03-14 09:21:07 -0400119 // This command buffer is only started once.
120 vk::CommandBuffer *commandBuffer = nullptr;
121 vk::CommandGraphNode *writingNode = nullptr;
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500122
Jamie Madill0cec82a2018-03-14 09:21:07 -0400123 const gl::FramebufferAttachment *depthAttachment = mState.getDepthAttachment();
124 bool clearDepth = (depthAttachment && (mask & GL_DEPTH_BUFFER_BIT) != 0);
125 ASSERT(!clearDepth || depthAttachment->isAttached());
126
127 const gl::FramebufferAttachment *stencilAttachment = mState.getStencilAttachment();
128 bool clearStencil = (stencilAttachment && (mask & GL_STENCIL_BUFFER_BIT) != 0);
129 ASSERT(!clearStencil || stencilAttachment->isAttached());
130
Luc Ferrona8af3a62018-03-29 14:44:24 -0400131 bool clearColor = IsMaskFlagSet(static_cast<int>(mask), GL_COLOR_BUFFER_BIT);
132
Luc Ferron8836f632018-04-05 07:26:53 -0400133 const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthStencilAttachment();
Jamie Madilld47044a2018-04-27 11:45:03 -0400134 const gl::State &glState = context->getGLState();
Luc Ferron8836f632018-04-05 07:26:53 -0400135
Jamie Madill9aef3672018-04-27 11:45:06 -0400136 // The most costly clear mode is when we need to mask out specific color channels. This can
137 // only be done with a draw call. The scissor region however can easily be integrated with
138 // this method. Similarly for depth/stencil clear.
139 VkColorComponentFlags colorMaskFlags = contextVk->getClearColorMask();
140 if (clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents)
141 {
142 return clearWithDraw(contextVk, colorMaskFlags);
143 }
144
Luc Ferron8836f632018-04-05 07:26:53 -0400145 // If we clear the depth OR the stencil but not both, and we have a packed depth stencil
146 // attachment, we need to use clearAttachment instead of clearDepthStencil since Vulkan won't
147 // allow us to clear one or the other separately.
148 bool isSingleClearOnPackedDepthStencilAttachment =
149 depthStencilAttachment && (clearDepth != clearStencil);
Jamie Madilld47044a2018-04-27 11:45:03 -0400150 if (glState.isScissorTestEnabled() || isSingleClearOnPackedDepthStencilAttachment)
Luc Ferrona8af3a62018-03-29 14:44:24 -0400151 {
152 // With scissor test enabled, we clear very differently and we don't need to access
153 // the image inside each attachment we can just use clearCmdAttachments with our
154 // scissor region instead.
Jamie Madillb90779e2018-04-27 11:45:01 -0400155 ANGLE_TRY(clearWithClearAttachments(contextVk, clearColor, clearDepth, clearStencil));
Luc Ferrona8af3a62018-03-29 14:44:24 -0400156 return gl::NoError();
157 }
158
159 // Standard Depth/stencil clear without scissor.
Jamie Madill0cec82a2018-03-14 09:21:07 -0400160 if (clearDepth || clearStencil)
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500161 {
Jamie Madill0cec82a2018-03-14 09:21:07 -0400162 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
Jamie Madill9cceac42018-03-31 14:19:16 -0400163 writingNode = getCurrentWritingNode();
Jamie Madill0cec82a2018-03-14 09:21:07 -0400164
165 const VkClearDepthStencilValue &clearDepthStencilValue =
166 contextVk->getClearDepthStencilValue().depthStencil;
167
168 // We only support packed depth/stencil, not separate.
Luc Ferron8836f632018-04-05 07:26:53 -0400169 ASSERT(!(clearDepth && clearStencil) || depthStencilAttachment);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400170
Luc Ferrone6a40d02018-03-22 10:30:57 -0400171 const VkImageAspectFlags aspectFlags =
172 (depthAttachment ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
173 (stencilAttachment ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400174
175 RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
176 renderTarget->resource->onWriteResource(writingNode, currentSerial);
Jamie Madill858c1cc2018-03-31 14:19:13 -0400177 renderTarget->image->clearDepthStencil(aspectFlags, clearDepthStencilValue, commandBuffer);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400178
Luc Ferrona8af3a62018-03-29 14:44:24 -0400179 if (!clearColor)
Jamie Madill0cec82a2018-03-14 09:21:07 -0400180 {
181 return gl::NoError();
182 }
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500183 }
184
Luc Ferrona8af3a62018-03-29 14:44:24 -0400185 ASSERT(clearColor);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500186 const auto *attachment = mState.getFirstNonNullAttachment();
187 ASSERT(attachment && attachment->isAttached());
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500188
Jamie Madill0cec82a2018-03-14 09:21:07 -0400189 if (!commandBuffer)
190 {
191 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
Jamie Madill9cceac42018-03-31 14:19:16 -0400192 writingNode = getCurrentWritingNode();
Jamie Madill0cec82a2018-03-14 09:21:07 -0400193 }
Jamie Madillefb5a5c2018-01-29 15:56:59 -0500194
Jamie Madill66546be2018-03-08 09:47:20 -0500195 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
196 const auto &colorRenderTargets = mRenderTargetCache.getColors();
Jamie Madill9aef3672018-04-27 11:45:06 -0400197 const VkClearColorValue &clearColorValue = contextVk->getClearColorValue().color;
Jamie Madill66546be2018-03-08 09:47:20 -0500198 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500199 {
Jamie Madill66546be2018-03-08 09:47:20 -0500200 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
201 ASSERT(colorRenderTarget);
Jamie Madill0cec82a2018-03-14 09:21:07 -0400202 colorRenderTarget->resource->onWriteResource(writingNode, currentSerial);
Jamie Madill9aef3672018-04-27 11:45:06 -0400203 colorRenderTarget->image->clearColor(clearColorValue, commandBuffer);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500204 }
205
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500206 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400207}
208
Jamie Madillc564c072017-06-01 12:45:42 -0400209gl::Error FramebufferVk::clearBufferfv(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400210 GLenum buffer,
211 GLint drawbuffer,
212 const GLfloat *values)
213{
214 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500215 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400216}
217
Jamie Madillc564c072017-06-01 12:45:42 -0400218gl::Error FramebufferVk::clearBufferuiv(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400219 GLenum buffer,
220 GLint drawbuffer,
221 const GLuint *values)
222{
223 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500224 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400225}
226
Jamie Madillc564c072017-06-01 12:45:42 -0400227gl::Error FramebufferVk::clearBufferiv(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400228 GLenum buffer,
229 GLint drawbuffer,
230 const GLint *values)
231{
232 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500233 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400234}
235
Jamie Madillc564c072017-06-01 12:45:42 -0400236gl::Error FramebufferVk::clearBufferfi(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400237 GLenum buffer,
238 GLint drawbuffer,
239 GLfloat depth,
240 GLint stencil)
241{
242 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500243 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400244}
245
Jamie Madill4928b7c2017-06-20 12:57:39 -0400246GLenum FramebufferVk::getImplementationColorReadFormat(const gl::Context *context) const
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400247{
Jamie Madill66546be2018-03-08 09:47:20 -0500248 return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).format;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400249}
250
Jamie Madill4928b7c2017-06-20 12:57:39 -0400251GLenum FramebufferVk::getImplementationColorReadType(const gl::Context *context) const
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400252{
Jamie Madill66546be2018-03-08 09:47:20 -0500253 return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).type;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400254}
255
Jamie Madillc564c072017-06-01 12:45:42 -0400256gl::Error FramebufferVk::readPixels(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400257 const gl::Rectangle &area,
258 GLenum format,
259 GLenum type,
Jamie Madilld4826152017-09-21 11:18:59 -0400260 void *pixels)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400261{
Jamie Madill66546be2018-03-08 09:47:20 -0500262 const gl::State &glState = context->getGLState();
Jamie Madille1f3ad42017-10-28 23:00:42 -0400263 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500264 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill5deea722017-02-16 10:44:46 -0500265 VkDevice device = renderer->getDevice();
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500266
Jamie Madill66546be2018-03-08 09:47:20 -0500267 RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
268 ASSERT(renderTarget);
269
Jamie Madill93edca12018-03-30 10:43:18 -0400270 vk::ImageHelper stagingImage;
271 ANGLE_TRY(stagingImage.init2DStaging(
Jamie Madillbc543422018-03-30 10:43:19 -0400272 device, renderer->getMemoryProperties(), renderTarget->image->getFormat(),
Jamie Madill93edca12018-03-30 10:43:18 -0400273 gl::Extents(area.width, area.height, 1), vk::StagingUsage::Read));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500274
Jamie Madill49ac74b2017-12-21 14:42:33 -0500275 vk::CommandBuffer *commandBuffer = nullptr;
Jamie Madill1f46bc12018-02-20 16:09:43 -0500276 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
Jamie Madilld4826152017-09-21 11:18:59 -0400277
Jamie Madill858c1cc2018-03-31 14:19:13 -0400278 stagingImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
279 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
280 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500281
Jamie Madill858c1cc2018-03-31 14:19:13 -0400282 vk::ImageHelper::Copy(renderTarget->image, &stagingImage, gl::Offset(area.x, area.y, 0),
283 gl::Offset(), gl::Extents(area.width, area.height, 1),
284 VK_IMAGE_ASPECT_COLOR_BIT, commandBuffer);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500285
Jamie Madill49ac74b2017-12-21 14:42:33 -0500286 // Triggers a full finish.
287 // TODO(jmadill): Don't block on asynchronous readback.
288 ANGLE_TRY(renderer->finish(context));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500289
290 // TODO(jmadill): parameters
291 uint8_t *mapPointer = nullptr;
Jamie Madill93edca12018-03-30 10:43:18 -0400292 ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, stagingImage.getAllocatedMemorySize(),
293 0, &mapPointer));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500294
Jamie Madillbc543422018-03-30 10:43:19 -0400295 const angle::Format &angleFormat = renderTarget->image->getFormat().textureFormat();
Jamie Madill6816d842018-03-31 14:19:17 -0400296 GLuint outputPitch = angleFormat.pixelBytes * area.width;
Luc Ferron60284222018-03-20 16:01:44 -0400297
298 // Get the staging image pitch and use it to pack the pixels later.
299 VkSubresourceLayout subresourceLayout;
300 stagingImage.getImage().getSubresourceLayout(device, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0,
301 &subresourceLayout);
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500302
303 PackPixelsParams params;
304 params.area = area;
305 params.format = format;
306 params.type = type;
Luc Ferron60284222018-03-20 16:01:44 -0400307 params.outputPitch = outputPitch;
Corentin Wallez336129f2017-10-17 15:55:40 -0400308 params.packBuffer = glState.getTargetBuffer(gl::BufferBinding::PixelPack);
Corentin Wallezcda6af12017-10-30 19:20:37 -0400309 params.pack = glState.getPackState();
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500310
Luc Ferron60284222018-03-20 16:01:44 -0400311 PackPixels(params, angleFormat, static_cast<int>(subresourceLayout.rowPitch), mapPointer,
312 reinterpret_cast<uint8_t *>(pixels));
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500313
Jamie Madill5deea722017-02-16 10:44:46 -0500314 stagingImage.getDeviceMemory().unmap(device);
Jamie Madille88ec8e2017-10-31 17:18:14 -0400315 renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
Jamie Madillf651c772017-02-21 15:03:51 -0500316
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500317 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400318}
319
Jamie Madillc564c072017-06-01 12:45:42 -0400320gl::Error FramebufferVk::blit(const gl::Context *context,
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400321 const gl::Rectangle &sourceArea,
322 const gl::Rectangle &destArea,
323 GLbitfield mask,
324 GLenum filter)
325{
326 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500327 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400328}
329
Kenneth Russellce8602a2017-10-03 18:23:08 -0700330bool FramebufferVk::checkStatus(const gl::Context *context) const
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400331{
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400332 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400333}
334
Jamie Madill19fa1c62018-03-08 09:47:21 -0500335gl::Error FramebufferVk::syncState(const gl::Context *context,
336 const gl::Framebuffer::DirtyBits &dirtyBits)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400337{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400338 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill7bd16662017-10-28 19:40:50 -0400339 RendererVk *renderer = contextVk->getRenderer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400340
341 ASSERT(dirtyBits.any());
Jamie Madill57d9cbb2018-04-27 11:45:04 -0400342 for (size_t dirtyBit : dirtyBits)
343 {
344 switch (dirtyBit)
345 {
346 case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
347 case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
348 ANGLE_TRY(mRenderTargetCache.updateDepthStencilRenderTarget(context, mState));
349 break;
350 case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
351 case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
352 case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
353 case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
354 case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
355 case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
356 break;
357 default:
358 {
359 ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
360 dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
361 size_t colorIndex =
362 static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
363 ANGLE_TRY(mRenderTargetCache.updateColorRenderTarget(context, mState, colorIndex));
Jamie Madill9aef3672018-04-27 11:45:06 -0400364
365 // Update cached masks for masked clears.
366 RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndex];
367 if (renderTarget)
368 {
369 const angle::Format &format = renderTarget->image->getFormat().textureFormat();
370 updateActiveColorMasks(colorIndex, format.redBits > 0, format.greenBits > 0,
371 format.blueBits > 0, format.alphaBits > 0);
372 }
373 else
374 {
375 updateActiveColorMasks(colorIndex, 0, 0, 0, 0);
376 }
Jamie Madill57d9cbb2018-04-27 11:45:04 -0400377 break;
378 }
379 }
380 }
Jamie Madill66546be2018-03-08 09:47:20 -0500381
Jamie Madill9aef3672018-04-27 11:45:06 -0400382 mActiveColorComponents = gl_vk::GetColorComponentFlags(
383 mActiveColorComponentMasks[0].any(), mActiveColorComponentMasks[1].any(),
384 mActiveColorComponentMasks[2].any(), mActiveColorComponentMasks[3].any());
385
Jamie Madill9f2a8612017-11-30 12:43:09 -0500386 mRenderPassDesc.reset();
Jamie Madill7bd16662017-10-28 19:40:50 -0400387 renderer->releaseResource(*this, &mFramebuffer);
Jamie Madill49ac74b2017-12-21 14:42:33 -0500388
Jamie Madill9cceac42018-03-31 14:19:16 -0400389 // Trigger a new set of secondary commands next time we render to this FBO.
390 getNewWritingNode(renderer);
Jamie Madill72106562017-03-24 14:18:50 -0400391
Jamie Madill72106562017-03-24 14:18:50 -0400392 contextVk->invalidateCurrentPipeline();
Jamie Madill19fa1c62018-03-08 09:47:21 -0500393
394 return gl::NoError();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500395}
396
Jamie Madillb90779e2018-04-27 11:45:01 -0400397const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc()
Jamie Madillab9f9c32017-01-17 17:47:34 -0500398{
Jamie Madill9f2a8612017-11-30 12:43:09 -0500399 if (mRenderPassDesc.valid())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500400 {
Jamie Madill9f2a8612017-11-30 12:43:09 -0500401 return mRenderPassDesc.value();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500402 }
403
Jamie Madill0b684ce2017-11-23 12:57:39 -0500404 vk::RenderPassDesc desc;
Jamie Madillab9f9c32017-01-17 17:47:34 -0500405
Jamie Madill66546be2018-03-08 09:47:20 -0500406 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
407 const auto &colorRenderTargets = mRenderTargetCache.getColors();
408 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500409 {
Jamie Madill66546be2018-03-08 09:47:20 -0500410 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
411 ASSERT(colorRenderTarget);
Jamie Madillbc543422018-03-30 10:43:19 -0400412 desc.packColorAttachment(*colorRenderTarget->image);
Jamie Madillab9f9c32017-01-17 17:47:34 -0500413 }
414
Jamie Madill66546be2018-03-08 09:47:20 -0500415 RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
416 if (depthStencilRenderTarget)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500417 {
Jamie Madillbc543422018-03-30 10:43:19 -0400418 desc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
Jamie Madillab9f9c32017-01-17 17:47:34 -0500419 }
420
Jamie Madill9f2a8612017-11-30 12:43:09 -0500421 mRenderPassDesc = desc;
422 return mRenderPassDesc.value();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500423}
424
Jamie Madillb90779e2018-04-27 11:45:01 -0400425gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(RendererVk *rendererVk)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500426{
427 // If we've already created our cached Framebuffer, return it.
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400428 if (mFramebuffer.valid())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500429 {
430 return &mFramebuffer;
431 }
432
Jamie Madillb90779e2018-04-27 11:45:01 -0400433 const vk::RenderPassDesc &desc = getRenderPassDesc();
Jamie Madill9f2a8612017-11-30 12:43:09 -0500434
Jamie Madillab9f9c32017-01-17 17:47:34 -0500435 vk::RenderPass *renderPass = nullptr;
Jamie Madill9f2a8612017-11-30 12:43:09 -0500436 ANGLE_TRY(rendererVk->getCompatibleRenderPass(desc, &renderPass));
Jamie Madillab9f9c32017-01-17 17:47:34 -0500437
438 // If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
Jamie Madill9f2a8612017-11-30 12:43:09 -0500439 VkDevice device = rendererVk->getDevice();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500440 if (mBackbuffer)
441 {
442 return mBackbuffer->getCurrentFramebuffer(device, *renderPass);
443 }
444
445 // Gather VkImageViews over all FBO attachments, also size of attached region.
446 std::vector<VkImageView> attachments;
447 gl::Extents attachmentsSize;
448
Jamie Madill66546be2018-03-08 09:47:20 -0500449 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
450 const auto &colorRenderTargets = mRenderTargetCache.getColors();
451 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madillab9f9c32017-01-17 17:47:34 -0500452 {
Jamie Madill66546be2018-03-08 09:47:20 -0500453 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
454 ASSERT(colorRenderTarget);
455 attachments.push_back(colorRenderTarget->imageView->getHandle());
Jamie Madillab9f9c32017-01-17 17:47:34 -0500456
Jamie Madillbc543422018-03-30 10:43:19 -0400457 ASSERT(attachmentsSize.empty() ||
458 attachmentsSize == colorRenderTarget->image->getExtents());
459 attachmentsSize = colorRenderTarget->image->getExtents();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500460 }
461
Jamie Madill66546be2018-03-08 09:47:20 -0500462 RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
463 if (depthStencilRenderTarget)
Jamie Madillab9f9c32017-01-17 17:47:34 -0500464 {
Jamie Madill66546be2018-03-08 09:47:20 -0500465 attachments.push_back(depthStencilRenderTarget->imageView->getHandle());
Jamie Madillab9f9c32017-01-17 17:47:34 -0500466
Jamie Madillbc543422018-03-30 10:43:19 -0400467 ASSERT(attachmentsSize.empty() ||
468 attachmentsSize == depthStencilRenderTarget->image->getExtents());
469 attachmentsSize = depthStencilRenderTarget->image->getExtents();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500470 }
471
472 ASSERT(!attachments.empty());
473
474 VkFramebufferCreateInfo framebufferInfo;
475
476 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
477 framebufferInfo.pNext = nullptr;
478 framebufferInfo.flags = 0;
Jamie Madill9f2a8612017-11-30 12:43:09 -0500479 framebufferInfo.renderPass = renderPass->getHandle();
Jamie Madillab9f9c32017-01-17 17:47:34 -0500480 framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
481 framebufferInfo.pAttachments = attachments.data();
482 framebufferInfo.width = static_cast<uint32_t>(attachmentsSize.width);
483 framebufferInfo.height = static_cast<uint32_t>(attachmentsSize.height);
484 framebufferInfo.layers = 1;
485
Jamie Madill25301b62017-10-28 20:59:31 -0400486 ANGLE_TRY(mFramebuffer.init(device, framebufferInfo));
Jamie Madill5deea722017-02-16 10:44:46 -0500487
Jamie Madillab9f9c32017-01-17 17:47:34 -0500488 return &mFramebuffer;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400489}
490
Jamie Madillb90779e2018-04-27 11:45:01 -0400491gl::Error FramebufferVk::clearWithClearAttachments(ContextVk *contextVk,
492 bool clearColor,
493 bool clearDepth,
494 bool clearStencil)
Luc Ferron5242d5b2018-02-15 07:14:35 -0500495{
Luc Ferron5242d5b2018-02-15 07:14:35 -0500496 RendererVk *renderer = contextVk->getRenderer();
497
Jamie Madill9aef3672018-04-27 11:45:06 -0400498 getNewWritingNode(renderer);
499
Luc Ferron5242d5b2018-02-15 07:14:35 -0500500 // This command can only happen inside a render pass, so obtain one if its already happening
501 // or create a new one if not.
502 vk::CommandGraphNode *node = nullptr;
503 vk::CommandBuffer *commandBuffer = nullptr;
Jamie Madillb90779e2018-04-27 11:45:01 -0400504 ANGLE_TRY(getCommandGraphNodeForDraw(contextVk, &node));
Luc Ferron5242d5b2018-02-15 07:14:35 -0500505 if (node->getInsideRenderPassCommands()->valid())
506 {
507 commandBuffer = node->getInsideRenderPassCommands();
508 }
509 else
510 {
511 ANGLE_TRY(node->beginInsideRenderPassRecording(renderer, &commandBuffer));
512 }
513
Luc Ferrone4c38be2018-04-17 11:09:16 -0400514 // TODO(jmadill): Cube map attachments. http://anglebug.com/2470
515 // We assume for now that we always need to clear only 1 layer starting at the
516 // baseArrayLayer 0, this might need to change depending how we'll implement
517 // cube maps, 3d textures and array textures.
518 VkClearRect clearRect;
519 clearRect.baseArrayLayer = 0;
520 clearRect.layerCount = 1;
521
522 // When clearing, the scissor region must be clipped to the renderArea per the validation rules
523 // in Vulkan.
524 gl::Rectangle intersection;
Jamie Madill9aef3672018-04-27 11:45:06 -0400525 if (!gl::ClipRectangle(contextVk->getGLState().getScissor(), node->getRenderPassRenderArea(),
526 &intersection))
Luc Ferrone4c38be2018-04-17 11:09:16 -0400527 {
528 // There is nothing to clear since the scissor is outside of the render area.
529 return gl::NoError();
530 }
Luc Ferrone4c38be2018-04-17 11:09:16 -0400531 clearRect.rect = gl_vk::GetRect(intersection);
532
Luc Ferron5242d5b2018-02-15 07:14:35 -0500533 gl::AttachmentArray<VkClearAttachment> clearAttachments;
534 int clearAttachmentIndex = 0;
Luc Ferrona8af3a62018-03-29 14:44:24 -0400535
536 if (clearColor)
Luc Ferron5242d5b2018-02-15 07:14:35 -0500537 {
Luc Ferrona8af3a62018-03-29 14:44:24 -0400538 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
539 for (size_t colorIndex : mState.getEnabledDrawBuffers())
540 {
541 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
542 clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
543 clearAttachment.colorAttachment = static_cast<uint32_t>(colorIndex);
544 clearAttachment.clearValue = contextVk->getClearColorValue();
545 ++clearAttachmentIndex;
546 }
547 }
548
549 if (clearDepth && clearStencil && mState.getDepthStencilAttachment() != nullptr)
550 {
551 // When we have a packed depth/stencil attachment we can do 1 clear for both when it
552 // applies.
Luc Ferron5242d5b2018-02-15 07:14:35 -0500553 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
Luc Ferrona8af3a62018-03-29 14:44:24 -0400554 clearAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
555 clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
556 clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
Luc Ferron5242d5b2018-02-15 07:14:35 -0500557 ++clearAttachmentIndex;
558 }
Luc Ferrona8af3a62018-03-29 14:44:24 -0400559 else
560 {
561 if (clearDepth)
562 {
563 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
564 clearAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
565 clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
566 clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
567 ++clearAttachmentIndex;
568 }
569
570 if (clearStencil)
571 {
572 VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
573 clearAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
574 clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
575 clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
576 ++clearAttachmentIndex;
577 }
578 }
Luc Ferron5242d5b2018-02-15 07:14:35 -0500579
Luc Ferrona8af3a62018-03-29 14:44:24 -0400580 commandBuffer->clearAttachments(static_cast<uint32_t>(clearAttachmentIndex),
Luc Ferron5242d5b2018-02-15 07:14:35 -0500581 clearAttachments.data(), 1, &clearRect);
582 return gl::NoError();
583}
584
Jamie Madill9aef3672018-04-27 11:45:06 -0400585gl::Error FramebufferVk::clearWithDraw(ContextVk *contextVk, VkColorComponentFlags colorMaskFlags)
586{
587 RendererVk *renderer = contextVk->getRenderer();
588 vk::ShaderLibrary *shaderLibrary = renderer->getShaderLibrary();
589
590 const vk::ShaderAndSerial *fullScreenQuad = nullptr;
591 ANGLE_TRY(shaderLibrary->getShader(renderer, vk::InternalShaderID::FullScreenQuad_vert,
592 &fullScreenQuad));
593
594 const vk::ShaderAndSerial *uniformColor = nullptr;
595 ANGLE_TRY(
596 shaderLibrary->getShader(renderer, vk::InternalShaderID::UniformColor_frag, &uniformColor));
597
598 const vk::PipelineLayout *pipelineLayout = nullptr;
599 ANGLE_TRY(renderer->getInternalUniformPipelineLayout(&pipelineLayout));
600
601 vk::CommandBuffer *commandBuffer = nullptr;
602 ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
603
604 vk::CommandGraphNode *node = nullptr;
605 ANGLE_TRY(getCommandGraphNodeForDraw(contextVk, &node));
606
607 // This pipeline desc could be cached.
608 vk::PipelineDesc pipelineDesc;
609 pipelineDesc.initDefaults();
610 pipelineDesc.updateColorWriteMask(colorMaskFlags);
611 pipelineDesc.updateRenderPassDesc(getRenderPassDesc());
612 pipelineDesc.updateShaders(fullScreenQuad->queueSerial(), uniformColor->queueSerial());
613 pipelineDesc.updateViewport(node->getRenderPassRenderArea(), 0.0f, 1.0f);
614
615 const gl::State &glState = contextVk->getGLState();
616 if (glState.isScissorTestEnabled())
617 {
618 gl::Rectangle intersection;
619 if (!gl::ClipRectangle(glState.getScissor(), node->getRenderPassRenderArea(),
620 &intersection))
621 {
622 return gl::NoError();
623 }
624
625 pipelineDesc.updateScissor(intersection);
626 }
627 else
628 {
629 pipelineDesc.updateScissor(node->getRenderPassRenderArea());
630 }
631
632 vk::PipelineAndSerial *pipeline = nullptr;
633 ANGLE_TRY(renderer->getInternalPipeline(*fullScreenQuad, *uniformColor, *pipelineLayout,
634 pipelineDesc, gl::AttributesMask(), &pipeline));
635 pipeline->updateSerial(renderer->getCurrentQueueSerial());
636
637 VkDevice device = renderer->getDevice();
638
639 if (!mMaskedClearUniformBuffer.buffer.valid())
640 {
641 ASSERT(mMaskedClearDescriptorSet == VK_NULL_HANDLE);
642
643 VkBufferUsageFlags bufferUsage =
644 (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
645
646 VkBufferCreateInfo uniformBufferInfo;
647 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
648 uniformBufferInfo.pNext = nullptr;
649 uniformBufferInfo.flags = 0;
650 uniformBufferInfo.size = sizeof(VkClearColorValue);
651 uniformBufferInfo.usage = bufferUsage;
652 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
653 uniformBufferInfo.queueFamilyIndexCount = 0;
654 uniformBufferInfo.pQueueFamilyIndices = nullptr;
655
656 ANGLE_TRY(mMaskedClearUniformBuffer.buffer.init(device, uniformBufferInfo));
657
658 VkMemoryPropertyFlags memoryFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
659 size_t requiredSize = 0;
660 ANGLE_TRY(vk::AllocateBufferMemory(renderer, memoryFlags, &mMaskedClearUniformBuffer.buffer,
661 &mMaskedClearUniformBuffer.memory, &requiredSize));
662
663 const vk::DescriptorSetLayout &descriptorSetLayout =
664 renderer->getInternalUniformDescriptorSetLayout();
665
666 // This might confuse the dynamic descriptor pool's counting, but it shouldn't cause
667 // overflow.
668 vk::DynamicDescriptorPool *descriptorPool = contextVk->getDynamicDescriptorPool();
669 descriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout.ptr(), 1,
670 &mMaskedClearDescriptorSet);
671
672 VkDescriptorBufferInfo bufferInfo;
673 bufferInfo.buffer = mMaskedClearUniformBuffer.buffer.getHandle();
674 bufferInfo.offset = 0;
675 bufferInfo.range = VK_WHOLE_SIZE;
676
677 VkWriteDescriptorSet writeSet;
678 writeSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
679 writeSet.pNext = nullptr;
680 writeSet.dstSet = mMaskedClearDescriptorSet;
681 writeSet.dstBinding = 1;
682 writeSet.dstArrayElement = 0;
683 writeSet.descriptorCount = 1;
684 writeSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
685 writeSet.pImageInfo = nullptr;
686 writeSet.pBufferInfo = &bufferInfo;
687 writeSet.pTexelBufferView = nullptr;
688
689 vkUpdateDescriptorSets(device, 1, &writeSet, 0, nullptr);
690 }
691
692 VkClearColorValue clearColorValue = contextVk->getClearColorValue().color;
693 commandBuffer->updateBuffer(mMaskedClearUniformBuffer.buffer, 0, sizeof(VkClearColorValue),
694 clearColorValue.float32);
695
696 vk::CommandBuffer *drawCommandBuffer = nullptr;
697 ANGLE_TRY(node->beginInsideRenderPassRecording(renderer, &drawCommandBuffer));
698
699 std::array<uint32_t, 2> dynamicOffsets = {{0, 0}};
700 drawCommandBuffer->bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1,
701 &mMaskedClearDescriptorSet, 2, dynamicOffsets.data());
702
703 // TODO(jmadill): Masked combined color and depth/stencil clear. http://anglebug.com/2455
704 // Any active queries submitted by the user should also be paused here.
705 drawCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->get());
706 drawCommandBuffer->draw(6, 1, 0, 0);
707
708 return gl::NoError();
709}
710
Geoff Lang13455072018-05-09 11:24:43 -0400711gl::Error FramebufferVk::getSamplePosition(const gl::Context *context,
712 size_t index,
713 GLfloat *xy) const
JiangYizhoubddc46b2016-12-09 09:50:51 +0800714{
715 UNIMPLEMENTED();
716 return gl::InternalError() << "getSamplePosition is unimplemented.";
717}
718
Jamie Madillb90779e2018-04-27 11:45:01 -0400719gl::Error FramebufferVk::getCommandGraphNodeForDraw(ContextVk *contextVk,
Jamie Madille4c5a232018-03-02 21:00:31 -0500720 vk::CommandGraphNode **nodeOut)
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500721{
Jamie Madill49ac74b2017-12-21 14:42:33 -0500722 RendererVk *renderer = contextVk->getRenderer();
723 Serial currentSerial = renderer->getCurrentQueueSerial();
Jamie Madillbef918c2017-12-13 13:11:30 -0500724
Jamie Madill9cceac42018-03-31 14:19:16 -0400725 // This will reset the current writing node if it has been completed.
726 updateQueueSerial(currentSerial);
727
728 if (hasChildlessWritingNode())
Jamie Madill4c26fc22017-02-24 11:04:10 -0500729 {
Jamie Madill9cceac42018-03-31 14:19:16 -0400730 *nodeOut = getCurrentWritingNode();
731 }
732 else
733 {
734 *nodeOut = getNewWritingNode(renderer);
Jamie Madill4c26fc22017-02-24 11:04:10 -0500735 }
736
Jamie Madill9cceac42018-03-31 14:19:16 -0400737 if ((*nodeOut)->getInsideRenderPassCommands()->valid())
738 {
739 return gl::NoError();
740 }
Jamie Madill4c26fc22017-02-24 11:04:10 -0500741
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500742 vk::Framebuffer *framebuffer = nullptr;
Jamie Madillb90779e2018-04-27 11:45:01 -0400743 ANGLE_TRY_RESULT(getFramebuffer(renderer), framebuffer);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500744
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500745 std::vector<VkClearValue> attachmentClearValues;
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500746
Jamie Madille4c5a232018-03-02 21:00:31 -0500747 vk::CommandBuffer *commandBuffer = nullptr;
Jamie Madill9cceac42018-03-31 14:19:16 -0400748 if (!(*nodeOut)->getOutsideRenderPassCommands()->valid())
749 {
750 ANGLE_TRY((*nodeOut)->beginOutsideRenderPassRecording(
751 renderer->getDevice(), renderer->getCommandPool(), &commandBuffer));
752 }
753 else
754 {
755 commandBuffer = (*nodeOut)->getOutsideRenderPassCommands();
756 }
Jamie Madille4c5a232018-03-02 21:00:31 -0500757
Jamie Madill49ac74b2017-12-21 14:42:33 -0500758 // Initialize RenderPass info.
Jamie Madill66546be2018-03-08 09:47:20 -0500759 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
760 const auto &colorRenderTargets = mRenderTargetCache.getColors();
761 for (size_t colorIndex : mState.getEnabledDrawBuffers())
Jamie Madill4c26fc22017-02-24 11:04:10 -0500762 {
Jamie Madill66546be2018-03-08 09:47:20 -0500763 RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
764 ASSERT(colorRenderTarget);
Jamie Madill49ac74b2017-12-21 14:42:33 -0500765
Jamie Madill9cceac42018-03-31 14:19:16 -0400766 (*nodeOut)->appendColorRenderTarget(currentSerial, colorRenderTarget);
Jamie Madill66546be2018-03-08 09:47:20 -0500767 attachmentClearValues.emplace_back(contextVk->getClearColorValue());
768 }
769
770 RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
771 if (depthStencilRenderTarget)
772 {
Jamie Madill9cceac42018-03-31 14:19:16 -0400773 (*nodeOut)->appendDepthStencilRenderTarget(currentSerial, depthStencilRenderTarget);
Jamie Madillf4d693c2018-02-14 16:38:16 -0500774 attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
Jamie Madill49ac74b2017-12-21 14:42:33 -0500775 }
776
Luc Ferrond17bdfe2018-04-05 13:50:10 -0400777 gl::Rectangle renderArea =
778 gl::Rectangle(0, 0, mState.getDimensions().width, mState.getDimensions().height);
Jamie Madillf4d693c2018-02-14 16:38:16 -0500779 // Hard-code RenderPass to clear the first render target to the current clear value.
780 // TODO(jmadill): Proper clear value implementation. http://anglebug.com/2361
Luc Ferrond17bdfe2018-04-05 13:50:10 -0400781 (*nodeOut)->storeRenderPassInfo(*framebuffer, renderArea, attachmentClearValues);
Jamie Madill49ac74b2017-12-21 14:42:33 -0500782
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500783 return gl::NoError();
784}
785
Jamie Madill9aef3672018-04-27 11:45:06 -0400786void FramebufferVk::updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a)
787{
788 mActiveColorComponentMasks[0].set(colorIndex, r);
789 mActiveColorComponentMasks[1].set(colorIndex, g);
790 mActiveColorComponentMasks[2].set(colorIndex, b);
791 mActiveColorComponentMasks[3].set(colorIndex, a);
792}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400793} // namespace rx