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