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