Home | History | Annotate | Download | only in libGL
      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 
     43 namespace gl
     44 {
     45 Context::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 
    204 Context::~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 
    264 void 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.
    308 void 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 
    323 void 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 
    331 void Context::setClearDepth(float depth)
    332 {
    333 	mState.depthClearValue = depth;
    334 }
    335 
    336 void Context::setClearStencil(int stencil)
    337 {
    338 	mState.stencilClearValue = stencil;
    339 }
    340 
    341 void Context::setCullFaceEnabled(bool enabled)
    342 {
    343 	mState.cullFaceEnabled = enabled;
    344 }
    345 
    346 bool Context::isCullFaceEnabled() const
    347 {
    348 	return mState.cullFaceEnabled;
    349 }
    350 
    351 void Context::setCullMode(GLenum mode)
    352 {
    353    mState.cullMode = mode;
    354 }
    355 
    356 void Context::setFrontFace(GLenum front)
    357 {
    358 	if(mState.frontFace != front)
    359 	{
    360 		mState.frontFace = front;
    361 		mFrontFaceDirty = true;
    362 	}
    363 }
    364 
    365 void Context::setDepthTestEnabled(bool enabled)
    366 {
    367 	if(mState.depthTestEnabled != enabled)
    368 	{
    369 		mState.depthTestEnabled = enabled;
    370 		mDepthStateDirty = true;
    371 	}
    372 }
    373 
    374 bool Context::isDepthTestEnabled() const
    375 {
    376 	return mState.depthTestEnabled;
    377 }
    378 
    379 void Context::setDepthFunc(GLenum depthFunc)
    380 {
    381 	if(mState.depthFunc != depthFunc)
    382 	{
    383 		mState.depthFunc = depthFunc;
    384 		mDepthStateDirty = true;
    385 	}
    386 }
    387 
    388 void Context::setDepthRange(float zNear, float zFar)
    389 {
    390 	mState.zNear = zNear;
    391 	mState.zFar = zFar;
    392 }
    393 
    394 void Context::setBlendEnabled(bool enabled)
    395 {
    396 	if(mState.blendEnabled != enabled)
    397 	{
    398 		mState.blendEnabled = enabled;
    399 		mBlendStateDirty = true;
    400 	}
    401 }
    402 
    403 bool Context::isBlendEnabled() const
    404 {
    405 	return mState.blendEnabled;
    406 }
    407 
    408 void 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 
    423 void 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 
    438 void 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 
    449 void Context::setStencilTestEnabled(bool enabled)
    450 {
    451 	if(mState.stencilTestEnabled != enabled)
    452 	{
    453 		mState.stencilTestEnabled = enabled;
    454 		mStencilStateDirty = true;
    455 	}
    456 }
    457 
    458 bool Context::isStencilTestEnabled() const
    459 {
    460 	return mState.stencilTestEnabled;
    461 }
    462 
    463 void 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 
    476 void 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 
    489 void Context::setStencilWritemask(GLuint stencilWritemask)
    490 {
    491 	if(mState.stencilWritemask != stencilWritemask)
    492 	{
    493 		mState.stencilWritemask = stencilWritemask;
    494 		mStencilStateDirty = true;
    495 	}
    496 }
    497 
    498 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
    499 {
    500 	if(mState.stencilBackWritemask != stencilBackWritemask)
    501 	{
    502 		mState.stencilBackWritemask = stencilBackWritemask;
    503 		mStencilStateDirty = true;
    504 	}
    505 }
    506 
    507 void 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 
    520 void 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 
    533 void Context::setPolygonOffsetFillEnabled(bool enabled)
    534 {
    535 	if(mState.polygonOffsetFillEnabled != enabled)
    536 	{
    537 		mState.polygonOffsetFillEnabled = enabled;
    538 		mPolygonOffsetStateDirty = true;
    539 	}
    540 }
    541 
    542 bool Context::isPolygonOffsetFillEnabled() const
    543 {
    544 	return mState.polygonOffsetFillEnabled;
    545 }
    546 
    547 void 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 
    558 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
    559 {
    560 	if(mState.sampleAlphaToCoverageEnabled != enabled)
    561 	{
    562 		mState.sampleAlphaToCoverageEnabled = enabled;
    563 		mSampleStateDirty = true;
    564 	}
    565 }
    566 
    567 bool Context::isSampleAlphaToCoverageEnabled() const
    568 {
    569 	return mState.sampleAlphaToCoverageEnabled;
    570 }
    571 
    572 void Context::setSampleCoverageEnabled(bool enabled)
    573 {
    574 	if(mState.sampleCoverageEnabled != enabled)
    575 	{
    576 		mState.sampleCoverageEnabled = enabled;
    577 		mSampleStateDirty = true;
    578 	}
    579 }
    580 
    581 bool Context::isSampleCoverageEnabled() const
    582 {
    583 	return mState.sampleCoverageEnabled;
    584 }
    585 
    586 void 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 
    597 void Context::setScissorTestEnabled(bool enabled)
    598 {
    599 	mState.scissorTestEnabled = enabled;
    600 }
    601 
    602 bool Context::isScissorTestEnabled() const
    603 {
    604 	return mState.scissorTestEnabled;
    605 }
    606 
    607 void Context::setDitherEnabled(bool enabled)
    608 {
    609 	if(mState.ditherEnabled != enabled)
    610 	{
    611 		mState.ditherEnabled = enabled;
    612 		mDitherStateDirty = true;
    613 	}
    614 }
    615 
    616 bool Context::isDitherEnabled() const
    617 {
    618 	return mState.ditherEnabled;
    619 }
    620 
    621 void 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 
    627 void Context::setGenerateMipmapHint(GLenum hint)
    628 {
    629 	mState.generateMipmapHint = hint;
    630 }
    631 
    632 void 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 
    640 void 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 
    648 void 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 
    656 void 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 
    669 void Context::setDepthMask(bool mask)
    670 {
    671 	if(mState.depthMask != mask)
    672 	{
    673 		mState.depthMask = mask;
    674 		mMaskStateDirty = true;
    675 	}
    676 }
    677 
    678 void Context::setActiveSampler(unsigned int active)
    679 {
    680 	mState.activeSampler = active;
    681 }
    682 
    683 GLuint Context::getReadFramebufferName() const
    684 {
    685 	return mState.readFramebuffer;
    686 }
    687 
    688 GLuint Context::getDrawFramebufferName() const
    689 {
    690 	return mState.drawFramebuffer;
    691 }
    692 
    693 GLuint Context::getRenderbufferName() const
    694 {
    695 	return mState.renderbuffer.name();
    696 }
    697 
    698 GLuint Context::getArrayBufferName() const
    699 {
    700 	return mState.arrayBuffer.name();
    701 }
    702 
    703 GLuint 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 
    727 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
    728 {
    729 	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
    730 }
    731 
    732 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
    733 {
    734 	return mState.vertexAttribute[attribNum];
    735 }
    736 
    737 void 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 
    748 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
    749 {
    750 	return mState.vertexAttribute[attribNum].mPointer;
    751 }
    752 
    753 const VertexAttributeArray &Context::getVertexAttributes()
    754 {
    755 	return mState.vertexAttribute;
    756 }
    757 
    758 void Context::setPackAlignment(GLint alignment)
    759 {
    760 	mState.packAlignment = alignment;
    761 }
    762 
    763 GLint Context::getPackAlignment() const
    764 {
    765 	return mState.packAlignment;
    766 }
    767 
    768 void Context::setUnpackAlignment(GLint alignment)
    769 {
    770 	mState.unpackAlignment = alignment;
    771 }
    772 
    773 GLint Context::getUnpackAlignment() const
    774 {
    775 	return mState.unpackAlignment;
    776 }
    777 
    778 GLuint Context::createBuffer()
    779 {
    780 	return mResourceManager->createBuffer();
    781 }
    782 
    783 GLuint Context::createProgram()
    784 {
    785 	return mResourceManager->createProgram();
    786 }
    787 
    788 GLuint Context::createShader(GLenum type)
    789 {
    790 	return mResourceManager->createShader(type);
    791 }
    792 
    793 GLuint Context::createTexture()
    794 {
    795 	return mResourceManager->createTexture();
    796 }
    797 
    798 GLuint Context::createRenderbuffer()
    799 {
    800 	return mResourceManager->createRenderbuffer();
    801 }
    802 
    803 // Returns an unused framebuffer name
    804 GLuint Context::createFramebuffer()
    805 {
    806 	return mFramebufferNameSpace.allocate();
    807 }
    808 
    809 GLuint Context::createFence()
    810 {
    811 	return mFenceNameSpace.allocate(new Fence());
    812 }
    813 
    814 // Returns an unused query name
    815 GLuint Context::createQuery()
    816 {
    817 	return mQueryNameSpace.allocate();
    818 }
    819 
    820 void Context::deleteBuffer(GLuint buffer)
    821 {
    822 	if(mResourceManager->getBuffer(buffer))
    823 	{
    824 		detachBuffer(buffer);
    825 	}
    826 
    827 	mResourceManager->deleteBuffer(buffer);
    828 }
    829 
    830 void Context::deleteShader(GLuint shader)
    831 {
    832 	mResourceManager->deleteShader(shader);
    833 }
    834 
    835 void Context::deleteProgram(GLuint program)
    836 {
    837 	mResourceManager->deleteProgram(program);
    838 }
    839 
    840 void Context::deleteTexture(GLuint texture)
    841 {
    842 	if(mResourceManager->getTexture(texture))
    843 	{
    844 		detachTexture(texture);
    845 	}
    846 
    847 	mResourceManager->deleteTexture(texture);
    848 }
    849 
    850 void Context::deleteRenderbuffer(GLuint renderbuffer)
    851 {
    852 	if(mResourceManager->getRenderbuffer(renderbuffer))
    853 	{
    854 		detachRenderbuffer(renderbuffer);
    855 	}
    856 
    857 	mResourceManager->deleteRenderbuffer(renderbuffer);
    858 }
    859 
    860 void 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 
    872 void Context::deleteFence(GLuint fence)
    873 {
    874 	Fence *fenceObject = mFenceNameSpace.remove(fence);
    875 
    876 	if(fenceObject)
    877 	{
    878 		delete fenceObject;
    879 	}
    880 }
    881 
    882 void Context::deleteQuery(GLuint query)
    883 {
    884 	Query *queryObject = mQueryNameSpace.remove(query);
    885 
    886 	if(queryObject)
    887 	{
    888 		queryObject->release();
    889 	}
    890 }
    891 
    892 Buffer *Context::getBuffer(GLuint handle)
    893 {
    894 	return mResourceManager->getBuffer(handle);
    895 }
    896 
    897 Shader *Context::getShader(GLuint handle)
    898 {
    899 	return mResourceManager->getShader(handle);
    900 }
    901 
    902 Program *Context::getProgram(GLuint handle)
    903 {
    904 	return mResourceManager->getProgram(handle);
    905 }
    906 
    907 Texture *Context::getTexture(GLuint handle)
    908 {
    909 	return mResourceManager->getTexture(handle);
    910 }
    911 
    912 Renderbuffer *Context::getRenderbuffer(GLuint handle)
    913 {
    914 	return mResourceManager->getRenderbuffer(handle);
    915 }
    916 
    917 Framebuffer *Context::getReadFramebuffer()
    918 {
    919 	return getFramebuffer(mState.readFramebuffer);
    920 }
    921 
    922 Framebuffer *Context::getDrawFramebuffer()
    923 {
    924 	return getFramebuffer(mState.drawFramebuffer);
    925 }
    926 
    927 void Context::bindArrayBuffer(unsigned int buffer)
    928 {
    929 	mResourceManager->checkBufferAllocation(buffer);
    930 
    931 	mState.arrayBuffer = getBuffer(buffer);
    932 }
    933 
    934 void Context::bindElementArrayBuffer(unsigned int buffer)
    935 {
    936 	mResourceManager->checkBufferAllocation(buffer);
    937 
    938 	mState.elementArrayBuffer = getBuffer(buffer);
    939 }
    940 
    941 void Context::bindTexture2D(GLuint texture)
    942 {
    943 	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
    944 
    945 	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
    946 }
    947 
    948 void Context::bindTextureCubeMap(GLuint texture)
    949 {
    950 	mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
    951 
    952 	mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
    953 }
    954 
    955 void Context::bindReadFramebuffer(GLuint framebuffer)
    956 {
    957 	if(!getFramebuffer(framebuffer))
    958 	{
    959 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
    960 	}
    961 
    962 	mState.readFramebuffer = framebuffer;
    963 }
    964 
    965 void Context::bindDrawFramebuffer(GLuint framebuffer)
    966 {
    967 	if(!getFramebuffer(framebuffer))
    968 	{
    969 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
    970 	}
    971 
    972 	mState.drawFramebuffer = framebuffer;
    973 }
    974 
    975 void Context::bindRenderbuffer(GLuint renderbuffer)
    976 {
    977 	mResourceManager->checkRenderbufferAllocation(renderbuffer);
    978 
    979 	mState.renderbuffer = getRenderbuffer(renderbuffer);
    980 }
    981 
    982 void 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 
   1004 void 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 
   1063 void 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 
   1091 void Context::setFramebufferZero(Framebuffer *buffer)
   1092 {
   1093 	delete mFramebufferNameSpace.remove(0);
   1094 	mFramebufferNameSpace.insert(0, buffer);
   1095 }
   1096 
   1097 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
   1098 {
   1099 	Renderbuffer *renderbufferObject = mState.renderbuffer;
   1100 	renderbufferObject->setStorage(renderbuffer);
   1101 }
   1102 
   1103 Framebuffer *Context::getFramebuffer(unsigned int handle)
   1104 {
   1105 	return mFramebufferNameSpace.find(handle);
   1106 }
   1107 
   1108 Fence *Context::getFence(unsigned int handle)
   1109 {
   1110 	return mFenceNameSpace.find(handle);
   1111 }
   1112 
   1113 Query *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 
   1133 Buffer *Context::getArrayBuffer()
   1134 {
   1135 	return mState.arrayBuffer;
   1136 }
   1137 
   1138 Buffer *Context::getElementArrayBuffer()
   1139 {
   1140 	return mState.elementArrayBuffer;
   1141 }
   1142 
   1143 Program *Context::getCurrentProgram()
   1144 {
   1145 	return mResourceManager->getProgram(mState.currentProgram);
   1146 }
   1147 
   1148 Texture2D *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 
   1163 TextureCubeMap *Context::getTextureCubeMap()
   1164 {
   1165 	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
   1166 }
   1167 
   1168 Texture *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 
   1186 bool 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 
   1215 bool 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 
   1274 bool 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 
   1480 bool 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
   1649 bool 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)
   1707 void 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 
   1933 GLenum 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
   1975 GLenum 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
   1988 void 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 
   2012 void Context::applyTextures()
   2013 {
   2014 	applyTextures(sw::SAMPLER_PIXEL);
   2015 	//applyTextures(sw::SAMPLER_VERTEX);
   2016 }
   2017 
   2018 void 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 
   2085 void 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 levelCount = baseTexture->getLevelCount();
   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 >= levelCount)
   2127 				{
   2128 					surfaceLevel = levelCount - 1;
   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 >= levelCount)
   2150 					{
   2151 						surfaceLevel = levelCount - 1;
   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 
   2167 void 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 
   2377 void 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 
   2424 void 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 
   2476 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
   2477 {
   2478 	if(!mState.currentProgram)
   2479 	{
   2480 		return error(GL_INVALID_OPERATION);
   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 
   2534 void Context::finish()
   2535 {
   2536 	device->finish();
   2537 }
   2538 
   2539 void Context::flush()
   2540 {
   2541 	// We don't queue anything without processing it as fast as possible
   2542 }
   2543 
   2544 void Context::recordInvalidEnum()
   2545 {
   2546 	mInvalidEnum = true;
   2547 }
   2548 
   2549 void Context::recordInvalidValue()
   2550 {
   2551 	mInvalidValue = true;
   2552 }
   2553 
   2554 void Context::recordInvalidOperation()
   2555 {
   2556 	mInvalidOperation = true;
   2557 }
   2558 
   2559 void Context::recordOutOfMemory()
   2560 {
   2561 	mOutOfMemory = true;
   2562 }
   2563 
   2564 void Context::recordInvalidFramebufferOperation()
   2565 {
   2566 	mInvalidFramebufferOperation = true;
   2567 }
   2568 
   2569 // Get one of the recorded errors and clear its flag, if any.
   2570 GLenum 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 
   2610 int 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 
   2627 void 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 
   2651 void 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 
   2685 void 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 
   2701 void 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 
   2729 bool Context::cullSkipsDraw(GLenum drawMode)
   2730 {
   2731 	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
   2732 }
   2733 
   2734 bool 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 
   2753 void 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 
   2765 void 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 
   3034 void Context::setMatrixMode(GLenum mode)
   3035 {
   3036 	matrixMode = mode;
   3037 }
   3038 
   3039 sw::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 
   3050 void Context::loadIdentity()
   3051 {
   3052 	if(drawing)
   3053 	{
   3054 		return error(GL_INVALID_OPERATION);
   3055 	}
   3056 
   3057 	currentMatrixStack().identity();
   3058 }
   3059 
   3060 void 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 
   3073 void 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 
   3086 void 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 
   3096 void 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 
   3106 void 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 
   3116 void Context::multiply(const GLdouble *m)
   3117 {
   3118 	if(drawing)
   3119 	{
   3120 		return error(GL_INVALID_OPERATION);
   3121 	}
   3122 
   3123 	currentMatrixStack().multiply(m);
   3124 }
   3125 
   3126 void Context::multiply(const GLfloat *m)
   3127 {
   3128 	if(drawing)
   3129 	{
   3130 		return error(GL_INVALID_OPERATION);
   3131 	}
   3132 
   3133 	currentMatrixStack().multiply(m);
   3134 }
   3135 
   3136 void 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 
   3146 void 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 
   3156 void Context::setLightingEnabled(bool enable)
   3157 {
   3158 	if(drawing)
   3159 	{
   3160 		return error(GL_INVALID_OPERATION);
   3161 	}
   3162 
   3163 	device->setLightingEnable(enable);
   3164 }
   3165 
   3166 void Context::setFogEnabled(bool enable)
   3167 {
   3168 	if(drawing)
   3169 	{
   3170 		return error(GL_INVALID_OPERATION);
   3171 	}
   3172 
   3173 	device->setFogEnable(enable);
   3174 }
   3175 
   3176 void Context::setAlphaTestEnabled(bool enable)
   3177 {
   3178 	if(drawing)
   3179 	{
   3180 		return error(GL_INVALID_OPERATION);
   3181 	}
   3182 
   3183 	device->setAlphaTestEnable(enable);
   3184 }
   3185 
   3186 void 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 
   3209 void Context::setTexture2DEnabled(bool enable)
   3210 {
   3211 	if(drawing)
   3212 	{
   3213 		return error(GL_INVALID_OPERATION);
   3214 	}
   3215 
   3216 	envEnable[mState.activeSampler] = enable;
   3217 }
   3218 
   3219 void 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 
   3234 void Context::setLightEnabled(int index, bool enable)
   3235 {
   3236 	device->setLightEnable(index, enable);
   3237 }
   3238 
   3239 void Context::setNormalizeNormalsEnabled(bool enable)
   3240 {
   3241 	device->setNormalizeNormals(enable);
   3242 }
   3243 
   3244 GLuint 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 
   3282 void 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 
   3296 void 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 
   3312 void 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 
   3321 void 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 
   3329 void 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 
   3342 void 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 
   3357 void Context::captureAttribs()
   3358 {
   3359 	memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute));
   3360 }
   3361 
   3362 void 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 
   3392 void Context::restoreAttribs()
   3393 {
   3394 	memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute));
   3395 }
   3396 
   3397 void Context::clientActiveTexture(GLenum texture)
   3398 {
   3399 	clientTexture = texture;
   3400 }
   3401 
   3402 GLenum Context::getClientActiveTexture() const
   3403 {
   3404 	return clientTexture;
   3405 }
   3406 
   3407 unsigned int Context::getActiveTexture() const
   3408 {
   3409 	return mState.activeSampler;
   3410 }
   3411 
   3412 void 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 
   3425 void 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 
   3453 void 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 
   3537 void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled)
   3538 {
   3539 	if(mState.colorLogicOpEnabled != colorLogicOpEnabled)
   3540 	{
   3541 		mState.colorLogicOpEnabled = colorLogicOpEnabled;
   3542 		mColorLogicOperatorDirty = true;
   3543 	}
   3544 }
   3545 
   3546 bool Context::isColorLogicOpEnabled()
   3547 {
   3548 	return mState.colorLogicOpEnabled;
   3549 }
   3550 
   3551 void Context::setLogicalOperation(GLenum logicalOperation)
   3552 {
   3553 	if(mState.logicalOperation != logicalOperation)
   3554 	{
   3555 		mState.logicalOperation = logicalOperation;
   3556 		mColorLogicOperatorDirty = true;
   3557 	}
   3558 }
   3559 
   3560 void Context::setColorMaterialEnabled(bool enable)
   3561 {
   3562 	device->setColorVertexEnable(enable);
   3563 }
   3564 
   3565 void 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 
   3604 Device *Context::getDevice()
   3605 {
   3606 	return device;
   3607 }
   3608 
   3609 }
   3610