blob: f90bba170aa73ab2db8e950c8c476ac2a8f22a04 [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
41} // 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 Madill9e54b5a2016-05-25 12:57:39 -040056FramebufferVk::FramebufferVk(const gl::FramebufferState &state) : FramebufferImpl(state)
57{
58}
59
Jamie Madill7b57b9d2017-01-13 09:33:38 -050060FramebufferVk::FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer)
61 : FramebufferImpl(state)
62{
63}
64
Jamie Madill9e54b5a2016-05-25 12:57:39 -040065FramebufferVk::~FramebufferVk()
66{
67}
68
69gl::Error FramebufferVk::discard(size_t count, const GLenum *attachments)
70{
71 UNIMPLEMENTED();
72 return gl::Error(GL_INVALID_OPERATION);
73}
74
75gl::Error FramebufferVk::invalidate(size_t count, const GLenum *attachments)
76{
77 UNIMPLEMENTED();
78 return gl::Error(GL_INVALID_OPERATION);
79}
80
81gl::Error FramebufferVk::invalidateSub(size_t count,
82 const GLenum *attachments,
83 const gl::Rectangle &area)
84{
85 UNIMPLEMENTED();
86 return gl::Error(GL_INVALID_OPERATION);
87}
88
89gl::Error FramebufferVk::clear(ContextImpl *context, GLbitfield mask)
90{
Jamie Madill7b57b9d2017-01-13 09:33:38 -050091 ContextVk *contextVk = GetAs<ContextVk>(context);
92
93 if (mState.getDepthAttachment() && (mask & GL_DEPTH_BUFFER_BIT) != 0)
94 {
95 // TODO(jmadill): Depth clear
96 UNIMPLEMENTED();
97 }
98
99 if (mState.getStencilAttachment() && (mask & GL_STENCIL_BUFFER_BIT) != 0)
100 {
101 // TODO(jmadill): Stencil clear
102 UNIMPLEMENTED();
103 }
104
105 if ((mask & GL_COLOR_BUFFER_BIT) == 0)
106 {
107 return gl::NoError();
108 }
109
110 const auto &glState = context->getGLState();
111 const auto &clearColor = glState.getColorClearValue();
112 VkClearColorValue clearColorValue;
113 clearColorValue.float32[0] = clearColor.red;
114 clearColorValue.float32[1] = clearColor.green;
115 clearColorValue.float32[2] = clearColor.blue;
116 clearColorValue.float32[3] = clearColor.alpha;
117
118 // TODO(jmadill): Scissored clears.
119 const auto *attachment = mState.getFirstNonNullAttachment();
120 ASSERT(attachment && attachment->isAttached());
121 const auto &size = attachment->getSize();
122 const gl::Rectangle renderArea(0, 0, size.width, size.height);
123
124 vk::CommandBuffer *commandBuffer = contextVk->getCommandBuffer();
125 ANGLE_TRY(commandBuffer->begin());
126
127 for (const auto &colorAttachment : mState.getColorAttachments())
128 {
129 if (colorAttachment.isAttached())
130 {
131 RenderTargetVk *renderTarget = nullptr;
132 ANGLE_TRY(colorAttachment.getRenderTarget(&renderTarget));
133 renderTarget->image->changeLayoutTop(
134 VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, commandBuffer);
135 commandBuffer->clearSingleColorImage(*renderTarget->image, clearColorValue);
136 }
137 }
138
139 commandBuffer->end();
140
141 ANGLE_TRY(contextVk->submitCommands(*commandBuffer));
142
143 return gl::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400144}
145
146gl::Error FramebufferVk::clearBufferfv(ContextImpl *context,
147 GLenum buffer,
148 GLint drawbuffer,
149 const GLfloat *values)
150{
151 UNIMPLEMENTED();
152 return gl::Error(GL_INVALID_OPERATION);
153}
154
155gl::Error FramebufferVk::clearBufferuiv(ContextImpl *context,
156 GLenum buffer,
157 GLint drawbuffer,
158 const GLuint *values)
159{
160 UNIMPLEMENTED();
161 return gl::Error(GL_INVALID_OPERATION);
162}
163
164gl::Error FramebufferVk::clearBufferiv(ContextImpl *context,
165 GLenum buffer,
166 GLint drawbuffer,
167 const GLint *values)
168{
169 UNIMPLEMENTED();
170 return gl::Error(GL_INVALID_OPERATION);
171}
172
173gl::Error FramebufferVk::clearBufferfi(ContextImpl *context,
174 GLenum buffer,
175 GLint drawbuffer,
176 GLfloat depth,
177 GLint stencil)
178{
179 UNIMPLEMENTED();
180 return gl::Error(GL_INVALID_OPERATION);
181}
182
183GLenum FramebufferVk::getImplementationColorReadFormat() const
184{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500185 auto errOrResult = GetReadAttachmentInfo(mState.getReadAttachment());
186
187 // TODO(jmadill): Handle getRenderTarget error.
188 if (errOrResult.isError())
189 {
190 ERR("Internal error in FramebufferVk::getImplementationColorReadFormat.");
191 return GL_NONE;
192 }
193
194 return errOrResult.getResult()->format;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400195}
196
197GLenum FramebufferVk::getImplementationColorReadType() const
198{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500199 auto errOrResult = GetReadAttachmentInfo(mState.getReadAttachment());
200
201 // TODO(jmadill): Handle getRenderTarget error.
202 if (errOrResult.isError())
203 {
204 ERR("Internal error in FramebufferVk::getImplementationColorReadFormat.");
205 return GL_NONE;
206 }
207
208 return errOrResult.getResult()->type;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400209}
210
211gl::Error FramebufferVk::readPixels(ContextImpl *context,
212 const gl::Rectangle &area,
213 GLenum format,
214 GLenum type,
215 GLvoid *pixels) const
216{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500217 const auto &glState = context->getGLState();
218 const auto *readFramebuffer = glState.getReadFramebuffer();
219 const auto *readAttachment = readFramebuffer->getReadColorbuffer();
220
221 RenderTargetVk *renderTarget = nullptr;
222 ANGLE_TRY(readAttachment->getRenderTarget(&renderTarget));
223
224 ContextVk *contextVk = GetAs<ContextVk>(context);
225 RendererVk *renderer = contextVk->getRenderer();
226
227 vk::Image *readImage = renderTarget->image;
228 vk::StagingImage stagingImage;
229 ANGLE_TRY_RESULT(renderer->createStagingImage(TextureDimension::TEX_2D, *renderTarget->format,
230 renderTarget->extents),
231 stagingImage);
232
233 vk::CommandBuffer *commandBuffer = contextVk->getCommandBuffer();
234 commandBuffer->begin();
235 stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
236 commandBuffer);
237
238 gl::Box copyRegion;
239 copyRegion.x = area.x;
240 copyRegion.y = area.y;
241 copyRegion.z = 0;
242 copyRegion.width = area.width;
243 copyRegion.height = area.height;
244 copyRegion.depth = 1;
245
246 readImage->changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
247 commandBuffer);
248 commandBuffer->copySingleImage(*readImage, stagingImage.getImage(), copyRegion,
249 VK_IMAGE_ASPECT_COLOR_BIT);
250 commandBuffer->end();
251
252 ANGLE_TRY(renderer->submitAndFinishCommandBuffer(*commandBuffer));
253
254 // TODO(jmadill): parameters
255 uint8_t *mapPointer = nullptr;
256 ANGLE_TRY(stagingImage.getDeviceMemory().map(0, stagingImage.getSize(), 0, &mapPointer));
257
258 const auto &angleFormat = renderTarget->format->format();
259
260 // TODO(jmadill): Use pixel bytes from the ANGLE format directly.
261 const auto &glFormat = gl::GetInternalFormatInfo(angleFormat.glInternalFormat);
262 int inputPitch = glFormat.pixelBytes * area.width;
263
264 PackPixelsParams params;
265 params.area = area;
266 params.format = format;
267 params.type = type;
268 params.outputPitch = inputPitch;
269 params.pack = glState.getPackState();
270
271 PackPixels(params, angleFormat, inputPitch, mapPointer, reinterpret_cast<uint8_t *>(pixels));
272
273 stagingImage.getDeviceMemory().unmap();
274
275 return vk::NoError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400276}
277
278gl::Error FramebufferVk::blit(ContextImpl *context,
279 const gl::Rectangle &sourceArea,
280 const gl::Rectangle &destArea,
281 GLbitfield mask,
282 GLenum filter)
283{
284 UNIMPLEMENTED();
285 return gl::Error(GL_INVALID_OPERATION);
286}
287
288bool FramebufferVk::checkStatus() const
289{
290 UNIMPLEMENTED();
291 return bool();
292}
293
294void FramebufferVk::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
295{
Jamie Madill7b57b9d2017-01-13 09:33:38 -0500296 // TODO(jmadill): Smarter update.
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400297}
298
JiangYizhoubddc46b2016-12-09 09:50:51 +0800299gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
300{
301 UNIMPLEMENTED();
302 return gl::InternalError() << "getSamplePosition is unimplemented.";
303}
304
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400305} // namespace rx