1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
16 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
17
18 #include "Framebuffer.h"
19
20 #include "main.h"
21 #include "Renderbuffer.h"
22 #include "Texture.h"
23 #include "utilities.h"
24
25 namespace es2
26 {
27
IsRenderbuffer(GLenum type)28 bool Framebuffer::IsRenderbuffer(GLenum type)
29 {
30 return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT;
31 }
32
Framebuffer()33 Framebuffer::Framebuffer()
34 {
35 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
36 {
37 mColorbufferType[i] = GL_NONE;
38 }
39 mDepthbufferType = GL_NONE;
40 mStencilbufferType = GL_NONE;
41
42 readBuffer = GL_BACK;
43 drawBuffer[0] = GL_BACK;
44 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; ++i)
45 {
46 drawBuffer[i] = GL_NONE;
47 }
48 }
49
~Framebuffer()50 Framebuffer::~Framebuffer()
51 {
52 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
53 {
54 mColorbufferPointer[i] = nullptr;
55 }
56 mDepthbufferPointer = nullptr;
57 mStencilbufferPointer = nullptr;
58 }
59
lookupRenderbuffer(GLenum type,GLuint handle,GLint level,GLint layer) const60 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const
61 {
62 Context *context = getContext();
63 Renderbuffer *buffer = nullptr;
64
65 if(type == GL_NONE)
66 {
67 buffer = nullptr;
68 }
69 else if(IsRenderbuffer(type))
70 {
71 buffer = context->getRenderbuffer(handle);
72 }
73 else if(IsTextureTarget(type))
74 {
75 buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer);
76 }
77 else UNREACHABLE(type);
78
79 return buffer;
80 }
81
setColorbuffer(GLenum type,GLuint colorbuffer,GLuint index,GLint level,GLint layer)82 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer)
83 {
84 mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
85 mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level, layer);
86 }
87
setDepthbuffer(GLenum type,GLuint depthbuffer,GLint level,GLint layer)88 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
89 {
90 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
91 mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level, layer);
92 }
93
setStencilbuffer(GLenum type,GLuint stencilbuffer,GLint level,GLint layer)94 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
95 {
96 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
97 mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level, layer);
98 }
99
setReadBuffer(GLenum buf)100 void Framebuffer::setReadBuffer(GLenum buf)
101 {
102 readBuffer = buf;
103 }
104
setDrawBuffer(GLuint index,GLenum buf)105 void Framebuffer::setDrawBuffer(GLuint index, GLenum buf)
106 {
107 drawBuffer[index] = buf;
108 }
109
getReadBuffer() const110 GLenum Framebuffer::getReadBuffer() const
111 {
112 return readBuffer;
113 }
114
getDrawBuffer(GLuint index) const115 GLenum Framebuffer::getDrawBuffer(GLuint index) const
116 {
117 return drawBuffer[index];
118 }
119
detachTexture(GLuint texture)120 void Framebuffer::detachTexture(GLuint texture)
121 {
122 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
123 {
124 if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i]))
125 {
126 mColorbufferType[i] = GL_NONE;
127 mColorbufferPointer[i] = nullptr;
128 }
129 }
130
131 if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
132 {
133 mDepthbufferType = GL_NONE;
134 mDepthbufferPointer = nullptr;
135 }
136
137 if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType))
138 {
139 mStencilbufferType = GL_NONE;
140 mStencilbufferPointer = nullptr;
141 }
142 }
143
detachRenderbuffer(GLuint renderbuffer)144 void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
145 {
146 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
147 {
148 if(mColorbufferPointer[i].name() == renderbuffer && IsRenderbuffer(mColorbufferType[i]))
149 {
150 mColorbufferType[i] = GL_NONE;
151 mColorbufferPointer[i] = nullptr;
152 }
153 }
154
155 if(mDepthbufferPointer.name() == renderbuffer && IsRenderbuffer(mDepthbufferType))
156 {
157 mDepthbufferType = GL_NONE;
158 mDepthbufferPointer = nullptr;
159 }
160
161 if(mStencilbufferPointer.name() == renderbuffer && IsRenderbuffer(mStencilbufferType))
162 {
163 mStencilbufferType = GL_NONE;
164 mStencilbufferPointer = nullptr;
165 }
166 }
167
168 // Increments refcount on surface.
169 // caller must Release() the returned surface
getRenderTarget(GLuint index)170 egl::Image *Framebuffer::getRenderTarget(GLuint index)
171 {
172 Renderbuffer *colorbuffer = mColorbufferPointer[index];
173
174 if(colorbuffer)
175 {
176 return colorbuffer->getRenderTarget();
177 }
178
179 return nullptr;
180 }
181
getReadRenderTarget()182 egl::Image *Framebuffer::getReadRenderTarget()
183 {
184 Context *context = getContext();
185 return getRenderTarget(context->getReadFramebufferColorIndex());
186 }
187
188 // Increments refcount on surface.
189 // caller must Release() the returned surface
getDepthBuffer()190 egl::Image *Framebuffer::getDepthBuffer()
191 {
192 Renderbuffer *depthbuffer = mDepthbufferPointer;
193
194 if(depthbuffer)
195 {
196 return depthbuffer->getRenderTarget();
197 }
198
199 return nullptr;
200 }
201
202 // Increments refcount on surface.
203 // caller must Release() the returned surface
getStencilBuffer()204 egl::Image *Framebuffer::getStencilBuffer()
205 {
206 Renderbuffer *stencilbuffer = mStencilbufferPointer;
207
208 if(stencilbuffer)
209 {
210 return stencilbuffer->getRenderTarget();
211 }
212
213 return nullptr;
214 }
215
getColorbuffer(GLuint index) const216 Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const
217 {
218 return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr;
219 }
220
getReadColorbuffer() const221 Renderbuffer *Framebuffer::getReadColorbuffer() const
222 {
223 Context *context = getContext();
224 return getColorbuffer(context->getReadFramebufferColorIndex());
225 }
226
getDepthbuffer() const227 Renderbuffer *Framebuffer::getDepthbuffer() const
228 {
229 return mDepthbufferPointer;
230 }
231
getStencilbuffer() const232 Renderbuffer *Framebuffer::getStencilbuffer() const
233 {
234 return mStencilbufferPointer;
235 }
236
getColorbufferType(GLuint index)237 GLenum Framebuffer::getColorbufferType(GLuint index)
238 {
239 return mColorbufferType[index];
240 }
241
getDepthbufferType()242 GLenum Framebuffer::getDepthbufferType()
243 {
244 return mDepthbufferType;
245 }
246
getStencilbufferType()247 GLenum Framebuffer::getStencilbufferType()
248 {
249 return mStencilbufferType;
250 }
251
getColorbufferName(GLuint index)252 GLuint Framebuffer::getColorbufferName(GLuint index)
253 {
254 return mColorbufferPointer[index].name();
255 }
256
getDepthbufferName()257 GLuint Framebuffer::getDepthbufferName()
258 {
259 return mDepthbufferPointer.name();
260 }
261
getStencilbufferName()262 GLuint Framebuffer::getStencilbufferName()
263 {
264 return mStencilbufferPointer.name();
265 }
266
getColorbufferLayer(GLuint index)267 GLint Framebuffer::getColorbufferLayer(GLuint index)
268 {
269 Renderbuffer *colorbuffer = mColorbufferPointer[index];
270 return colorbuffer ? colorbuffer->getLayer() : 0;
271 }
272
getDepthbufferLayer()273 GLint Framebuffer::getDepthbufferLayer()
274 {
275 return mDepthbufferPointer ? mDepthbufferPointer->getLayer() : 0;
276 }
277
getStencilbufferLayer()278 GLint Framebuffer::getStencilbufferLayer()
279 {
280 return mStencilbufferPointer ? mStencilbufferPointer->getLayer() : 0;
281 }
282
hasStencil()283 bool Framebuffer::hasStencil()
284 {
285 if(mStencilbufferType != GL_NONE)
286 {
287 Renderbuffer *stencilbufferObject = getStencilbuffer();
288
289 if(stencilbufferObject)
290 {
291 return stencilbufferObject->getStencilSize() > 0;
292 }
293 }
294
295 return false;
296 }
297
completeness()298 GLenum Framebuffer::completeness()
299 {
300 int width;
301 int height;
302 int samples;
303
304 return completeness(width, height, samples);
305 }
306
completeness(int & width,int & height,int & samples)307 GLenum Framebuffer::completeness(int &width, int &height, int &samples)
308 {
309 width = -1;
310 height = -1;
311 samples = -1;
312
313 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
314 {
315 if(mColorbufferType[i] != GL_NONE)
316 {
317 Renderbuffer *colorbuffer = getColorbuffer(i);
318
319 if(!colorbuffer)
320 {
321 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
322 }
323
324 if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= colorbuffer->getLayer()))
325 {
326 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
327 }
328
329 if(IsRenderbuffer(mColorbufferType[i]))
330 {
331 if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion(), false))
332 {
333 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
334 }
335 }
336 else if(IsTextureTarget(mColorbufferType[i]))
337 {
338 GLenum format = colorbuffer->getFormat();
339
340 if(!IsColorRenderable(format, egl::getClientVersion(), true))
341 {
342 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
343 }
344
345 if(IsDepthTexture(format) || IsStencilTexture(format))
346 {
347 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
348 }
349 }
350 else
351 {
352 UNREACHABLE(mColorbufferType[i]);
353 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
354 }
355
356 width = colorbuffer->getWidth();
357 height = colorbuffer->getHeight();
358
359 if(samples == -1)
360 {
361 samples = colorbuffer->getSamples();
362 }
363 else if(samples != colorbuffer->getSamples())
364 {
365 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
366 }
367 }
368 }
369
370 Renderbuffer *depthbuffer = nullptr;
371 Renderbuffer *stencilbuffer = nullptr;
372
373 if(mDepthbufferType != GL_NONE)
374 {
375 depthbuffer = getDepthbuffer();
376
377 if(!depthbuffer)
378 {
379 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
380 }
381
382 if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
383 {
384 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
385 }
386
387 if(IsRenderbuffer(mDepthbufferType))
388 {
389 if(!es2::IsDepthRenderable(depthbuffer->getFormat(), egl::getClientVersion()))
390 {
391 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
392 }
393 }
394 else if(IsTextureTarget(mDepthbufferType))
395 {
396 if(!es2::IsDepthTexture(depthbuffer->getFormat()))
397 {
398 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
399 }
400 }
401 else
402 {
403 UNREACHABLE(mDepthbufferType);
404 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
405 }
406
407 if(width == -1 || height == -1)
408 {
409 width = depthbuffer->getWidth();
410 height = depthbuffer->getHeight();
411 samples = depthbuffer->getSamples();
412 }
413 else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
414 {
415 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
416 }
417 else if(samples != depthbuffer->getSamples())
418 {
419 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
420 }
421 }
422
423 if(mStencilbufferType != GL_NONE)
424 {
425 stencilbuffer = getStencilbuffer();
426
427 if(!stencilbuffer)
428 {
429 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
430 }
431
432 if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
433 {
434 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
435 }
436
437 if(IsRenderbuffer(mStencilbufferType))
438 {
439 if(!es2::IsStencilRenderable(stencilbuffer->getFormat(), egl::getClientVersion()))
440 {
441 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
442 }
443 }
444 else if(IsTextureTarget(mStencilbufferType))
445 {
446 GLenum internalformat = stencilbuffer->getFormat();
447
448 if(!es2::IsStencilTexture(internalformat))
449 {
450 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
451 }
452 }
453 else
454 {
455 UNREACHABLE(mStencilbufferType);
456 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
457 }
458
459 if(width == -1 || height == -1)
460 {
461 width = stencilbuffer->getWidth();
462 height = stencilbuffer->getHeight();
463 samples = stencilbuffer->getSamples();
464 }
465 else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
466 {
467 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
468 }
469 else if(samples != stencilbuffer->getSamples())
470 {
471 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
472 }
473 }
474
475 if((egl::getClientVersion() >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
476 {
477 // In the GLES 3.0 spec, section 4.4.4, Framebuffer Completeness:
478 // "The framebuffer object target is said to be framebuffer complete if all the following conditions are true:
479 // [...]
480 // Depth and stencil attachments, if present, are the same image.
481 // { FRAMEBUFFER_UNSUPPORTED }"
482 return GL_FRAMEBUFFER_UNSUPPORTED;
483 }
484
485 // We need to have at least one attachment to be complete
486 if(width == -1 || height == -1)
487 {
488 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
489 }
490
491 return GL_FRAMEBUFFER_COMPLETE;
492 }
493
getImplementationColorReadFormat() const494 GLenum Framebuffer::getImplementationColorReadFormat() const
495 {
496 Renderbuffer *colorbuffer = getReadColorbuffer();
497
498 if(colorbuffer)
499 {
500 switch(colorbuffer->getInternalFormat())
501 {
502 case sw::FORMAT_A8B8G8R8I: return GL_RGBA_INTEGER;
503 case sw::FORMAT_A8B8G8R8UI: return GL_RGBA_INTEGER;
504 case sw::FORMAT_A16B16G16R16I: return GL_RGBA_INTEGER;
505 case sw::FORMAT_A16B16G16R16UI: return GL_RGBA_INTEGER;
506 case sw::FORMAT_A32B32G32R32I: return GL_RGBA_INTEGER;
507 case sw::FORMAT_A32B32G32R32UI: return GL_RGBA_INTEGER;
508 case sw::FORMAT_A2B10G10R10: return GL_RGB10_A2;
509 case sw::FORMAT_A8B8G8R8I_SNORM: return GL_RGBA;
510 case sw::FORMAT_A8B8G8R8: return GL_RGBA;
511 case sw::FORMAT_SRGB8_A8: return GL_RGBA;
512 case sw::FORMAT_A8R8G8B8: return GL_BGRA_EXT;
513 case sw::FORMAT_A1R5G5B5: return GL_BGRA_EXT;
514 case sw::FORMAT_X8B8G8R8I: return GL_RGBA_INTEGER;
515 case sw::FORMAT_X8B8G8R8UI: return GL_RGBA_INTEGER;
516 case sw::FORMAT_X16B16G16R16I: return GL_RGBA_INTEGER;
517 case sw::FORMAT_X16B16G16R16UI: return GL_RGBA_INTEGER;
518 case sw::FORMAT_X32B32G32R32I: return GL_RGBA_INTEGER;
519 case sw::FORMAT_X32B32G32R32UI: return GL_RGBA_INTEGER;
520 case sw::FORMAT_X8B8G8R8I_SNORM: return GL_RGBA;
521 case sw::FORMAT_SRGB8_X8: return GL_RGBA;
522 case sw::FORMAT_X8B8G8R8: return GL_RGBA;
523 case sw::FORMAT_X8R8G8B8: return GL_BGRA_EXT;
524 case sw::FORMAT_R5G6B5: return GL_RGB;
525 case sw::FORMAT_G8R8I: return GL_RG_INTEGER;
526 case sw::FORMAT_G8R8UI: return GL_RG_INTEGER;
527 case sw::FORMAT_G16R16I: return GL_RG_INTEGER;
528 case sw::FORMAT_G16R16UI: return GL_RG_INTEGER;
529 case sw::FORMAT_G32R32I: return GL_RG_INTEGER;
530 case sw::FORMAT_G32R32UI: return GL_RG_INTEGER;
531 case sw::FORMAT_R8I: return GL_RED_INTEGER;
532 case sw::FORMAT_R8UI: return GL_RED_INTEGER;
533 case sw::FORMAT_R16I: return GL_RED_INTEGER;
534 case sw::FORMAT_R16UI: return GL_RED_INTEGER;
535 case sw::FORMAT_R32I: return GL_RED_INTEGER;
536 case sw::FORMAT_R32UI: return GL_RED_INTEGER;
537 case sw::FORMAT_R8: return GL_RED;
538 case sw::FORMAT_R8I_SNORM: return GL_RED;
539 case sw::FORMAT_R16F: return GL_RED;
540 case sw::FORMAT_R32F: return GL_RED;
541 case sw::FORMAT_G8R8: return GL_RG;
542 case sw::FORMAT_G8R8I_SNORM: return GL_RG;
543 case sw::FORMAT_G16R16F: return GL_RG;
544 case sw::FORMAT_G32R32F: return GL_RG;
545 case sw::FORMAT_B16G16R16F: return GL_RGB;
546 case sw::FORMAT_X32B32G32R32F: return GL_RGBA;
547 case sw::FORMAT_A16B16G16R16F: return GL_RGBA;
548 case sw::FORMAT_A32B32G32R32F: return GL_RGBA;
549 default:
550 UNREACHABLE(colorbuffer->getInternalFormat());
551 }
552 }
553
554 return GL_RGBA;
555 }
556
getImplementationColorReadType() const557 GLenum Framebuffer::getImplementationColorReadType() const
558 {
559 Renderbuffer *colorbuffer = getReadColorbuffer();
560
561 if(colorbuffer)
562 {
563 switch(colorbuffer->getInternalFormat())
564 {
565 case sw::FORMAT_R16F: return GL_FLOAT;
566 case sw::FORMAT_G16R16F: return GL_FLOAT;
567 case sw::FORMAT_B16G16R16F: return GL_FLOAT;
568 case sw::FORMAT_A16B16G16R16F: return GL_FLOAT;
569 case sw::FORMAT_R32F: return GL_FLOAT;
570 case sw::FORMAT_G32R32F: return GL_FLOAT;
571 case sw::FORMAT_B32G32R32F: return GL_FLOAT;
572 case sw::FORMAT_X32B32G32R32F: return GL_FLOAT;
573 case sw::FORMAT_A32B32G32R32F: return GL_FLOAT;
574 case sw::FORMAT_R8I_SNORM: return GL_BYTE;
575 case sw::FORMAT_G8R8I_SNORM: return GL_BYTE;
576 case sw::FORMAT_X8B8G8R8I_SNORM: return GL_BYTE;
577 case sw::FORMAT_A8B8G8R8I_SNORM: return GL_BYTE;
578 case sw::FORMAT_R8: return GL_UNSIGNED_BYTE;
579 case sw::FORMAT_G8R8: return GL_UNSIGNED_BYTE;
580 case sw::FORMAT_SRGB8_X8: return GL_UNSIGNED_BYTE;
581 case sw::FORMAT_SRGB8_A8: return GL_UNSIGNED_BYTE;
582 case sw::FORMAT_A8R8G8B8: return GL_UNSIGNED_BYTE;
583 case sw::FORMAT_A8B8G8R8: return GL_UNSIGNED_BYTE;
584 case sw::FORMAT_X8R8G8B8: return GL_UNSIGNED_BYTE;
585 case sw::FORMAT_X8B8G8R8: return GL_UNSIGNED_BYTE;
586 case sw::FORMAT_R8I: return GL_INT;
587 case sw::FORMAT_G8R8I: return GL_INT;
588 case sw::FORMAT_X8B8G8R8I: return GL_INT;
589 case sw::FORMAT_A8B8G8R8I: return GL_INT;
590 case sw::FORMAT_R16I: return GL_INT;
591 case sw::FORMAT_G16R16I: return GL_INT;
592 case sw::FORMAT_X16B16G16R16I: return GL_INT;
593 case sw::FORMAT_A16B16G16R16I: return GL_INT;
594 case sw::FORMAT_R32I: return GL_INT;
595 case sw::FORMAT_G32R32I: return GL_INT;
596 case sw::FORMAT_X32B32G32R32I: return GL_INT;
597 case sw::FORMAT_A32B32G32R32I: return GL_INT;
598 case sw::FORMAT_R8UI: return GL_UNSIGNED_INT;
599 case sw::FORMAT_G8R8UI: return GL_UNSIGNED_INT;
600 case sw::FORMAT_X8B8G8R8UI: return GL_UNSIGNED_INT;
601 case sw::FORMAT_A8B8G8R8UI: return GL_UNSIGNED_INT;
602 case sw::FORMAT_R16UI: return GL_UNSIGNED_INT;
603 case sw::FORMAT_G16R16UI: return GL_UNSIGNED_INT;
604 case sw::FORMAT_X16B16G16R16UI: return GL_UNSIGNED_INT;
605 case sw::FORMAT_A16B16G16R16UI: return GL_UNSIGNED_INT;
606 case sw::FORMAT_R32UI: return GL_UNSIGNED_INT;
607 case sw::FORMAT_G32R32UI: return GL_UNSIGNED_INT;
608 case sw::FORMAT_X32B32G32R32UI: return GL_UNSIGNED_INT;
609 case sw::FORMAT_A32B32G32R32UI: return GL_UNSIGNED_INT;
610 case sw::FORMAT_A2B10G10R10: return GL_UNSIGNED_INT_10_10_10_2_OES;
611 case sw::FORMAT_A1R5G5B5: return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
612 case sw::FORMAT_R5G6B5: return GL_UNSIGNED_SHORT_5_6_5;
613 default:
614 UNREACHABLE(colorbuffer->getInternalFormat());
615 }
616 }
617
618 return GL_UNSIGNED_BYTE;
619 }
620
getDepthReadFormat() const621 GLenum Framebuffer::getDepthReadFormat() const
622 {
623 Renderbuffer *depthbuffer = getDepthbuffer();
624
625 if(depthbuffer)
626 {
627 // There is only one depth read format.
628 return GL_DEPTH_COMPONENT;
629 }
630
631 // If there is no depth buffer, GL_INVALID_OPERATION occurs.
632 return GL_NONE;
633 }
634
getDepthReadType() const635 GLenum Framebuffer::getDepthReadType() const
636 {
637 Renderbuffer *depthbuffer = getDepthbuffer();
638
639 if(depthbuffer)
640 {
641 switch(depthbuffer->getInternalFormat())
642 {
643 case sw::FORMAT_D16: return GL_UNSIGNED_SHORT;
644 case sw::FORMAT_D24S8: return GL_UNSIGNED_INT_24_8_OES;
645 case sw::FORMAT_D32: return GL_UNSIGNED_INT;
646 case sw::FORMAT_D32F:
647 case sw::FORMAT_D32F_COMPLEMENTARY:
648 case sw::FORMAT_D32F_LOCKABLE:
649 case sw::FORMAT_D32FS8_TEXTURE:
650 case sw::FORMAT_D32FS8_SHADOW: return GL_FLOAT;
651 default:
652 UNREACHABLE(depthbuffer->getInternalFormat());
653 }
654 }
655
656 // If there is no depth buffer, GL_INVALID_OPERATION occurs.
657 return GL_NONE;
658 }
659
DefaultFramebuffer(Colorbuffer * colorbuffer,DepthStencilbuffer * depthStencil)660 DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
661 {
662 GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT;
663 mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer);
664 mColorbufferType[0] = defaultRenderbufferType;
665
666 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++)
667 {
668 mColorbufferPointer[i] = nullptr;
669 mColorbufferType[i] = GL_NONE;
670 }
671
672 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
673 mDepthbufferPointer = depthStencilRenderbuffer;
674 mStencilbufferPointer = depthStencilRenderbuffer;
675
676 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? defaultRenderbufferType : GL_NONE;
677 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? defaultRenderbufferType : GL_NONE;
678 }
679
680 }
681