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