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 gl::Context class, managing all GL state and performing
16// rendering operations.
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 "Shader.h"
31#include "Texture.h"
32#include "VertexDataManager.h"
33#include "IndexDataManager.h"
34#include "Display.h"
35#include "Surface.h"
36#include "Common/Half.hpp"
37
38#define _GDI32_
39#include <windows.h>
40#include <GL/GL.h>
41#include <GL/glext.h>
42
43namespace gl
44{
45Context::Context(const Context *shareContext)
46	: modelView(32),
47	  projection(2)
48{
49	sw::Context *context = new sw::Context();
50	device = new gl::Device(context);
51
52	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
53
54	mState.depthClearValue = 1.0f;
55	mState.stencilClearValue = 0;
56
57	mState.cullFaceEnabled = false;
58	mState.cullMode = GL_BACK;
59	mState.frontFace = GL_CCW;
60	mState.depthTestEnabled = false;
61	mState.depthFunc = GL_LESS;
62	mState.blendEnabled = false;
63	mState.sourceBlendRGB = GL_ONE;
64	mState.sourceBlendAlpha = GL_ONE;
65	mState.destBlendRGB = GL_ZERO;
66	mState.destBlendAlpha = GL_ZERO;
67	mState.blendEquationRGB = GL_FUNC_ADD;
68	mState.blendEquationAlpha = GL_FUNC_ADD;
69	mState.blendColor.red = 0;
70	mState.blendColor.green = 0;
71	mState.blendColor.blue = 0;
72	mState.blendColor.alpha = 0;
73	mState.stencilTestEnabled = false;
74	mState.stencilFunc = GL_ALWAYS;
75	mState.stencilRef = 0;
76	mState.stencilMask = -1;
77	mState.stencilWritemask = -1;
78	mState.stencilBackFunc = GL_ALWAYS;
79	mState.stencilBackRef = 0;
80	mState.stencilBackMask = - 1;
81	mState.stencilBackWritemask = -1;
82	mState.stencilFail = GL_KEEP;
83	mState.stencilPassDepthFail = GL_KEEP;
84	mState.stencilPassDepthPass = GL_KEEP;
85	mState.stencilBackFail = GL_KEEP;
86	mState.stencilBackPassDepthFail = GL_KEEP;
87	mState.stencilBackPassDepthPass = GL_KEEP;
88	mState.polygonOffsetFillEnabled = false;
89	mState.polygonOffsetFactor = 0.0f;
90	mState.polygonOffsetUnits = 0.0f;
91	mState.sampleAlphaToCoverageEnabled = false;
92	mState.sampleCoverageEnabled = false;
93	mState.sampleCoverageValue = 1.0f;
94	mState.sampleCoverageInvert = false;
95	mState.scissorTestEnabled = false;
96	mState.ditherEnabled = true;
97	mState.generateMipmapHint = GL_DONT_CARE;
98	mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
99	mState.colorLogicOpEnabled = false;
100	mState.logicalOperation = GL_COPY;
101
102	mState.lineWidth = 1.0f;
103
104	mState.viewportX = 0;
105	mState.viewportY = 0;
106	mState.viewportWidth = 0;
107	mState.viewportHeight = 0;
108	mState.zNear = 0.0f;
109	mState.zFar = 1.0f;
110
111	mState.scissorX = 0;
112	mState.scissorY = 0;
113	mState.scissorWidth = 0;
114	mState.scissorHeight = 0;
115
116	mState.colorMaskRed = true;
117	mState.colorMaskGreen = true;
118	mState.colorMaskBlue = true;
119	mState.colorMaskAlpha = true;
120	mState.depthMask = true;
121
122	if(shareContext)
123	{
124		mResourceManager = shareContext->mResourceManager;
125		mResourceManager->addRef();
126	}
127	else
128	{
129		mResourceManager = new ResourceManager();
130	}
131
132	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
133	// and cube map texture state vectors respectively associated with them.
134	// In order that access to these initial textures not be lost, they are treated as texture
135	// objects all of whose names are 0.
136
137	mTexture2DZero = new Texture2D(0);
138	mProxyTexture2DZero = new Texture2D(0);
139	mTextureCubeMapZero = new TextureCubeMap(0);
140
141	mState.activeSampler = 0;
142	bindArrayBuffer(0);
143	bindElementArrayBuffer(0);
144	bindTextureCubeMap(0);
145	bindTexture2D(0);
146	bindReadFramebuffer(0);
147	bindDrawFramebuffer(0);
148	bindRenderbuffer(0);
149
150	mState.currentProgram = 0;
151
152	mState.packAlignment = 4;
153	mState.unpackAlignment = 4;
154
155	mVertexDataManager = nullptr;
156	mIndexDataManager = nullptr;
157
158	mInvalidEnum = false;
159	mInvalidValue = false;
160	mInvalidOperation = false;
161	mOutOfMemory = false;
162	mInvalidFramebufferOperation = false;
163
164	mHasBeenCurrent = false;
165
166	markAllStateDirty();
167
168	matrixMode = GL_MODELVIEW;
169
170	listMode = 0;
171	//memset(displayList, 0, sizeof(displayList));
172	listIndex = 0;
173	list = 0;
174	firstFreeIndex = 1;
175
176	clientTexture = GL_TEXTURE0;
177
178	drawing = false;
179	drawMode = 0;   // FIXME
180
181	mState.vertexAttribute[sw::Color0].mCurrentValue[0] = 1.0f;
182	mState.vertexAttribute[sw::Color0].mCurrentValue[1] = 1.0f;
183	mState.vertexAttribute[sw::Color0].mCurrentValue[2] = 1.0f;
184	mState.vertexAttribute[sw::Color0].mCurrentValue[3] = 1.0f;
185	mState.vertexAttribute[sw::Normal].mCurrentValue[0] = 0.0f;
186	mState.vertexAttribute[sw::Normal].mCurrentValue[1] = 0.0f;
187	mState.vertexAttribute[sw::Normal].mCurrentValue[2] = 1.0f;
188	mState.vertexAttribute[sw::Normal].mCurrentValue[3] = 0.0f;
189	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0] = 0.0f;
190	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1] = 0.0f;
191	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2] = 0.0f;
192	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3] = 1.0f;
193	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0] = 0.0f;
194	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1] = 0.0f;
195	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2] = 0.0f;
196	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3] = 1.0f;
197
198	for(int i = 0; i < 8; i++)
199	{
200		envEnable[i] = true;
201	}
202}
203
204Context::~Context()
205{
206	if(mState.currentProgram != 0)
207	{
208		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
209		if(programObject)
210		{
211			programObject->release();
212		}
213		mState.currentProgram = 0;
214	}
215
216	while(!mFramebufferNameSpace.empty())
217	{
218		deleteFramebuffer(mFramebufferNameSpace.firstName());
219	}
220
221	while(!mFenceNameSpace.empty())
222	{
223		deleteFence(mFenceNameSpace.firstName());
224	}
225
226	while(!mQueryNameSpace.empty())
227	{
228		deleteQuery(mQueryNameSpace.firstName());
229	}
230
231	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
232	{
233		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
234		{
235			mState.samplerTexture[type][sampler] = nullptr;
236		}
237	}
238
239	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
240	{
241		mState.vertexAttribute[i].mBoundBuffer = nullptr;
242	}
243
244	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
245	{
246		mState.activeQuery[i] = nullptr;
247	}
248
249	mState.arrayBuffer = nullptr;
250	mState.elementArrayBuffer = nullptr;
251	mState.renderbuffer = nullptr;
252
253	mTexture2DZero = nullptr;
254	mProxyTexture2DZero = nullptr;
255	mTextureCubeMapZero = nullptr;
256
257	delete mVertexDataManager;
258	delete mIndexDataManager;
259
260	mResourceManager->release();
261	delete device;
262}
263
264void Context::makeCurrent(Surface *surface)
265{
266	if(!mHasBeenCurrent)
267	{
268		mVertexDataManager = new VertexDataManager(this);
269		mIndexDataManager = new IndexDataManager();
270
271		mState.viewportX = 0;
272		mState.viewportY = 0;
273		mState.viewportWidth = surface->getWidth();
274		mState.viewportHeight = surface->getHeight();
275
276		mState.scissorX = 0;
277		mState.scissorY = 0;
278		mState.scissorWidth = surface->getWidth();
279		mState.scissorHeight = surface->getHeight();
280
281		mHasBeenCurrent = true;
282	}
283
284	// Wrap the existing resources into GL objects and assign them to the '0' names
285	Image *defaultRenderTarget = surface->getRenderTarget();
286	Image *depthStencil = surface->getDepthStencil();
287
288	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
289	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
290	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
291
292	setFramebufferZero(framebufferZero);
293
294	if(defaultRenderTarget)
295	{
296		defaultRenderTarget->release();
297	}
298
299	if(depthStencil)
300	{
301		depthStencil->release();
302	}
303
304	markAllStateDirty();
305}
306
307// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
308void Context::markAllStateDirty()
309{
310	mAppliedProgramSerial = 0;
311
312	mDepthStateDirty = true;
313	mMaskStateDirty = true;
314	mBlendStateDirty = true;
315	mStencilStateDirty = true;
316	mPolygonOffsetStateDirty = true;
317	mSampleStateDirty = true;
318	mDitherStateDirty = true;
319	mFrontFaceDirty = true;
320	mColorLogicOperatorDirty = true;
321}
322
323void Context::setClearColor(float red, float green, float blue, float alpha)
324{
325	mState.colorClearValue.red = red;
326	mState.colorClearValue.green = green;
327	mState.colorClearValue.blue = blue;
328	mState.colorClearValue.alpha = alpha;
329}
330
331void Context::setClearDepth(float depth)
332{
333	mState.depthClearValue = depth;
334}
335
336void Context::setClearStencil(int stencil)
337{
338	mState.stencilClearValue = stencil;
339}
340
341void Context::setCullFaceEnabled(bool enabled)
342{
343	mState.cullFaceEnabled = enabled;
344}
345
346bool Context::isCullFaceEnabled() const
347{
348	return mState.cullFaceEnabled;
349}
350
351void Context::setCullMode(GLenum mode)
352{
353   mState.cullMode = mode;
354}
355
356void Context::setFrontFace(GLenum front)
357{
358	if(mState.frontFace != front)
359	{
360		mState.frontFace = front;
361		mFrontFaceDirty = true;
362	}
363}
364
365void Context::setDepthTestEnabled(bool enabled)
366{
367	if(mState.depthTestEnabled != enabled)
368	{
369		mState.depthTestEnabled = enabled;
370		mDepthStateDirty = true;
371	}
372}
373
374bool Context::isDepthTestEnabled() const
375{
376	return mState.depthTestEnabled;
377}
378
379void Context::setDepthFunc(GLenum depthFunc)
380{
381	if(mState.depthFunc != depthFunc)
382	{
383		mState.depthFunc = depthFunc;
384		mDepthStateDirty = true;
385	}
386}
387
388void Context::setDepthRange(float zNear, float zFar)
389{
390	mState.zNear = zNear;
391	mState.zFar = zFar;
392}
393
394void Context::setBlendEnabled(bool enabled)
395{
396	if(mState.blendEnabled != enabled)
397	{
398		mState.blendEnabled = enabled;
399		mBlendStateDirty = true;
400	}
401}
402
403bool Context::isBlendEnabled() const
404{
405	return mState.blendEnabled;
406}
407
408void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
409{
410	if(mState.sourceBlendRGB != sourceRGB ||
411	   mState.sourceBlendAlpha != sourceAlpha ||
412	   mState.destBlendRGB != destRGB ||
413	   mState.destBlendAlpha != destAlpha)
414	{
415		mState.sourceBlendRGB = sourceRGB;
416		mState.destBlendRGB = destRGB;
417		mState.sourceBlendAlpha = sourceAlpha;
418		mState.destBlendAlpha = destAlpha;
419		mBlendStateDirty = true;
420	}
421}
422
423void Context::setBlendColor(float red, float green, float blue, float alpha)
424{
425	if(mState.blendColor.red != red ||
426	   mState.blendColor.green != green ||
427	   mState.blendColor.blue != blue ||
428	   mState.blendColor.alpha != alpha)
429	{
430		mState.blendColor.red = red;
431		mState.blendColor.green = green;
432		mState.blendColor.blue = blue;
433		mState.blendColor.alpha = alpha;
434		mBlendStateDirty = true;
435	}
436}
437
438void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
439{
440	if(mState.blendEquationRGB != rgbEquation ||
441	   mState.blendEquationAlpha != alphaEquation)
442	{
443		mState.blendEquationRGB = rgbEquation;
444		mState.blendEquationAlpha = alphaEquation;
445		mBlendStateDirty = true;
446	}
447}
448
449void Context::setStencilTestEnabled(bool enabled)
450{
451	if(mState.stencilTestEnabled != enabled)
452	{
453		mState.stencilTestEnabled = enabled;
454		mStencilStateDirty = true;
455	}
456}
457
458bool Context::isStencilTestEnabled() const
459{
460	return mState.stencilTestEnabled;
461}
462
463void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
464{
465	if(mState.stencilFunc != stencilFunc ||
466	   mState.stencilRef != stencilRef ||
467	   mState.stencilMask != stencilMask)
468	{
469		mState.stencilFunc = stencilFunc;
470		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
471		mState.stencilMask = stencilMask;
472		mStencilStateDirty = true;
473	}
474}
475
476void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
477{
478	if(mState.stencilBackFunc != stencilBackFunc ||
479	   mState.stencilBackRef != stencilBackRef ||
480	   mState.stencilBackMask != stencilBackMask)
481	{
482		mState.stencilBackFunc = stencilBackFunc;
483		mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
484		mState.stencilBackMask = stencilBackMask;
485		mStencilStateDirty = true;
486	}
487}
488
489void Context::setStencilWritemask(GLuint stencilWritemask)
490{
491	if(mState.stencilWritemask != stencilWritemask)
492	{
493		mState.stencilWritemask = stencilWritemask;
494		mStencilStateDirty = true;
495	}
496}
497
498void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
499{
500	if(mState.stencilBackWritemask != stencilBackWritemask)
501	{
502		mState.stencilBackWritemask = stencilBackWritemask;
503		mStencilStateDirty = true;
504	}
505}
506
507void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
508{
509	if(mState.stencilFail != stencilFail ||
510	   mState.stencilPassDepthFail != stencilPassDepthFail ||
511	   mState.stencilPassDepthPass != stencilPassDepthPass)
512	{
513		mState.stencilFail = stencilFail;
514		mState.stencilPassDepthFail = stencilPassDepthFail;
515		mState.stencilPassDepthPass = stencilPassDepthPass;
516		mStencilStateDirty = true;
517	}
518}
519
520void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
521{
522	if(mState.stencilBackFail != stencilBackFail ||
523	   mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
524	   mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
525	{
526		mState.stencilBackFail = stencilBackFail;
527		mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
528		mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
529		mStencilStateDirty = true;
530	}
531}
532
533void Context::setPolygonOffsetFillEnabled(bool enabled)
534{
535	if(mState.polygonOffsetFillEnabled != enabled)
536	{
537		mState.polygonOffsetFillEnabled = enabled;
538		mPolygonOffsetStateDirty = true;
539	}
540}
541
542bool Context::isPolygonOffsetFillEnabled() const
543{
544	return mState.polygonOffsetFillEnabled;
545}
546
547void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
548{
549	if(mState.polygonOffsetFactor != factor ||
550	   mState.polygonOffsetUnits != units)
551	{
552		mState.polygonOffsetFactor = factor;
553		mState.polygonOffsetUnits = units;
554		mPolygonOffsetStateDirty = true;
555	}
556}
557
558void Context::setSampleAlphaToCoverageEnabled(bool enabled)
559{
560	if(mState.sampleAlphaToCoverageEnabled != enabled)
561	{
562		mState.sampleAlphaToCoverageEnabled = enabled;
563		mSampleStateDirty = true;
564	}
565}
566
567bool Context::isSampleAlphaToCoverageEnabled() const
568{
569	return mState.sampleAlphaToCoverageEnabled;
570}
571
572void Context::setSampleCoverageEnabled(bool enabled)
573{
574	if(mState.sampleCoverageEnabled != enabled)
575	{
576		mState.sampleCoverageEnabled = enabled;
577		mSampleStateDirty = true;
578	}
579}
580
581bool Context::isSampleCoverageEnabled() const
582{
583	return mState.sampleCoverageEnabled;
584}
585
586void Context::setSampleCoverageParams(GLclampf value, bool invert)
587{
588	if(mState.sampleCoverageValue != value ||
589		mState.sampleCoverageInvert != invert)
590	{
591		mState.sampleCoverageValue = value;
592		mState.sampleCoverageInvert = invert;
593		mSampleStateDirty = true;
594	}
595}
596
597void Context::setScissorTestEnabled(bool enabled)
598{
599	mState.scissorTestEnabled = enabled;
600}
601
602bool Context::isScissorTestEnabled() const
603{
604	return mState.scissorTestEnabled;
605}
606
607void Context::setDitherEnabled(bool enabled)
608{
609	if(mState.ditherEnabled != enabled)
610	{
611		mState.ditherEnabled = enabled;
612		mDitherStateDirty = true;
613	}
614}
615
616bool Context::isDitherEnabled() const
617{
618	return mState.ditherEnabled;
619}
620
621void Context::setLineWidth(GLfloat width)
622{
623	mState.lineWidth = width;
624	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
625}
626
627void Context::setGenerateMipmapHint(GLenum hint)
628{
629	mState.generateMipmapHint = hint;
630}
631
632void Context::setFragmentShaderDerivativeHint(GLenum hint)
633{
634	mState.fragmentShaderDerivativeHint = hint;
635	// TODO: Propagate the hint to shader translator so we can write
636	// ddx, ddx_coarse, or ddx_fine depending on the hint.
637	// Ignore for now. It is valid for implementations to ignore hint.
638}
639
640void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
641{
642	mState.viewportX = x;
643	mState.viewportY = y;
644	mState.viewportWidth = width;
645	mState.viewportHeight = height;
646}
647
648void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
649{
650	mState.scissorX = x;
651	mState.scissorY = y;
652	mState.scissorWidth = width;
653	mState.scissorHeight = height;
654}
655
656void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
657{
658	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
659	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
660	{
661		mState.colorMaskRed = red;
662		mState.colorMaskGreen = green;
663		mState.colorMaskBlue = blue;
664		mState.colorMaskAlpha = alpha;
665		mMaskStateDirty = true;
666	}
667}
668
669void Context::setDepthMask(bool mask)
670{
671	if(mState.depthMask != mask)
672	{
673		mState.depthMask = mask;
674		mMaskStateDirty = true;
675	}
676}
677
678void Context::setActiveSampler(unsigned int active)
679{
680	mState.activeSampler = active;
681}
682
683GLuint Context::getReadFramebufferName() const
684{
685	return mState.readFramebuffer;
686}
687
688GLuint Context::getDrawFramebufferName() const
689{
690	return mState.drawFramebuffer;
691}
692
693GLuint Context::getRenderbufferName() const
694{
695	return mState.renderbuffer.name();
696}
697
698GLuint Context::getArrayBufferName() const
699{
700	return mState.arrayBuffer.name();
701}
702
703GLuint Context::getActiveQuery(GLenum target) const
704{
705	Query *queryObject = nullptr;
706
707	switch(target)
708	{
709	case GL_ANY_SAMPLES_PASSED:
710		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
711		break;
712	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
713		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
714		break;
715	default:
716		ASSERT(false);
717	}
718
719	if(queryObject)
720	{
721		return queryObject->name;
722	}
723
724	return 0;
725}
726
727void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
728{
729	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
730}
731
732const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
733{
734	return mState.vertexAttribute[attribNum];
735}
736
737void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
738                                   GLsizei stride, const void *pointer)
739{
740	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
741	mState.vertexAttribute[attribNum].mSize = size;
742	mState.vertexAttribute[attribNum].mType = type;
743	mState.vertexAttribute[attribNum].mNormalized = normalized;
744	mState.vertexAttribute[attribNum].mStride = stride;
745	mState.vertexAttribute[attribNum].mPointer = pointer;
746}
747
748const void *Context::getVertexAttribPointer(unsigned int attribNum) const
749{
750	return mState.vertexAttribute[attribNum].mPointer;
751}
752
753const VertexAttributeArray &Context::getVertexAttributes()
754{
755	return mState.vertexAttribute;
756}
757
758void Context::setPackAlignment(GLint alignment)
759{
760	mState.packAlignment = alignment;
761}
762
763GLint Context::getPackAlignment() const
764{
765	return mState.packAlignment;
766}
767
768void Context::setUnpackAlignment(GLint alignment)
769{
770	mState.unpackAlignment = alignment;
771}
772
773GLint Context::getUnpackAlignment() const
774{
775	return mState.unpackAlignment;
776}
777
778GLuint Context::createBuffer()
779{
780	return mResourceManager->createBuffer();
781}
782
783GLuint Context::createProgram()
784{
785	return mResourceManager->createProgram();
786}
787
788GLuint Context::createShader(GLenum type)
789{
790	return mResourceManager->createShader(type);
791}
792
793GLuint Context::createTexture()
794{
795	return mResourceManager->createTexture();
796}
797
798GLuint Context::createRenderbuffer()
799{
800	return mResourceManager->createRenderbuffer();
801}
802
803// Returns an unused framebuffer name
804GLuint Context::createFramebuffer()
805{
806	return mFramebufferNameSpace.allocate();
807}
808
809GLuint Context::createFence()
810{
811	return mFenceNameSpace.allocate(new Fence());
812}
813
814// Returns an unused query name
815GLuint Context::createQuery()
816{
817	return mQueryNameSpace.allocate();
818}
819
820void Context::deleteBuffer(GLuint buffer)
821{
822	if(mResourceManager->getBuffer(buffer))
823	{
824		detachBuffer(buffer);
825	}
826
827	mResourceManager->deleteBuffer(buffer);
828}
829
830void Context::deleteShader(GLuint shader)
831{
832	mResourceManager->deleteShader(shader);
833}
834
835void Context::deleteProgram(GLuint program)
836{
837	mResourceManager->deleteProgram(program);
838}
839
840void Context::deleteTexture(GLuint texture)
841{
842	if(mResourceManager->getTexture(texture))
843	{
844		detachTexture(texture);
845	}
846
847	mResourceManager->deleteTexture(texture);
848}
849
850void Context::deleteRenderbuffer(GLuint renderbuffer)
851{
852	if(mResourceManager->getRenderbuffer(renderbuffer))
853	{
854		detachRenderbuffer(renderbuffer);
855	}
856
857	mResourceManager->deleteRenderbuffer(renderbuffer);
858}
859
860void Context::deleteFramebuffer(GLuint framebuffer)
861{
862	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
863
864	if(framebufferObject)
865	{
866		detachFramebuffer(framebuffer);
867
868		delete framebufferObject;
869	}
870}
871
872void Context::deleteFence(GLuint fence)
873{
874	Fence *fenceObject = mFenceNameSpace.remove(fence);
875
876	if(fenceObject)
877	{
878		delete fenceObject;
879	}
880}
881
882void Context::deleteQuery(GLuint query)
883{
884	Query *queryObject = mQueryNameSpace.remove(query);
885
886	if(queryObject)
887	{
888		queryObject->release();
889	}
890}
891
892Buffer *Context::getBuffer(GLuint handle)
893{
894	return mResourceManager->getBuffer(handle);
895}
896
897Shader *Context::getShader(GLuint handle)
898{
899	return mResourceManager->getShader(handle);
900}
901
902Program *Context::getProgram(GLuint handle)
903{
904	return mResourceManager->getProgram(handle);
905}
906
907Texture *Context::getTexture(GLuint handle)
908{
909	return mResourceManager->getTexture(handle);
910}
911
912Renderbuffer *Context::getRenderbuffer(GLuint handle)
913{
914	return mResourceManager->getRenderbuffer(handle);
915}
916
917Framebuffer *Context::getReadFramebuffer()
918{
919	return getFramebuffer(mState.readFramebuffer);
920}
921
922Framebuffer *Context::getDrawFramebuffer()
923{
924	return getFramebuffer(mState.drawFramebuffer);
925}
926
927void Context::bindArrayBuffer(unsigned int buffer)
928{
929	mResourceManager->checkBufferAllocation(buffer);
930
931	mState.arrayBuffer = getBuffer(buffer);
932}
933
934void Context::bindElementArrayBuffer(unsigned int buffer)
935{
936	mResourceManager->checkBufferAllocation(buffer);
937
938	mState.elementArrayBuffer = getBuffer(buffer);
939}
940
941void Context::bindTexture2D(GLuint texture)
942{
943	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
944
945	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
946}
947
948void Context::bindTextureCubeMap(GLuint texture)
949{
950	mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
951
952	mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
953}
954
955void Context::bindReadFramebuffer(GLuint framebuffer)
956{
957	if(!getFramebuffer(framebuffer))
958	{
959		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
960	}
961
962	mState.readFramebuffer = framebuffer;
963}
964
965void Context::bindDrawFramebuffer(GLuint framebuffer)
966{
967	if(!getFramebuffer(framebuffer))
968	{
969		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
970	}
971
972	mState.drawFramebuffer = framebuffer;
973}
974
975void Context::bindRenderbuffer(GLuint renderbuffer)
976{
977	mResourceManager->checkRenderbufferAllocation(renderbuffer);
978
979	mState.renderbuffer = getRenderbuffer(renderbuffer);
980}
981
982void Context::useProgram(GLuint program)
983{
984	GLuint priorProgram = mState.currentProgram;
985	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
986
987	if(priorProgram != program)
988	{
989		Program *newProgram = mResourceManager->getProgram(program);
990		Program *oldProgram = mResourceManager->getProgram(priorProgram);
991
992		if(newProgram)
993		{
994			newProgram->addRef();
995		}
996
997		if(oldProgram)
998		{
999			oldProgram->release();
1000		}
1001	}
1002}
1003
1004void Context::beginQuery(GLenum target, GLuint query)
1005{
1006	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1007	// of zero, if the active query object name for <target> is non-zero (for the
1008	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1009	// the active query for either target is non-zero), if <id> is the name of an
1010	// existing query object whose type does not match <target>, or if <id> is the
1011	// active query object name for any query type, the error INVALID_OPERATION is
1012	// generated.
1013
1014	// Ensure no other queries are active
1015	// NOTE: If other queries than occlusion are supported, we will need to check
1016	// separately that:
1017	//    a) The query ID passed is not the current active query for any target/type
1018	//    b) There are no active queries for the requested target (and in the case
1019	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1020	//       no query may be active for either if glBeginQuery targets either.
1021	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1022	{
1023		if(mState.activeQuery[i])
1024		{
1025			return error(GL_INVALID_OPERATION);
1026		}
1027	}
1028
1029	QueryType qType;
1030	switch(target)
1031	{
1032	case GL_ANY_SAMPLES_PASSED:
1033		qType = QUERY_ANY_SAMPLES_PASSED;
1034		break;
1035	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
1036		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1037		break;
1038	default:
1039		ASSERT(false);
1040	}
1041
1042	Query *queryObject = getQuery(query, true, target);
1043
1044	// Check that name was obtained with glGenQueries
1045	if(!queryObject)
1046	{
1047		return error(GL_INVALID_OPERATION);
1048	}
1049
1050	// Check for type mismatch
1051	if(queryObject->getType() != target)
1052	{
1053		return error(GL_INVALID_OPERATION);
1054	}
1055
1056	// Set query as active for specified target
1057	mState.activeQuery[qType] = queryObject;
1058
1059	// Begin query
1060	queryObject->begin();
1061}
1062
1063void Context::endQuery(GLenum target)
1064{
1065	QueryType qType;
1066
1067	switch(target)
1068	{
1069	case GL_ANY_SAMPLES_PASSED:
1070		qType = QUERY_ANY_SAMPLES_PASSED;
1071		break;
1072	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
1073		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1074		break;
1075	default:
1076		ASSERT(false);
1077	}
1078
1079	Query *queryObject = mState.activeQuery[qType];
1080
1081	if(!queryObject)
1082	{
1083		return error(GL_INVALID_OPERATION);
1084	}
1085
1086	queryObject->end();
1087
1088	mState.activeQuery[qType] = nullptr;
1089}
1090
1091void Context::setFramebufferZero(Framebuffer *buffer)
1092{
1093	delete mFramebufferNameSpace.remove(0);
1094	mFramebufferNameSpace.insert(0, buffer);
1095}
1096
1097void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1098{
1099	Renderbuffer *renderbufferObject = mState.renderbuffer;
1100	renderbufferObject->setStorage(renderbuffer);
1101}
1102
1103Framebuffer *Context::getFramebuffer(unsigned int handle)
1104{
1105	return mFramebufferNameSpace.find(handle);
1106}
1107
1108Fence *Context::getFence(unsigned int handle)
1109{
1110	return mFenceNameSpace.find(handle);
1111}
1112
1113Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1114{
1115	if(!mQueryNameSpace.isReserved(handle))
1116	{
1117		return nullptr;
1118	}
1119	else
1120	{
1121		Query *query = mQueryNameSpace.find(handle);
1122		if(!query && create)
1123		{
1124			query = new Query(handle, type);
1125			query->addRef();
1126			mQueryNameSpace.insert(handle, query);
1127		}
1128
1129		return query;
1130	}
1131}
1132
1133Buffer *Context::getArrayBuffer()
1134{
1135	return mState.arrayBuffer;
1136}
1137
1138Buffer *Context::getElementArrayBuffer()
1139{
1140	return mState.elementArrayBuffer;
1141}
1142
1143Program *Context::getCurrentProgram()
1144{
1145	return mResourceManager->getProgram(mState.currentProgram);
1146}
1147
1148Texture2D *Context::getTexture2D(GLenum target)
1149{
1150	if(target == GL_TEXTURE_2D)
1151	{
1152		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1153	}
1154	else if(target == GL_PROXY_TEXTURE_2D)
1155	{
1156		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, PROXY_TEXTURE_2D));
1157	}
1158	else UNREACHABLE(target);
1159
1160	return nullptr;
1161}
1162
1163TextureCubeMap *Context::getTextureCubeMap()
1164{
1165	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1166}
1167
1168Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1169{
1170	GLuint texid = mState.samplerTexture[type][sampler].name();
1171
1172	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1173	{
1174		switch(type)
1175		{
1176		case TEXTURE_2D:       return mTexture2DZero;
1177		case PROXY_TEXTURE_2D: return mProxyTexture2DZero;
1178		case TEXTURE_CUBE:     return mTextureCubeMapZero;
1179		default: UNREACHABLE(type);
1180		}
1181	}
1182
1183	return mState.samplerTexture[type][sampler];
1184}
1185
1186bool Context::getBooleanv(GLenum pname, GLboolean *params)
1187{
1188	switch(pname)
1189	{
1190	case GL_SHADER_COMPILER:          *params = GL_TRUE;                             break;
1191	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
1192	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
1193	case GL_COLOR_WRITEMASK:
1194		params[0] = mState.colorMaskRed;
1195		params[1] = mState.colorMaskGreen;
1196		params[2] = mState.colorMaskBlue;
1197		params[3] = mState.colorMaskAlpha;
1198		break;
1199	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
1200	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
1201	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1202	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
1203	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
1204	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
1205	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
1206	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
1207	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
1208	default:
1209		return false;
1210	}
1211
1212	return true;
1213}
1214
1215bool Context::getFloatv(GLenum pname, GLfloat *params)
1216{
1217	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1218	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1219	// GetIntegerv as its native query function. As it would require conversion in any
1220	// case, this should make no difference to the calling application.
1221	switch(pname)
1222	{
1223	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1224	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1225	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1226	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1227	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1228	case GL_ALIASED_LINE_WIDTH_RANGE:
1229		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1230		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1231		break;
1232	case GL_ALIASED_POINT_SIZE_RANGE:
1233		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1234		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1235		break;
1236	case GL_DEPTH_RANGE:
1237		params[0] = mState.zNear;
1238		params[1] = mState.zFar;
1239		break;
1240	case GL_COLOR_CLEAR_VALUE:
1241		params[0] = mState.colorClearValue.red;
1242		params[1] = mState.colorClearValue.green;
1243		params[2] = mState.colorClearValue.blue;
1244		params[3] = mState.colorClearValue.alpha;
1245		break;
1246	case GL_BLEND_COLOR:
1247		params[0] = mState.blendColor.red;
1248		params[1] = mState.blendColor.green;
1249		params[2] = mState.blendColor.blue;
1250		params[3] = mState.blendColor.alpha;
1251		break;
1252	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1253		*params = MAX_TEXTURE_MAX_ANISOTROPY;
1254		break;
1255	case GL_MODELVIEW_MATRIX:
1256		for(int i = 0; i < 16; i++)
1257		{
1258			params[i] = modelView.current()[i % 4][i / 4];
1259		}
1260		break;
1261	case GL_PROJECTION_MATRIX:
1262		for(int i = 0; i < 16; i++)
1263		{
1264			params[i] = projection.current()[i % 4][i / 4];
1265		}
1266		break;
1267	default:
1268		return false;
1269	}
1270
1271	return true;
1272}
1273
1274bool Context::getIntegerv(GLenum pname, GLint *params)
1275{
1276	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1277	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1278	// GetIntegerv as its native query function. As it would require conversion in any
1279	// case, this should make no difference to the calling application. You may find it in
1280	// Context::getFloatv.
1281	switch(pname)
1282	{
1283	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
1284	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
1285	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:    *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
1286	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
1287	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
1288	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
1289	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
1290	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
1291	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:  *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
1292	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
1293	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
1294	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
1295	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
1296	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
1297//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1298	case GL_DRAW_FRAMEBUFFER_BINDING:         *params = mState.drawFramebuffer;               break;
1299	case GL_READ_FRAMEBUFFER_BINDING:         *params = mState.readFramebuffer;               break;
1300	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
1301	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
1302	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1303	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
1304	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1305	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:  *params = mState.fragmentShaderDerivativeHint; break;
1306	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1307	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
1308	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
1309	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
1310	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
1311	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
1312	case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.stencilBackMask;               break;
1313	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
1314	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
1315	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
1316	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
1317	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
1318	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
1319	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
1320	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
1321	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
1322	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
1323	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
1324	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
1325	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
1326	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
1327	case GL_STENCIL_BACK_WRITEMASK:           *params = mState.stencilBackWritemask;          break;
1328	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1329	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1330	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
1331	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
1332	case GL_MAX_ARRAY_TEXTURE_LAYERS:         *params = 0;                                    break;
1333	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
1334	case GL_MAX_SAMPLES:                      *params = IMPLEMENTATION_MAX_SAMPLES;           break;
1335	case GL_SAMPLE_BUFFERS:
1336	case GL_SAMPLES:
1337		{
1338			Framebuffer *framebuffer = getDrawFramebuffer();
1339			int width, height, samples;
1340
1341			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
1342			{
1343				switch(pname)
1344				{
1345				case GL_SAMPLE_BUFFERS:
1346					if(samples > 1)
1347					{
1348						*params = 1;
1349					}
1350					else
1351					{
1352						*params = 0;
1353					}
1354					break;
1355				case GL_SAMPLES:
1356					*params = samples;
1357					break;
1358				}
1359			}
1360			else
1361			{
1362				*params = 0;
1363			}
1364		}
1365		break;
1366	case GL_IMPLEMENTATION_COLOR_READ_TYPE:   *params = IMPLEMENTATION_COLOR_READ_TYPE;   break;
1367	case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;
1368	case GL_MAX_VIEWPORT_DIMS:
1369		{
1370			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1371			params[0] = maxDimension;
1372			params[1] = maxDimension;
1373		}
1374		break;
1375	case GL_COMPRESSED_TEXTURE_FORMATS:
1376		{
1377			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1378			{
1379				params[i] = compressedTextureFormats[i];
1380			}
1381		}
1382		break;
1383	case GL_VIEWPORT:
1384		params[0] = mState.viewportX;
1385		params[1] = mState.viewportY;
1386		params[2] = mState.viewportWidth;
1387		params[3] = mState.viewportHeight;
1388		break;
1389	case GL_SCISSOR_BOX:
1390		params[0] = mState.scissorX;
1391		params[1] = mState.scissorY;
1392		params[2] = mState.scissorWidth;
1393		params[3] = mState.scissorHeight;
1394		break;
1395	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
1396	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
1397	case GL_RED_BITS:
1398	case GL_GREEN_BITS:
1399	case GL_BLUE_BITS:
1400	case GL_ALPHA_BITS:
1401		{
1402			Framebuffer *framebuffer = getDrawFramebuffer();
1403			Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
1404
1405			if(colorbuffer)
1406			{
1407				switch(pname)
1408				{
1409				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
1410				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1411				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
1412				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1413				}
1414			}
1415			else
1416			{
1417				*params = 0;
1418			}
1419		}
1420		break;
1421	case GL_DEPTH_BITS:
1422		{
1423			Framebuffer *framebuffer = getDrawFramebuffer();
1424			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1425
1426			if(depthbuffer)
1427			{
1428				*params = depthbuffer->getDepthSize();
1429			}
1430			else
1431			{
1432				*params = 0;
1433			}
1434		}
1435		break;
1436	case GL_STENCIL_BITS:
1437		{
1438			Framebuffer *framebuffer = getDrawFramebuffer();
1439			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1440
1441			if(stencilbuffer)
1442			{
1443				*params = stencilbuffer->getStencilSize();
1444			}
1445			else
1446			{
1447				*params = 0;
1448			}
1449		}
1450		break;
1451	case GL_TEXTURE_BINDING_2D:
1452		{
1453			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1454			{
1455				error(GL_INVALID_OPERATION);
1456				return false;
1457			}
1458
1459			*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
1460		}
1461		break;
1462	case GL_TEXTURE_BINDING_CUBE_MAP:
1463		{
1464			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1465			{
1466				error(GL_INVALID_OPERATION);
1467				return false;
1468			}
1469
1470			*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
1471		}
1472		break;
1473	default:
1474		return false;
1475	}
1476
1477	return true;
1478}
1479
1480bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1481{
1482	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1483	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1484	// to the fact that it is stored internally as a float, and so would require conversion
1485	// if returned from Context::getIntegerv. Since this conversion is already implemented
1486	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1487	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1488	// application.
1489	switch(pname)
1490	{
1491	case GL_COMPRESSED_TEXTURE_FORMATS:
1492		{
1493			*type = GL_INT;
1494			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
1495		}
1496		break;
1497	case GL_SHADER_BINARY_FORMATS:
1498		{
1499			*type = GL_INT;
1500			*numParams = 0;
1501		}
1502		break;
1503	case GL_MAX_VERTEX_ATTRIBS:
1504	case GL_MAX_VERTEX_UNIFORM_VECTORS:
1505	case GL_MAX_VARYING_VECTORS:
1506	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1507	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1508	case GL_MAX_TEXTURE_IMAGE_UNITS:
1509	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1510	case GL_MAX_RENDERBUFFER_SIZE:
1511	case GL_NUM_SHADER_BINARY_FORMATS:
1512	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1513	case GL_ARRAY_BUFFER_BINDING:
1514	case GL_FRAMEBUFFER_BINDING:
1515	case GL_RENDERBUFFER_BINDING:
1516	case GL_CURRENT_PROGRAM:
1517	case GL_PACK_ALIGNMENT:
1518	case GL_UNPACK_ALIGNMENT:
1519	case GL_GENERATE_MIPMAP_HINT:
1520	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
1521	case GL_RED_BITS:
1522	case GL_GREEN_BITS:
1523	case GL_BLUE_BITS:
1524	case GL_ALPHA_BITS:
1525	case GL_DEPTH_BITS:
1526	case GL_STENCIL_BITS:
1527	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1528	case GL_CULL_FACE_MODE:
1529	case GL_FRONT_FACE:
1530	case GL_ACTIVE_TEXTURE:
1531	case GL_STENCIL_FUNC:
1532	case GL_STENCIL_VALUE_MASK:
1533	case GL_STENCIL_REF:
1534	case GL_STENCIL_FAIL:
1535	case GL_STENCIL_PASS_DEPTH_FAIL:
1536	case GL_STENCIL_PASS_DEPTH_PASS:
1537	case GL_STENCIL_BACK_FUNC:
1538	case GL_STENCIL_BACK_VALUE_MASK:
1539	case GL_STENCIL_BACK_REF:
1540	case GL_STENCIL_BACK_FAIL:
1541	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1542	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1543	case GL_DEPTH_FUNC:
1544	case GL_BLEND_SRC_RGB:
1545	case GL_BLEND_SRC_ALPHA:
1546	case GL_BLEND_DST_RGB:
1547	case GL_BLEND_DST_ALPHA:
1548	case GL_BLEND_EQUATION_RGB:
1549	case GL_BLEND_EQUATION_ALPHA:
1550	case GL_STENCIL_WRITEMASK:
1551	case GL_STENCIL_BACK_WRITEMASK:
1552	case GL_STENCIL_CLEAR_VALUE:
1553	case GL_SUBPIXEL_BITS:
1554	case GL_MAX_TEXTURE_SIZE:
1555	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1556	case GL_SAMPLE_BUFFERS:
1557	case GL_SAMPLES:
1558	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1559	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1560	case GL_TEXTURE_BINDING_2D:
1561	case GL_TEXTURE_BINDING_CUBE_MAP:
1562	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1563	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1564	case GL_MAX_ARRAY_TEXTURE_LAYERS:
1565		{
1566			*type = GL_INT;
1567			*numParams = 1;
1568		}
1569		break;
1570	case GL_MAX_SAMPLES:
1571		{
1572			*type = GL_INT;
1573			*numParams = 1;
1574		}
1575		break;
1576	case GL_MAX_VIEWPORT_DIMS:
1577		{
1578			*type = GL_INT;
1579			*numParams = 2;
1580		}
1581		break;
1582	case GL_VIEWPORT:
1583	case GL_SCISSOR_BOX:
1584		{
1585			*type = GL_INT;
1586			*numParams = 4;
1587		}
1588		break;
1589	case GL_SHADER_COMPILER:
1590	case GL_SAMPLE_COVERAGE_INVERT:
1591	case GL_DEPTH_WRITEMASK:
1592	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1593	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1594	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1595	case GL_SAMPLE_COVERAGE:
1596	case GL_SCISSOR_TEST:
1597	case GL_STENCIL_TEST:
1598	case GL_DEPTH_TEST:
1599	case GL_BLEND:
1600	case GL_DITHER:
1601		{
1602			*type = GL_BOOL;
1603			*numParams = 1;
1604		}
1605		break;
1606	case GL_COLOR_WRITEMASK:
1607		{
1608			*type = GL_BOOL;
1609			*numParams = 4;
1610		}
1611		break;
1612	case GL_POLYGON_OFFSET_FACTOR:
1613	case GL_POLYGON_OFFSET_UNITS:
1614	case GL_SAMPLE_COVERAGE_VALUE:
1615	case GL_DEPTH_CLEAR_VALUE:
1616	case GL_LINE_WIDTH:
1617		{
1618			*type = GL_FLOAT;
1619			*numParams = 1;
1620		}
1621		break;
1622	case GL_ALIASED_LINE_WIDTH_RANGE:
1623	case GL_ALIASED_POINT_SIZE_RANGE:
1624	case GL_DEPTH_RANGE:
1625		{
1626			*type = GL_FLOAT;
1627			*numParams = 2;
1628		}
1629		break;
1630	case GL_COLOR_CLEAR_VALUE:
1631	case GL_BLEND_COLOR:
1632		{
1633			*type = GL_FLOAT;
1634			*numParams = 4;
1635		}
1636		break;
1637	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1638		*type = GL_FLOAT;
1639		*numParams = 1;
1640		break;
1641	default:
1642		return false;
1643	}
1644
1645	return true;
1646}
1647
1648// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
1649bool Context::applyRenderTarget()
1650{
1651	Framebuffer *framebuffer = getDrawFramebuffer();
1652	int width, height, samples;
1653
1654	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
1655	{
1656		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
1657	}
1658
1659	Image *renderTarget = framebuffer->getRenderTarget();
1660	device->setRenderTarget(0, renderTarget);
1661	if(renderTarget) renderTarget->release();
1662
1663	Image *depthStencil = framebuffer->getDepthStencil();
1664	device->setDepthStencilSurface(depthStencil);
1665	if(depthStencil) depthStencil->release();
1666
1667	Viewport viewport;
1668	float zNear = clamp01(mState.zNear);
1669	float zFar = clamp01(mState.zFar);
1670
1671	viewport.x0 = mState.viewportX;
1672	viewport.y0 = mState.viewportY;
1673	viewport.width = mState.viewportWidth;
1674	viewport.height = mState.viewportHeight;
1675	viewport.minZ = zNear;
1676	viewport.maxZ = zFar;
1677
1678	device->setViewport(viewport);
1679
1680	if(mState.scissorTestEnabled)
1681	{
1682		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
1683		scissor.clip(0, 0, width, height);
1684
1685		device->setScissorRect(scissor);
1686		device->setScissorEnable(true);
1687	}
1688	else
1689	{
1690		device->setScissorEnable(false);
1691	}
1692
1693	Program *program = getCurrentProgram();
1694
1695	if(program)
1696	{
1697		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
1698		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
1699		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
1700		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
1701	}
1702
1703	return true;
1704}
1705
1706// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
1707void Context::applyState(GLenum drawMode)
1708{
1709	Framebuffer *framebuffer = getDrawFramebuffer();
1710
1711	if(mState.cullFaceEnabled)
1712	{
1713		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
1714	}
1715	else
1716	{
1717		device->setCullMode(sw::CULL_NONE);
1718	}
1719
1720	if(mDepthStateDirty)
1721	{
1722		if(mState.depthTestEnabled)
1723		{
1724			device->setDepthBufferEnable(true);
1725			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
1726		}
1727		else
1728		{
1729			device->setDepthBufferEnable(false);
1730		}
1731
1732		mDepthStateDirty = false;
1733	}
1734
1735	if(mBlendStateDirty)
1736	{
1737		if(mState.blendEnabled)
1738		{
1739			device->setAlphaBlendEnable(true);
1740			device->setSeparateAlphaBlendEnable(true);
1741
1742			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
1743
1744			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
1745			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
1746			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
1747
1748			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
1749			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
1750			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
1751		}
1752		else
1753		{
1754			device->setAlphaBlendEnable(false);
1755		}
1756
1757		mBlendStateDirty = false;
1758	}
1759
1760	if(mColorLogicOperatorDirty)
1761	{
1762		if(mState.colorLogicOpEnabled)
1763		{
1764			device->setColorLogicOpEnabled(true);
1765			device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation));
1766		}
1767		else
1768		{
1769			device->setColorLogicOpEnabled(false);
1770		}
1771
1772		mColorLogicOperatorDirty = false;
1773	}
1774
1775	if(mStencilStateDirty || mFrontFaceDirty)
1776	{
1777		if(mState.stencilTestEnabled && framebuffer->hasStencil())
1778		{
1779			device->setStencilEnable(true);
1780			device->setTwoSidedStencil(true);
1781
1782			if(mState.stencilWritemask != mState.stencilBackWritemask ||
1783			   mState.stencilRef != mState.stencilBackRef ||
1784			   mState.stencilMask != mState.stencilBackMask)
1785			{
1786				ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
1787				return error(GL_INVALID_OPERATION);
1788			}
1789
1790			// get the maximum size of the stencil ref
1791			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1792			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
1793
1794			if(mState.frontFace == GL_CCW)
1795			{
1796				device->setStencilWriteMask(mState.stencilWritemask);
1797				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
1798
1799				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1800				device->setStencilMask(mState.stencilMask);
1801
1802				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
1803				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1804				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1805
1806				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
1807				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1808
1809				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1810				device->setStencilMaskCCW(mState.stencilBackMask);
1811
1812				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
1813				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1814				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1815			}
1816			else
1817			{
1818				device->setStencilWriteMaskCCW(mState.stencilWritemask);
1819				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
1820
1821				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1822				device->setStencilMaskCCW(mState.stencilMask);
1823
1824				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
1825				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1826				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1827
1828				device->setStencilWriteMask(mState.stencilBackWritemask);
1829				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1830
1831				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1832				device->setStencilMask(mState.stencilBackMask);
1833
1834				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
1835				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1836				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1837			}
1838		}
1839		else
1840		{
1841			device->setStencilEnable(false);
1842		}
1843
1844		mStencilStateDirty = false;
1845		mFrontFaceDirty = false;
1846	}
1847
1848	if(mMaskStateDirty)
1849	{
1850		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
1851		device->setDepthWriteEnable(mState.depthMask);
1852
1853		mMaskStateDirty = false;
1854	}
1855
1856	if(mPolygonOffsetStateDirty)
1857	{
1858		if(mState.polygonOffsetFillEnabled)
1859		{
1860			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1861			if(depthbuffer)
1862			{
1863				device->setSlopeDepthBias(mState.polygonOffsetFactor);
1864				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
1865				device->setDepthBias(depthBias);
1866			}
1867		}
1868		else
1869		{
1870			device->setSlopeDepthBias(0);
1871			device->setDepthBias(0);
1872		}
1873
1874		mPolygonOffsetStateDirty = false;
1875	}
1876
1877	if(mSampleStateDirty)
1878	{
1879		if(mState.sampleAlphaToCoverageEnabled)
1880		{
1881			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
1882		}
1883		else
1884		{
1885			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
1886		}
1887
1888		if(mState.sampleCoverageEnabled)
1889		{
1890			unsigned int mask = 0;
1891			if(mState.sampleCoverageValue != 0)
1892			{
1893				int width, height, samples;
1894				framebuffer->completeness(width, height, samples);
1895
1896				float threshold = 0.5f;
1897
1898				for(int i = 0; i < samples; i++)
1899				{
1900					mask <<= 1;
1901
1902					if((i + 1) * mState.sampleCoverageValue >= threshold)
1903					{
1904						threshold += 1.0f;
1905						mask |= 1;
1906					}
1907				}
1908			}
1909
1910			if(mState.sampleCoverageInvert)
1911			{
1912				mask = ~mask;
1913			}
1914
1915			device->setMultiSampleMask(mask);
1916		}
1917		else
1918		{
1919			device->setMultiSampleMask(0xFFFFFFFF);
1920		}
1921
1922		mSampleStateDirty = false;
1923	}
1924
1925	if(mDitherStateDirty)
1926	{
1927	//	UNIMPLEMENTED();   // FIXME
1928
1929		mDitherStateDirty = false;
1930	}
1931}
1932
1933GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
1934{
1935	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
1936
1937	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
1938	if(err != GL_NO_ERROR)
1939	{
1940		return err;
1941	}
1942
1943	Program *program = getCurrentProgram();
1944
1945	device->resetInputStreams(false);
1946
1947	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
1948	{
1949		if(program && program->getAttributeStream(i) == -1)
1950		{
1951			continue;
1952		}
1953
1954		sw::Resource *resource = attributes[i].vertexBuffer;
1955		const void *buffer = (char*)resource->data() + attributes[i].offset;
1956
1957		int stride = attributes[i].stride;
1958
1959		buffer = (char*)buffer + stride * base;
1960
1961		sw::Stream attribute(resource, buffer, stride);
1962
1963		attribute.type = attributes[i].type;
1964		attribute.count = attributes[i].count;
1965		attribute.normalized = attributes[i].normalized;
1966
1967		int stream = program ? program->getAttributeStream(i) : i;
1968		device->setInputStream(stream, attribute);
1969	}
1970
1971	return GL_NO_ERROR;
1972}
1973
1974// Applies the indices and element array bindings
1975GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
1976{
1977	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
1978
1979	if(err == GL_NO_ERROR)
1980	{
1981		device->setIndexBuffer(indexInfo->indexBuffer);
1982	}
1983
1984	return err;
1985}
1986
1987// Applies the shaders and shader constants
1988void Context::applyShaders()
1989{
1990	Program *programObject = getCurrentProgram();
1991	if(!programObject)
1992	{
1993		device->setVertexShader(0);
1994		device->setPixelShader(0);
1995		return;
1996	}
1997	sw::VertexShader *vertexShader = programObject->getVertexShader();
1998	sw::PixelShader *pixelShader = programObject->getPixelShader();
1999
2000	device->setVertexShader(vertexShader);
2001	device->setPixelShader(pixelShader);
2002
2003	if(programObject->getSerial() != mAppliedProgramSerial)
2004	{
2005		programObject->dirtyAllUniforms();
2006		mAppliedProgramSerial = programObject->getSerial();
2007	}
2008
2009	programObject->applyUniforms();
2010}
2011
2012void Context::applyTextures()
2013{
2014	applyTextures(sw::SAMPLER_PIXEL);
2015	//applyTextures(sw::SAMPLER_VERTEX);
2016}
2017
2018void Context::applyTextures(sw::SamplerType samplerType)
2019{
2020	Program *programObject = getCurrentProgram();
2021
2022	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
2023
2024	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
2025	{
2026		int textureUnit = programObject ? programObject->getSamplerMapping(samplerType, samplerIndex) : samplerIndex;   // OpenGL texture image unit index
2027
2028		if(textureUnit != -1)
2029		{
2030			TextureType textureType = programObject ? programObject->getSamplerTextureType(samplerType, samplerIndex) : TEXTURE_2D;
2031
2032			Texture *texture = getSamplerTexture(textureUnit, textureType);
2033
2034			if(envEnable[samplerIndex] && texture->isSamplerComplete())
2035			{
2036				GLenum wrapS = texture->getWrapS();
2037				GLenum wrapT = texture->getWrapT();
2038				GLenum minFilter = texture->getMinFilter();
2039				GLenum magFilter = texture->getMagFilter();
2040				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
2041
2042				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
2043				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
2044
2045				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
2046				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
2047				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
2048
2049				applyTexture(samplerType, samplerIndex, texture);
2050
2051				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE);
2052				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
2053				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2054				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2055
2056				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE);
2057				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
2058				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2059				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2060
2061				//device->setConstantColor(0, sw::Color<float>(0.0f, 0.0f, 0.0f, 0.0f));
2062			}
2063			else
2064			{
2065				applyTexture(samplerType, samplerIndex, nullptr);
2066
2067				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
2068				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2069				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2070				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2071
2072				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
2073				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2074				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2075				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2076			}
2077		}
2078		else
2079		{
2080			applyTexture(samplerType, samplerIndex, nullptr);
2081		}
2082	}
2083}
2084
2085void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
2086{
2087	Program *program = getCurrentProgram();
2088	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
2089	bool textureUsed = false;
2090
2091	if(type == sw::SAMPLER_PIXEL)
2092	{
2093		textureUsed = program ? program->getPixelShader()->usesSampler(index) : true;
2094	}
2095	else if(type == sw::SAMPLER_VERTEX)
2096	{
2097		textureUsed = program ? program->getVertexShader()->usesSampler(index) : false;
2098	}
2099	else UNREACHABLE(type);
2100
2101	sw::Resource *resource = nullptr;
2102
2103	if(baseTexture && textureUsed)
2104	{
2105		resource = baseTexture->getResource();
2106	}
2107
2108	device->setTextureResource(sampler, resource);
2109
2110	if(baseTexture && textureUsed)
2111	{
2112		int topLevel = baseTexture->getTopLevel();
2113
2114		if(baseTexture->getTarget() == GL_TEXTURE_2D)
2115		{
2116			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2117
2118			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2119			{
2120				int surfaceLevel = mipmapLevel;
2121
2122				if(surfaceLevel < 0)
2123				{
2124					surfaceLevel = 0;
2125				}
2126				else if(surfaceLevel > topLevel)
2127				{
2128					surfaceLevel = topLevel;
2129				}
2130
2131				Image *surface = texture->getImage(surfaceLevel);
2132				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2133			}
2134		}
2135		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
2136		{
2137			for(int face = 0; face < 6; face++)
2138			{
2139				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
2140
2141				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2142				{
2143					int surfaceLevel = mipmapLevel;
2144
2145					if(surfaceLevel < 0)
2146					{
2147						surfaceLevel = 0;
2148					}
2149					else if(surfaceLevel > topLevel)
2150					{
2151						surfaceLevel = topLevel;
2152					}
2153
2154					Image *surface = cubeTexture->getImage(face, surfaceLevel);
2155					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
2156				}
2157			}
2158		}
2159		else UNIMPLEMENTED();
2160	}
2161	else
2162	{
2163		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
2164	}
2165}
2166
2167void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2168                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2169{
2170	Framebuffer *framebuffer = getReadFramebuffer();
2171	int framebufferWidth, framebufferHeight, framebufferSamples;
2172
2173	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2174	{
2175		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2176	}
2177
2178	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
2179	{
2180		return error(GL_INVALID_OPERATION);
2181	}
2182
2183	GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
2184
2185	// Sized query sanity check
2186	if(bufSize)
2187	{
2188		int requiredSize = outputPitch * height;
2189		if(requiredSize > *bufSize)
2190		{
2191			return error(GL_INVALID_OPERATION);
2192		}
2193	}
2194
2195	Image *renderTarget = framebuffer->getRenderTarget();
2196
2197	if(!renderTarget)
2198	{
2199		return error(GL_OUT_OF_MEMORY);
2200	}
2201
2202	sw::Rect rect = {x, y, x + width, y + height};
2203	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2204
2205	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
2206	unsigned char *dest = (unsigned char*)pixels;
2207	unsigned short *dest16 = (unsigned short*)pixels;
2208	int inputPitch = (int)renderTarget->getPitch();
2209
2210	for(int j = 0; j < rect.y1 - rect.y0; j++)
2211	{
2212		if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2213		   format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2214		{
2215			// Fast path for EXT_read_format_bgra, given an RGBA source buffer
2216			// Note that buffers with no alpha go through the slow path below
2217			memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);
2218		}
2219		else
2220		{
2221			for(int i = 0; i < rect.x1 - rect.x0; i++)
2222			{
2223				float r;
2224				float g;
2225				float b;
2226				float a;
2227
2228				switch(renderTarget->getInternalFormat())
2229				{
2230				case sw::FORMAT_R5G6B5:
2231					{
2232						unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2233
2234						a = 1.0f;
2235						b = (rgb & 0x001F) * (1.0f / 0x001F);
2236						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2237						r = (rgb & 0xF800) * (1.0f / 0xF800);
2238					}
2239					break;
2240				case sw::FORMAT_A1R5G5B5:
2241					{
2242						unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2243
2244						a = (argb & 0x8000) ? 1.0f : 0.0f;
2245						b = (argb & 0x001F) * (1.0f / 0x001F);
2246						g = (argb & 0x03E0) * (1.0f / 0x03E0);
2247						r = (argb & 0x7C00) * (1.0f / 0x7C00);
2248					}
2249					break;
2250				case sw::FORMAT_A8R8G8B8:
2251					{
2252						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2253
2254						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2255						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2256						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2257						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2258					}
2259					break;
2260				case sw::FORMAT_X8R8G8B8:
2261					{
2262						unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2263
2264						a = 1.0f;
2265						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2266						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2267						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2268					}
2269					break;
2270				case sw::FORMAT_A2R10G10B10:
2271					{
2272						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2273
2274						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2275						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2276						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2277						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2278					}
2279					break;
2280				case sw::FORMAT_A32B32G32R32F:
2281					{
2282						r = *((float*)(source + 16 * i + j * inputPitch) + 0);
2283						g = *((float*)(source + 16 * i + j * inputPitch) + 1);
2284						b = *((float*)(source + 16 * i + j * inputPitch) + 2);
2285						a = *((float*)(source + 16 * i + j * inputPitch) + 3);
2286					}
2287					break;
2288				case sw::FORMAT_A16B16G16R16F:
2289					{
2290						r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);
2291						g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);
2292						b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);
2293						a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);
2294					}
2295					break;
2296				default:
2297					UNIMPLEMENTED();   // FIXME
2298					UNREACHABLE(renderTarget->getInternalFormat());
2299				}
2300
2301				switch(format)
2302				{
2303				case GL_RGBA:
2304					switch(type)
2305					{
2306					case GL_UNSIGNED_BYTE:
2307						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
2308						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2309						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
2310						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2311						break;
2312					default: UNREACHABLE(type);
2313					}
2314					break;
2315				case GL_BGRA_EXT:
2316					switch(type)
2317					{
2318					case GL_UNSIGNED_BYTE:
2319						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
2320						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2321						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
2322						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2323						break;
2324					case GL_UNSIGNED_SHORT_4_4_4_4_REV:
2325						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2326						// this type is packed as follows:
2327						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2328						//  --------------------------------------------------------------------------------
2329						// |       4th         |        3rd         |        2nd        |   1st component   |
2330						//  --------------------------------------------------------------------------------
2331						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2332						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2333							((unsigned short)(15 * a + 0.5f) << 12)|
2334							((unsigned short)(15 * r + 0.5f) << 8) |
2335							((unsigned short)(15 * g + 0.5f) << 4) |
2336							((unsigned short)(15 * b + 0.5f) << 0);
2337						break;
2338					case GL_UNSIGNED_SHORT_1_5_5_5_REV:
2339						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2340						// this type is packed as follows:
2341						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2342						//  --------------------------------------------------------------------------------
2343						// | 4th |          3rd           |           2nd          |      1st component     |
2344						//  --------------------------------------------------------------------------------
2345						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2346						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2347							((unsigned short)(     a + 0.5f) << 15) |
2348							((unsigned short)(31 * r + 0.5f) << 10) |
2349							((unsigned short)(31 * g + 0.5f) << 5) |
2350							((unsigned short)(31 * b + 0.5f) << 0);
2351						break;
2352					default: UNREACHABLE(type);
2353					}
2354					break;
2355				case GL_RGB:   // IMPLEMENTATION_COLOR_READ_FORMAT
2356					switch(type)
2357					{
2358					case GL_UNSIGNED_SHORT_5_6_5:   // IMPLEMENTATION_COLOR_READ_TYPE
2359						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2360							((unsigned short)(31 * b + 0.5f) << 0) |
2361							((unsigned short)(63 * g + 0.5f) << 5) |
2362							((unsigned short)(31 * r + 0.5f) << 11);
2363						break;
2364					default: UNREACHABLE(type);
2365					}
2366					break;
2367				default: UNREACHABLE(format);
2368				}
2369			}
2370		}
2371	}
2372
2373	renderTarget->unlock();
2374	renderTarget->release();
2375}
2376
2377void Context::clear(GLbitfield mask)
2378{
2379	Framebuffer *framebuffer = getDrawFramebuffer();
2380
2381	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2382	{
2383		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2384	}
2385
2386	if(!applyRenderTarget())
2387	{
2388		return;
2389	}
2390
2391	float depth = clamp01(mState.depthClearValue);
2392	int stencil = mState.stencilClearValue & 0x000000FF;
2393
2394	if(mask & GL_COLOR_BUFFER_BIT)
2395	{
2396		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2397		                        (mState.colorMaskGreen ? 0x2 : 0) |
2398		                        (mState.colorMaskBlue ? 0x4 : 0) |
2399		                        (mState.colorMaskAlpha ? 0x8 : 0);
2400
2401		if(rgbaMask != 0)
2402		{
2403			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
2404		}
2405	}
2406
2407	if(mask & GL_DEPTH_BUFFER_BIT)
2408	{
2409		if(mState.depthMask != 0)
2410		{
2411			device->clearDepth(depth);
2412		}
2413	}
2414
2415	if(mask & GL_STENCIL_BUFFER_BIT)
2416	{
2417		if(mState.stencilWritemask != 0)
2418		{
2419			device->clearStencil(stencil, mState.stencilWritemask);
2420		}
2421	}
2422}
2423
2424void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2425{
2426	if(!mState.currentProgram)
2427	{
2428		device->setProjectionMatrix(projection.current());
2429		device->setViewMatrix(modelView.current());
2430		device->setTextureMatrix(0, texture[0].current());
2431		device->setTextureMatrix(1, texture[1].current());
2432		device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
2433		device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
2434		device->setTexGen(0, sw::TEXGEN_NONE);
2435		device->setTexGen(1, sw::TEXGEN_NONE);
2436	}
2437
2438	PrimitiveType primitiveType;
2439	int primitiveCount;
2440
2441	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2442		return error(GL_INVALID_ENUM);
2443
2444	if(primitiveCount <= 0)
2445	{
2446		return;
2447	}
2448
2449	if(!applyRenderTarget())
2450	{
2451		return;
2452	}
2453
2454	applyState(mode);
2455
2456	GLenum err = applyVertexBuffer(0, first, count);
2457	if(err != GL_NO_ERROR)
2458	{
2459		return error(err);
2460	}
2461
2462	applyShaders();
2463	applyTextures();
2464
2465	if(getCurrentProgram() && !getCurrentProgram()->validateSamplers(false))
2466	{
2467		return error(GL_INVALID_OPERATION);
2468	}
2469
2470	if(!cullSkipsDraw(mode))
2471	{
2472		device->drawPrimitive(primitiveType, primitiveCount);
2473	}
2474}
2475
2476void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2477{
2478	if(!mState.currentProgram)
2479	{
2480		return;
2481	}
2482
2483	if(!indices && !mState.elementArrayBuffer)
2484	{
2485		return error(GL_INVALID_OPERATION);
2486	}
2487
2488	PrimitiveType primitiveType;
2489	int primitiveCount;
2490
2491	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2492		return error(GL_INVALID_ENUM);
2493
2494	if(primitiveCount <= 0)
2495	{
2496		return;
2497	}
2498
2499	if(!applyRenderTarget())
2500	{
2501		return;
2502	}
2503
2504	applyState(mode);
2505
2506	TranslatedIndexData indexInfo;
2507	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2508	if(err != GL_NO_ERROR)
2509	{
2510		return error(err);
2511	}
2512
2513	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2514	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2515	if(err != GL_NO_ERROR)
2516	{
2517		return error(err);
2518	}
2519
2520	applyShaders();
2521	applyTextures();
2522
2523	if(!getCurrentProgram()->validateSamplers(false))
2524	{
2525		return error(GL_INVALID_OPERATION);
2526	}
2527
2528	if(!cullSkipsDraw(mode))
2529	{
2530		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
2531	}
2532}
2533
2534void Context::finish()
2535{
2536	device->finish();
2537}
2538
2539void Context::flush()
2540{
2541	// We don't queue anything without processing it as fast as possible
2542}
2543
2544void Context::recordInvalidEnum()
2545{
2546	mInvalidEnum = true;
2547}
2548
2549void Context::recordInvalidValue()
2550{
2551	mInvalidValue = true;
2552}
2553
2554void Context::recordInvalidOperation()
2555{
2556	mInvalidOperation = true;
2557}
2558
2559void Context::recordOutOfMemory()
2560{
2561	mOutOfMemory = true;
2562}
2563
2564void Context::recordInvalidFramebufferOperation()
2565{
2566	mInvalidFramebufferOperation = true;
2567}
2568
2569// Get one of the recorded errors and clear its flag, if any.
2570GLenum Context::getError()
2571{
2572	if(mInvalidEnum)
2573	{
2574		mInvalidEnum = false;
2575
2576		return GL_INVALID_ENUM;
2577	}
2578
2579	if(mInvalidValue)
2580	{
2581		mInvalidValue = false;
2582
2583		return GL_INVALID_VALUE;
2584	}
2585
2586	if(mInvalidOperation)
2587	{
2588		mInvalidOperation = false;
2589
2590		return GL_INVALID_OPERATION;
2591	}
2592
2593	if(mOutOfMemory)
2594	{
2595		mOutOfMemory = false;
2596
2597		return GL_OUT_OF_MEMORY;
2598	}
2599
2600	if(mInvalidFramebufferOperation)
2601	{
2602		mInvalidFramebufferOperation = false;
2603
2604		return GL_INVALID_FRAMEBUFFER_OPERATION;
2605	}
2606
2607	return GL_NO_ERROR;
2608}
2609
2610int Context::getSupportedMultisampleCount(int requested)
2611{
2612	int supported = 0;
2613
2614	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
2615	{
2616		if(supported >= requested)
2617		{
2618			return supported;
2619		}
2620
2621		supported = multisampleCount[i];
2622	}
2623
2624	return supported;
2625}
2626
2627void Context::detachBuffer(GLuint buffer)
2628{
2629	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
2630	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
2631
2632	if(mState.arrayBuffer.name() == buffer)
2633	{
2634		mState.arrayBuffer = nullptr;
2635	}
2636
2637	if(mState.elementArrayBuffer.name() == buffer)
2638	{
2639		mState.elementArrayBuffer = nullptr;
2640	}
2641
2642	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2643	{
2644		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
2645		{
2646			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
2647		}
2648	}
2649}
2650
2651void Context::detachTexture(GLuint texture)
2652{
2653	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2654	// rebound to texture object zero
2655
2656	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2657	{
2658		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
2659		{
2660			if(mState.samplerTexture[type][sampler].name() == texture)
2661			{
2662				mState.samplerTexture[type][sampler] = nullptr;
2663			}
2664		}
2665	}
2666
2667	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2668	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2669	// image was attached in the currently bound framebuffer.
2670
2671	Framebuffer *readFramebuffer = getReadFramebuffer();
2672	Framebuffer *drawFramebuffer = getDrawFramebuffer();
2673
2674	if(readFramebuffer)
2675	{
2676		readFramebuffer->detachTexture(texture);
2677	}
2678
2679	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2680	{
2681		drawFramebuffer->detachTexture(texture);
2682	}
2683}
2684
2685void Context::detachFramebuffer(GLuint framebuffer)
2686{
2687	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2688	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2689
2690	if(mState.readFramebuffer == framebuffer)
2691	{
2692		bindReadFramebuffer(0);
2693	}
2694
2695	if(mState.drawFramebuffer == framebuffer)
2696	{
2697		bindDrawFramebuffer(0);
2698	}
2699}
2700
2701void Context::detachRenderbuffer(GLuint renderbuffer)
2702{
2703	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
2704	// had been executed with the target RENDERBUFFER and name of zero.
2705
2706	if(mState.renderbuffer.name() == renderbuffer)
2707	{
2708		bindRenderbuffer(0);
2709	}
2710
2711	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
2712	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
2713	// point to which this image was attached in the currently bound framebuffer.
2714
2715	Framebuffer *readFramebuffer = getReadFramebuffer();
2716	Framebuffer *drawFramebuffer = getDrawFramebuffer();
2717
2718	if(readFramebuffer)
2719	{
2720		readFramebuffer->detachRenderbuffer(renderbuffer);
2721	}
2722
2723	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2724	{
2725		drawFramebuffer->detachRenderbuffer(renderbuffer);
2726	}
2727}
2728
2729bool Context::cullSkipsDraw(GLenum drawMode)
2730{
2731	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
2732}
2733
2734bool Context::isTriangleMode(GLenum drawMode)
2735{
2736	switch(drawMode)
2737	{
2738	case GL_TRIANGLES:
2739	case GL_TRIANGLE_FAN:
2740	case GL_TRIANGLE_STRIP:
2741		return true;
2742	case GL_POINTS:
2743	case GL_LINES:
2744	case GL_LINE_LOOP:
2745	case GL_LINE_STRIP:
2746		return false;
2747	default: UNREACHABLE(drawMode);
2748	}
2749
2750	return false;
2751}
2752
2753void Context::setVertexAttrib(GLuint index, float x, float y, float z, float w)
2754{
2755	ASSERT(index < MAX_VERTEX_ATTRIBS);
2756
2757	mState.vertexAttribute[index].mCurrentValue[0] = x;
2758	mState.vertexAttribute[index].mCurrentValue[1] = y;
2759	mState.vertexAttribute[index].mCurrentValue[2] = z;
2760	mState.vertexAttribute[index].mCurrentValue[3] = w;
2761
2762	mVertexDataManager->dirtyCurrentValue(index);
2763}
2764
2765void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2766                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2767                              GLbitfield mask)
2768{
2769	Framebuffer *readFramebuffer = getReadFramebuffer();
2770	Framebuffer *drawFramebuffer = getDrawFramebuffer();
2771
2772	int readBufferWidth, readBufferHeight, readBufferSamples;
2773	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
2774
2775	if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
2776	   !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2777	{
2778		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2779	}
2780
2781	if(drawBufferSamples > 1)
2782	{
2783		return error(GL_INVALID_OPERATION);
2784	}
2785
2786	sw::SliceRect sourceRect;
2787	sw::SliceRect destRect;
2788
2789	if(srcX0 < srcX1)
2790	{
2791		sourceRect.x0 = srcX0;
2792		sourceRect.x1 = srcX1;
2793		destRect.x0 = dstX0;
2794		destRect.x1 = dstX1;
2795	}
2796	else
2797	{
2798		sourceRect.x0 = srcX1;
2799		destRect.x0 = dstX1;
2800		sourceRect.x1 = srcX0;
2801		destRect.x1 = dstX0;
2802	}
2803
2804	if(srcY0 < srcY1)
2805	{
2806		sourceRect.y0 = srcY0;
2807		destRect.y0 = dstY0;
2808		sourceRect.y1 = srcY1;
2809		destRect.y1 = dstY1;
2810	}
2811	else
2812	{
2813		sourceRect.y0 = srcY1;
2814		destRect.y0 = dstY1;
2815		sourceRect.y1 = srcY0;
2816		destRect.y1 = dstY0;
2817	}
2818
2819	sw::Rect sourceScissoredRect = sourceRect;
2820	sw::Rect destScissoredRect = destRect;
2821
2822	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
2823	{
2824		if(destRect.x0 < mState.scissorX)
2825		{
2826			int xDiff = mState.scissorX - destRect.x0;
2827			destScissoredRect.x0 = mState.scissorX;
2828			sourceScissoredRect.x0 += xDiff;
2829		}
2830
2831		if(destRect.x1 > mState.scissorX + mState.scissorWidth)
2832		{
2833			int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
2834			destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
2835			sourceScissoredRect.x1 -= xDiff;
2836		}
2837
2838		if(destRect.y0 < mState.scissorY)
2839		{
2840			int yDiff = mState.scissorY - destRect.y0;
2841			destScissoredRect.y0 = mState.scissorY;
2842			sourceScissoredRect.y0 += yDiff;
2843		}
2844
2845		if(destRect.y1 > mState.scissorY + mState.scissorHeight)
2846		{
2847			int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
2848			destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
2849			sourceScissoredRect.y1 -= yDiff;
2850		}
2851	}
2852
2853	sw::Rect sourceTrimmedRect = sourceScissoredRect;
2854	sw::Rect destTrimmedRect = destScissoredRect;
2855
2856	// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
2857	// the actual draw and read surfaces.
2858	if(sourceTrimmedRect.x0 < 0)
2859	{
2860		int xDiff = 0 - sourceTrimmedRect.x0;
2861		sourceTrimmedRect.x0 = 0;
2862		destTrimmedRect.x0 += xDiff;
2863	}
2864
2865	if(sourceTrimmedRect.x1 > readBufferWidth)
2866	{
2867		int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
2868		sourceTrimmedRect.x1 = readBufferWidth;
2869		destTrimmedRect.x1 -= xDiff;
2870	}
2871
2872	if(sourceTrimmedRect.y0 < 0)
2873	{
2874		int yDiff = 0 - sourceTrimmedRect.y0;
2875		sourceTrimmedRect.y0 = 0;
2876		destTrimmedRect.y0 += yDiff;
2877	}
2878
2879	if(sourceTrimmedRect.y1 > readBufferHeight)
2880	{
2881		int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
2882		sourceTrimmedRect.y1 = readBufferHeight;
2883		destTrimmedRect.y1 -= yDiff;
2884	}
2885
2886	if(destTrimmedRect.x0 < 0)
2887	{
2888		int xDiff = 0 - destTrimmedRect.x0;
2889		destTrimmedRect.x0 = 0;
2890		sourceTrimmedRect.x0 += xDiff;
2891	}
2892
2893	if(destTrimmedRect.x1 > drawBufferWidth)
2894	{
2895		int xDiff = destTrimmedRect.x1 - drawBufferWidth;
2896		destTrimmedRect.x1 = drawBufferWidth;
2897		sourceTrimmedRect.x1 -= xDiff;
2898	}
2899
2900	if(destTrimmedRect.y0 < 0)
2901	{
2902		int yDiff = 0 - destTrimmedRect.y0;
2903		destTrimmedRect.y0 = 0;
2904		sourceTrimmedRect.y0 += yDiff;
2905	}
2906
2907	if(destTrimmedRect.y1 > drawBufferHeight)
2908	{
2909		int yDiff = destTrimmedRect.y1 - drawBufferHeight;
2910		destTrimmedRect.y1 = drawBufferHeight;
2911		sourceTrimmedRect.y1 -= yDiff;
2912	}
2913
2914	bool partialBufferCopy = false;
2915
2916	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
2917	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
2918	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
2919	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
2920	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
2921	{
2922		partialBufferCopy = true;
2923	}
2924
2925	bool blitRenderTarget = false;
2926	bool blitDepthStencil = false;
2927
2928	if(mask & GL_COLOR_BUFFER_BIT)
2929	{
2930		const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2931		                           readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2932		const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2933		                           drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2934		if(!validReadType || !validDrawType ||
2935		   readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())
2936		{
2937			ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
2938			return error(GL_INVALID_OPERATION);
2939		}
2940
2941		if(partialBufferCopy && readBufferSamples > 1)
2942		{
2943			return error(GL_INVALID_OPERATION);
2944		}
2945
2946		blitRenderTarget = true;
2947	}
2948
2949	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
2950	{
2951		Renderbuffer *readDSBuffer = nullptr;
2952		Renderbuffer *drawDSBuffer = nullptr;
2953
2954		// We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
2955		// both a depth and stencil buffer, it will be the same buffer.
2956
2957		if(mask & GL_DEPTH_BUFFER_BIT)
2958		{
2959			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2960			{
2961				if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
2962				   readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
2963				{
2964					return error(GL_INVALID_OPERATION);
2965				}
2966
2967				blitDepthStencil = true;
2968				readDSBuffer = readFramebuffer->getDepthbuffer();
2969				drawDSBuffer = drawFramebuffer->getDepthbuffer();
2970			}
2971		}
2972
2973		if(mask & GL_STENCIL_BUFFER_BIT)
2974		{
2975			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2976			{
2977				if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
2978				   readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
2979				{
2980					return error(GL_INVALID_OPERATION);
2981				}
2982
2983				blitDepthStencil = true;
2984				readDSBuffer = readFramebuffer->getStencilbuffer();
2985				drawDSBuffer = drawFramebuffer->getStencilbuffer();
2986			}
2987		}
2988
2989		if(partialBufferCopy)
2990		{
2991			ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
2992			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
2993		}
2994
2995		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
2996		   (readDSBuffer && readDSBuffer->getSamples() > 1))
2997		{
2998			return error(GL_INVALID_OPERATION);
2999		}
3000	}
3001
3002	if(blitRenderTarget || blitDepthStencil)
3003	{
3004		if(blitRenderTarget)
3005		{
3006			Image *readRenderTarget = readFramebuffer->getRenderTarget();
3007			Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
3008
3009			bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
3010
3011			readRenderTarget->release();
3012			drawRenderTarget->release();
3013
3014			if(!success)
3015			{
3016				ERR("BlitFramebufferANGLE failed.");
3017				return;
3018			}
3019		}
3020
3021		if(blitDepthStencil)
3022		{
3023			bool success = device->stretchRect(readFramebuffer->getDepthStencil(), nullptr, drawFramebuffer->getDepthStencil(), nullptr, false);
3024
3025			if(!success)
3026			{
3027				ERR("BlitFramebufferANGLE failed.");
3028				return;
3029			}
3030		}
3031	}
3032}
3033
3034void Context::setMatrixMode(GLenum mode)
3035{
3036	matrixMode = mode;
3037}
3038
3039sw::MatrixStack &Context::currentMatrixStack()
3040{
3041	switch(matrixMode)
3042	{
3043	case GL_MODELVIEW:  return modelView;                     break;
3044	case GL_PROJECTION: return projection;                    break;
3045	case GL_TEXTURE:    return texture[mState.activeSampler]; break;
3046	default:            UNREACHABLE(matrixMode); return modelView;      break;
3047	}
3048}
3049
3050void Context::loadIdentity()
3051{
3052	if(drawing)
3053	{
3054		return error(GL_INVALID_OPERATION);
3055	}
3056
3057	currentMatrixStack().identity();
3058}
3059
3060void Context::pushMatrix()
3061{
3062	//if(drawing)
3063	//{
3064	//    return error(GL_INVALID_OPERATION);
3065	//}
3066
3067	if(!currentMatrixStack().push())
3068	{
3069		return error(GL_STACK_OVERFLOW);
3070	}
3071}
3072
3073void Context::popMatrix()
3074{
3075	//if(drawing)
3076	//{
3077	//    return error(GL_INVALID_OPERATION);
3078	//}
3079
3080	if(!currentMatrixStack().pop())
3081	{
3082		return error(GL_STACK_OVERFLOW);
3083	}
3084}
3085
3086void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3087{
3088	if(drawing)
3089	{
3090		return error(GL_INVALID_OPERATION);
3091	}
3092
3093	currentMatrixStack().rotate(angle, x, y, z);
3094}
3095
3096void Context::translate(GLfloat x, GLfloat y, GLfloat z)
3097{
3098	if(drawing)
3099	{
3100		return error(GL_INVALID_OPERATION);
3101	}
3102
3103	currentMatrixStack().translate(x, y, z);
3104}
3105
3106void Context::scale(GLfloat x, GLfloat y, GLfloat z)
3107{
3108	if(drawing)
3109	{
3110		return error(GL_INVALID_OPERATION);
3111	}
3112
3113	currentMatrixStack().scale(x, y, z);
3114}
3115
3116void Context::multiply(const GLdouble *m)
3117{
3118	if(drawing)
3119	{
3120		return error(GL_INVALID_OPERATION);
3121	}
3122
3123	currentMatrixStack().multiply(m);
3124}
3125
3126void Context::multiply(const GLfloat *m)
3127{
3128	if(drawing)
3129	{
3130		return error(GL_INVALID_OPERATION);
3131	}
3132
3133	currentMatrixStack().multiply(m);
3134}
3135
3136void Context::frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
3137{
3138	if(drawing)
3139	{
3140		return error(GL_INVALID_OPERATION);
3141	}
3142
3143	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
3144}
3145
3146void Context::ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
3147{
3148	if(drawing)
3149	{
3150		return error(GL_INVALID_OPERATION);
3151	}
3152
3153	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
3154}
3155
3156void Context::setLightingEnabled(bool enable)
3157{
3158	if(drawing)
3159	{
3160		return error(GL_INVALID_OPERATION);
3161	}
3162
3163	device->setLightingEnable(enable);
3164}
3165
3166void Context::setFogEnabled(bool enable)
3167{
3168	if(drawing)
3169	{
3170		return error(GL_INVALID_OPERATION);
3171	}
3172
3173	device->setFogEnable(enable);
3174}
3175
3176void Context::setAlphaTestEnabled(bool enable)
3177{
3178	if(drawing)
3179	{
3180		return error(GL_INVALID_OPERATION);
3181	}
3182
3183	device->setAlphaTestEnable(enable);
3184}
3185
3186void Context::alphaFunc(GLenum func, GLclampf ref)
3187{
3188	if(drawing)
3189	{
3190		return error(GL_INVALID_OPERATION);
3191	}
3192
3193	switch(func)
3194	{
3195	case GL_NEVER:    device->setAlphaCompare(sw::ALPHA_NEVER);        break;
3196	case GL_LESS:     device->setAlphaCompare(sw::ALPHA_LESS);         break;
3197	case GL_EQUAL:    device->setAlphaCompare(sw::ALPHA_EQUAL);        break;
3198	case GL_LEQUAL:   device->setAlphaCompare(sw::ALPHA_LESSEQUAL);    break;
3199	case GL_GREATER:  device->setAlphaCompare(sw::ALPHA_GREATER);      break;
3200	case GL_NOTEQUAL: device->setAlphaCompare(sw::ALPHA_NOTEQUAL);     break;
3201	case GL_GEQUAL:   device->setAlphaCompare(sw::ALPHA_GREATEREQUAL); break;
3202	case GL_ALWAYS:   device->setAlphaCompare(sw::ALPHA_ALWAYS);       break;
3203	default: UNREACHABLE(func);
3204	}
3205
3206	device->setAlphaReference(gl::clamp01(ref));
3207}
3208
3209void Context::setTexture2DEnabled(bool enable)
3210{
3211	if(drawing)
3212	{
3213		return error(GL_INVALID_OPERATION);
3214	}
3215
3216	envEnable[mState.activeSampler] = enable;
3217}
3218
3219void Context::setShadeModel(GLenum mode)
3220{
3221	//if(drawing)
3222	//{
3223	//    return error(GL_INVALID_OPERATION);
3224	//}
3225
3226	switch(mode)
3227	{
3228	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
3229	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
3230	default: return error(GL_INVALID_ENUM);
3231	}
3232}
3233
3234void Context::setLightEnabled(int index, bool enable)
3235{
3236	device->setLightEnable(index, enable);
3237}
3238
3239void Context::setNormalizeNormalsEnabled(bool enable)
3240{
3241	device->setNormalizeNormals(enable);
3242}
3243
3244GLuint Context::genLists(GLsizei range)
3245{
3246	if(drawing)
3247	{
3248		return error(GL_INVALID_OPERATION, 0);
3249	}
3250
3251	int firstIndex = std::max(1u, firstFreeIndex);
3252	for(; true; firstIndex++)
3253	{
3254		int empty = 0;
3255		for(; empty < range; empty++)
3256		{
3257			if(displayList[firstIndex + empty] != 0)
3258			{
3259				break;
3260			}
3261		}
3262
3263		if(empty == range)
3264		{
3265			for(int i = firstIndex; i < firstIndex + range; i++)
3266			{
3267				displayList[i] = new DisplayList();
3268			}
3269
3270			if(firstIndex == firstFreeIndex)
3271			{
3272				firstFreeIndex = firstIndex + range;
3273			}
3274
3275			return firstIndex;
3276		}
3277	}
3278
3279	return 0;
3280}
3281
3282void Context::newList(GLuint list, GLenum mode)
3283{
3284	if(drawing || listIndex != 0)
3285	{
3286		return error(GL_INVALID_OPERATION);
3287	}
3288
3289	ASSERT(!this->list);
3290	this->list = new DisplayList();
3291
3292	listIndex = list;
3293	listMode = mode;
3294}
3295
3296void Context::endList()
3297{
3298	if(drawing || listIndex == 0)
3299	{
3300		return error(GL_INVALID_OPERATION);
3301	}
3302
3303	ASSERT(list);
3304	delete displayList[listIndex];
3305	displayList[listIndex] = list;
3306	list = 0;
3307
3308	listIndex = 0;
3309	listMode = 0;
3310}
3311
3312void Context::callList(GLuint list)
3313{
3314	// As per GL specifications, if the list does not exist, it is ignored
3315	if(displayList[list])
3316	{
3317		displayList[list]->call();
3318	}
3319}
3320
3321void Context::deleteList(GLuint list)
3322{
3323	delete displayList[list];
3324	displayList[list] = 0;
3325	displayList.erase(list);
3326	firstFreeIndex = std::min(firstFreeIndex , list);
3327}
3328
3329void Context::listCommand(Command *command)
3330{
3331	ASSERT(list);
3332	list->list.push_back(command);
3333
3334	if(listMode == GL_COMPILE_AND_EXECUTE)
3335	{
3336		listMode = 0;
3337		command->call();
3338		listMode = GL_COMPILE_AND_EXECUTE;
3339	}
3340}
3341
3342void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
3343{
3344	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
3345	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
3346	      index, size, type, normalized, stride, ptr);
3347
3348	gl::Context *context = gl::getContext();
3349
3350	if(context)
3351	{
3352		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
3353		context->setVertexAttribArrayEnabled(index, ptr != 0);
3354	}
3355}
3356
3357void Context::captureAttribs()
3358{
3359	memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute));
3360}
3361
3362void Context::captureDrawArrays(GLenum mode, GLint first, GLsizei count)
3363{
3364	ASSERT(first == 0);   // FIXME: UNIMPLEMENTED!
3365
3366	for(GLuint i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3367	{
3368		GLint size = mState.vertexAttribute[i].mSize;
3369		GLenum type = mState.vertexAttribute[i].mType;
3370		GLboolean normalized = mState.vertexAttribute[i].mNormalized;
3371		GLsizei stride = mState.vertexAttribute[i].mStride;
3372		const GLvoid *pointer = mState.vertexAttribute[i].mPointer;
3373
3374		size_t length = count * mState.vertexAttribute[i].stride();
3375
3376		if(mState.vertexAttribute[i].mArrayEnabled)
3377		{
3378			ASSERT(pointer);   // FIXME: Add to condition?
3379			const int padding = 1024;   // For SIMD processing of vertices   // FIXME: Still necessary?
3380			void *buffer = new unsigned char[length + padding];
3381			memcpy(buffer, pointer, length);
3382
3383			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)buffer));
3384		}
3385		else
3386		{
3387			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)0));
3388		}
3389	}
3390}
3391
3392void Context::restoreAttribs()
3393{
3394	memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute));
3395}
3396
3397void Context::clientActiveTexture(GLenum texture)
3398{
3399	clientTexture = texture;
3400}
3401
3402GLenum Context::getClientActiveTexture() const
3403{
3404	return clientTexture;
3405}
3406
3407unsigned int Context::getActiveTexture() const
3408{
3409	return mState.activeSampler;
3410}
3411
3412void Context::begin(GLenum mode)
3413{
3414	if(drawing)
3415	{
3416		return error(GL_INVALID_OPERATION);
3417	}
3418
3419	drawing = true;
3420	drawMode = mode;
3421
3422	vertex.clear();
3423}
3424
3425void Context::position(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3426{
3427	InVertex v;
3428
3429	v.P.x = x;
3430	v.P.y = y;
3431	v.P.z = z;
3432	v.P.w = w;
3433	v.C.x = mState.vertexAttribute[sw::Color0].mCurrentValue[0];
3434	v.C.y = mState.vertexAttribute[sw::Color0].mCurrentValue[1];
3435	v.C.z = mState.vertexAttribute[sw::Color0].mCurrentValue[2];
3436	v.C.w = mState.vertexAttribute[sw::Color0].mCurrentValue[3];
3437	v.N.x = mState.vertexAttribute[sw::Normal].mCurrentValue[0];
3438	v.N.y = mState.vertexAttribute[sw::Normal].mCurrentValue[1];
3439	v.N.z = mState.vertexAttribute[sw::Normal].mCurrentValue[2];
3440	v.N.w = mState.vertexAttribute[sw::Normal].mCurrentValue[3];
3441	v.T0.x = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0];
3442	v.T0.y = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1];
3443	v.T0.z = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2];
3444	v.T0.w = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3];
3445	v.T1.x = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0];
3446	v.T1.y = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1];
3447	v.T1.z = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2];
3448	v.T1.w = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3];
3449
3450	vertex.push_back(v);
3451}
3452
3453void Context::end()
3454{
3455	if(!drawing)
3456	{
3457		return error(GL_INVALID_OPERATION);
3458	}
3459
3460	device->setProjectionMatrix(projection.current());
3461	device->setViewMatrix(modelView.current());
3462	device->setTextureMatrix(0, texture[0].current());
3463	device->setTextureMatrix(1, texture[1].current());
3464	device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
3465	device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
3466
3467	captureAttribs();
3468
3469	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3470	{
3471		mState.vertexAttribute[i].mArrayEnabled = false;
3472	}
3473
3474	setVertexAttribState(sw::Position, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].P);
3475	setVertexAttribState(sw::Normal, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].N);
3476	setVertexAttribState(sw::Color0, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].C);
3477	setVertexAttribState(sw::TexCoord0, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T0);
3478	setVertexAttribState(sw::TexCoord1, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T1);
3479
3480	mState.vertexAttribute[sw::Position].mArrayEnabled = true;
3481	mState.vertexAttribute[sw::Normal].mArrayEnabled = true;
3482	mState.vertexAttribute[sw::Color0].mArrayEnabled = true;
3483	mState.vertexAttribute[sw::TexCoord0].mArrayEnabled = true;
3484	mState.vertexAttribute[sw::TexCoord1].mArrayEnabled = true;
3485
3486	applyState(drawMode);
3487
3488	GLenum err = applyVertexBuffer(0, 0, vertex.size());
3489	if(err != GL_NO_ERROR)
3490	{
3491		return error(err);
3492	}
3493
3494	applyTextures();
3495
3496	switch(drawMode)
3497	{
3498	case GL_POINTS:
3499		UNIMPLEMENTED();
3500		break;
3501	case GL_LINES:
3502		UNIMPLEMENTED();
3503		break;
3504	case GL_LINE_STRIP:
3505		UNIMPLEMENTED();
3506		break;
3507	case GL_LINE_LOOP:
3508		UNIMPLEMENTED();
3509		break;
3510	case GL_TRIANGLES:
3511		UNIMPLEMENTED();
3512		break;
3513	case GL_TRIANGLE_STRIP:
3514		device->drawPrimitive(DRAW_TRIANGLESTRIP, vertex.size() - 2);
3515		break;
3516	case GL_TRIANGLE_FAN:
3517		UNIMPLEMENTED();
3518		break;
3519	case GL_QUADS:
3520		UNIMPLEMENTED();
3521		break;
3522	case GL_QUAD_STRIP:
3523		UNIMPLEMENTED();
3524		break;
3525	case GL_POLYGON:
3526		UNIMPLEMENTED();
3527		break;
3528	default:
3529		UNREACHABLE(drawMode);
3530	}
3531
3532	restoreAttribs();
3533
3534	drawing = false;
3535}
3536
3537void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled)
3538{
3539	if(mState.colorLogicOpEnabled != colorLogicOpEnabled)
3540	{
3541		mState.colorLogicOpEnabled = colorLogicOpEnabled;
3542		mColorLogicOperatorDirty = true;
3543	}
3544}
3545
3546bool Context::isColorLogicOpEnabled()
3547{
3548	return mState.colorLogicOpEnabled;
3549}
3550
3551void Context::setLogicalOperation(GLenum logicalOperation)
3552{
3553	if(mState.logicalOperation != logicalOperation)
3554	{
3555		mState.logicalOperation = logicalOperation;
3556		mColorLogicOperatorDirty = true;
3557	}
3558}
3559
3560void Context::setColorMaterialEnabled(bool enable)
3561{
3562	device->setColorVertexEnable(enable);
3563}
3564
3565void Context::setColorMaterialMode(GLenum mode)
3566{
3567	switch(mode)
3568	{
3569	case GL_EMISSION:
3570		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3571		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3572		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3573		device->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
3574		break;
3575	case GL_AMBIENT:
3576		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3577		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3578		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3579		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3580		break;
3581	case GL_DIFFUSE:
3582		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3583		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3584		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3585		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3586		break;
3587	case GL_SPECULAR:
3588		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3589		device->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
3590		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3591		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3592		break;
3593	case GL_AMBIENT_AND_DIFFUSE:
3594		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3595		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3596		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3597		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3598		break;
3599	default:
3600		UNREACHABLE(mode);
3601	}
3602}
3603
3604Device *Context::getDevice()
3605{
3606	return device;
3607}
3608
3609}
3610