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