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