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// Context.cpp: Implements the es2::Context class, managing all GL state and performing
16// rendering operations. It is the GLES2 specific implementation of EGLContext.
17
18#include "Context.h"
19
20#include "main.h"
21#include "mathutil.h"
22#include "utilities.h"
23#include "ResourceManager.h"
24#include "Buffer.h"
25#include "Fence.h"
26#include "Framebuffer.h"
27#include "Program.h"
28#include "Query.h"
29#include "Renderbuffer.h"
30#include "Sampler.h"
31#include "Shader.h"
32#include "Texture.h"
33#include "TransformFeedback.h"
34#include "VertexArray.h"
35#include "VertexDataManager.h"
36#include "IndexDataManager.h"
37#include "libEGL/Display.h"
38#include "common/Surface.hpp"
39#include "Common/Half.hpp"
40
41#include <EGL/eglext.h>
42
43#include <algorithm>
44#include <string>
45
46namespace es2
47{
48Context::Context(egl::Display *display, const Context *shareContext, const egl::Config *config)
49 : egl::Context(display), config(config)
50{
51 sw::Context *context = new sw::Context();
52 device = new es2::Device(context);
53
54 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
55
56 mState.depthClearValue = 1.0f;
57 mState.stencilClearValue = 0;
58
59 mState.cullFaceEnabled = false;
60 mState.cullMode = GL_BACK;
61 mState.frontFace = GL_CCW;
62 mState.depthTestEnabled = false;
63 mState.depthFunc = GL_LESS;
64 mState.blendEnabled = false;
65 mState.sourceBlendRGB = GL_ONE;
66 mState.sourceBlendAlpha = GL_ONE;
67 mState.destBlendRGB = GL_ZERO;
68 mState.destBlendAlpha = GL_ZERO;
69 mState.blendEquationRGB = GL_FUNC_ADD;
70 mState.blendEquationAlpha = GL_FUNC_ADD;
71 mState.blendColor.red = 0;
72 mState.blendColor.green = 0;
73 mState.blendColor.blue = 0;
74 mState.blendColor.alpha = 0;
75 mState.stencilTestEnabled = false;
76 mState.stencilFunc = GL_ALWAYS;
77 mState.stencilRef = 0;
78 mState.stencilMask = 0xFFFFFFFFu;
79 mState.stencilWritemask = 0xFFFFFFFFu;
80 mState.stencilBackFunc = GL_ALWAYS;
81 mState.stencilBackRef = 0;
82 mState.stencilBackMask = 0xFFFFFFFFu;
83 mState.stencilBackWritemask = 0xFFFFFFFFu;
84 mState.stencilFail = GL_KEEP;
85 mState.stencilPassDepthFail = GL_KEEP;
86 mState.stencilPassDepthPass = GL_KEEP;
87 mState.stencilBackFail = GL_KEEP;
88 mState.stencilBackPassDepthFail = GL_KEEP;
89 mState.stencilBackPassDepthPass = GL_KEEP;
90 mState.polygonOffsetFillEnabled = false;
91 mState.polygonOffsetFactor = 0.0f;
92 mState.polygonOffsetUnits = 0.0f;
93 mState.sampleAlphaToCoverageEnabled = false;
94 mState.sampleCoverageEnabled = false;
95 mState.sampleCoverageValue = 1.0f;
96 mState.sampleCoverageInvert = false;
97 mState.scissorTestEnabled = false;
98 mState.ditherEnabled = true;
99 mState.primitiveRestartFixedIndexEnabled = false;
100 mState.rasterizerDiscardEnabled = false;
101 mState.generateMipmapHint = GL_DONT_CARE;
102 mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
103 mState.textureFilteringHint = GL_DONT_CARE;
104
105 mState.lineWidth = 1.0f;
106
107 mState.viewportX = 0;
108 mState.viewportY = 0;
109 mState.viewportWidth = 0;
110 mState.viewportHeight = 0;
111 mState.zNear = 0.0f;
112 mState.zFar = 1.0f;
113
114 mState.scissorX = 0;
115 mState.scissorY = 0;
116 mState.scissorWidth = 0;
117 mState.scissorHeight = 0;
118
119 mState.colorMaskRed = true;
120 mState.colorMaskGreen = true;
121 mState.colorMaskBlue = true;
122 mState.colorMaskAlpha = true;
123 mState.depthMask = true;
124
125 if(shareContext)
126 {
127 mResourceManager = shareContext->mResourceManager;
128 mResourceManager->addRef();
129 }
130 else
131 {
132 mResourceManager = new ResourceManager();
133 }
134
135 // [OpenGL ES 2.0.24] section 3.7 page 83:
136 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
137 // and cube map texture state vectors respectively associated with them.
138 // In order that access to these initial textures not be lost, they are treated as texture
139 // objects all of whose names are 0.
140
141 mTexture2DZero = new Texture2D(0);
142 mTexture3DZero = new Texture3D(0);
143 mTexture2DArrayZero = new Texture2DArray(0);
144 mTextureCubeMapZero = new TextureCubeMap(0);
145 mTexture2DRectZero = new Texture2DRect(0);
146 mTextureExternalZero = new TextureExternal(0);
147
148 mState.activeSampler = 0;
149
150 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
151 {
152 bindTexture((TextureType)type, 0);
153 }
154
155 bindVertexArray(0);
156 bindArrayBuffer(0);
157 bindElementArrayBuffer(0);
158 bindReadFramebuffer(0);
159 bindDrawFramebuffer(0);
160 bindRenderbuffer(0);
161 bindGenericUniformBuffer(0);
162 bindTransformFeedback(0);
163
164 mState.currentProgram = 0;
165
166 mVertexDataManager = nullptr;
167 mIndexDataManager = nullptr;
168
169 mInvalidEnum = false;
170 mInvalidValue = false;
171 mInvalidOperation = false;
172 mOutOfMemory = false;
173 mInvalidFramebufferOperation = false;
174
175 mHasBeenCurrent = false;
176
177 markAllStateDirty();
178}
179
180Context::~Context()
181{
182 if(mState.currentProgram != 0)
183 {
184 Program *programObject = mResourceManager->getProgram(mState.currentProgram);
185 if(programObject)
186 {
187 programObject->release();
188 }
189 mState.currentProgram = 0;
190 }
191
192 while(!mFramebufferNameSpace.empty())
193 {
194 deleteFramebuffer(mFramebufferNameSpace.firstName());
195 }
196
197 while(!mFenceNameSpace.empty())
198 {
199 deleteFence(mFenceNameSpace.firstName());
200 }
201
202 while(!mQueryNameSpace.empty())
203 {
204 deleteQuery(mQueryNameSpace.firstName());
205 }
206
207 while(!mVertexArrayNameSpace.empty())
208 {
209 deleteVertexArray(mVertexArrayNameSpace.lastName());
210 }
211
212 while(!mTransformFeedbackNameSpace.empty())
213 {
214 deleteTransformFeedback(mTransformFeedbackNameSpace.firstName());
215 }
216
217 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
218 {
219 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
220 {
221 mState.samplerTexture[type][sampler] = nullptr;
222 }
223 }
224
225 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
226 {
227 mState.vertexAttribute[i].mBoundBuffer = nullptr;
228 }
229
230 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
231 {
232 mState.activeQuery[i] = nullptr;
233 }
234
235 mState.arrayBuffer = nullptr;
236 mState.copyReadBuffer = nullptr;
237 mState.copyWriteBuffer = nullptr;
238 mState.pixelPackBuffer = nullptr;
239 mState.pixelUnpackBuffer = nullptr;
240 mState.genericUniformBuffer = nullptr;
241 mState.genericTransformFeedbackBuffer = nullptr;
242
243 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++) {
244 mState.uniformBuffers[i].set(nullptr, 0, 0);
245 }
246
247 mState.renderbuffer = nullptr;
248
249 for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
250 {
251 mState.sampler[i] = nullptr;
252 }
253
254 mTexture2DZero = nullptr;
255 mTexture3DZero = nullptr;
256 mTexture2DArrayZero = nullptr;
257 mTextureCubeMapZero = nullptr;
258 mTexture2DRectZero = nullptr;
259 mTextureExternalZero = nullptr;
260
261 delete mVertexDataManager;
262 delete mIndexDataManager;
263
264 mResourceManager->release();
265 delete device;
266}
267
268void Context::makeCurrent(gl::Surface *surface)
269{
270 if(!mHasBeenCurrent)
271 {
272 mVertexDataManager = new VertexDataManager(this);
273 mIndexDataManager = new IndexDataManager();
274
275 mState.viewportX = 0;
276 mState.viewportY = 0;
277 mState.viewportWidth = surface ? surface->getWidth() : 0;
278 mState.viewportHeight = surface ? surface->getHeight() : 0;
279
280 mState.scissorX = 0;
281 mState.scissorY = 0;
282 mState.scissorWidth = surface ? surface->getWidth() : 0;
283 mState.scissorHeight = surface ? surface->getHeight() : 0;
284
285 mHasBeenCurrent = true;
286 }
287
288 if(surface)
289 {
290 // Wrap the existing resources into GL objects and assign them to the '0' names
291 egl::Image *defaultRenderTarget = surface->getRenderTarget();
292 egl::Image *depthStencil = surface->getDepthStencil();
293
294 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
295 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
296 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
297
298 setFramebufferZero(framebufferZero);
299
300 if(defaultRenderTarget)
301 {
302 defaultRenderTarget->release();
303 }
304
305 if(depthStencil)
306 {
307 depthStencil->release();
308 }
309 }
310 else
311 {
312 setFramebufferZero(nullptr);
313 }
314
315 markAllStateDirty();
316}
317
318EGLint Context::getClientVersion() const
319{
320 return 3;
321}
322
323EGLint Context::getConfigID() const
324{
325 return config->mConfigID;
326}
327
328// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
329void Context::markAllStateDirty()
330{
331 mAppliedProgramSerial = 0;
332
333 mDepthStateDirty = true;
334 mMaskStateDirty = true;
335 mBlendStateDirty = true;
336 mStencilStateDirty = true;
337 mPolygonOffsetStateDirty = true;
338 mSampleStateDirty = true;
339 mDitherStateDirty = true;
340 mFrontFaceDirty = true;
341}
342
343void Context::setClearColor(float red, float green, float blue, float alpha)
344{
345 mState.colorClearValue.red = red;
346 mState.colorClearValue.green = green;
347 mState.colorClearValue.blue = blue;
348 mState.colorClearValue.alpha = alpha;
349}
350
351void Context::setClearDepth(float depth)
352{
353 mState.depthClearValue = depth;
354}
355
356void Context::setClearStencil(int stencil)
357{
358 mState.stencilClearValue = stencil;
359}
360
361void Context::setCullFaceEnabled(bool enabled)
362{
363 mState.cullFaceEnabled = enabled;
364}
365
366bool Context::isCullFaceEnabled() const
367{
368 return mState.cullFaceEnabled;
369}
370
371void Context::setCullMode(GLenum mode)
372{
373 mState.cullMode = mode;
374}
375
376void Context::setFrontFace(GLenum front)
377{
378 if(mState.frontFace != front)
379 {
380 mState.frontFace = front;
381 mFrontFaceDirty = true;
382 }
383}
384
385void Context::setDepthTestEnabled(bool enabled)
386{
387 if(mState.depthTestEnabled != enabled)
388 {
389 mState.depthTestEnabled = enabled;
390 mDepthStateDirty = true;
391 }
392}
393
394bool Context::isDepthTestEnabled() const
395{
396 return mState.depthTestEnabled;
397}
398
399void Context::setDepthFunc(GLenum depthFunc)
400{
401 if(mState.depthFunc != depthFunc)
402 {
403 mState.depthFunc = depthFunc;
404 mDepthStateDirty = true;
405 }
406}
407
408void Context::setDepthRange(float zNear, float zFar)
409{
410 mState.zNear = zNear;
411 mState.zFar = zFar;
412}
413
414void Context::setBlendEnabled(bool enabled)
415{
416 if(mState.blendEnabled != enabled)
417 {
418 mState.blendEnabled = enabled;
419 mBlendStateDirty = true;
420 }
421}
422
423bool Context::isBlendEnabled() const
424{
425 return mState.blendEnabled;
426}
427
428void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
429{
430 if(mState.sourceBlendRGB != sourceRGB ||
431 mState.sourceBlendAlpha != sourceAlpha ||
432 mState.destBlendRGB != destRGB ||
433 mState.destBlendAlpha != destAlpha)
434 {
435 mState.sourceBlendRGB = sourceRGB;
436 mState.destBlendRGB = destRGB;
437 mState.sourceBlendAlpha = sourceAlpha;
438 mState.destBlendAlpha = destAlpha;
439 mBlendStateDirty = true;
440 }
441}
442
443void Context::setBlendColor(float red, float green, float blue, float alpha)
444{
445 if(mState.blendColor.red != red ||
446 mState.blendColor.green != green ||
447 mState.blendColor.blue != blue ||
448 mState.blendColor.alpha != alpha)
449 {
450 mState.blendColor.red = red;
451 mState.blendColor.green = green;
452 mState.blendColor.blue = blue;
453 mState.blendColor.alpha = alpha;
454 mBlendStateDirty = true;
455 }
456}
457
458void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
459{
460 if(mState.blendEquationRGB != rgbEquation ||
461 mState.blendEquationAlpha != alphaEquation)
462 {
463 mState.blendEquationRGB = rgbEquation;
464 mState.blendEquationAlpha = alphaEquation;
465 mBlendStateDirty = true;
466 }
467}
468
469void Context::setStencilTestEnabled(bool enabled)
470{
471 if(mState.stencilTestEnabled != enabled)
472 {
473 mState.stencilTestEnabled = enabled;
474 mStencilStateDirty = true;
475 }
476}
477
478bool Context::isStencilTestEnabled() const
479{
480 return mState.stencilTestEnabled;
481}
482
483void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
484{
485 if(mState.stencilFunc != stencilFunc ||
486 mState.stencilRef != stencilRef ||
487 mState.stencilMask != stencilMask)
488 {
489 mState.stencilFunc = stencilFunc;
490 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
491 mState.stencilMask = stencilMask;
492 mStencilStateDirty = true;
493 }
494}
495
496void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
497{
498 if(mState.stencilBackFunc != stencilBackFunc ||
499 mState.stencilBackRef != stencilBackRef ||
500 mState.stencilBackMask != stencilBackMask)
501 {
502 mState.stencilBackFunc = stencilBackFunc;
503 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
504 mState.stencilBackMask = stencilBackMask;
505 mStencilStateDirty = true;
506 }
507}
508
509void Context::setStencilWritemask(GLuint stencilWritemask)
510{
511 if(mState.stencilWritemask != stencilWritemask)
512 {
513 mState.stencilWritemask = stencilWritemask;
514 mStencilStateDirty = true;
515 }
516}
517
518void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
519{
520 if(mState.stencilBackWritemask != stencilBackWritemask)
521 {
522 mState.stencilBackWritemask = stencilBackWritemask;
523 mStencilStateDirty = true;
524 }
525}
526
527void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
528{
529 if(mState.stencilFail != stencilFail ||
530 mState.stencilPassDepthFail != stencilPassDepthFail ||
531 mState.stencilPassDepthPass != stencilPassDepthPass)
532 {
533 mState.stencilFail = stencilFail;
534 mState.stencilPassDepthFail = stencilPassDepthFail;
535 mState.stencilPassDepthPass = stencilPassDepthPass;
536 mStencilStateDirty = true;
537 }
538}
539
540void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
541{
542 if(mState.stencilBackFail != stencilBackFail ||
543 mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
544 mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
545 {
546 mState.stencilBackFail = stencilBackFail;
547 mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
548 mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
549 mStencilStateDirty = true;
550 }
551}
552
553void Context::setPolygonOffsetFillEnabled(bool enabled)
554{
555 if(mState.polygonOffsetFillEnabled != enabled)
556 {
557 mState.polygonOffsetFillEnabled = enabled;
558 mPolygonOffsetStateDirty = true;
559 }
560}
561
562bool Context::isPolygonOffsetFillEnabled() const
563{
564 return mState.polygonOffsetFillEnabled;
565}
566
567void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
568{
569 if(mState.polygonOffsetFactor != factor ||
570 mState.polygonOffsetUnits != units)
571 {
572 mState.polygonOffsetFactor = factor;
573 mState.polygonOffsetUnits = units;
574 mPolygonOffsetStateDirty = true;
575 }
576}
577
578void Context::setSampleAlphaToCoverageEnabled(bool enabled)
579{
580 if(mState.sampleAlphaToCoverageEnabled != enabled)
581 {
582 mState.sampleAlphaToCoverageEnabled = enabled;
583 mSampleStateDirty = true;
584 }
585}
586
587bool Context::isSampleAlphaToCoverageEnabled() const
588{
589 return mState.sampleAlphaToCoverageEnabled;
590}
591
592void Context::setSampleCoverageEnabled(bool enabled)
593{
594 if(mState.sampleCoverageEnabled != enabled)
595 {
596 mState.sampleCoverageEnabled = enabled;
597 mSampleStateDirty = true;
598 }
599}
600
601bool Context::isSampleCoverageEnabled() const
602{
603 return mState.sampleCoverageEnabled;
604}
605
606void Context::setSampleCoverageParams(GLclampf value, bool invert)
607{
608 if(mState.sampleCoverageValue != value ||
609 mState.sampleCoverageInvert != invert)
610 {
611 mState.sampleCoverageValue = value;
612 mState.sampleCoverageInvert = invert;
613 mSampleStateDirty = true;
614 }
615}
616
617void Context::setScissorTestEnabled(bool enabled)
618{
619 mState.scissorTestEnabled = enabled;
620}
621
622bool Context::isScissorTestEnabled() const
623{
624 return mState.scissorTestEnabled;
625}
626
627void Context::setDitherEnabled(bool enabled)
628{
629 if(mState.ditherEnabled != enabled)
630 {
631 mState.ditherEnabled = enabled;
632 mDitherStateDirty = true;
633 }
634}
635
636bool Context::isDitherEnabled() const
637{
638 return mState.ditherEnabled;
639}
640
641void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)
642{
643 mState.primitiveRestartFixedIndexEnabled = enabled;
644}
645
646bool Context::isPrimitiveRestartFixedIndexEnabled() const
647{
648 return mState.primitiveRestartFixedIndexEnabled;
649}
650
651void Context::setRasterizerDiscardEnabled(bool enabled)
652{
653 mState.rasterizerDiscardEnabled = enabled;
654}
655
656bool Context::isRasterizerDiscardEnabled() const
657{
658 return mState.rasterizerDiscardEnabled;
659}
660
661void Context::setLineWidth(GLfloat width)
662{
663 mState.lineWidth = width;
664 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
665}
666
667void Context::setGenerateMipmapHint(GLenum hint)
668{
669 mState.generateMipmapHint = hint;
670}
671
672void Context::setFragmentShaderDerivativeHint(GLenum hint)
673{
674 mState.fragmentShaderDerivativeHint = hint;
675 // TODO: Propagate the hint to shader translator so we can write
676 // ddx, ddx_coarse, or ddx_fine depending on the hint.
677 // Ignore for now. It is valid for implementations to ignore hint.
678}
679
680void Context::setTextureFilteringHint(GLenum hint)
681{
682 mState.textureFilteringHint = hint;
683}
684
685void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
686{
687 mState.viewportX = x;
688 mState.viewportY = y;
689 mState.viewportWidth = std::min<GLsizei>(width, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE); // GL_MAX_VIEWPORT_DIMS[0]
690 mState.viewportHeight = std::min<GLsizei>(height, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE); // GL_MAX_VIEWPORT_DIMS[1]
691}
692
693void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
694{
695 mState.scissorX = x;
696 mState.scissorY = y;
697
698 // An overflow happens when (infinite precision) X + Width > INT32_MAX. We
699 // can change that formula to "X > INT32_MAX - Width". And when we bring it
700 // down to 32-bit precision, we know it's safe because width is non-negative.
701 if (x > INT32_MAX - width)
702 {
703 width = INT32_MAX - x;
704 }
705
706 if (y > INT32_MAX - height)
707 {
708 height = INT32_MAX - y;
709 }
710
711 mState.scissorWidth = width;
712 mState.scissorHeight = height;
713}
714
715void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
716{
717 if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
718 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
719 {
720 mState.colorMaskRed = red;
721 mState.colorMaskGreen = green;
722 mState.colorMaskBlue = blue;
723 mState.colorMaskAlpha = alpha;
724 mMaskStateDirty = true;
725 }
726}
727
728unsigned int Context::getColorMask() const
729{
730 return (mState.colorMaskRed ? 0x1 : 0) |
731 (mState.colorMaskGreen ? 0x2 : 0) |
732 (mState.colorMaskBlue ? 0x4 : 0) |
733 (mState.colorMaskAlpha ? 0x8 : 0);
734}
735
736void Context::setDepthMask(bool mask)
737{
738 if(mState.depthMask != mask)
739 {
740 mState.depthMask = mask;
741 mMaskStateDirty = true;
742 }
743}
744
745void Context::setActiveSampler(unsigned int active)
746{
747 mState.activeSampler = active;
748}
749
750GLuint Context::getReadFramebufferName() const
751{
752 return mState.readFramebuffer;
753}
754
755GLuint Context::getDrawFramebufferName() const
756{
757 return mState.drawFramebuffer;
758}
759
760GLuint Context::getRenderbufferName() const
761{
762 return mState.renderbuffer.name();
763}
764
765void Context::setFramebufferReadBuffer(GLuint buf)
766{
767 Framebuffer *framebuffer = getReadFramebuffer();
768
769 if(framebuffer)
770 {
771 framebuffer->setReadBuffer(buf);
772 }
773 else
774 {
775 return error(GL_INVALID_OPERATION);
776 }
777}
778
779void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
780{
781 Framebuffer *drawFramebuffer = getDrawFramebuffer();
782
783 if(drawFramebuffer)
784 {
785 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
786 {
787 drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
788 }
789 }
790 else
791 {
792 return error(GL_INVALID_OPERATION);
793 }
794}
795
796GLuint Context::getArrayBufferName() const
797{
798 return mState.arrayBuffer.name();
799}
800
801GLuint Context::getElementArrayBufferName() const
802{
803 Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();
804 return elementArrayBuffer ? elementArrayBuffer->name : 0;
805}
806
807GLuint Context::getActiveQuery(GLenum target) const
808{
809 Query *queryObject = nullptr;
810
811 switch(target)
812 {
813 case GL_ANY_SAMPLES_PASSED_EXT:
814 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
815 break;
816 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
817 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
818 break;
819 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
820 queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];
821 break;
822 default:
823 ASSERT(false);
824 }
825
826 if(queryObject)
827 {
828 return queryObject->name;
829 }
830
831 return 0;
832}
833
834void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
835{
836 getCurrentVertexArray()->enableAttribute(attribNum, enabled);
837}
838
839void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
840{
841 getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);
842}
843
844const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
845{
846 return getCurrentVertexArray()->getVertexAttribute(attribNum);
847}
848
849void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
850 bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
851{
852 getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
853}
854
855const void *Context::getVertexAttribPointer(unsigned int attribNum) const
856{
857 return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
858}
859
860const VertexAttributeArray &Context::getVertexArrayAttributes()
861{
862 return getCurrentVertexArray()->getVertexAttributes();
863}
864
865const VertexAttributeArray &Context::getCurrentVertexAttributes()
866{
867 return mState.vertexAttribute;
868}
869
870void Context::setPackAlignment(GLint alignment)
871{
872 mState.packParameters.alignment = alignment;
873}
874
875void Context::setUnpackAlignment(GLint alignment)
876{
877 mState.unpackParameters.alignment = alignment;
878}
879
880const gl::PixelStorageModes &Context::getUnpackParameters() const
881{
882 return mState.unpackParameters;
883}
884
885void Context::setPackRowLength(GLint rowLength)
886{
887 mState.packParameters.rowLength = rowLength;
888}
889
890void Context::setPackSkipPixels(GLint skipPixels)
891{
892 mState.packParameters.skipPixels = skipPixels;
893}
894
895void Context::setPackSkipRows(GLint skipRows)
896{
897 mState.packParameters.skipRows = skipRows;
898}
899
900void Context::setUnpackRowLength(GLint rowLength)
901{
902 mState.unpackParameters.rowLength = rowLength;
903}
904
905void Context::setUnpackImageHeight(GLint imageHeight)
906{
907 mState.unpackParameters.imageHeight = imageHeight;
908}
909
910void Context::setUnpackSkipPixels(GLint skipPixels)
911{
912 mState.unpackParameters.skipPixels = skipPixels;
913}
914
915void Context::setUnpackSkipRows(GLint skipRows)
916{
917 mState.unpackParameters.skipRows = skipRows;
918}
919
920void Context::setUnpackSkipImages(GLint skipImages)
921{
922 mState.unpackParameters.skipImages = skipImages;
923}
924
925GLuint Context::createBuffer()
926{
927 return mResourceManager->createBuffer();
928}
929
930GLuint Context::createProgram()
931{
932 return mResourceManager->createProgram();
933}
934
935GLuint Context::createShader(GLenum type)
936{
937 return mResourceManager->createShader(type);
938}
939
940GLuint Context::createTexture()
941{
942 return mResourceManager->createTexture();
943}
944
945GLuint Context::createRenderbuffer()
946{
947 return mResourceManager->createRenderbuffer();
948}
949
950// Returns an unused framebuffer name
951GLuint Context::createFramebuffer()
952{
953 return mFramebufferNameSpace.allocate();
954}
955
956GLuint Context::createFence()
957{
958 return mFenceNameSpace.allocate(new Fence());
959}
960
961// Returns an unused query name
962GLuint Context::createQuery()
963{
964 return mQueryNameSpace.allocate();
965}
966
967// Returns an unused vertex array name
968GLuint Context::createVertexArray()
969{
970 return mVertexArrayNameSpace.allocate();
971}
972
973GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
974{
975 GLuint handle = mResourceManager->createFenceSync(condition, flags);
976
977 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
978}
979
980// Returns an unused transform feedback name
981GLuint Context::createTransformFeedback()
982{
983 return mTransformFeedbackNameSpace.allocate();
984}
985
986// Returns an unused sampler name
987GLuint Context::createSampler()
988{
989 return mResourceManager->createSampler();
990}
991
992void Context::deleteBuffer(GLuint buffer)
993{
994 detachBuffer(buffer);
995
996 mResourceManager->deleteBuffer(buffer);
997}
998
999void Context::deleteShader(GLuint shader)
1000{
1001 mResourceManager->deleteShader(shader);
1002}
1003
1004void Context::deleteProgram(GLuint program)
1005{
1006 mResourceManager->deleteProgram(program);
1007}
1008
1009void Context::deleteTexture(GLuint texture)
1010{
1011 detachTexture(texture);
1012
1013 mResourceManager->deleteTexture(texture);
1014}
1015
1016void Context::deleteRenderbuffer(GLuint renderbuffer)
1017{
1018 if(mResourceManager->getRenderbuffer(renderbuffer))
1019 {
1020 detachRenderbuffer(renderbuffer);
1021 }
1022
1023 mResourceManager->deleteRenderbuffer(renderbuffer);
1024}
1025
1026void Context::deleteFramebuffer(GLuint framebuffer)
1027{
1028 detachFramebuffer(framebuffer);
1029
1030 Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
1031
1032 if(framebufferObject)
1033 {
1034 delete framebufferObject;
1035 }
1036}
1037
1038void Context::deleteFence(GLuint fence)
1039{
1040 Fence *fenceObject = mFenceNameSpace.remove(fence);
1041
1042 if(fenceObject)
1043 {
1044 delete fenceObject;
1045 }
1046}
1047
1048void Context::deleteQuery(GLuint query)
1049{
1050 Query *queryObject = mQueryNameSpace.remove(query);
1051
1052 if(queryObject)
1053 {
1054 queryObject->release();
1055 }
1056}
1057
1058void Context::deleteVertexArray(GLuint vertexArray)
1059{
1060 // [OpenGL ES 3.0.2] section 2.10 page 43:
1061 // If a vertex array object that is currently bound is deleted, the binding
1062 // for that object reverts to zero and the default vertex array becomes current.
1063 if(getCurrentVertexArray()->name == vertexArray)
1064 {
1065 bindVertexArray(0);
1066 }
1067
1068 VertexArray *vertexArrayObject = mVertexArrayNameSpace.remove(vertexArray);
1069
1070 if(vertexArrayObject)
1071 {
1072 delete vertexArrayObject;
1073 }
1074}
1075
1076void Context::deleteFenceSync(GLsync fenceSync)
1077{
1078 // The spec specifies the underlying Fence object is not deleted until all current
1079 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
1080 // and since our API is currently designed for being called from a single thread, we can delete
1081 // the fence immediately.
1082 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
1083}
1084
1085void Context::deleteTransformFeedback(GLuint transformFeedback)
1086{
1087 TransformFeedback *transformFeedbackObject = mTransformFeedbackNameSpace.remove(transformFeedback);
1088
1089 // Detach if currently bound.
1090 if(mState.transformFeedback == transformFeedback)
1091 {
1092 mState.transformFeedback = 0;
1093 }
1094
1095 if(transformFeedbackObject)
1096 {
1097 delete transformFeedbackObject;
1098 }
1099}
1100
1101void Context::deleteSampler(GLuint sampler)
1102{
1103 detachSampler(sampler);
1104
1105 mResourceManager->deleteSampler(sampler);
1106}
1107
1108Buffer *Context::getBuffer(GLuint handle) const
1109{
1110 return mResourceManager->getBuffer(handle);
1111}
1112
1113Shader *Context::getShader(GLuint handle) const
1114{
1115 return mResourceManager->getShader(handle);
1116}
1117
1118Program *Context::getProgram(GLuint handle) const
1119{
1120 return mResourceManager->getProgram(handle);
1121}
1122
1123Texture *Context::getTexture(GLuint handle) const
1124{
1125 return mResourceManager->getTexture(handle);
1126}
1127
1128Renderbuffer *Context::getRenderbuffer(GLuint handle) const
1129{
1130 return mResourceManager->getRenderbuffer(handle);
1131}
1132
1133Framebuffer *Context::getReadFramebuffer() const
1134{
1135 return getFramebuffer(mState.readFramebuffer);
1136}
1137
1138Framebuffer *Context::getDrawFramebuffer() const
1139{
1140 return getFramebuffer(mState.drawFramebuffer);
1141}
1142
1143void Context::bindArrayBuffer(unsigned int buffer)
1144{
1145 mResourceManager->checkBufferAllocation(buffer);
1146
1147 mState.arrayBuffer = getBuffer(buffer);
1148}
1149
1150void Context::bindElementArrayBuffer(unsigned int buffer)
1151{
1152 mResourceManager->checkBufferAllocation(buffer);
1153
1154 getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
1155}
1156
1157void Context::bindCopyReadBuffer(GLuint buffer)
1158{
1159 mResourceManager->checkBufferAllocation(buffer);
1160
1161 mState.copyReadBuffer = getBuffer(buffer);
1162}
1163
1164void Context::bindCopyWriteBuffer(GLuint buffer)
1165{
1166 mResourceManager->checkBufferAllocation(buffer);
1167
1168 mState.copyWriteBuffer = getBuffer(buffer);
1169}
1170
1171void Context::bindPixelPackBuffer(GLuint buffer)
1172{
1173 mResourceManager->checkBufferAllocation(buffer);
1174
1175 mState.pixelPackBuffer = getBuffer(buffer);
1176}
1177
1178void Context::bindPixelUnpackBuffer(GLuint buffer)
1179{
1180 mResourceManager->checkBufferAllocation(buffer);
1181
1182 mState.pixelUnpackBuffer = getBuffer(buffer);
1183}
1184
1185void Context::bindTransformFeedbackBuffer(GLuint buffer)
1186{
1187 mResourceManager->checkBufferAllocation(buffer);
1188
1189 mState.genericTransformFeedbackBuffer = getBuffer(buffer);
1190}
1191
1192void Context::bindTexture(TextureType type, GLuint texture)
1193{
1194 mResourceManager->checkTextureAllocation(texture, type);
1195
1196 mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
1197}
1198
1199void Context::bindReadFramebuffer(GLuint framebuffer)
1200{
1201 if(!getFramebuffer(framebuffer))
1202 {
1203 if(framebuffer == 0)
1204 {
1205 mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1206 }
1207 else
1208 {
1209 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1210 }
1211 }
1212
1213 mState.readFramebuffer = framebuffer;
1214}
1215
1216void Context::bindDrawFramebuffer(GLuint framebuffer)
1217{
1218 if(!getFramebuffer(framebuffer))
1219 {
1220 if(framebuffer == 0)
1221 {
1222 mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1223 }
1224 else
1225 {
1226 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1227 }
1228 }
1229
1230 mState.drawFramebuffer = framebuffer;
1231}
1232
1233void Context::bindRenderbuffer(GLuint renderbuffer)
1234{
1235 mResourceManager->checkRenderbufferAllocation(renderbuffer);
1236
1237 mState.renderbuffer = getRenderbuffer(renderbuffer);
1238}
1239
1240void Context::bindVertexArray(GLuint array)
1241{
1242 VertexArray *vertexArray = getVertexArray(array);
1243
1244 if(!vertexArray)
1245 {
1246 vertexArray = new VertexArray(array);
1247 mVertexArrayNameSpace.insert(array, vertexArray);
1248 }
1249
1250 mState.vertexArray = array;
1251}
1252
1253void Context::bindGenericUniformBuffer(GLuint buffer)
1254{
1255 mResourceManager->checkBufferAllocation(buffer);
1256
1257 mState.genericUniformBuffer = getBuffer(buffer);
1258}
1259
1260void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1261{
1262 mResourceManager->checkBufferAllocation(buffer);
1263
1264 Buffer* bufferObject = getBuffer(buffer);
1265 mState.uniformBuffers[index].set(bufferObject, static_cast<int>(offset), static_cast<int>(size));
1266}
1267
1268void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1269{
1270 mResourceManager->checkBufferAllocation(buffer);
1271
1272 mState.genericTransformFeedbackBuffer = getBuffer(buffer);
1273}
1274
1275void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1276{
1277 mResourceManager->checkBufferAllocation(buffer);
1278
1279 Buffer* bufferObject = getBuffer(buffer);
1280 getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
1281 mState.genericTransformFeedbackBuffer = bufferObject;
1282}
1283
1284void Context::bindTransformFeedback(GLuint id)
1285{
1286 if(!getTransformFeedback(id))
1287 {
1288 mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));
1289 }
1290
1291 mState.transformFeedback = id;
1292}
1293
1294bool Context::bindSampler(GLuint unit, GLuint sampler)
1295{
1296 mResourceManager->checkSamplerAllocation(sampler);
1297
1298 Sampler* samplerObject = getSampler(sampler);
1299
1300 mState.sampler[unit] = samplerObject;
1301
1302 return !!samplerObject;
1303}
1304
1305void Context::useProgram(GLuint program)
1306{
1307 GLuint priorProgram = mState.currentProgram;
1308 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
1309
1310 if(priorProgram != program)
1311 {
1312 Program *newProgram = mResourceManager->getProgram(program);
1313 Program *oldProgram = mResourceManager->getProgram(priorProgram);
1314
1315 if(newProgram)
1316 {
1317 newProgram->addRef();
1318 }
1319
1320 if(oldProgram)
1321 {
1322 oldProgram->release();
1323 }
1324 }
1325}
1326
1327void Context::beginQuery(GLenum target, GLuint query)
1328{
1329 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1330 // of zero, if the active query object name for <target> is non-zero (for the
1331 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1332 // the active query for either target is non-zero), if <id> is the name of an
1333 // existing query object whose type does not match <target>, or if <id> is the
1334 // active query object name for any query type, the error INVALID_OPERATION is
1335 // generated.
1336
1337 // Ensure no other queries are active
1338 // NOTE: If other queries than occlusion are supported, we will need to check
1339 // separately that:
1340 // a) The query ID passed is not the current active query for any target/type
1341 // b) There are no active queries for the requested target (and in the case
1342 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1343 // no query may be active for either if glBeginQuery targets either.
1344 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1345 {
1346 if(mState.activeQuery[i])
1347 {
1348 switch(mState.activeQuery[i]->getType())
1349 {
1350 case GL_ANY_SAMPLES_PASSED_EXT:
1351 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1352 if((target == GL_ANY_SAMPLES_PASSED_EXT) ||
1353 (target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT))
1354 {
1355 return error(GL_INVALID_OPERATION);
1356 }
1357 break;
1358 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1359 if(target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)
1360 {
1361 return error(GL_INVALID_OPERATION);
1362 }
1363 break;
1364 default:
1365 break;
1366 }
1367 }
1368 }
1369
1370 QueryType qType;
1371 switch(target)
1372 {
1373 case GL_ANY_SAMPLES_PASSED_EXT:
1374 qType = QUERY_ANY_SAMPLES_PASSED;
1375 break;
1376 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1377 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1378 break;
1379 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1380 qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1381 break;
1382 default:
1383 UNREACHABLE(target);
1384 return error(GL_INVALID_ENUM);
1385 }
1386
1387 Query *queryObject = createQuery(query, target);
1388
1389 // Check that name was obtained with glGenQueries
1390 if(!queryObject)
1391 {
1392 return error(GL_INVALID_OPERATION);
1393 }
1394
1395 // Check for type mismatch
1396 if(queryObject->getType() != target)
1397 {
1398 return error(GL_INVALID_OPERATION);
1399 }
1400
1401 // Set query as active for specified target
1402 mState.activeQuery[qType] = queryObject;
1403
1404 // Begin query
1405 queryObject->begin();
1406}
1407
1408void Context::endQuery(GLenum target)
1409{
1410 QueryType qType;
1411
1412 switch(target)
1413 {
1414 case GL_ANY_SAMPLES_PASSED_EXT: qType = QUERY_ANY_SAMPLES_PASSED; break;
1415 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; break;
1416 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
1417 default: UNREACHABLE(target); return;
1418 }
1419
1420 Query *queryObject = mState.activeQuery[qType];
1421
1422 if(!queryObject)
1423 {
1424 return error(GL_INVALID_OPERATION);
1425 }
1426
1427 queryObject->end();
1428
1429 mState.activeQuery[qType] = nullptr;
1430}
1431
1432void Context::setFramebufferZero(Framebuffer *buffer)
1433{
1434 delete mFramebufferNameSpace.remove(0);
1435 mFramebufferNameSpace.insert(0, buffer);
1436}
1437
1438void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1439{
1440 Renderbuffer *renderbufferObject = mState.renderbuffer;
1441 renderbufferObject->setStorage(renderbuffer);
1442}
1443
1444Framebuffer *Context::getFramebuffer(unsigned int handle) const
1445{
1446 return mFramebufferNameSpace.find(handle);
1447}
1448
1449Fence *Context::getFence(unsigned int handle) const
1450{
1451 return mFenceNameSpace.find(handle);
1452}
1453
1454FenceSync *Context::getFenceSync(GLsync handle) const
1455{
1456 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
1457}
1458
1459Query *Context::getQuery(unsigned int handle) const
1460{
1461 return mQueryNameSpace.find(handle);
1462}
1463
1464Query *Context::createQuery(unsigned int handle, GLenum type)
1465{
1466 if(!mQueryNameSpace.isReserved(handle))
1467 {
1468 return nullptr;
1469 }
1470 else
1471 {
1472 Query *query = mQueryNameSpace.find(handle);
1473 if(!query)
1474 {
1475 query = new Query(handle, type);
1476 query->addRef();
1477 mQueryNameSpace.insert(handle, query);
1478 }
1479
1480 return query;
1481 }
1482}
1483
1484VertexArray *Context::getVertexArray(GLuint array) const
1485{
1486 return mVertexArrayNameSpace.find(array);
1487}
1488
1489VertexArray *Context::getCurrentVertexArray() const
1490{
1491 return getVertexArray(mState.vertexArray);
1492}
1493
1494bool Context::isVertexArray(GLuint array) const
1495{
1496 return mVertexArrayNameSpace.isReserved(array);
1497}
1498
1499bool Context::hasZeroDivisor() const
1500{
1501 // Verify there is at least one active attribute with a divisor of zero
1502 es2::Program *programObject = getCurrentProgram();
1503 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
1504 {
1505 bool active = (programObject->getAttributeStream(attributeIndex) != -1);
1506 if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
1507 {
1508 return true;
1509 }
1510 }
1511
1512 return false;
1513}
1514
1515TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
1516{
1517 return mTransformFeedbackNameSpace.find(transformFeedback);
1518}
1519
1520bool Context::isTransformFeedback(GLuint array) const
1521{
1522 return mTransformFeedbackNameSpace.isReserved(array);
1523}
1524
1525Sampler *Context::getSampler(GLuint sampler) const
1526{
1527 return mResourceManager->getSampler(sampler);
1528}
1529
1530bool Context::isSampler(GLuint sampler) const
1531{
1532 return mResourceManager->isSampler(sampler);
1533}
1534
1535Buffer *Context::getArrayBuffer() const
1536{
1537 return mState.arrayBuffer;
1538}
1539
1540Buffer *Context::getElementArrayBuffer() const
1541{
1542 return getCurrentVertexArray()->getElementArrayBuffer();
1543}
1544
1545Buffer *Context::getCopyReadBuffer() const
1546{
1547 return mState.copyReadBuffer;
1548}
1549
1550Buffer *Context::getCopyWriteBuffer() const
1551{
1552 return mState.copyWriteBuffer;
1553}
1554
1555Buffer *Context::getPixelPackBuffer() const
1556{
1557 return mState.pixelPackBuffer;
1558}
1559
1560Buffer *Context::getPixelUnpackBuffer() const
1561{
1562 return mState.pixelUnpackBuffer;
1563}
1564
1565Buffer *Context::getGenericUniformBuffer() const
1566{
1567 return mState.genericUniformBuffer;
1568}
1569
1570// The "required buffer size" is the number of bytes from the start of the
1571// buffer to the last byte referenced within the buffer. If the caller of this
1572// function has to worry about offsets within the buffer, it only needs to add
1573// that byte offset to this function's return value to get its required buffer
1574// size.
1575size_t Context::getRequiredBufferSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type) const
1576{
1577 // 0-dimensional images have no bytes in them.
1578 if (width == 0 || height == 0 || depth == 0)
1579 {
1580 return 0;
1581 }
1582
1583 GLint pixelsPerRow = (mState.unpackParameters.rowLength) > 0 ? mState.unpackParameters.rowLength : width;
1584 GLint rowsPerImage = (mState.unpackParameters.imageHeight) > 0 ? mState.unpackParameters.imageHeight : height;
1585
1586 GLint bytesPerPixel = gl::ComputePixelSize(format, type);
1587 GLint bytesPerRow = gl::ComputePitch(pixelsPerRow, format, type, mState.unpackParameters.alignment);
1588 GLint bytesPerImage = rowsPerImage * bytesPerRow;
1589
1590 // Depth and height are subtracted by 1, while width is not, because we're not
1591 // reading the full last row or image, but we are reading the full last pixel.
1592 return (mState.unpackParameters.skipImages + (depth - 1)) * bytesPerImage
1593 + (mState.unpackParameters.skipRows + (height - 1)) * bytesPerRow
1594 + (mState.unpackParameters.skipPixels + (width)) * bytesPerPixel;
1595}
1596
1597GLenum Context::getPixels(const GLvoid **pixels, GLenum type, size_t imageSize) const
1598{
1599 if(mState.pixelUnpackBuffer)
1600 {
1601 ASSERT(mState.pixelUnpackBuffer->name != 0);
1602
1603 if(mState.pixelUnpackBuffer->isMapped())
1604 {
1605 return GL_INVALID_OPERATION;
1606 }
1607
1608 size_t offset = static_cast<size_t>((ptrdiff_t)(*pixels));
1609
1610 if(offset % GetTypeSize(type) != 0)
1611 {
1612 return GL_INVALID_OPERATION;
1613 }
1614
1615 if(offset > mState.pixelUnpackBuffer->size())
1616 {
1617 return GL_INVALID_OPERATION;
1618 }
1619
1620 if(mState.pixelUnpackBuffer->size() - offset < imageSize)
1621 {
1622 return GL_INVALID_OPERATION;
1623 }
1624
1625 *pixels = static_cast<const unsigned char*>(mState.pixelUnpackBuffer->data()) + offset;
1626 }
1627
1628 return GL_NO_ERROR;
1629}
1630
1631bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
1632{
1633 switch(target)
1634 {
1635 case GL_ARRAY_BUFFER:
1636 *buffer = getArrayBuffer();
1637 break;
1638 case GL_ELEMENT_ARRAY_BUFFER:
1639 *buffer = getElementArrayBuffer();
1640 break;
1641 case GL_COPY_READ_BUFFER:
1642 *buffer = getCopyReadBuffer();
1643 break;
1644 case GL_COPY_WRITE_BUFFER:
1645 *buffer = getCopyWriteBuffer();
1646 break;
1647 case GL_PIXEL_PACK_BUFFER:
1648 *buffer = getPixelPackBuffer();
1649 break;
1650 case GL_PIXEL_UNPACK_BUFFER:
1651 *buffer = getPixelUnpackBuffer();
1652 break;
1653 case GL_TRANSFORM_FEEDBACK_BUFFER:
1654 *buffer = static_cast<es2::Buffer*>(mState.genericTransformFeedbackBuffer);
1655 break;
1656 case GL_UNIFORM_BUFFER:
1657 *buffer = getGenericUniformBuffer();
1658 break;
1659 default:
1660 return false;
1661 }
1662 return true;
1663}
1664
1665TransformFeedback *Context::getTransformFeedback() const
1666{
1667 return getTransformFeedback(mState.transformFeedback);
1668}
1669
1670Program *Context::getCurrentProgram() const
1671{
1672 return mResourceManager->getProgram(mState.currentProgram);
1673}
1674
1675Texture *Context::getTargetTexture(GLenum target) const
1676{
1677 Texture *texture = nullptr;
1678
1679 switch(target)
1680 {
1681 case GL_TEXTURE_2D: texture = getTexture2D(); break;
1682 case GL_TEXTURE_2D_ARRAY: texture = getTexture2DArray(); break;
1683 case GL_TEXTURE_3D: texture = getTexture3D(); break;
1684 case GL_TEXTURE_CUBE_MAP: texture = getTextureCubeMap(); break;
1685 case GL_TEXTURE_EXTERNAL_OES: texture = getTextureExternal(); break;
1686 case GL_TEXTURE_RECTANGLE_ARB: texture = getTexture2DRect(); break;
1687 default:
1688 return error(GL_INVALID_ENUM, nullptr);
1689 }
1690
1691 ASSERT(texture); // Must always have a default texture to fall back to.
1692
1693 return texture;
1694}
1695
1696Texture2D *Context::getTexture2D() const
1697{
1698 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1699}
1700
1701Texture2D *Context::getTexture2D(GLenum target) const
1702{
1703 switch(target)
1704 {
1705 case GL_TEXTURE_2D: return getTexture2D();
1706 case GL_TEXTURE_RECTANGLE_ARB: return getTexture2DRect();
1707 case GL_TEXTURE_EXTERNAL_OES: return getTextureExternal();
1708 default: UNREACHABLE(target);
1709 }
1710
1711 return nullptr;
1712}
1713
1714Texture3D *Context::getTexture3D() const
1715{
1716 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1717}
1718
1719Texture2DArray *Context::getTexture2DArray() const
1720{
1721 return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1722}
1723
1724TextureCubeMap *Context::getTextureCubeMap() const
1725{
1726 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1727}
1728
1729Texture2DRect *Context::getTexture2DRect() const
1730{
1731 return static_cast<Texture2DRect*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_RECT));
1732}
1733
1734TextureExternal *Context::getTextureExternal() const
1735{
1736 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1737}
1738
1739Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1740{
1741 GLuint texid = mState.samplerTexture[type][sampler].name();
1742
1743 if(texid == 0) // Special case: 0 refers to different initial textures based on the target
1744 {
1745 switch(type)
1746 {
1747 case TEXTURE_2D: return mTexture2DZero;
1748 case TEXTURE_3D: return mTexture3DZero;
1749 case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
1750 case TEXTURE_CUBE: return mTextureCubeMapZero;
1751 case TEXTURE_2D_RECT: return mTexture2DRectZero;
1752 case TEXTURE_EXTERNAL: return mTextureExternalZero;
1753 default: UNREACHABLE(type);
1754 }
1755 }
1756
1757 return mState.samplerTexture[type][sampler];
1758}
1759
1760void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1761{
1762 mResourceManager->checkSamplerAllocation(sampler);
1763
1764 Sampler *samplerObject = getSampler(sampler);
1765 ASSERT(samplerObject);
1766
1767 switch(pname)
1768 {
1769 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1770 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1771 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1772 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1773 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1774 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1775 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1776 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1777 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1778 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(static_cast<GLfloat>(param)); break;
1779 default: UNREACHABLE(pname); break;
1780 }
1781}
1782
1783void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1784{
1785 mResourceManager->checkSamplerAllocation(sampler);
1786
1787 Sampler *samplerObject = getSampler(sampler);
1788 ASSERT(samplerObject);
1789
1790 switch(pname)
1791 {
1792 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(roundf(param))); break;
1793 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(roundf(param))); break;
1794 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(roundf(param))); break;
1795 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(roundf(param))); break;
1796 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(roundf(param))); break;
1797 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1798 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1799 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(roundf(param))); break;
1800 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(roundf(param))); break;
1801 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(param); break;
1802 default: UNREACHABLE(pname); break;
1803 }
1804}
1805
1806GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1807{
1808 mResourceManager->checkSamplerAllocation(sampler);
1809
1810 Sampler *samplerObject = getSampler(sampler);
1811 ASSERT(samplerObject);
1812
1813 switch(pname)
1814 {
1815 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1816 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1817 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1818 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1819 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1820 case GL_TEXTURE_MIN_LOD: return static_cast<GLint>(roundf(samplerObject->getMinLod()));
1821 case GL_TEXTURE_MAX_LOD: return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
1822 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1823 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1824 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1825 default: UNREACHABLE(pname); return 0;
1826 }
1827}
1828
1829GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1830{
1831 mResourceManager->checkSamplerAllocation(sampler);
1832
1833 Sampler *samplerObject = getSampler(sampler);
1834 ASSERT(samplerObject);
1835
1836 switch(pname)
1837 {
1838 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1839 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1840 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1841 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1842 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1843 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1844 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1845 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1846 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1847 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1848 default: UNREACHABLE(pname); return 0;
1849 }
1850}
1851
1852bool Context::getBooleanv(GLenum pname, GLboolean *params) const
1853{
1854 switch(pname)
1855 {
1856 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
1857 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
1858 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
1859 case GL_COLOR_WRITEMASK:
1860 params[0] = mState.colorMaskRed;
1861 params[1] = mState.colorMaskGreen;
1862 params[2] = mState.colorMaskBlue;
1863 params[3] = mState.colorMaskAlpha;
1864 break;
1865 case GL_CULL_FACE: *params = mState.cullFaceEnabled; break;
1866 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFillEnabled; break;
1867 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1868 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverageEnabled; break;
1869 case GL_SCISSOR_TEST: *params = mState.scissorTestEnabled; break;
1870 case GL_STENCIL_TEST: *params = mState.stencilTestEnabled; break;
1871 case GL_DEPTH_TEST: *params = mState.depthTestEnabled; break;
1872 case GL_BLEND: *params = mState.blendEnabled; break;
1873 case GL_DITHER: *params = mState.ditherEnabled; break;
1874 case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
1875 case GL_RASTERIZER_DISCARD: *params = mState.rasterizerDiscardEnabled; break;
1876 case GL_TRANSFORM_FEEDBACK_ACTIVE:
1877 {
1878 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1879 if(transformFeedback)
1880 {
1881 *params = transformFeedback->isActive();
1882 break;
1883 }
1884 else return false;
1885 }
1886 case GL_TRANSFORM_FEEDBACK_PAUSED:
1887 {
1888 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1889 if(transformFeedback)
1890 {
1891 *params = transformFeedback->isPaused();
1892 break;
1893 }
1894 else return false;
1895 }
1896 default:
1897 return false;
1898 }
1899
1900 return true;
1901}
1902
1903bool Context::getFloatv(GLenum pname, GLfloat *params) const
1904{
1905 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1906 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1907 // GetIntegerv as its native query function. As it would require conversion in any
1908 // case, this should make no difference to the calling application.
1909 switch(pname)
1910 {
1911 case GL_LINE_WIDTH: *params = mState.lineWidth; break;
1912 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
1913 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
1914 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break;
1915 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break;
1916 case GL_ALIASED_LINE_WIDTH_RANGE:
1917 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1918 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1919 break;
1920 case GL_ALIASED_POINT_SIZE_RANGE:
1921 params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1922 params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1923 break;
1924 case GL_DEPTH_RANGE:
1925 params[0] = mState.zNear;
1926 params[1] = mState.zFar;
1927 break;
1928 case GL_COLOR_CLEAR_VALUE:
1929 params[0] = mState.colorClearValue.red;
1930 params[1] = mState.colorClearValue.green;
1931 params[2] = mState.colorClearValue.blue;
1932 params[3] = mState.colorClearValue.alpha;
1933 break;
1934 case GL_BLEND_COLOR:
1935 params[0] = mState.blendColor.red;
1936 params[1] = mState.blendColor.green;
1937 params[2] = mState.blendColor.blue;
1938 params[3] = mState.blendColor.alpha;
1939 break;
1940 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1941 *params = MAX_TEXTURE_MAX_ANISOTROPY;
1942 break;
1943 default:
1944 return false;
1945 }
1946
1947 return true;
1948}
1949
1950template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
1951template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
1952
1953template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
1954{
1955 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1956 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1957 // GetIntegerv as its native query function. As it would require conversion in any
1958 // case, this should make no difference to the calling application. You may find it in
1959 // Context::getFloatv.
1960 switch(pname)
1961 {
1962 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; return true;
1963 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; return true;
1964 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; return true;
1965 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; return true;
1966 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; return true;
1967 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; return true;
1968 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; return true;
1969 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; return true;
1970 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; return true;
1971 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ return true;
1972 case GL_ARRAY_BUFFER_BINDING: *params = getArrayBufferName(); return true;
1973 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getElementArrayBufferName(); return true;
1974// case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1975 case GL_DRAW_FRAMEBUFFER_BINDING: *params = mState.drawFramebuffer; return true;
1976 case GL_READ_FRAMEBUFFER_BINDING: *params = mState.readFramebuffer; return true;
1977 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); return true;
1978 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; return true;
1979 case GL_PACK_ALIGNMENT: *params = mState.packParameters.alignment; return true;
1980 case GL_UNPACK_ALIGNMENT: *params = mState.unpackParameters.alignment; return true;
1981 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; return true;
1982 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; return true;
1983 case GL_TEXTURE_FILTERING_HINT_CHROMIUM: *params = mState.textureFilteringHint; return true;
1984 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); return true;
1985 case GL_STENCIL_FUNC: *params = mState.stencilFunc; return true;
1986 case GL_STENCIL_REF: *params = mState.stencilRef; return true;
1987 case GL_STENCIL_VALUE_MASK: *params = sw::clampToSignedInt(mState.stencilMask); return true;
1988 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; return true;
1989 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; return true;
1990 case GL_STENCIL_BACK_VALUE_MASK: *params = sw::clampToSignedInt(mState.stencilBackMask); return true;
1991 case GL_STENCIL_FAIL: *params = mState.stencilFail; return true;
1992 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; return true;
1993 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; return true;
1994 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; return true;
1995 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; return true;
1996 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; return true;
1997 case GL_DEPTH_FUNC: *params = mState.depthFunc; return true;
1998 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; return true;
1999 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; return true;
2000 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; return true;
2001 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; return true;
2002 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; return true;
2003 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; return true;
2004 case GL_STENCIL_WRITEMASK: *params = sw::clampToSignedInt(mState.stencilWritemask); return true;
2005 case GL_STENCIL_BACK_WRITEMASK: *params = sw::clampToSignedInt(mState.stencilBackWritemask); return true;
2006 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; return true;
2007 case GL_SUBPIXEL_BITS: *params = 4; return true;
2008 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
2009 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; return true;
2010 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; return true;
2011 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; return true;
2012 case GL_MAX_SAMPLES: *params = IMPLEMENTATION_MAX_SAMPLES; return true;
2013 case GL_SAMPLE_BUFFERS:
2014 case GL_SAMPLES:
2015 {
2016 Framebuffer *framebuffer = getDrawFramebuffer();
2017 int width, height, samples;
2018
2019 if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE))
2020 {
2021 switch(pname)
2022 {
2023 case GL_SAMPLE_BUFFERS:
2024 if(samples > 1)
2025 {
2026 *params = 1;
2027 }
2028 else
2029 {
2030 *params = 0;
2031 }
2032 break;
2033 case GL_SAMPLES:
2034 *params = samples;
2035 break;
2036 }
2037 }
2038 else
2039 {
2040 *params = 0;
2041 }
2042 }
2043 return true;
2044 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2045 {
2046 Framebuffer *framebuffer = getReadFramebuffer();
2047 if(framebuffer)
2048 {
2049 *params = framebuffer->getImplementationColorReadType();
2050 }
2051 else
2052 {
2053 return error(GL_INVALID_OPERATION, true);
2054 }
2055 }
2056 return true;
2057 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2058 {
2059 Framebuffer *framebuffer = getReadFramebuffer();
2060 if(framebuffer)
2061 {
2062 *params = framebuffer->getImplementationColorReadFormat();
2063 }
2064 else
2065 {
2066 return error(GL_INVALID_OPERATION, true);
2067 }
2068 }
2069 return true;
2070 case GL_MAX_VIEWPORT_DIMS:
2071 {
2072 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
2073 params[0] = maxDimension;
2074 params[1] = maxDimension;
2075 }
2076 return true;
2077 case GL_COMPRESSED_TEXTURE_FORMATS:
2078 {
2079 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
2080 {
2081 params[i] = compressedTextureFormats[i];
2082 }
2083 }
2084 return true;
2085 case GL_VIEWPORT:
2086 params[0] = mState.viewportX;
2087 params[1] = mState.viewportY;
2088 params[2] = mState.viewportWidth;
2089 params[3] = mState.viewportHeight;
2090 return true;
2091 case GL_SCISSOR_BOX:
2092 params[0] = mState.scissorX;
2093 params[1] = mState.scissorY;
2094 params[2] = mState.scissorWidth;
2095 params[3] = mState.scissorHeight;
2096 return true;
2097 case GL_CULL_FACE_MODE: *params = mState.cullMode; return true;
2098 case GL_FRONT_FACE: *params = mState.frontFace; return true;
2099 case GL_RED_BITS:
2100 case GL_GREEN_BITS:
2101 case GL_BLUE_BITS:
2102 case GL_ALPHA_BITS:
2103 {
2104 Framebuffer *framebuffer = getDrawFramebuffer();
2105 Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer(0) : nullptr;
2106
2107 if(colorbuffer)
2108 {
2109 switch(pname)
2110 {
2111 case GL_RED_BITS: *params = colorbuffer->getRedSize(); return true;
2112 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); return true;
2113 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); return true;
2114 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); return true;
2115 }
2116 }
2117 else
2118 {
2119 *params = 0;
2120 }
2121 }
2122 return true;
2123 case GL_DEPTH_BITS:
2124 {
2125 Framebuffer *framebuffer = getDrawFramebuffer();
2126 Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
2127
2128 if(depthbuffer)
2129 {
2130 *params = depthbuffer->getDepthSize();
2131 }
2132 else
2133 {
2134 *params = 0;
2135 }
2136 }
2137 return true;
2138 case GL_STENCIL_BITS:
2139 {
2140 Framebuffer *framebuffer = getDrawFramebuffer();
2141 Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
2142
2143 if(stencilbuffer)
2144 {
2145 *params = stencilbuffer->getStencilSize();
2146 }
2147 else
2148 {
2149 *params = 0;
2150 }
2151 }
2152 return true;
2153 case GL_TEXTURE_BINDING_2D:
2154 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2155 {
2156 error(GL_INVALID_OPERATION);
2157 return false;
2158 }
2159
2160 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
2161 return true;
2162 case GL_TEXTURE_BINDING_CUBE_MAP:
2163 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2164 {
2165 error(GL_INVALID_OPERATION);
2166 return false;
2167 }
2168
2169 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
2170 return true;
2171 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2172 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2173 {
2174 error(GL_INVALID_OPERATION);
2175 return false;
2176 }
2177
2178 *params = mState.samplerTexture[TEXTURE_2D_RECT][mState.activeSampler].name();
2179 return true;
2180 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2181 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2182 {
2183 error(GL_INVALID_OPERATION);
2184 return false;
2185 }
2186
2187 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
2188 return true;
2189 case GL_TEXTURE_BINDING_3D_OES:
2190 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2191 {
2192 error(GL_INVALID_OPERATION);
2193 return false;
2194 }
2195
2196 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
2197 return true;
2198 case GL_DRAW_BUFFER0:
2199 case GL_DRAW_BUFFER1:
2200 case GL_DRAW_BUFFER2:
2201 case GL_DRAW_BUFFER3:
2202 case GL_DRAW_BUFFER4:
2203 case GL_DRAW_BUFFER5:
2204 case GL_DRAW_BUFFER6:
2205 case GL_DRAW_BUFFER7:
2206 case GL_DRAW_BUFFER8:
2207 case GL_DRAW_BUFFER9:
2208 case GL_DRAW_BUFFER10:
2209 case GL_DRAW_BUFFER11:
2210 case GL_DRAW_BUFFER12:
2211 case GL_DRAW_BUFFER13:
2212 case GL_DRAW_BUFFER14:
2213 case GL_DRAW_BUFFER15:
2214 if((pname - GL_DRAW_BUFFER0) < MAX_DRAW_BUFFERS)
2215 {
2216 Framebuffer* framebuffer = getDrawFramebuffer();
2217 *params = framebuffer ? framebuffer->getDrawBuffer(pname - GL_DRAW_BUFFER0) : GL_NONE;
2218 }
2219 else
2220 {
2221 return false;
2222 }
2223 return true;
2224 case GL_MAX_DRAW_BUFFERS:
2225 *params = MAX_DRAW_BUFFERS;
2226 return true;
2227 case GL_MAX_COLOR_ATTACHMENTS: // Note: MAX_COLOR_ATTACHMENTS_EXT added by GL_EXT_draw_buffers
2228 *params = MAX_COLOR_ATTACHMENTS;
2229 return true;
2230 case GL_TEXTURE_BINDING_2D_ARRAY:
2231 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2232 {
2233 error(GL_INVALID_OPERATION);
2234 return false;
2235 }
2236
2237 *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();
2238 return true;
2239 case GL_COPY_READ_BUFFER_BINDING:
2240 *params = mState.copyReadBuffer.name();
2241 return true;
2242 case GL_COPY_WRITE_BUFFER_BINDING:
2243 *params = mState.copyWriteBuffer.name();
2244 return true;
2245 case GL_MAJOR_VERSION:
2246 *params = 3;
2247 return true;
2248 case GL_MINOR_VERSION:
2249 *params = 0;
2250 return true;
2251 case GL_MAX_3D_TEXTURE_SIZE:
2252 *params = IMPLEMENTATION_MAX_3D_TEXTURE_SIZE;
2253 return true;
2254 case GL_MAX_ARRAY_TEXTURE_LAYERS:
2255 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2256 return true;
2257 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2258 *params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
2259 return true;
2260 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2261 *params = MAX_VERTEX_UNIFORM_BLOCKS + MAX_FRAGMENT_UNIFORM_BLOCKS;
2262 return true;
2263 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2264 *params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
2265 return true;
2266 case GL_MAX_ELEMENT_INDEX:
2267 *params = MAX_ELEMENT_INDEX;
2268 return true;
2269 case GL_MAX_ELEMENTS_INDICES:
2270 *params = MAX_ELEMENTS_INDICES;
2271 return true;
2272 case GL_MAX_ELEMENTS_VERTICES:
2273 *params = MAX_ELEMENTS_VERTICES;
2274 return true;
2275 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2276 *params = MAX_FRAGMENT_INPUT_VECTORS * 4;
2277 return true;
2278 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2279 *params = MAX_FRAGMENT_UNIFORM_BLOCKS;
2280 return true;
2281 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2282 *params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
2283 return true;
2284 case GL_MAX_PROGRAM_TEXEL_OFFSET:
2285 // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2286 // In any case, any behavior outside the specified range is valid since the spec mentions:
2287 // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2288 // "If any of the offset values are outside the range of the implementation-defined values
2289 // MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2290 // undefined."
2291 *params = MAX_PROGRAM_TEXEL_OFFSET;
2292 return true;
2293 case GL_MAX_SERVER_WAIT_TIMEOUT:
2294 *params = 0;
2295 return true;
2296 case GL_MAX_TEXTURE_LOD_BIAS:
2297 *params = MAX_TEXTURE_LOD_BIAS;
2298 return true;
2299 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2300 *params = sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
2301 return true;
2302 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2303 *params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
2304 return true;
2305 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2306 *params = sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
2307 return true;
2308 case GL_MAX_UNIFORM_BLOCK_SIZE:
2309 *params = MAX_UNIFORM_BLOCK_SIZE;
2310 return true;
2311 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2312 *params = MAX_UNIFORM_BUFFER_BINDINGS;
2313 return true;
2314 case GL_MAX_VARYING_COMPONENTS:
2315 *params = MAX_VARYING_VECTORS * 4;
2316 return true;
2317 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2318 *params = MAX_VERTEX_OUTPUT_VECTORS * 4;
2319 return true;
2320 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2321 *params = MAX_VERTEX_UNIFORM_BLOCKS;
2322 return true;
2323 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2324 *params = MAX_VERTEX_UNIFORM_COMPONENTS;
2325 return true;
2326 case GL_MIN_PROGRAM_TEXEL_OFFSET:
2327 // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2328 // In any case, any behavior outside the specified range is valid since the spec mentions:
2329 // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2330 // "If any of the offset values are outside the range of the implementation-defined values
2331 // MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2332 // undefined."
2333 *params = MIN_PROGRAM_TEXEL_OFFSET;
2334 return true;
2335 case GL_NUM_EXTENSIONS:
2336 GLuint numExtensions;
2337 getExtensions(0, &numExtensions);
2338 *params = numExtensions;
2339 return true;
2340 case GL_NUM_PROGRAM_BINARY_FORMATS:
2341 *params = NUM_PROGRAM_BINARY_FORMATS;
2342 return true;
2343 case GL_PACK_ROW_LENGTH:
2344 *params = mState.packParameters.rowLength;
2345 return true;
2346 case GL_PACK_SKIP_PIXELS:
2347 *params = mState.packParameters.skipPixels;
2348 return true;
2349 case GL_PACK_SKIP_ROWS:
2350 *params = mState.packParameters.skipRows;
2351 return true;
2352 case GL_PIXEL_PACK_BUFFER_BINDING:
2353 *params = mState.pixelPackBuffer.name();
2354 return true;
2355 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2356 *params = mState.pixelUnpackBuffer.name();
2357 return true;
2358 case GL_PROGRAM_BINARY_FORMATS:
2359 // Since NUM_PROGRAM_BINARY_FORMATS is 0, the input
2360 // should be a 0 sized array, so don't write to params
2361 return true;
2362 case GL_READ_BUFFER:
2363 {
2364 Framebuffer* framebuffer = getReadFramebuffer();
2365 *params = framebuffer ? framebuffer->getReadBuffer() : GL_NONE;
2366 }
2367 return true;
2368 case GL_SAMPLER_BINDING:
2369 *params = mState.sampler[mState.activeSampler].name();
2370 return true;
2371 case GL_UNIFORM_BUFFER_BINDING:
2372 *params = mState.genericUniformBuffer.name();
2373 return true;
2374 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2375 *params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;
2376 return true;
2377 case GL_UNPACK_IMAGE_HEIGHT:
2378 *params = mState.unpackParameters.imageHeight;
2379 return true;
2380 case GL_UNPACK_ROW_LENGTH:
2381 *params = mState.unpackParameters.rowLength;
2382 return true;
2383 case GL_UNPACK_SKIP_IMAGES:
2384 *params = mState.unpackParameters.skipImages;
2385 return true;
2386 case GL_UNPACK_SKIP_PIXELS:
2387 *params = mState.unpackParameters.skipPixels;
2388 return true;
2389 case GL_UNPACK_SKIP_ROWS:
2390 *params = mState.unpackParameters.skipRows;
2391 return true;
2392 case GL_VERTEX_ARRAY_BINDING:
2393 *params = getCurrentVertexArray()->name;
2394 return true;
2395 case GL_TRANSFORM_FEEDBACK_BINDING:
2396 {
2397 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2398 if(transformFeedback)
2399 {
2400 *params = transformFeedback->name;
2401 }
2402 else
2403 {
2404 return false;
2405 }
2406 }
2407 return true;
2408 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2409 {
2410 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2411 if(transformFeedback)
2412 {
2413 *params = mState.genericTransformFeedbackBuffer.name();
2414 }
2415 else
2416 {
2417 return false;
2418 }
2419 }
2420 return true;
2421 default:
2422 break;
2423 }
2424
2425 return false;
2426}
2427
2428template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2429template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2430
2431template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
2432{
2433 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2434 if(!transformFeedback)
2435 {
2436 return false;
2437 }
2438
2439 switch(pname)
2440 {
2441 case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
2442 *param = transformFeedback->name;
2443 break;
2444 case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
2445 *param = transformFeedback->isActive();
2446 break;
2447 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
2448 *param = transformFeedback->getBufferName(index);
2449 break;
2450 case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
2451 *param = transformFeedback->isPaused();
2452 break;
2453 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2454 if(transformFeedback->getBuffer(index))
2455 {
2456 *param = transformFeedback->getSize(index);
2457 break;
2458 }
2459 else return false;
2460 case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2461 if(transformFeedback->getBuffer(index))
2462 {
2463 *param = transformFeedback->getOffset(index);
2464 break;
2465 }
2466 else return false;
2467 default:
2468 return false;
2469 }
2470
2471 return true;
2472}
2473
2474template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2475template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2476
2477template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
2478{
2479 switch(pname)
2480 {
2481 case GL_UNIFORM_BUFFER_BINDING:
2482 case GL_UNIFORM_BUFFER_SIZE:
2483 case GL_UNIFORM_BUFFER_START:
2484 break;
2485 default:
2486 return false;
2487 }
2488
2489 if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
2490 {
2491 return error(GL_INVALID_VALUE, true);
2492 }
2493
2494 const BufferBinding& uniformBuffer = mState.uniformBuffers[index];
2495
2496 switch(pname)
2497 {
2498 case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
2499 *param = uniformBuffer.get().name();
2500 break;
2501 case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2502 *param = uniformBuffer.getSize();
2503 break;
2504 case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2505 *param = uniformBuffer.getOffset();
2506 break;
2507 default:
2508 return false;
2509 }
2510
2511 return true;
2512}
2513
2514bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
2515{
2516 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2517 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2518 // to the fact that it is stored internally as a float, and so would require conversion
2519 // if returned from Context::getIntegerv. Since this conversion is already implemented
2520 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2521 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2522 // application.
2523 switch(pname)
2524 {
2525 case GL_COMPRESSED_TEXTURE_FORMATS:
2526 {
2527 *type = GL_INT;
2528 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
2529 }
2530 break;
2531 case GL_SHADER_BINARY_FORMATS:
2532 {
2533 *type = GL_INT;
2534 *numParams = 0;
2535 }
2536 break;
2537 case GL_MAX_VERTEX_ATTRIBS:
2538 case GL_MAX_VERTEX_UNIFORM_VECTORS:
2539 case GL_MAX_VARYING_VECTORS:
2540 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2541 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2542 case GL_MAX_TEXTURE_IMAGE_UNITS:
2543 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2544 case GL_MAX_RENDERBUFFER_SIZE:
2545 case GL_NUM_SHADER_BINARY_FORMATS:
2546 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2547 case GL_ARRAY_BUFFER_BINDING:
2548 case GL_FRAMEBUFFER_BINDING: // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
2549 case GL_READ_FRAMEBUFFER_BINDING: // Same as GL_READ_FRAMEBUFFER_BINDING_ANGLE
2550 case GL_RENDERBUFFER_BINDING:
2551 case GL_CURRENT_PROGRAM:
2552 case GL_PACK_ALIGNMENT:
2553 case GL_UNPACK_ALIGNMENT:
2554 case GL_GENERATE_MIPMAP_HINT:
2555 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2556 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2557 case GL_RED_BITS:
2558 case GL_GREEN_BITS:
2559 case GL_BLUE_BITS:
2560 case GL_ALPHA_BITS:
2561 case GL_DEPTH_BITS:
2562 case GL_STENCIL_BITS:
2563 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2564 case GL_CULL_FACE_MODE:
2565 case GL_FRONT_FACE:
2566 case GL_ACTIVE_TEXTURE:
2567 case GL_STENCIL_FUNC:
2568 case GL_STENCIL_VALUE_MASK:
2569 case GL_STENCIL_REF:
2570 case GL_STENCIL_FAIL:
2571 case GL_STENCIL_PASS_DEPTH_FAIL:
2572 case GL_STENCIL_PASS_DEPTH_PASS:
2573 case GL_STENCIL_BACK_FUNC:
2574 case GL_STENCIL_BACK_VALUE_MASK:
2575 case GL_STENCIL_BACK_REF:
2576 case GL_STENCIL_BACK_FAIL:
2577 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2578 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2579 case GL_DEPTH_FUNC:
2580 case GL_BLEND_SRC_RGB:
2581 case GL_BLEND_SRC_ALPHA:
2582 case GL_BLEND_DST_RGB:
2583 case GL_BLEND_DST_ALPHA:
2584 case GL_BLEND_EQUATION_RGB:
2585 case GL_BLEND_EQUATION_ALPHA:
2586 case GL_STENCIL_WRITEMASK:
2587 case GL_STENCIL_BACK_WRITEMASK:
2588 case GL_STENCIL_CLEAR_VALUE:
2589 case GL_SUBPIXEL_BITS:
2590 case GL_MAX_TEXTURE_SIZE:
2591 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2592 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
2593 case GL_SAMPLE_BUFFERS:
2594 case GL_SAMPLES:
2595 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2596 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2597 case GL_TEXTURE_BINDING_2D:
2598 case GL_TEXTURE_BINDING_CUBE_MAP:
2599 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2600 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2601 case GL_TEXTURE_BINDING_3D_OES:
2602 case GL_COPY_READ_BUFFER_BINDING:
2603 case GL_COPY_WRITE_BUFFER_BINDING:
2604 case GL_DRAW_BUFFER0:
2605 case GL_DRAW_BUFFER1:
2606 case GL_DRAW_BUFFER2:
2607 case GL_DRAW_BUFFER3:
2608 case GL_DRAW_BUFFER4:
2609 case GL_DRAW_BUFFER5:
2610 case GL_DRAW_BUFFER6:
2611 case GL_DRAW_BUFFER7:
2612 case GL_DRAW_BUFFER8:
2613 case GL_DRAW_BUFFER9:
2614 case GL_DRAW_BUFFER10:
2615 case GL_DRAW_BUFFER11:
2616 case GL_DRAW_BUFFER12:
2617 case GL_DRAW_BUFFER13:
2618 case GL_DRAW_BUFFER14:
2619 case GL_DRAW_BUFFER15:
2620 case GL_MAJOR_VERSION:
2621 case GL_MAX_3D_TEXTURE_SIZE:
2622 case GL_MAX_ARRAY_TEXTURE_LAYERS:
2623 case GL_MAX_COLOR_ATTACHMENTS:
2624 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2625 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2626 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2627 case GL_MAX_DRAW_BUFFERS:
2628 case GL_MAX_ELEMENT_INDEX:
2629 case GL_MAX_ELEMENTS_INDICES:
2630 case GL_MAX_ELEMENTS_VERTICES:
2631 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2632 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2633 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2634 case GL_MAX_PROGRAM_TEXEL_OFFSET:
2635 case GL_MAX_SERVER_WAIT_TIMEOUT:
2636 case GL_MAX_TEXTURE_LOD_BIAS:
2637 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2638 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2639 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2640 case GL_MAX_UNIFORM_BLOCK_SIZE:
2641 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2642 case GL_MAX_VARYING_COMPONENTS:
2643 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2644 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2645 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2646 case GL_MIN_PROGRAM_TEXEL_OFFSET:
2647 case GL_MINOR_VERSION:
2648 case GL_NUM_EXTENSIONS:
2649 case GL_NUM_PROGRAM_BINARY_FORMATS:
2650 case GL_PACK_ROW_LENGTH:
2651 case GL_PACK_SKIP_PIXELS:
2652 case GL_PACK_SKIP_ROWS:
2653 case GL_PIXEL_PACK_BUFFER_BINDING:
2654 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2655 case GL_PROGRAM_BINARY_FORMATS:
2656 case GL_READ_BUFFER:
2657 case GL_SAMPLER_BINDING:
2658 case GL_TEXTURE_BINDING_2D_ARRAY:
2659 case GL_UNIFORM_BUFFER_BINDING:
2660 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2661 case GL_UNPACK_IMAGE_HEIGHT:
2662 case GL_UNPACK_ROW_LENGTH:
2663 case GL_UNPACK_SKIP_IMAGES:
2664 case GL_UNPACK_SKIP_PIXELS:
2665 case GL_UNPACK_SKIP_ROWS:
2666 case GL_VERTEX_ARRAY_BINDING:
2667 case GL_TRANSFORM_FEEDBACK_BINDING:
2668 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2669 {
2670 *type = GL_INT;
2671 *numParams = 1;
2672 }
2673 break;
2674 case GL_MAX_SAMPLES:
2675 {
2676 *type = GL_INT;
2677 *numParams = 1;
2678 }
2679 break;
2680 case GL_MAX_VIEWPORT_DIMS:
2681 {
2682 *type = GL_INT;
2683 *numParams = 2;
2684 }
2685 break;
2686 case GL_VIEWPORT:
2687 case GL_SCISSOR_BOX:
2688 {
2689 *type = GL_INT;
2690 *numParams = 4;
2691 }
2692 break;
2693 case GL_SHADER_COMPILER:
2694 case GL_SAMPLE_COVERAGE_INVERT:
2695 case GL_DEPTH_WRITEMASK:
2696 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
2697 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
2698 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2699 case GL_SAMPLE_COVERAGE:
2700 case GL_SCISSOR_TEST:
2701 case GL_STENCIL_TEST:
2702 case GL_DEPTH_TEST:
2703 case GL_BLEND:
2704 case GL_DITHER:
2705 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2706 case GL_RASTERIZER_DISCARD:
2707 case GL_TRANSFORM_FEEDBACK_ACTIVE:
2708 case GL_TRANSFORM_FEEDBACK_PAUSED:
2709 {
2710 *type = GL_BOOL;
2711 *numParams = 1;
2712 }
2713 break;
2714 case GL_COLOR_WRITEMASK:
2715 {
2716 *type = GL_BOOL;
2717 *numParams = 4;
2718 }
2719 break;
2720 case GL_POLYGON_OFFSET_FACTOR:
2721 case GL_POLYGON_OFFSET_UNITS:
2722 case GL_SAMPLE_COVERAGE_VALUE:
2723 case GL_DEPTH_CLEAR_VALUE:
2724 case GL_LINE_WIDTH:
2725 {
2726 *type = GL_FLOAT;
2727 *numParams = 1;
2728 }
2729 break;
2730 case GL_ALIASED_LINE_WIDTH_RANGE:
2731 case GL_ALIASED_POINT_SIZE_RANGE:
2732 case GL_DEPTH_RANGE:
2733 {
2734 *type = GL_FLOAT;
2735 *numParams = 2;
2736 }
2737 break;
2738 case GL_COLOR_CLEAR_VALUE:
2739 case GL_BLEND_COLOR:
2740 {
2741 *type = GL_FLOAT;
2742 *numParams = 4;
2743 }
2744 break;
2745 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2746 *type = GL_FLOAT;
2747 *numParams = 1;
2748 break;
2749 default:
2750 return false;
2751 }
2752
2753 return true;
2754}
2755
2756void Context::applyScissor(int width, int height)
2757{
2758 if(mState.scissorTestEnabled)
2759 {
2760 sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
2761 scissor.clip(0, 0, width, height);
2762
2763 device->setScissorRect(scissor);
2764 device->setScissorEnable(true);
2765 }
2766 else
2767 {
2768 device->setScissorEnable(false);
2769 }
2770}
2771
2772// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
2773bool Context::applyRenderTarget()
2774{
2775 Framebuffer *framebuffer = getDrawFramebuffer();
2776 int width, height, samples;
2777
2778 if(!framebuffer || (framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE))
2779 {
2780 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2781 }
2782
2783 for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2784 {
2785 if(framebuffer->getDrawBuffer(i) != GL_NONE)
2786 {
2787 egl::Image *renderTarget = framebuffer->getRenderTarget(i);
2788 GLint layer = framebuffer->getColorbufferLayer(i);
2789 device->setRenderTarget(i, renderTarget, layer);
2790 if(renderTarget) renderTarget->release();
2791 }
2792 else
2793 {
2794 device->setRenderTarget(i, nullptr, 0);
2795 }
2796 }
2797
2798 egl::Image *depthBuffer = framebuffer->getDepthBuffer();
2799 GLint dLayer = framebuffer->getDepthbufferLayer();
2800 device->setDepthBuffer(depthBuffer, dLayer);
2801 if(depthBuffer) depthBuffer->release();
2802
2803 egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
2804 GLint sLayer = framebuffer->getStencilbufferLayer();
2805 device->setStencilBuffer(stencilBuffer, sLayer);
2806 if(stencilBuffer) stencilBuffer->release();
2807
2808 Viewport viewport;
2809 float zNear = clamp01(mState.zNear);
2810 float zFar = clamp01(mState.zFar);
2811
2812 viewport.x0 = mState.viewportX;
2813 viewport.y0 = mState.viewportY;
2814 viewport.width = mState.viewportWidth;
2815 viewport.height = mState.viewportHeight;
2816 viewport.minZ = zNear;
2817 viewport.maxZ = zFar;
2818
2819 if (viewport.x0 > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
2820 viewport.y0 > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
2821 {
2822 TransformFeedback* transformFeedback = getTransformFeedback();
2823 if (!transformFeedback->isActive() || transformFeedback->isPaused())
2824 {
2825 return false;
2826 }
2827 else
2828 {
2829 viewport.x0 = 0;
2830 viewport.y0 = 0;
2831 viewport.width = 0;
2832 viewport.height = 0;
2833 }
2834 }
2835
2836 device->setViewport(viewport);
2837
2838 applyScissor(width, height);
2839
2840 Program *program = getCurrentProgram();
2841
2842 if(program)
2843 {
2844 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
2845 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
2846 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
2847 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
2848 }
2849
2850 return true;
2851}
2852
2853// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
2854void Context::applyState(GLenum drawMode)
2855{
2856 Framebuffer *framebuffer = getDrawFramebuffer();
2857 bool frontFaceCCW = (mState.frontFace == GL_CCW);
2858
2859 if(mState.cullFaceEnabled)
2860 {
2861 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace), frontFaceCCW);
2862 }
2863 else
2864 {
2865 device->setCullMode(sw::CULL_NONE, frontFaceCCW);
2866 }
2867
2868 if(mDepthStateDirty)
2869 {
2870 if(mState.depthTestEnabled)
2871 {
2872 device->setDepthBufferEnable(true);
2873 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
2874 }
2875 else
2876 {
2877 device->setDepthBufferEnable(false);
2878 }
2879
2880 mDepthStateDirty = false;
2881 }
2882
2883 if(mBlendStateDirty)
2884 {
2885 if(mState.blendEnabled)
2886 {
2887 device->setAlphaBlendEnable(true);
2888 device->setSeparateAlphaBlendEnable(true);
2889
2890 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
2891
2892 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
2893 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
2894 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
2895
2896 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
2897 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
2898 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
2899 }
2900 else
2901 {
2902 device->setAlphaBlendEnable(false);
2903 }
2904
2905 mBlendStateDirty = false;
2906 }
2907
2908 if(mStencilStateDirty || mFrontFaceDirty)
2909 {
2910 if(mState.stencilTestEnabled && framebuffer->hasStencil())
2911 {
2912 device->setStencilEnable(true);
2913 device->setTwoSidedStencil(true);
2914
2915 // get the maximum size of the stencil ref
2916 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2917 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
2918
2919 if(mState.frontFace == GL_CCW)
2920 {
2921 device->setStencilWriteMask(mState.stencilWritemask);
2922 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
2923
2924 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2925 device->setStencilMask(mState.stencilMask);
2926
2927 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
2928 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2929 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2930
2931 device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
2932 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2933
2934 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2935 device->setStencilMaskCCW(mState.stencilBackMask);
2936
2937 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
2938 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2939 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2940 }
2941 else
2942 {
2943 device->setStencilWriteMaskCCW(mState.stencilWritemask);
2944 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
2945
2946 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2947 device->setStencilMaskCCW(mState.stencilMask);
2948
2949 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
2950 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2951 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2952
2953 device->setStencilWriteMask(mState.stencilBackWritemask);
2954 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2955
2956 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2957 device->setStencilMask(mState.stencilBackMask);
2958
2959 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
2960 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2961 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2962 }
2963 }
2964 else
2965 {
2966 device->setStencilEnable(false);
2967 }
2968
2969 mStencilStateDirty = false;
2970 mFrontFaceDirty = false;
2971 }
2972
2973 if(mMaskStateDirty)
2974 {
2975 for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2976 {
2977 device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
2978 }
2979
2980 device->setDepthWriteEnable(mState.depthMask);
2981
2982 mMaskStateDirty = false;
2983 }
2984
2985 if(mPolygonOffsetStateDirty)
2986 {
2987 if(mState.polygonOffsetFillEnabled)
2988 {
2989 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2990 if(depthbuffer)
2991 {
2992 device->setSlopeDepthBias(mState.polygonOffsetFactor);
2993 float depthBias = ldexp(mState.polygonOffsetUnits, -23); // We use 32-bit floating-point for all depth formats, with 23 mantissa bits.
2994 device->setDepthBias(depthBias);
2995 }
2996 }
2997 else
2998 {
2999 device->setSlopeDepthBias(0);
3000 device->setDepthBias(0);
3001 }
3002
3003 mPolygonOffsetStateDirty = false;
3004 }
3005
3006 if(mSampleStateDirty)
3007 {
3008 if(mState.sampleAlphaToCoverageEnabled)
3009 {
3010 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
3011 }
3012 else
3013 {
3014 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
3015 }
3016
3017 if(mState.sampleCoverageEnabled)
3018 {
3019 unsigned int mask = 0;
3020 if(mState.sampleCoverageValue != 0)
3021 {
3022 int width, height, samples;
3023 framebuffer->completeness(width, height, samples);
3024
3025 float threshold = 0.5f;
3026
3027 for(int i = 0; i < samples; i++)
3028 {
3029 mask <<= 1;
3030
3031 if((i + 1) * mState.sampleCoverageValue >= threshold)
3032 {
3033 threshold += 1.0f;
3034 mask |= 1;
3035 }
3036 }
3037 }
3038
3039 if(mState.sampleCoverageInvert)
3040 {
3041 mask = ~mask;
3042 }
3043
3044 device->setMultiSampleMask(mask);
3045 }
3046 else
3047 {
3048 device->setMultiSampleMask(0xFFFFFFFF);
3049 }
3050
3051 mSampleStateDirty = false;
3052 }
3053
3054 if(mDitherStateDirty)
3055 {
3056 // UNIMPLEMENTED(); // FIXME
3057
3058 mDitherStateDirty = false;
3059 }
3060
3061 device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);
3062}
3063
3064GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
3065{
3066 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
3067
3068 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
3069 if(err != GL_NO_ERROR)
3070 {
3071 return err;
3072 }
3073
3074 Program *program = getCurrentProgram();
3075
3076 device->resetInputStreams(false);
3077
3078 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3079 {
3080 if(program->getAttributeStream(i) == -1)
3081 {
3082 continue;
3083 }
3084
3085 sw::Resource *resource = attributes[i].vertexBuffer;
3086 const void *buffer = (char*)resource->data() + attributes[i].offset;
3087
3088 int stride = attributes[i].stride;
3089
3090 buffer = (char*)buffer + stride * base;
3091
3092 sw::Stream attribute(resource, buffer, stride);
3093
3094 attribute.type = attributes[i].type;
3095 attribute.count = attributes[i].count;
3096 attribute.normalized = attributes[i].normalized;
3097
3098 int stream = program->getAttributeStream(i);
3099 device->setInputStream(stream, attribute);
3100 }
3101
3102 return GL_NO_ERROR;
3103}
3104
3105// Applies the indices and element array bindings
3106GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
3107{
3108 GLenum err = mIndexDataManager->prepareIndexData(mode, type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo, isPrimitiveRestartFixedIndexEnabled());
3109
3110 if(err == GL_NO_ERROR)
3111 {
3112 device->setIndexBuffer(indexInfo->indexBuffer);
3113 }
3114
3115 return err;
3116}
3117
3118// Applies the shaders and shader constants
3119void Context::applyShaders()
3120{
3121 Program *programObject = getCurrentProgram();
3122 sw::VertexShader *vertexShader = programObject->getVertexShader();
3123 sw::PixelShader *pixelShader = programObject->getPixelShader();
3124
3125 device->setVertexShader(vertexShader);
3126 device->setPixelShader(pixelShader);
3127
3128 if(programObject->getSerial() != mAppliedProgramSerial)
3129 {
3130 programObject->dirtyAllUniforms();
3131 mAppliedProgramSerial = programObject->getSerial();
3132 }
3133
3134 programObject->applyTransformFeedback(device, getTransformFeedback());
3135 programObject->applyUniformBuffers(device, mState.uniformBuffers);
3136 programObject->applyUniforms(device);
3137}
3138
3139void Context::applyTextures()
3140{
3141 applyTextures(sw::SAMPLER_PIXEL);
3142 applyTextures(sw::SAMPLER_VERTEX);
3143}
3144
3145void Context::applyTextures(sw::SamplerType samplerType)
3146{
3147 Program *programObject = getCurrentProgram();
3148
3149 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type
3150
3151 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
3152 {
3153 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index
3154
3155 if(textureUnit != -1)
3156 {
3157 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
3158
3159 Texture *texture = getSamplerTexture(textureUnit, textureType);
3160 Sampler *samplerObject = mState.sampler[textureUnit];
3161
3162 if(texture->isSamplerComplete(samplerObject))
3163 {
3164 GLenum wrapS, wrapT, wrapR, minFilter, magFilter, compFunc, compMode;
3165 GLfloat minLOD, maxLOD, maxAnisotropy;
3166
3167 if(samplerObject)
3168 {
3169 wrapS = samplerObject->getWrapS();
3170 wrapT = samplerObject->getWrapT();
3171 wrapR = samplerObject->getWrapR();
3172 minFilter = samplerObject->getMinFilter();
3173 magFilter = samplerObject->getMagFilter();
3174 minLOD = samplerObject->getMinLod();
3175 maxLOD = samplerObject->getMaxLod();
3176 compFunc = samplerObject->getCompareFunc();
3177 compMode = samplerObject->getCompareMode();
3178 maxAnisotropy = samplerObject->getMaxAnisotropy();
3179 }
3180 else
3181 {
3182 wrapS = texture->getWrapS();
3183 wrapT = texture->getWrapT();
3184 wrapR = texture->getWrapR();
3185 minFilter = texture->getMinFilter();
3186 magFilter = texture->getMagFilter();
3187 minLOD = texture->getMinLOD();
3188 maxLOD = texture->getMaxLOD();
3189 compFunc = texture->getCompareFunc();
3190 compMode = texture->getCompareMode();
3191 maxAnisotropy = texture->getMaxAnisotropy();
3192 }
3193
3194 GLint baseLevel = texture->getBaseLevel();
3195 GLint maxLevel = texture->getMaxLevel();
3196 GLenum swizzleR = texture->getSwizzleR();
3197 GLenum swizzleG = texture->getSwizzleG();
3198 GLenum swizzleB = texture->getSwizzleB();
3199 GLenum swizzleA = texture->getSwizzleA();
3200
3201 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
3202 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
3203 device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
3204 device->setCompareFunc(samplerType, samplerIndex, es2sw::ConvertCompareFunc(compFunc, compMode));
3205 device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
3206 device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
3207 device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
3208 device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
3209 device->setMinLod(samplerType, samplerIndex, minLOD);
3210 device->setMaxLod(samplerType, samplerIndex, maxLOD);
3211 device->setBaseLevel(samplerType, samplerIndex, baseLevel);
3212 device->setMaxLevel(samplerType, samplerIndex, maxLevel);
3213 device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
3214 device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
3215 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
3216 device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
3217 device->setSyncRequired(samplerType, samplerIndex, texture->requiresSync());
3218
3219 applyTexture(samplerType, samplerIndex, texture);
3220 }
3221 else
3222 {
3223 applyTexture(samplerType, samplerIndex, nullptr);
3224 }
3225 }
3226 else
3227 {
3228 applyTexture(samplerType, samplerIndex, nullptr);
3229 }
3230 }
3231}
3232
3233void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
3234{
3235 Program *program = getCurrentProgram();
3236 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
3237 bool textureUsed = false;
3238
3239 if(type == sw::SAMPLER_PIXEL)
3240 {
3241 textureUsed = program->getPixelShader()->usesSampler(index);
3242 }
3243 else if(type == sw::SAMPLER_VERTEX)
3244 {
3245 textureUsed = program->getVertexShader()->usesSampler(index);
3246 }
3247 else UNREACHABLE(type);
3248
3249 sw::Resource *resource = nullptr;
3250
3251 if(baseTexture && textureUsed)
3252 {
3253 resource = baseTexture->getResource();
3254 }
3255
3256 device->setTextureResource(sampler, resource);
3257
3258 if(baseTexture && textureUsed)
3259 {
3260 int baseLevel = baseTexture->getBaseLevel();
3261 int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
3262 GLenum target = baseTexture->getTarget();
3263
3264 switch(target)
3265 {
3266 case GL_TEXTURE_2D:
3267 case GL_TEXTURE_EXTERNAL_OES:
3268 case GL_TEXTURE_RECTANGLE_ARB:
3269 {
3270 Texture2D *texture = static_cast<Texture2D*>(baseTexture);
3271
3272 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3273 {
3274 int surfaceLevel = mipmapLevel + baseLevel;
3275
3276 if(surfaceLevel > maxLevel)
3277 {
3278 surfaceLevel = maxLevel;
3279 }
3280
3281 egl::Image *surface = texture->getImage(surfaceLevel);
3282 device->setTextureLevel(sampler, 0, mipmapLevel, surface,
3283 (target == GL_TEXTURE_RECTANGLE_ARB) ? sw::TEXTURE_RECTANGLE : sw::TEXTURE_2D);
3284 }
3285 }
3286 break;
3287 case GL_TEXTURE_3D:
3288 {
3289 Texture3D *texture = static_cast<Texture3D*>(baseTexture);
3290
3291 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3292 {
3293 int surfaceLevel = mipmapLevel + baseLevel;
3294
3295 if(surfaceLevel > maxLevel)
3296 {
3297 surfaceLevel = maxLevel;
3298 }
3299
3300 egl::Image *surface = texture->getImage(surfaceLevel);
3301 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
3302 }
3303 }
3304 break;
3305 case GL_TEXTURE_2D_ARRAY:
3306 {
3307 Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
3308
3309 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3310 {
3311 int surfaceLevel = mipmapLevel + baseLevel;
3312
3313 if(surfaceLevel > maxLevel)
3314 {
3315 surfaceLevel = maxLevel;
3316 }
3317
3318 egl::Image *surface = texture->getImage(surfaceLevel);
3319 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
3320 }
3321 }
3322 break;
3323 case GL_TEXTURE_CUBE_MAP:
3324 {
3325 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
3326
3327 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3328 {
3329 cubeTexture->updateBorders(mipmapLevel);
3330
3331 for(int face = 0; face < 6; face++)
3332 {
3333 int surfaceLevel = mipmapLevel + baseLevel;
3334
3335 if(surfaceLevel > maxLevel)
3336 {
3337 surfaceLevel = maxLevel;
3338 }
3339
3340 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
3341 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
3342 }
3343 }
3344 }
3345 break;
3346 default:
3347 UNIMPLEMENTED();
3348 break;
3349 }
3350 }
3351 else
3352 {
3353 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
3354 }
3355}
3356
3357void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
3358{
3359 Framebuffer *framebuffer = getReadFramebuffer();
3360 int framebufferWidth, framebufferHeight, framebufferSamples;
3361
3362 if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE))
3363 {
3364 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3365 }
3366
3367 if(getReadFramebufferName() != 0 && framebufferSamples != 0)
3368 {
3369 return error(GL_INVALID_OPERATION);
3370 }
3371
3372 if(!ValidateReadPixelsFormatType(framebuffer, format, type))
3373 {
3374 return;
3375 }
3376
3377 GLsizei outputWidth = (mState.packParameters.rowLength > 0) ? mState.packParameters.rowLength : width;
3378 GLsizei outputPitch = gl::ComputePitch(outputWidth, format, type, mState.packParameters.alignment);
3379 GLsizei outputHeight = (mState.packParameters.imageHeight == 0) ? height : mState.packParameters.imageHeight;
3380 pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
3381 pixels = ((char*)pixels) + gl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packParameters);
3382
3383 // Sized query sanity check
3384 if(bufSize)
3385 {
3386 int requiredSize = outputPitch * height;
3387 if(requiredSize > *bufSize)
3388 {
3389 return error(GL_INVALID_OPERATION);
3390 }
3391 }
3392
3393 egl::Image *renderTarget = nullptr;
3394 switch(format)
3395 {
3396 case GL_DEPTH_COMPONENT: // GL_NV_read_depth
3397 case GL_DEPTH_STENCIL_OES: // GL_NV_read_depth_stencil
3398 renderTarget = framebuffer->getDepthBuffer();
3399 break;
3400 case GL_STENCIL_INDEX_OES: // GL_NV_read_stencil
3401 renderTarget = framebuffer->getStencilBuffer();
3402 break;
3403 default:
3404 renderTarget = framebuffer->getReadRenderTarget();
3405 break;
3406 }
3407
3408 if(!renderTarget)
3409 {
3410 return error(GL_INVALID_OPERATION);
3411 }
3412
3413 sw::SliceRectF srcRect((float)x, (float)y, (float)(x + width), (float)(y + height), 0);
3414 sw::SliceRect dstRect(0, 0, width, height, 0);
3415 srcRect.clip(0.0f, 0.0f, (float)renderTarget->getWidth(), (float)renderTarget->getHeight());
3416
3417 if(format != GL_DEPTH_STENCIL_OES) // The blitter only handles reading either depth or stencil.
3418 {
3419 sw::Surface *externalSurface = sw::Surface::create(width, height, 1, es2::ConvertReadFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
3420 device->blit(renderTarget, srcRect, externalSurface, dstRect, false, false, false);
3421 externalSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
3422 externalSurface->unlockExternal();
3423 delete externalSurface;
3424 }
3425 else // format == GL_DEPTH_STENCIL_OES
3426 {
3427 ASSERT(renderTarget->getInternalFormat() == sw::FORMAT_D32F_LOCKABLE);
3428 float *depth = (float*)renderTarget->lockInternal((int)srcRect.x0, (int)srcRect.y0, 0, sw::LOCK_READONLY, sw::PUBLIC);
3429 uint8_t *stencil = (uint8_t*)renderTarget->lockStencil((int)srcRect.x0, (int)srcRect.y0, 0, sw::PUBLIC);
3430
3431 switch(type)
3432 {
3433 case GL_UNSIGNED_INT_24_8_OES:
3434 {
3435 uint32_t *output = (uint32_t*)pixels;
3436
3437 for(int y = 0; y < height; y++)
3438 {
3439 for(int x = 0; x < width; x++)
3440 {
3441 output[x] = ((uint32_t)roundf(depth[x] * 0xFFFFFF00) & 0xFFFFFF00) | stencil[x];
3442 }
3443
3444 depth += renderTarget->getInternalPitchP();
3445 stencil += renderTarget->getStencilPitchB();
3446 (uint8_t*&)output += outputPitch;
3447 }
3448 }
3449 break;
3450 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
3451 {
3452 struct D32FS8 { float depth32f; unsigned int stencil24_8; };
3453 D32FS8 *output = (D32FS8*)pixels;
3454
3455 for(int y = 0; y < height; y++)
3456 {
3457 for(int x = 0; x < width; x++)
3458 {
3459 output[x].depth32f = depth[x];
3460 output[x].stencil24_8 = stencil[x];
3461 }
3462
3463 depth += renderTarget->getInternalPitchP();
3464 stencil += renderTarget->getStencilPitchB();
3465 (uint8_t*&)output += outputPitch;
3466 }
3467 }
3468 break;
3469 default: UNREACHABLE(type);
3470 }
3471
3472 renderTarget->unlockInternal();
3473 renderTarget->unlockStencil();
3474 }
3475
3476 renderTarget->release();
3477}
3478
3479void Context::clear(GLbitfield mask)
3480{
3481 if(mState.rasterizerDiscardEnabled)
3482 {
3483 return;
3484 }
3485
3486 Framebuffer *framebuffer = getDrawFramebuffer();
3487
3488 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3489 {
3490 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3491 }
3492
3493 if(!applyRenderTarget())
3494 {
3495 return;
3496 }
3497
3498 if(mask & GL_COLOR_BUFFER_BIT)
3499 {
3500 unsigned int rgbaMask = getColorMask();
3501
3502 if(rgbaMask != 0)
3503 {
3504 device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
3505 }
3506 }
3507
3508 if(mask & GL_DEPTH_BUFFER_BIT)
3509 {
3510 if(mState.depthMask != 0)
3511 {
3512 float depth = clamp01(mState.depthClearValue);
3513 device->clearDepth(depth);
3514 }
3515 }
3516
3517 if(mask & GL_STENCIL_BUFFER_BIT)
3518 {
3519 if(mState.stencilWritemask != 0)
3520 {
3521 int stencil = mState.stencilClearValue & 0x000000FF;
3522 device->clearStencil(stencil, mState.stencilWritemask);
3523 }
3524 }
3525}
3526
3527void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
3528{
3529 unsigned int rgbaMask = getColorMask();
3530 if(rgbaMask && !mState.rasterizerDiscardEnabled)
3531 {
3532 Framebuffer *framebuffer = getDrawFramebuffer();
3533 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3534 {
3535 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3536 }
3537 egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
3538
3539 if(colorbuffer)
3540 {
3541 sw::Rect clearRect = colorbuffer->getRect();
3542
3543 if(mState.scissorTestEnabled)
3544 {
3545 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3546 }
3547
3548 device->clear(value, format, colorbuffer, clearRect, rgbaMask);
3549
3550 colorbuffer->release();
3551 }
3552 }
3553}
3554
3555void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
3556{
3557 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
3558}
3559
3560void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
3561{
3562 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
3563}
3564
3565void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
3566{
3567 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
3568}
3569
3570void Context::clearDepthBuffer(const GLfloat value)
3571{
3572 if(mState.depthMask && !mState.rasterizerDiscardEnabled)
3573 {
3574 Framebuffer *framebuffer = getDrawFramebuffer();
3575 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3576 {
3577 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3578 }
3579 egl::Image *depthbuffer = framebuffer->getDepthBuffer();
3580
3581 if(depthbuffer)
3582 {
3583 float depth = clamp01(value);
3584 sw::Rect clearRect = depthbuffer->getRect();
3585
3586 if(mState.scissorTestEnabled)
3587 {
3588 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3589 }
3590
3591 depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3592
3593 depthbuffer->release();
3594 }
3595 }
3596}
3597
3598void Context::clearStencilBuffer(const GLint value)
3599{
3600 if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
3601 {
3602 Framebuffer *framebuffer = getDrawFramebuffer();
3603 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3604 {
3605 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3606 }
3607 egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
3608
3609 if(stencilbuffer)
3610 {
3611 unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);
3612 sw::Rect clearRect = stencilbuffer->getRect();
3613
3614 if(mState.scissorTestEnabled)
3615 {
3616 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3617 }
3618
3619 stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3620
3621 stencilbuffer->release();
3622 }
3623 }
3624}
3625
3626void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
3627{
3628 if(!applyRenderTarget())
3629 {
3630 return;
3631 }
3632
3633 if(mState.currentProgram == 0)
3634 {
3635 return; // Nothing to process.
3636 }
3637
3638 sw::DrawType primitiveType;
3639 int primitiveCount;
3640 int verticesPerPrimitive;
3641
3642 if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount, verticesPerPrimitive))
3643 {
3644 return error(GL_INVALID_ENUM);
3645 }
3646
3647 applyState(mode);
3648
3649 for(int i = 0; i < instanceCount; ++i)
3650 {
3651 device->setInstanceID(i);
3652
3653 GLenum err = applyVertexBuffer(0, first, count, i);
3654 if(err != GL_NO_ERROR)
3655 {
3656 return error(err);
3657 }
3658
3659 applyShaders();
3660 applyTextures();
3661
3662 if(!getCurrentProgram()->validateSamplers(false))
3663 {
3664 return error(GL_INVALID_OPERATION);
3665 }
3666
3667 if(primitiveCount <= 0)
3668 {
3669 return;
3670 }
3671
3672 TransformFeedback* transformFeedback = getTransformFeedback();
3673 if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3674 {
3675 device->drawPrimitive(primitiveType, primitiveCount);
3676 }
3677 if(transformFeedback)
3678 {
3679 transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
3680 }
3681 }
3682}
3683
3684void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
3685{
3686 if(!applyRenderTarget())
3687 {
3688 return;
3689 }
3690
3691 if(mState.currentProgram == 0)
3692 {
3693 return; // Nothing to process.
3694 }
3695
3696 if(count == 0)
3697 {
3698 return;
3699 }
3700
3701 if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
3702 {
3703 return error(GL_INVALID_OPERATION);
3704 }
3705
3706 GLenum internalMode = mode;
3707 if(isPrimitiveRestartFixedIndexEnabled())
3708 {
3709 switch(mode)
3710 {
3711 case GL_TRIANGLE_FAN:
3712 case GL_TRIANGLE_STRIP:
3713 internalMode = GL_TRIANGLES;
3714 break;
3715 case GL_LINE_LOOP:
3716 case GL_LINE_STRIP:
3717 internalMode = GL_LINES;
3718 break;
3719 default:
3720 break;
3721 }
3722 }
3723
3724 sw::DrawType primitiveType;
3725 int primitiveCount;
3726 int verticesPerPrimitive;
3727
3728 if(!es2sw::ConvertPrimitiveType(internalMode, count, type, primitiveType, primitiveCount, verticesPerPrimitive))
3729 {
3730 return error(GL_INVALID_ENUM);
3731 }
3732
3733 TranslatedIndexData indexInfo(primitiveCount);
3734 GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
3735 if(err != GL_NO_ERROR)
3736 {
3737 return error(err);
3738 }
3739
3740 applyState(internalMode);
3741
3742 for(int i = 0; i < instanceCount; ++i)
3743 {
3744 device->setInstanceID(i);
3745
3746 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
3747 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
3748 if(err != GL_NO_ERROR)
3749 {
3750 return error(err);
3751 }
3752
3753 applyShaders();
3754 applyTextures();
3755
3756 if(!getCurrentProgram()->validateSamplers(false))
3757 {
3758 return error(GL_INVALID_OPERATION);
3759 }
3760
3761 if(primitiveCount <= 0)
3762 {
3763 return;
3764 }
3765
3766 TransformFeedback* transformFeedback = getTransformFeedback();
3767 if(!cullSkipsDraw(internalMode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3768 {
3769 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, indexInfo.primitiveCount);
3770 }
3771 if(transformFeedback)
3772 {
3773 transformFeedback->addVertexOffset(indexInfo.primitiveCount * verticesPerPrimitive);
3774 }
3775 }
3776}
3777
3778void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
3779{
3780 sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
3781 device->blit(source, sRectF, dest, dRect, false);
3782}
3783
3784void Context::finish()
3785{
3786 device->finish();
3787}
3788
3789void Context::flush()
3790{
3791 // We don't queue anything without processing it as fast as possible
3792}
3793
3794void Context::recordInvalidEnum()
3795{
3796 mInvalidEnum = true;
3797}
3798
3799void Context::recordInvalidValue()
3800{
3801 mInvalidValue = true;
3802}
3803
3804void Context::recordInvalidOperation()
3805{
3806 mInvalidOperation = true;
3807}
3808
3809void Context::recordOutOfMemory()
3810{
3811 mOutOfMemory = true;
3812}
3813
3814void Context::recordInvalidFramebufferOperation()
3815{
3816 mInvalidFramebufferOperation = true;
3817}
3818
3819// Get one of the recorded errors and clear its flag, if any.
3820// [OpenGL ES 2.0.24] section 2.5 page 13.
3821GLenum Context::getError()
3822{
3823 if(mInvalidEnum)
3824 {
3825 mInvalidEnum = false;
3826
3827 return GL_INVALID_ENUM;
3828 }
3829
3830 if(mInvalidValue)
3831 {
3832 mInvalidValue = false;
3833
3834 return GL_INVALID_VALUE;
3835 }
3836
3837 if(mInvalidOperation)
3838 {
3839 mInvalidOperation = false;
3840
3841 return GL_INVALID_OPERATION;
3842 }
3843
3844 if(mOutOfMemory)
3845 {
3846 mOutOfMemory = false;
3847
3848 return GL_OUT_OF_MEMORY;
3849 }
3850
3851 if(mInvalidFramebufferOperation)
3852 {
3853 mInvalidFramebufferOperation = false;
3854
3855 return GL_INVALID_FRAMEBUFFER_OPERATION;
3856 }
3857
3858 return GL_NO_ERROR;
3859}
3860
3861int Context::getSupportedMultisampleCount(int requested)
3862{
3863 int supported = 0;
3864
3865 for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
3866 {
3867 if(supported >= requested)
3868 {
3869 return supported;
3870 }
3871
3872 supported = multisampleCount[i];
3873 }
3874
3875 return supported;
3876}
3877
3878void Context::detachBuffer(GLuint buffer)
3879{
3880 // [OpenGL ES 2.0.24] section 2.9 page 22:
3881 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3882 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3883
3884 if(mState.copyReadBuffer.name() == buffer)
3885 {
3886 mState.copyReadBuffer = nullptr;
3887 }
3888
3889 if(mState.copyWriteBuffer.name() == buffer)
3890 {
3891 mState.copyWriteBuffer = nullptr;
3892 }
3893
3894 if(mState.pixelPackBuffer.name() == buffer)
3895 {
3896 mState.pixelPackBuffer = nullptr;
3897 }
3898
3899 if(mState.pixelUnpackBuffer.name() == buffer)
3900 {
3901 mState.pixelUnpackBuffer = nullptr;
3902 }
3903
3904 if(mState.genericUniformBuffer.name() == buffer)
3905 {
3906 mState.genericUniformBuffer = nullptr;
3907 }
3908 if (mState.genericTransformFeedbackBuffer.name() == buffer)
3909 {
3910 mState.genericTransformFeedbackBuffer = nullptr;
3911 }
3912
3913 if(getArrayBufferName() == buffer)
3914 {
3915 mState.arrayBuffer = nullptr;
3916 }
3917
3918 // Only detach from the current transform feedback
3919 TransformFeedback* currentTransformFeedback = getTransformFeedback();
3920 if(currentTransformFeedback)
3921 {
3922 currentTransformFeedback->detachBuffer(buffer);
3923 }
3924
3925 // Only detach from the current vertex array
3926 VertexArray* currentVertexArray = getCurrentVertexArray();
3927 if(currentVertexArray)
3928 {
3929 currentVertexArray->detachBuffer(buffer);
3930 }
3931
3932 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3933 {
3934 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3935 {
3936 mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
3937 }
3938 }
3939}
3940
3941void Context::detachTexture(GLuint texture)
3942{
3943 // [OpenGL ES 2.0.24] section 3.8 page 84:
3944 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3945 // rebound to texture object zero
3946
3947 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3948 {
3949 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3950 {
3951 if(mState.samplerTexture[type][sampler].name() == texture)
3952 {
3953 mState.samplerTexture[type][sampler] = nullptr;
3954 }
3955 }
3956 }
3957
3958 // [OpenGL ES 2.0.24] section 4.4 page 112:
3959 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3960 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3961 // image was attached in the currently bound framebuffer.
3962
3963 Framebuffer *readFramebuffer = getReadFramebuffer();
3964 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3965
3966 if(readFramebuffer)
3967 {
3968 readFramebuffer->detachTexture(texture);
3969 }
3970
3971 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3972 {
3973 drawFramebuffer->detachTexture(texture);
3974 }
3975}
3976
3977void Context::detachFramebuffer(GLuint framebuffer)
3978{
3979 // [OpenGL ES 2.0.24] section 4.4 page 107:
3980 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3981 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3982
3983 if(mState.readFramebuffer == framebuffer)
3984 {
3985 bindReadFramebuffer(0);
3986 }
3987
3988 if(mState.drawFramebuffer == framebuffer)
3989 {
3990 bindDrawFramebuffer(0);
3991 }
3992}
3993
3994void Context::detachRenderbuffer(GLuint renderbuffer)
3995{
3996 // [OpenGL ES 2.0.24] section 4.4 page 109:
3997 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3998 // had been executed with the target RENDERBUFFER and name of zero.
3999
4000 if(mState.renderbuffer.name() == renderbuffer)
4001 {
4002 bindRenderbuffer(0);
4003 }
4004
4005 // [OpenGL ES 2.0.24] section 4.4 page 111:
4006 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
4007 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
4008 // point to which this image was attached in the currently bound framebuffer.
4009
4010 Framebuffer *readFramebuffer = getReadFramebuffer();
4011 Framebuffer *drawFramebuffer = getDrawFramebuffer();
4012
4013 if(readFramebuffer)
4014 {
4015 readFramebuffer->detachRenderbuffer(renderbuffer);
4016 }
4017
4018 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
4019 {
4020 drawFramebuffer->detachRenderbuffer(renderbuffer);
4021 }
4022}
4023
4024void Context::detachSampler(GLuint sampler)
4025{
4026 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
4027 // If a sampler object that is currently bound to one or more texture units is
4028 // deleted, it is as though BindSampler is called once for each texture unit to
4029 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
4030 for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
4031 {
4032 gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
4033 if(samplerBinding.name() == sampler)
4034 {
4035 samplerBinding = nullptr;
4036 }
4037 }
4038}
4039
4040bool Context::cullSkipsDraw(GLenum drawMode)
4041{
4042 return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
4043}
4044
4045bool Context::isTriangleMode(GLenum drawMode)
4046{
4047 switch(drawMode)
4048 {
4049 case GL_TRIANGLES:
4050 case GL_TRIANGLE_FAN:
4051 case GL_TRIANGLE_STRIP:
4052 return true;
4053 case GL_POINTS:
4054 case GL_LINES:
4055 case GL_LINE_LOOP:
4056 case GL_LINE_STRIP:
4057 return false;
4058 default: UNREACHABLE(drawMode);
4059 }
4060
4061 return false;
4062}
4063
4064void Context::setVertexAttrib(GLuint index, const GLfloat *values)
4065{
4066 ASSERT(index < MAX_VERTEX_ATTRIBS);
4067
4068 mState.vertexAttribute[index].setCurrentValue(values);
4069
4070 mVertexDataManager->dirtyCurrentValue(index);
4071}
4072
4073void Context::setVertexAttrib(GLuint index, const GLint *values)
4074{
4075 ASSERT(index < MAX_VERTEX_ATTRIBS);
4076
4077 mState.vertexAttribute[index].setCurrentValue(values);
4078
4079 mVertexDataManager->dirtyCurrentValue(index);
4080}
4081
4082void Context::setVertexAttrib(GLuint index, const GLuint *values)
4083{
4084 ASSERT(index < MAX_VERTEX_ATTRIBS);
4085
4086 mState.vertexAttribute[index].setCurrentValue(values);
4087
4088 mVertexDataManager->dirtyCurrentValue(index);
4089}
4090
4091void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4092 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4093 GLbitfield mask, bool filter, bool allowPartialDepthStencilBlit)
4094{
4095 Framebuffer *readFramebuffer = getReadFramebuffer();
4096 Framebuffer *drawFramebuffer = getDrawFramebuffer();
4097
4098 int readBufferWidth, readBufferHeight, readBufferSamples;
4099 int drawBufferWidth, drawBufferHeight, drawBufferSamples;
4100
4101 if(!readFramebuffer || (readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE) ||
4102 !drawFramebuffer || (drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE))
4103 {
4104 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
4105 }
4106
4107 if(drawBufferSamples > 1)
4108 {
4109 return error(GL_INVALID_OPERATION);
4110 }
4111
4112 sw::SliceRect sourceRect;
4113 sw::SliceRect destRect;
4114 bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
4115 bool flipY = (srcY0 < srcY1) ^ (dstY0 < dstY1);
4116
4117 if(srcX0 < srcX1)
4118 {
4119 sourceRect.x0 = srcX0;
4120 sourceRect.x1 = srcX1;
4121 }
4122 else
4123 {
4124 sourceRect.x0 = srcX1;
4125 sourceRect.x1 = srcX0;
4126 }
4127
4128 if(dstX0 < dstX1)
4129 {
4130 destRect.x0 = dstX0;
4131 destRect.x1 = dstX1;
4132 }
4133 else
4134 {
4135 destRect.x0 = dstX1;
4136 destRect.x1 = dstX0;
4137 }
4138
4139 if(srcY0 < srcY1)
4140 {
4141 sourceRect.y0 = srcY0;
4142 sourceRect.y1 = srcY1;
4143 }
4144 else
4145 {
4146 sourceRect.y0 = srcY1;
4147 sourceRect.y1 = srcY0;
4148 }
4149
4150 if(dstY0 < dstY1)
4151 {
4152 destRect.y0 = dstY0;
4153 destRect.y1 = dstY1;
4154 }
4155 else
4156 {
4157 destRect.y0 = dstY1;
4158 destRect.y1 = dstY0;
4159 }
4160
4161 sw::RectF sourceScissoredRect(static_cast<float>(sourceRect.x0), static_cast<float>(sourceRect.y0),
4162 static_cast<float>(sourceRect.x1), static_cast<float>(sourceRect.y1));
4163 sw::Rect destScissoredRect = destRect;
4164
4165 if(mState.scissorTestEnabled) // Only write to parts of the destination framebuffer which pass the scissor test
4166 {
4167 sw::Rect scissorRect(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
4168 if (!Device::ClipDstRect(sourceScissoredRect, destScissoredRect, scissorRect, flipX, flipY))
4169 {
4170 // Failed to clip, blitting can't happen.
4171 return error(GL_INVALID_OPERATION);
4172 }
4173 }
4174
4175 sw::SliceRectF sourceTrimmedRect = sourceScissoredRect;
4176 sw::SliceRect destTrimmedRect = destScissoredRect;
4177
4178 // The source & destination rectangles also may need to be trimmed if
4179 // they fall out of the bounds of the actual draw and read surfaces.
4180 sw::Rect sourceTrimRect(0, 0, readBufferWidth, readBufferHeight);
4181 if (!Device::ClipSrcRect(sourceTrimmedRect, destTrimmedRect, sourceTrimRect, flipX, flipY))
4182 {
4183 // Failed to clip, blitting can't happen.
4184 return error(GL_INVALID_OPERATION);
4185 }
4186
4187 sw::Rect destTrimRect(0, 0, drawBufferWidth, drawBufferHeight);
4188 if (!Device::ClipDstRect(sourceTrimmedRect, destTrimmedRect, destTrimRect, flipX, flipY))
4189 {
4190 // Failed to clip, blitting can't happen.
4191 return error(GL_INVALID_OPERATION);
4192 }
4193
4194 bool partialBufferCopy = false;
4195
4196 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
4197 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
4198 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
4199 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
4200 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
4201 {
4202 partialBufferCopy = true;
4203 }
4204
4205 bool sameBounds = (srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1);
4206 bool blitRenderTarget = false;
4207 bool blitDepth = false;
4208 bool blitStencil = false;
4209
4210 if(mask & GL_COLOR_BUFFER_BIT)
4211 {
4212 GLenum readColorbufferType = readFramebuffer->getReadBufferType();
4213 GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);
4214 const bool validReadType = readColorbufferType == GL_TEXTURE_2D || readColorbufferType == GL_TEXTURE_RECTANGLE_ARB || readColorbufferType == GL_TEXTURE_2D_ARRAY || readColorbufferType == GL_TEXTURE_3D || Framebuffer::IsRenderbuffer(readColorbufferType);
4215 const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || drawColorbufferType == GL_TEXTURE_RECTANGLE_ARB || readColorbufferType == GL_TEXTURE_2D_ARRAY || readColorbufferType == GL_TEXTURE_3D || Framebuffer::IsRenderbuffer(drawColorbufferType);
4216 if(!validReadType || !validDrawType)
4217 {
4218 return error(GL_INVALID_OPERATION);
4219 }
4220
4221 if(partialBufferCopy && readBufferSamples > 1 && !sameBounds)
4222 {
4223 return error(GL_INVALID_OPERATION);
4224 }
4225
4226 // The GL ES 3.0.2 spec (pg 193) states that:
4227 // 1) If the read buffer is fixed point format, the draw buffer must be as well
4228 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
4229 // as well
4230 // 3) If the read buffer is a signed integer format, the draw buffer must be as
4231 // well
4232 es2::Renderbuffer *readRenderbuffer = readFramebuffer->getReadColorbuffer();
4233 es2::Renderbuffer *drawRenderbuffer = drawFramebuffer->getColorbuffer(0);
4234 GLint readFormat = readRenderbuffer->getFormat();
4235 GLint drawFormat = drawRenderbuffer->getFormat();
4236 GLenum readComponentType = GetComponentType(readFormat, GL_COLOR_ATTACHMENT0);
4237 GLenum drawComponentType = GetComponentType(drawFormat, GL_COLOR_ATTACHMENT0);
4238 bool readFixedPoint = ((readComponentType == GL_UNSIGNED_NORMALIZED) ||
4239 (readComponentType == GL_SIGNED_NORMALIZED));
4240 bool drawFixedPoint = ((drawComponentType == GL_UNSIGNED_NORMALIZED) ||
4241 (drawComponentType == GL_SIGNED_NORMALIZED));
4242 bool readFixedOrFloat = (readFixedPoint || (readComponentType == GL_FLOAT));
4243 bool drawFixedOrFloat = (drawFixedPoint || (drawComponentType == GL_FLOAT));
4244
4245 if(readFixedOrFloat != drawFixedOrFloat)
4246 {
4247 return error(GL_INVALID_OPERATION);
4248 }
4249
4250 if((readComponentType == GL_UNSIGNED_INT) && (drawComponentType != GL_UNSIGNED_INT))
4251 {
4252 return error(GL_INVALID_OPERATION);
4253 }
4254
4255 if((readComponentType == GL_INT) && (drawComponentType != GL_INT))
4256 {
4257 return error(GL_INVALID_OPERATION);
4258 }
4259
4260 // Cannot filter integer data
4261 if(((readComponentType == GL_UNSIGNED_INT) || (readComponentType == GL_INT)) && filter)
4262 {
4263 return error(GL_INVALID_OPERATION);
4264 }
4265
4266 if((readRenderbuffer->getSamples() > 0) && (readFormat != drawFormat))
4267 {
4268 // RGBA8 and BGRA8 should be interchangeable here
4269 if(!(((readFormat == GL_RGBA8) && (drawFormat == GL_BGRA8_EXT)) ||
4270 ((readFormat == GL_BGRA8_EXT) && (drawFormat == GL_RGBA8))))
4271 {
4272 return error(GL_INVALID_OPERATION);
4273 }
4274 }
4275
4276 blitRenderTarget = true;
4277 }
4278
4279 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
4280 {
4281 Renderbuffer *readDSBuffer = nullptr;
4282 Renderbuffer *drawDSBuffer = nullptr;
4283
4284 if(mask & GL_DEPTH_BUFFER_BIT)
4285 {
4286 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
4287 {
4288 GLenum readDepthBufferType = readFramebuffer->getDepthbufferType();
4289 GLenum drawDepthBufferType = drawFramebuffer->getDepthbufferType();
4290 if((readDepthBufferType != drawDepthBufferType) &&
4291 !(Framebuffer::IsRenderbuffer(readDepthBufferType) && Framebuffer::IsRenderbuffer(drawDepthBufferType)))
4292 {
4293 return error(GL_INVALID_OPERATION);
4294 }
4295
4296 blitDepth = true;
4297 readDSBuffer = readFramebuffer->getDepthbuffer();
4298 drawDSBuffer = drawFramebuffer->getDepthbuffer();
4299
4300 if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4301 {
4302 return error(GL_INVALID_OPERATION);
4303 }
4304 }
4305 }
4306
4307 if(mask & GL_STENCIL_BUFFER_BIT)
4308 {
4309 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
4310 {
4311 GLenum readStencilBufferType = readFramebuffer->getStencilbufferType();
4312 GLenum drawStencilBufferType = drawFramebuffer->getStencilbufferType();
4313 if((readStencilBufferType != drawStencilBufferType) &&
4314 !(Framebuffer::IsRenderbuffer(readStencilBufferType) && Framebuffer::IsRenderbuffer(drawStencilBufferType)))
4315 {
4316 return error(GL_INVALID_OPERATION);
4317 }
4318
4319 blitStencil = true;
4320 readDSBuffer = readFramebuffer->getStencilbuffer();
4321 drawDSBuffer = drawFramebuffer->getStencilbuffer();
4322
4323 if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4324 {
4325 return error(GL_INVALID_OPERATION);
4326 }
4327 }
4328 }
4329
4330 if(partialBufferCopy && !allowPartialDepthStencilBlit)
4331 {
4332 ERR("Only whole-buffer depth and stencil blits are supported by ANGLE_framebuffer_blit.");
4333 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted
4334 }
4335
4336 // OpenGL ES 3.0.4 spec, p.199:
4337 // ...an INVALID_OPERATION error is generated if the formats of the read
4338 // and draw framebuffers are not identical or if the source and destination
4339 // rectangles are not defined with the same(X0, Y 0) and (X1, Y 1) bounds.
4340 // If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, an
4341 // INVALID_OPERATION error is generated.
4342 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
4343 ((readDSBuffer && readDSBuffer->getSamples() > 1) &&
4344 (!sameBounds || (drawDSBuffer->getFormat() != readDSBuffer->getFormat()))))
4345 {
4346 return error(GL_INVALID_OPERATION);
4347 }
4348 }
4349
4350 if(blitRenderTarget || blitDepth || blitStencil)
4351 {
4352 if(flipX)
4353 {
4354 swap(destTrimmedRect.x0, destTrimmedRect.x1);
4355 }
4356 if(flipY)
4357 {
4358 swap(destTrimmedRect.y0, destTrimmedRect.y1);
4359 }
4360
4361 if(blitRenderTarget)
4362 {
4363 egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
4364 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
4365
4366 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::COLOR_BUFFER);
4367
4368 readRenderTarget->release();
4369 drawRenderTarget->release();
4370
4371 if(!success)
4372 {
4373 ERR("BlitFramebuffer failed.");
4374 return;
4375 }
4376 }
4377
4378 if(blitDepth)
4379 {
4380 egl::Image *readRenderTarget = readFramebuffer->getDepthBuffer();
4381 egl::Image *drawRenderTarget = drawFramebuffer->getDepthBuffer();
4382
4383 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::DEPTH_BUFFER);
4384
4385 readRenderTarget->release();
4386 drawRenderTarget->release();
4387
4388 if(!success)
4389 {
4390 ERR("BlitFramebuffer failed.");
4391 return;
4392 }
4393 }
4394
4395 if(blitStencil)
4396 {
4397 egl::Image *readRenderTarget = readFramebuffer->getStencilBuffer();
4398 egl::Image *drawRenderTarget = drawFramebuffer->getStencilBuffer();
4399
4400 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::STENCIL_BUFFER);
4401
4402 readRenderTarget->release();
4403 drawRenderTarget->release();
4404
4405 if(!success)
4406 {
4407 ERR("BlitFramebuffer failed.");
4408 return;
4409 }
4410 }
4411 }
4412}
4413
4414void Context::bindTexImage(gl::Surface *surface)
4415{
4416 bool isRect = (surface->getTextureTarget() == EGL_TEXTURE_RECTANGLE_ANGLE);
4417 es2::Texture2D *textureObject = isRect ? getTexture2DRect() : getTexture2D();
4418
4419 if(textureObject)
4420 {
4421 textureObject->bindTexImage(surface);
4422 }
4423}
4424
4425EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4426{
4427 GLenum textureTarget = GL_NONE;
4428
4429 switch(target)
4430 {
4431 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break;
4432 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4433 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4434 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4435 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4436 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4437 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4438 case EGL_GL_RENDERBUFFER_KHR:
4439 break;
4440 default:
4441 return EGL_BAD_PARAMETER;
4442 }
4443
4444 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4445 {
4446 return EGL_BAD_MATCH;
4447 }
4448
4449 if(textureTarget != GL_NONE)
4450 {
4451 es2::Texture *texture = getTexture(name);
4452
4453 if(!texture)
4454 {
4455 return EGL_BAD_PARAMETER;
4456 }
4457
4458 if (texture->getTarget() != GL_TEXTURE_CUBE_MAP && texture->getTarget() != textureTarget)
4459 {
4460 return EGL_BAD_PARAMETER;
4461 }
4462
4463 if (texture->getTarget() == GL_TEXTURE_CUBE_MAP && !IsCubemapTextureTarget(textureTarget))
4464 {
4465 return EGL_BAD_PARAMETER;
4466 }
4467
4468 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
4469 {
4470 return EGL_BAD_ACCESS;
4471 }
4472
4473 if(textureLevel != 0 && !texture->isSamplerComplete(nullptr))
4474 {
4475 return EGL_BAD_PARAMETER;
4476 }
4477
4478 if(textureLevel == 0 && !texture->isSamplerComplete(nullptr) && texture->hasNonBaseLevels())
4479 {
4480 return EGL_BAD_PARAMETER;
4481 }
4482 }
4483 else if(target == EGL_GL_RENDERBUFFER_KHR)
4484 {
4485 es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4486
4487 if(!renderbuffer)
4488 {
4489 return EGL_BAD_PARAMETER;
4490 }
4491
4492 if(renderbuffer->isShared()) // Already an EGLImage sibling
4493 {
4494 return EGL_BAD_ACCESS;
4495 }
4496 }
4497 else UNREACHABLE(target);
4498
4499 return EGL_SUCCESS;
4500}
4501
4502egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4503{
4504 GLenum textureTarget = GL_NONE;
4505
4506 switch(target)
4507 {
4508 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break;
4509 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4510 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4511 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4512 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4513 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4514 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4515 }
4516
4517 if(textureTarget != GL_NONE)
4518 {
4519 es2::Texture *texture = getTexture(name);
4520
4521 return texture->createSharedImage(textureTarget, textureLevel);
4522 }
4523 else if(target == EGL_GL_RENDERBUFFER_KHR)
4524 {
4525 es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4526
4527 return renderbuffer->createSharedImage();
4528 }
4529 else UNREACHABLE(target);
4530
4531 return nullptr;
4532}
4533
4534egl::Image *Context::getSharedImage(GLeglImageOES image)
4535{
4536 return display->getSharedImage(image);
4537}
4538
4539Device *Context::getDevice()
4540{
4541 return device;
4542}
4543
4544const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const
4545{
4546 // Keep list sorted in following order:
4547 // OES extensions
4548 // EXT extensions
4549 // Vendor extensions
4550 static const char *extensions[] =
4551 {
4552 "GL_OES_compressed_ETC1_RGB8_texture",
4553 "GL_OES_depth24",
4554 "GL_OES_depth32",
4555 "GL_OES_depth_texture",
4556 "GL_OES_depth_texture_cube_map",
4557 "GL_OES_EGL_image",
4558 "GL_OES_EGL_image_external",
4559 "GL_OES_EGL_image_external_essl3", // client version is always 3, so this is fine
4560 "GL_OES_EGL_sync",
4561 "GL_OES_element_index_uint",
4562 "GL_OES_fbo_render_mipmap",
4563 "GL_OES_framebuffer_object",
4564 "GL_OES_packed_depth_stencil",
4565 "GL_OES_rgb8_rgba8",
4566 "GL_OES_standard_derivatives",
4567 "GL_OES_surfaceless_context",
4568 "GL_OES_texture_float",
4569 "GL_OES_texture_float_linear",
4570 "GL_OES_texture_half_float",
4571 "GL_OES_texture_half_float_linear",
4572 "GL_OES_texture_npot",
4573 "GL_OES_texture_3D",
4574 "GL_OES_vertex_array_object",
4575 "GL_OES_vertex_half_float",
4576 "GL_EXT_blend_minmax",
4577 "GL_EXT_color_buffer_float", // OpenGL ES 3.0 specific.
4578 "GL_EXT_color_buffer_half_float",
4579 "GL_EXT_draw_buffers",
4580 "GL_EXT_float_blend",
4581 "GL_EXT_instanced_arrays",
4582 "GL_EXT_occlusion_query_boolean",
4583 "GL_EXT_read_format_bgra",
4584 "GL_EXT_texture_compression_dxt1",
4585 "GL_EXT_texture_filter_anisotropic",
4586 "GL_EXT_texture_format_BGRA8888",
4587 "GL_EXT_texture_rg",
4588#if (ASTC_SUPPORT)
4589 "GL_KHR_texture_compression_astc_hdr",
4590 "GL_KHR_texture_compression_astc_ldr",
4591#endif
4592 "GL_ARB_texture_rectangle",
4593 "GL_ANGLE_framebuffer_blit",
4594 "GL_ANGLE_framebuffer_multisample",
4595 "GL_ANGLE_instanced_arrays",
4596 "GL_ANGLE_texture_compression_dxt3",
4597 "GL_ANGLE_texture_compression_dxt5",
4598 "GL_APPLE_texture_format_BGRA8888",
4599 "GL_CHROMIUM_color_buffer_float_rgba", // A subset of EXT_color_buffer_float on top of OpenGL ES 2.0
4600 "GL_CHROMIUM_texture_filtering_hint",
4601 "GL_NV_depth_buffer_float2",
4602 "GL_NV_fence",
4603 "GL_NV_framebuffer_blit",
4604 "GL_NV_read_depth",
4605 "GL_NV_read_depth_stencil",
4606 "GL_NV_read_stencil",
4607 };
4608
4609 GLuint numExtensions = sizeof(extensions) / sizeof(extensions[0]);
4610
4611 if(numExt)
4612 {
4613 *numExt = numExtensions;
4614
4615 return nullptr;
4616 }
4617
4618 if(index == GL_INVALID_INDEX)
4619 {
4620 static std::string extensionsCat;
4621
4622 if(extensionsCat.empty() && (numExtensions > 0))
4623 {
4624 for(const char *extension : extensions)
4625 {
4626 extensionsCat += std::string(extension) + " ";
4627 }
4628 }
4629
4630 return (const GLubyte*)extensionsCat.c_str();
4631 }
4632
4633 if(index >= numExtensions)
4634 {
4635 return nullptr;
4636 }
4637
4638 return (const GLubyte*)extensions[index];
4639}
4640
4641}
4642
4643NO_SANITIZE_FUNCTION egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config)
4644{
4645 return new es2::Context(display, static_cast<const es2::Context*>(shareContext), config);
4646}
4647