Implement missing state and queries.

Change-Id: I4858980fc32df435ffc0fc0917905116bea54aa8
Reviewed-on: https://swiftshader-review.googlesource.com/3790
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGL/Context.cpp b/src/OpenGL/libGL/Context.cpp
index 8d0aeba..4ea7b6b 100644
--- a/src/OpenGL/libGL/Context.cpp
+++ b/src/OpenGL/libGL/Context.cpp
@@ -319,6 +319,7 @@
     mSampleStateDirty = true;

     mDitherStateDirty = true;

     mFrontFaceDirty = true;

+	mColorLogicOperatorDirty = true;

 }

 

 void Context::setClearColor(float red, float green, float blue, float alpha)

@@ -3630,7 +3631,11 @@
 

 void Context::setLogicalOperation(GLenum logicalOperation)

 {

-	mState.logicalOperation = logicalOperation;

+	if(mState.logicalOperation != logicalOperation)

+	{

+		mState.logicalOperation = logicalOperation;

+		mColorLogicOperatorDirty = true;

+	}

 }

 

 void Context::setColorMaterialEnabled(bool enable)

diff --git a/src/OpenGL/libGL/utilities.cpp b/src/OpenGL/libGL/utilities.cpp
index 93ea23c..ebdfdca 100644
--- a/src/OpenGL/libGL/utilities.cpp
+++ b/src/OpenGL/libGL/utilities.cpp
@@ -513,22 +513,22 @@
 	{

 		switch(logicalOperation)

 		{

-		case GL_CLEAR:              return sw::LOGICALOP_CLEAR;

-		case GL_SET:                return sw::LOGICALOP_SET;

-		case GL_COPY:               return sw::LOGICALOP_COPY;

-		case GL_COPY_INVERTED:      return sw::LOGICALOP_COPY_INVERTED;

-		case GL_NOOP:               return sw::LOGICALOP_NOOP;

-		case GL_INVERT:             return sw::LOGICALOP_INVERT;

-		case GL_AND:                return sw::LOGICALOP_AND;

-		case GL_NAND:               return sw::LOGICALOP_NAND;

-		case GL_OR:                 return sw::LOGICALOP_OR;

-		case GL_NOR:                return sw::LOGICALOP_NOR;

-		case GL_XOR:                return sw::LOGICALOP_XOR;

-		case GL_EQUIV:              return sw::LOGICALOP_EQUIV;

-		case GL_AND_REVERSE:        return sw::LOGICALOP_AND_REVERSE;

-		case GL_AND_INVERTED:       return sw::LOGICALOP_AND_INVERTED;

-		case GL_OR_REVERSE:         return sw::LOGICALOP_OR_REVERSE;

-		case GL_OR_INVERTED:        return sw::LOGICALOP_OR_INVERTED;

+		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;

+		case GL_SET:           return sw::LOGICALOP_SET;

+		case GL_COPY:          return sw::LOGICALOP_COPY;

+		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;

+		case GL_NOOP:          return sw::LOGICALOP_NOOP;

+		case GL_INVERT:        return sw::LOGICALOP_INVERT;

+		case GL_AND:           return sw::LOGICALOP_AND;

+		case GL_NAND:          return sw::LOGICALOP_NAND;

+		case GL_OR:            return sw::LOGICALOP_OR;

+		case GL_NOR:           return sw::LOGICALOP_NOR;

+		case GL_XOR:           return sw::LOGICALOP_XOR;

+		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;

+		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;

+		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;

+		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;

+		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;

 		default: UNREACHABLE(logicalOperation);

 		}

 

diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index 5fc94d5..1574f97 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -86,8 +86,7 @@
 	mState.shadeModel = GL_SMOOTH;

     mState.generateMipmapHint = GL_DONT_CARE;

 	mState.perspectiveCorrectionHint = GL_DONT_CARE;

-	mState.colorLogicOpEnabled = false;

-	mState.logicalOperation = GL_COPY;

+	mState.fogHint = GL_DONT_CARE;

 

     mState.lineWidth = 1.0f;

 

@@ -177,6 +176,8 @@
 		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};

 		light[i].direction = {0.0f, 0.0f, -1.0f};

 		light[i].attenuation = {1.0f, 0.0f, 0.0f};

+		light[i].spotExponent = 0.0f;

+		light[i].spotCutoffAngle = 180.0f;

 	}

 

 	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};

@@ -188,6 +189,7 @@
 	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};

 	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};

 	materialShininess = 0.0f;

+	lightModelTwoSide = false;

 

 	matrixMode = GL_MODELVIEW;

     

@@ -215,6 +217,30 @@
 	alphaTestFunc = GL_ALWAYS;

 	alphaTestRef = 0;

 

+	fogEnabled = false;

+	fogMode = GL_EXP;

+	fogDensity = 1.0f;

+	fogStart = 0.0f;

+	fogEnd = 1.0f;

+	fogColor = {0, 0, 0, 0};

+

+	lineSmoothEnabled = false;

+	colorMaterialEnabled = false;

+	normalizeEnabled = false;

+	rescaleNormalEnabled = false;

+	multisampleEnabled = true;

+	sampleAlphaToOneEnabled = false;

+

+	colorLogicOpEnabled = false;

+	logicalOperation = GL_COPY;

+

+	pointSpriteEnabled = false;

+	pointSmoothEnabled = false;

+	pointSizeMin = 0.0f;

+	pointSizeMax = 1.0f;

+	pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};

+	pointFadeThresholdSize = 1.0f;

+

     mHasBeenCurrent = false;

 

     markAllStateDirty();

@@ -456,8 +482,8 @@
 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)

 {

     if(mState.stencilFunc != stencilFunc ||

-        mState.stencilRef != stencilRef ||

-        mState.stencilMask != stencilMask)

+       mState.stencilRef != stencilRef ||

+       mState.stencilMask != stencilMask)

     {

         mState.stencilFunc = stencilFunc;

         mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;

@@ -478,8 +504,8 @@
 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)

 {

     if(mState.stencilFail != stencilFail ||

-        mState.stencilPassDepthFail != stencilPassDepthFail ||

-        mState.stencilPassDepthPass != stencilPassDepthPass)

+       mState.stencilPassDepthFail != stencilPassDepthFail ||

+       mState.stencilPassDepthPass != stencilPassDepthPass)

     {

         mState.stencilFail = stencilFail;

         mState.stencilPassDepthFail = stencilPassDepthFail;

@@ -505,7 +531,7 @@
 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)

 {

     if(mState.polygonOffsetFactor != factor ||

-        mState.polygonOffsetUnits != units)

+       mState.polygonOffsetUnits != units)

     {

         mState.polygonOffsetFactor = factor;

         mState.polygonOffsetUnits = units;

@@ -586,11 +612,21 @@
     lightingEnabled = enable;

 }

 

+bool Context::isLightingEnabled() const

+{

+	return lightingEnabled;

+}

+

 void Context::setLightEnabled(int index, bool enable)

 {

     light[index].enabled = enable;

 }

 

+bool Context::isLightEnabled(int index) const

+{

+	return light[index].enabled;

+}

+

 void Context::setLightAmbient(int index, float r, float g, float b, float a)

 {

 	light[index].ambient = {r, g, b, a};

@@ -637,6 +673,16 @@
 	light[index].attenuation.quadratic = quadratic;

 }

 

+void Context::setSpotLightExponent(int index, float exponent)

+{

+	light[index].spotExponent = exponent;

+}

+

+void Context::setSpotLightCutoff(int index, float cutoff)

+{

+	light[index].spotCutoffAngle = cutoff;

+}

+

 void Context::setGlobalAmbient(float red, float green, float blue, float alpha)

 {

 	globalAmbient.red = red;

@@ -682,47 +728,44 @@
 	materialShininess = shininess;

 }

 

+void Context::setLightModelTwoSide(bool enable)

+{

+	lightModelTwoSide = enable;

+}

+

 void Context::setFogEnabled(bool enable)

 {

-	device->setFogEnable(enable);

+	fogEnabled = enable;

+}

+

+bool Context::isFogEnabled() const

+{

+	return fogEnabled;

 }

 

 void Context::setFogMode(GLenum mode)

 {

-	switch(mode)

-	{

-	case GL_LINEAR:

-		device->setPixelFogMode(sw::FOG_LINEAR);

-		break;

-	case GL_EXP:

-		device->setPixelFogMode(sw::FOG_EXP);

-		break;

-	case GL_EXP2:

-		device->setPixelFogMode(sw::FOG_EXP2);

-		break;

-	default:

-		UNREACHABLE(mode);

-	}

+	fogMode = mode;

 }

 

 void Context::setFogDensity(float fogDensity)

 {

-	device->setFogDensity(fogDensity);

+	this->fogDensity = fogDensity;

 }

 

 void Context::setFogStart(float fogStart)

 {

-	device->setFogStart(fogStart);

+	this->fogStart = fogStart;

 }

 

 void Context::setFogEnd(float fogEnd)

 {

-	device->setFogEnd(fogEnd);

+	this->fogEnd = fogEnd;

 }

 

 void Context::setFogColor(float r, float g, float b, float a)

 {

-	device->setFogColor(sw::Color<float>(r, g, b, a));

+	this->fogColor = {r, g, b, a};

 }

 

 void Context::setTexture2Denabled(bool enable)

@@ -730,11 +773,21 @@
     texture2Denabled[mState.activeSampler] = enable;

 }

 

+bool Context::isTexture2Denabled() const

+{

+	return texture2Denabled[mState.activeSampler];

+}

+

 void Context::setTextureExternalEnabled(bool enable)

 {

     textureExternalEnabled[mState.activeSampler] = enable;

 }

 

+bool Context::isTextureExternalEnabled() const

+{

+    return textureExternalEnabled[mState.activeSampler];

+}

+

 void Context::setLineWidth(GLfloat width)

 {

     mState.lineWidth = width;

@@ -751,6 +804,11 @@
     mState.perspectiveCorrectionHint = hint;

 }

 

+void Context::setFogHint(GLenum hint)

+{

+    mState.fogHint = hint;

+}

+

 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)

 {

     mState.viewportX = x;

@@ -1044,7 +1102,7 @@
 

     if(texid == 0)   // Special case: 0 refers to different initial textures based on the target

     {

-        switch (type)

+        switch(type)

         {

         case TEXTURE_2D: return mTexture2DZero;

         case TEXTURE_EXTERNAL: return mTextureExternalZero;

@@ -1076,6 +1134,7 @@
     case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;

     case GL_BLEND:                    *params = mState.blendEnabled;                 break;

     case GL_DITHER:                   *params = mState.ditherEnabled;                break;

+	case GL_LIGHT_MODEL_TWO_SIDE:     *params = lightModelTwoSide;                   break;

     default:

         return false;

     }

@@ -1104,6 +1163,14 @@
         params[0] = ALIASED_POINT_SIZE_RANGE_MIN;

         params[1] = ALIASED_POINT_SIZE_RANGE_MAX;

         break;

+	case GL_SMOOTH_LINE_WIDTH_RANGE:

+        params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;

+        params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;

+        break;

+    case GL_SMOOTH_POINT_SIZE_RANGE:

+        params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;

+        params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;

+        break;

     case GL_DEPTH_RANGE:

         params[0] = mState.zNear;

         params[1] = mState.zFar;

@@ -1143,7 +1210,7 @@
     // GetIntegerv as its native query function. As it would require conversion in any

     // case, this should make no difference to the calling application. You may find it in

     // Context::getFloatv.

-    switch (pname)

+    switch(pname)

     {

     case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;

     case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;

@@ -1254,12 +1321,12 @@
 

             if(colorbuffer)

             {

-                switch (pname)

+                switch(pname)

                 {

-                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;

-                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;

-                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;

-                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;

+                case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;

+                case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;

+                case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;

+                case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;

                 }

             }

             else

@@ -1298,45 +1365,30 @@
             }

         }

         break;

-    case GL_TEXTURE_BINDING_2D:

-        {

-            if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1)

-            {

-                error(GL_INVALID_OPERATION);

-                return false;

-            }

-

-            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();

-        }

-        break;

-    case GL_TEXTURE_BINDING_CUBE_MAP_OES:

-        {

-            if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1)

-            {

-                error(GL_INVALID_OPERATION);

-                return false;

-            }

-

-            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();

-        }

-        break;

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:

-        {

-            if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1)

-            {

-                error(GL_INVALID_OPERATION);

-                return false;

-            }

-

-            *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();

-        }

-        break;

-	case GL_MAX_LIGHTS:                 *params = MAX_LIGHTS;                 break;

-    case GL_MAX_MODELVIEW_STACK_DEPTH:  *params = MAX_MODELVIEW_STACK_DEPTH;  break;

-	case GL_MAX_PROJECTION_STACK_DEPTH: *params = MAX_PROJECTION_STACK_DEPTH; break;

-	case GL_MAX_TEXTURE_STACK_DEPTH:    *params = MAX_TEXTURE_STACK_DEPTH;    break;

-	case GL_MAX_TEXTURE_UNITS:          *params = MAX_TEXTURE_UNITS;          break;

-	case GL_MAX_CLIP_PLANES:            *params = MAX_CLIP_PLANES;            break;

+    case GL_TEXTURE_BINDING_2D:                  *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();                   break;

+    case GL_TEXTURE_BINDING_CUBE_MAP_OES:        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();                 break;

+    case GL_TEXTURE_BINDING_EXTERNAL_OES:        *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();             break;

+	case GL_MAX_LIGHTS:                          *params = MAX_LIGHTS;                                                                       break;

+    case GL_MAX_MODELVIEW_STACK_DEPTH:           *params = MAX_MODELVIEW_STACK_DEPTH;                                                        break;

+	case GL_MAX_PROJECTION_STACK_DEPTH:          *params = MAX_PROJECTION_STACK_DEPTH;                                                       break;

+	case GL_MAX_TEXTURE_STACK_DEPTH:             *params = MAX_TEXTURE_STACK_DEPTH;                                                          break;

+	case GL_MAX_TEXTURE_UNITS:                   *params = MAX_TEXTURE_UNITS;                                                                break;

+	case GL_MAX_CLIP_PLANES:                     *params = MAX_CLIP_PLANES;                                                                  break;

+	case GL_POINT_SIZE_ARRAY_TYPE_OES:           *params = mState.vertexAttribute[sw::PointSize].mType;                                      break;

+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:         *params = mState.vertexAttribute[sw::PointSize].mStride;                                    break;

+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name();                        break;

+	case GL_VERTEX_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Position].mType;                                       break;

+	case GL_VERTEX_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Position].mStride;                                     break;

+	case GL_VERTEX_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name();                         break;

+	case GL_NORMAL_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Normal].mType;                                         break;

+	case GL_NORMAL_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Normal].mStride;                                       break;

+	case GL_NORMAL_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name();                           break;

+	case GL_COLOR_ARRAY_TYPE:                    *params = mState.vertexAttribute[sw::Color0].mType;                                         break;

+	case GL_COLOR_ARRAY_STRIDE:                  *params = mState.vertexAttribute[sw::Color0].mStride;                                       break;

+	case GL_COLOR_ARRAY_BUFFER_BINDING:          *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name();                           break;

+	case GL_TEXTURE_COORD_ARRAY_TYPE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType;               break;

+	case GL_TEXTURE_COORD_ARRAY_STRIDE:          *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride;             break;

+	case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;

     default:

         return false;

     }

@@ -1353,7 +1405,7 @@
     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

     // application.

-    switch (pname)

+    switch(pname)

     {

     case GL_COMPRESSED_TEXTURE_FORMATS:

 		return NUM_COMPRESSED_TEXTURE_FORMATS;

@@ -1438,7 +1490,58 @@
 	case GL_MAX_TEXTURE_STACK_DEPTH:

 	case GL_MAX_TEXTURE_UNITS:

 	case GL_MAX_CLIP_PLANES:

+	case GL_POINT_SIZE_ARRAY_TYPE_OES:

+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:

+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:

         return 1;

+	case GL_CURRENT_COLOR:

+		return 4;

+	case GL_CURRENT_NORMAL:

+		return 3;

+	case GL_CURRENT_TEXTURE_COORDS:

+		return 4;

+	case GL_POINT_SIZE:

+	case GL_POINT_SIZE_MIN:

+	case GL_POINT_SIZE_MAX:

+	case GL_POINT_FADE_THRESHOLD_SIZE:

+		return 1;

+	case GL_POINT_DISTANCE_ATTENUATION:

+		return 3;

+	case GL_SMOOTH_POINT_SIZE_RANGE:

+	case GL_SMOOTH_LINE_WIDTH_RANGE:

+		return 2;

+	case GL_SHADE_MODEL:

+	case GL_MATRIX_MODE:

+	case GL_MODELVIEW_STACK_DEPTH:

+	case GL_PROJECTION_STACK_DEPTH:

+	case GL_TEXTURE_STACK_DEPTH:

+		return 1;

+	case GL_MODELVIEW_MATRIX:

+	case GL_PROJECTION_MATRIX:

+	case GL_TEXTURE_MATRIX:

+		return 16;

+	case GL_ALPHA_TEST_FUNC:

+	case GL_ALPHA_TEST_REF:

+	case GL_BLEND_DST:

+	case GL_BLEND_SRC:

+	case GL_LOGIC_OP_MODE:

+	case GL_VERTEX_ARRAY_SIZE:

+	case GL_VERTEX_ARRAY_TYPE:

+	case GL_VERTEX_ARRAY_STRIDE:

+	case GL_NORMAL_ARRAY_TYPE:

+	case GL_NORMAL_ARRAY_STRIDE:

+	case GL_COLOR_ARRAY_SIZE:

+	case GL_COLOR_ARRAY_TYPE:

+	case GL_COLOR_ARRAY_STRIDE:

+	case GL_TEXTURE_COORD_ARRAY_SIZE:

+	case GL_TEXTURE_COORD_ARRAY_TYPE:

+	case GL_TEXTURE_COORD_ARRAY_STRIDE:

+	case GL_VERTEX_ARRAY_POINTER:

+	case GL_NORMAL_ARRAY_POINTER:

+	case GL_COLOR_ARRAY_POINTER:

+	case GL_TEXTURE_COORD_ARRAY_POINTER:

+	case GL_LIGHT_MODEL_TWO_SIDE:

+		return 1;

 	default:

 		UNREACHABLE(pname);

     }

@@ -1508,9 +1611,11 @@
 	case GL_MAX_PROJECTION_STACK_DEPTH:

 	case GL_MAX_TEXTURE_STACK_DEPTH:

 	case GL_MAX_TEXTURE_UNITS:

+	case GL_MAX_CLIP_PLANES:

+	case GL_POINT_SIZE_ARRAY_TYPE_OES:

+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:

+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:

         return true;

-	default:

-		ASSERT(isQueryParameterFloat(pname) || isQueryParameterBool(pname));

     }

 

     return false;

@@ -1534,12 +1639,17 @@
     case GL_LINE_WIDTH:

     case GL_ALIASED_LINE_WIDTH_RANGE:

     case GL_ALIASED_POINT_SIZE_RANGE:

+    case GL_SMOOTH_LINE_WIDTH_RANGE:

+    case GL_SMOOTH_POINT_SIZE_RANGE:

     case GL_DEPTH_RANGE:

     case GL_COLOR_CLEAR_VALUE:

 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

+	case GL_LIGHT_MODEL_AMBIENT:

+	case GL_POINT_SIZE_MIN:

+	case GL_POINT_SIZE_MAX:

+	case GL_POINT_DISTANCE_ATTENUATION:

+	case GL_POINT_FADE_THRESHOLD_SIZE:

         return true;

-    default:

-        ASSERT(isQueryParameterInt(pname) || isQueryParameterBool(pname));

     }

 

     return false;

@@ -1561,9 +1671,23 @@
     case GL_BLEND:

     case GL_DITHER:

     case GL_COLOR_WRITEMASK:

+	case GL_LIGHT_MODEL_TWO_SIDE:

         return true;

-    default:

-        ASSERT(isQueryParameterInt(pname) || isQueryParameterFloat(pname));

+    }

+

+    return false;

+}

+

+bool Context::isQueryParameterPointer(GLenum pname)

+{

+    switch(pname)

+    {

+	case GL_VERTEX_ARRAY_POINTER:

+	case GL_NORMAL_ARRAY_POINTER:

+	case GL_COLOR_ARRAY_POINTER:

+	case GL_TEXTURE_COORD_ARRAY_POINTER:

+	case GL_POINT_SIZE_ARRAY_POINTER_OES:

+        return true;

     }

 

     return false;

@@ -1851,6 +1975,25 @@
 	device->setAlphaTestEnable(alphaTestEnabled);

 	device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));

 	device->setAlphaReference(alphaTestRef * 0xFF);

+

+	device->setFogEnable(fogEnabled);

+	device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));

+	device->setFogDensity(fogDensity);

+	device->setFogStart(fogStart);

+	device->setFogEnd(fogEnd);

+

+	switch(fogMode)

+	{

+	case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;

+	case GL_EXP:    device->setVertexFogMode(sw::FOG_EXP);    break;

+	case GL_EXP2:   device->setVertexFogMode(sw::FOG_EXP2);   break;

+	default: UNREACHABLE(fogMode);

+	}

+

+	device->setColorLogicOpEnabled(colorLogicOpEnabled);

+	device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));

+

+	device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);

 }

 

 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)

@@ -2638,8 +2781,8 @@
 {

 	es1::Framebuffer *framebuffer = getFramebuffer();

 	es1::Renderbuffer *renderbuffer = framebuffer->getColorbuffer();

-	float targetWidth = renderbuffer->getWidth();

-	float targetHeight = renderbuffer->getHeight();

+	float targetWidth = (float)renderbuffer->getWidth();

+	float targetHeight = (float)renderbuffer->getHeight();

 	float x0 = 2.0f * x / targetWidth - 1.0f;

 	float y0 = 2.0f * y / targetHeight - 1.0f;

 	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;

@@ -2653,8 +2796,8 @@
 

 	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented

 	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);

-	float textureWidth = texture->getWidth(GL_TEXTURE_2D, 0);

-	float textureHeight = texture->getHeight(GL_TEXTURE_2D, 0);

+	float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);

+	float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);

 	int Ucr = texture->getCropRectU();

 	int Vcr = texture->getCropRectV();

 	int Wcr = texture->getCropRectW();

@@ -2898,18 +3041,18 @@
 

 bool Context::isTriangleMode(GLenum drawMode)

 {

-    switch (drawMode)

+    switch(drawMode)

     {

-      case GL_TRIANGLES:

-      case GL_TRIANGLE_FAN:

-      case GL_TRIANGLE_STRIP:

+    case GL_TRIANGLES:

+    case GL_TRIANGLE_FAN:

+    case GL_TRIANGLE_STRIP:

         return true;

-      case GL_POINTS:

-      case GL_LINES:

-      case GL_LINE_LOOP:

-      case GL_LINE_STRIP:

+    case GL_POINTS:

+    case GL_LINES:

+    case GL_LINE_LOOP:

+    case GL_LINE_STRIP:

         return false;

-      default: UNREACHABLE(drawMode);

+    default: UNREACHABLE(drawMode);

     }

 

     return false;

@@ -3120,6 +3263,172 @@
 	return (clipFlags & (1 << index)) != 0;

 }

 

+void Context::setColorLogicOpEnabled(bool enable)

+{

+	colorLogicOpEnabled = enable;

+}

+

+bool Context::isColorLogicOpEnabled() const

+{

+	return colorLogicOpEnabled;

+}

+

+void Context::setLogicalOperation(GLenum logicOp)

+{

+	logicalOperation = logicOp;

+}

+

+void Context::setLineSmoothEnabled(bool enable)

+{

+	lineSmoothEnabled = enable;

+}

+

+bool Context::isLineSmoothEnabled() const

+{

+	return lineSmoothEnabled;

+}

+

+void Context::setColorMaterialEnabled(bool enable)

+{

+	colorMaterialEnabled = enable;

+}

+

+bool Context::isColorMaterialEnabled() const

+{

+	return colorMaterialEnabled;

+}

+

+void Context::setNormalizeEnabled(bool enable)

+{

+	normalizeEnabled = enable;

+}

+

+bool Context::isNormalizeEnabled() const

+{

+	return normalizeEnabled;

+}

+

+void Context::setRescaleNormalEnabled(bool enable)

+{

+	rescaleNormalEnabled = enable;

+}

+

+bool Context::isRescaleNormalEnabled() const

+{

+	return rescaleNormalEnabled;

+}

+

+void Context::setVertexArrayEnabled(bool enable)

+{

+	mState.vertexAttribute[sw::Position].mArrayEnabled = enable;

+}

+

+bool Context::isVertexArrayEnabled() const

+{

+	return mState.vertexAttribute[sw::Position].mArrayEnabled;

+}

+

+void Context::setNormalArrayEnabled(bool enable)

+{

+	mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;

+}

+

+bool Context::isNormalArrayEnabled() const

+{

+	return mState.vertexAttribute[sw::Normal].mArrayEnabled;

+}

+

+void Context::setColorArrayEnabled(bool enable)

+{

+	mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;

+}

+

+bool Context::isColorArrayEnabled() const

+{

+	return mState.vertexAttribute[sw::Color0].mArrayEnabled;

+}

+

+void Context::setPointSizeArrayEnabled(bool enable)

+{

+	mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;

+}

+

+bool Context::isPointSizeArrayEnabled() const

+{

+	return mState.vertexAttribute[sw::PointSize].mArrayEnabled;

+}

+

+void Context::setTextureCoordArrayEnabled(bool enable)

+{

+	mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;

+}

+

+bool Context::isTextureCoordArrayEnabled() const

+{

+	return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;

+}

+

+void Context::setMultisampleEnabled(bool enable)

+{

+	multisampleEnabled = enable;

+}

+

+bool Context::isMultisampleEnabled() const

+{

+	return multisampleEnabled;

+}

+

+void Context::setSampleAlphaToOneEnabled(bool enable)

+{

+	sampleAlphaToOneEnabled = enable;

+}

+

+bool Context::isSampleAlphaToOneEnabled() const

+{

+	return sampleAlphaToOneEnabled;

+}

+

+void Context::setPointSpriteEnabled(bool enable)

+{

+	pointSpriteEnabled = enable;

+}

+

+bool Context::isPointSpriteEnabled() const

+{

+	return pointSpriteEnabled;

+}

+

+void Context::setPointSmoothEnabled(bool enable)

+{

+	pointSmoothEnabled = enable;

+}

+

+bool Context::isPointSmoothEnabled() const

+{

+	return pointSmoothEnabled;

+}

+

+

+void Context::setPointSizeMin(float min)

+{

+	pointSizeMin = min;

+}

+

+void Context::setPointSizeMax(float max)

+{

+	pointSizeMax = max;

+}

+

+void Context::setPointDistanceAttenuation(float a, float b, float c)

+{

+	pointDistanceAttenuation = {a, b, c};

+}

+

+void Context::setPointFadeThresholdSize(float threshold)

+{

+	pointFadeThresholdSize = threshold;

+}

+

 void Context::clientActiveTexture(GLenum texture)

 {

 	clientTexture = texture;

diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index b1073a4..262caad 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -86,6 +86,10 @@
 const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;

 const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;

 const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;

+const float SMOOTH_LINE_WIDTH_RANGE_MIN = 1.0f;

+const float SMOOTH_LINE_WIDTH_RANGE_MAX = 1.0f;

+const float SMOOTH_POINT_SIZE_RANGE_MIN = 0.125f;

+const float SMOOTH_POINT_SIZE_RANGE_MAX = 8192.0f;

 const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;

 

 struct Color

@@ -127,12 +131,14 @@
 	Point position;

 	Vector direction;

 	Attenuation attenuation;

+	float spotExponent;

+	float spotCutoffAngle;

 };

 

 // Helper structure describing a single vertex attribute

 class VertexAttribute

 {

-  public:

+public:

     VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)

     {

         mCurrentValue[0] = 0.0f;

@@ -237,13 +243,12 @@
     bool scissorTestEnabled;

     bool ditherEnabled;

 	GLenum shadeModel;

-	bool colorLogicOpEnabled;

-	GLenum logicalOperation;

 

     GLfloat lineWidth;

 

     GLenum generateMipmapHint;

 	GLenum perspectiveCorrectionHint;

+	GLenum fogHint;

 

     GLint viewportX;

     GLint viewportY;

@@ -332,7 +337,9 @@
     void setDitherEnabled(bool enabled);

     bool isDitherEnabled() const;

 	void setLightingEnabled(bool enabled);

+	bool isLightingEnabled() const;

 	void setLightEnabled(int index, bool enable);

+	bool isLightEnabled(int index) const;

 	void setLightAmbient(int index, float r, float g, float b, float a);

 	void setLightDiffuse(int index, float r, float g, float b, float a);

 	void setLightSpecular(int index, float r, float g, float b, float a);

@@ -341,6 +348,8 @@
 	void setLightAttenuationConstant(int index, float constant);

 	void setLightAttenuationLinear(int index, float linear);

 	void setLightAttenuationQuadratic(int index, float quadratic);

+	void setSpotLightExponent(int index, float exponent);

+	void setSpotLightCutoff(int index, float cutoff);

 	

 	void setGlobalAmbient(float red, float green, float blue, float alpha);

 	void setMaterialAmbient(float red, float green, float blue, float alpha);

@@ -348,8 +357,10 @@
 	void setMaterialSpecular(float red, float green, float blue, float alpha);

 	void setMaterialEmission(float red, float green, float blue, float alpha);

 	void setMaterialShininess(float shininess);

+	void setLightModelTwoSide(bool enable);

 

 	void setFogEnabled(bool enabled);

+	bool isFogEnabled() const;

 	void setFogMode(GLenum mode);

 	void setFogDensity(float fogDensity);

 	void setFogStart(float fogStart);

@@ -357,7 +368,9 @@
 	void setFogColor(float r, float g, float b, float a);

 

     void setTexture2Denabled(bool enabled);

+	bool isTexture2Denabled() const;

 	void setTextureExternalEnabled(bool enabled);

+	bool isTextureExternalEnabled() const;

     void clientActiveTexture(GLenum texture);

 	GLenum getClientActiveTexture() const;

 	unsigned int getActiveTexture() const;

@@ -383,6 +396,7 @@
 

     void setGenerateMipmapHint(GLenum hint);

 	void setPerspectiveCorrectionHint(GLenum hint);

+	void setFogHint(GLenum hint);

 

     void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);

 

@@ -414,7 +428,7 @@
     void setPackAlignment(GLint alignment);

     GLint getPackAlignment() const;

 

-    // These create  and destroy methods are merely pass-throughs to

+    // These create and destroy methods are merely pass-throughs to

     // ResourceManager, which owns these object types

     GLuint createBuffer();

     GLuint createTexture();

@@ -461,6 +475,7 @@
 	bool isQueryParameterInt(GLenum pname);

 	bool isQueryParameterFloat(GLenum pname);

 	bool isQueryParameterBool(GLenum pname);

+	bool isQueryParameterPointer(GLenum pname);

 

     void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);

     void clear(GLbitfield mask);

@@ -504,6 +519,53 @@
 	void setClipPlaneEnabled(int index, bool enable);

 	bool isClipPlaneEnabled(int index) const;

 

+	void setColorLogicOpEnabled(bool enable);

+	bool isColorLogicOpEnabled() const;

+	void setLogicalOperation(GLenum logicOp);

+

+	void setPointSmoothEnabled(bool enable);

+	bool isPointSmoothEnabled() const;

+

+	void setLineSmoothEnabled(bool enable);

+	bool isLineSmoothEnabled() const;

+

+	void setColorMaterialEnabled(bool enable);

+	bool isColorMaterialEnabled() const;

+

+	void setNormalizeEnabled(bool enable);

+	bool isNormalizeEnabled() const;

+

+	void setRescaleNormalEnabled(bool enable);

+	bool isRescaleNormalEnabled() const;

+

+	void setVertexArrayEnabled(bool enable);

+	bool isVertexArrayEnabled() const;

+

+	void setNormalArrayEnabled(bool enable);

+	bool isNormalArrayEnabled() const;

+

+	void setColorArrayEnabled(bool enable);

+	bool isColorArrayEnabled() const;

+

+	void setPointSizeArrayEnabled(bool enable);

+	bool isPointSizeArrayEnabled() const;

+

+	void setTextureCoordArrayEnabled(bool enable);

+	bool isTextureCoordArrayEnabled() const;

+

+	void setMultisampleEnabled(bool enable);

+	bool isMultisampleEnabled() const;

+

+	void setSampleAlphaToOneEnabled(bool enable);

+	bool isSampleAlphaToOneEnabled() const;

+

+	void setPointSpriteEnabled(bool enable);

+	bool isPointSpriteEnabled() const;

+	void setPointSizeMin(float min);

+	void setPointSizeMax(float max);

+	void setPointDistanceAttenuation(float a, float b, float c);

+	void setPointFadeThresholdSize(float threshold);

+

 private:

 	virtual ~Context();

 

@@ -542,6 +604,7 @@
 	Color materialSpecular;

 	Color materialEmission;

 	GLfloat materialShininess;

+	bool lightModelTwoSide;

 

     // Recorded errors

     bool mInvalidEnum;

@@ -582,6 +645,30 @@
 	GLenum alphaTestFunc;

 	float alphaTestRef;

 

+	bool fogEnabled;

+	GLenum fogMode;

+	float fogDensity;

+	float fogStart;

+	float fogEnd;

+	Color fogColor;

+

+	bool lineSmoothEnabled;

+	bool colorMaterialEnabled;

+	bool normalizeEnabled;

+	bool rescaleNormalEnabled;

+	bool multisampleEnabled;

+	bool sampleAlphaToOneEnabled;

+

+	bool pointSpriteEnabled;

+	bool pointSmoothEnabled;

+	float pointSizeMin;

+	float pointSizeMax;

+	Attenuation pointDistanceAttenuation;

+	float pointFadeThresholdSize;

+

+	bool colorLogicOpEnabled;

+	GLenum logicalOperation;

+

 	Device *device;

     ResourceManager *mResourceManager;

 };

diff --git a/src/OpenGL/libGLES_CM/Device.cpp b/src/OpenGL/libGLES_CM/Device.cpp
index d3151db..bc2121f 100644
--- a/src/OpenGL/libGLES_CM/Device.cpp
+++ b/src/OpenGL/libGLES_CM/Device.cpp
@@ -87,8 +87,6 @@
 		setDestBlendFactorAlpha(BLEND_ZERO);

 		setBlendOperationAlpha(BLENDOP_ADD);

 		setPointSpriteEnable(true);

-		setColorLogicOpEnabled(false);

-		setLogicalOperation(LOGICALOP_COPY);

 

 		for(int i = 0; i < 16; i++)

 		{

diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
index 2d3f6fa..6888185 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -1216,24 +1216,26 @@
 		case GL_TEXTURE_2D:               context->setTexture2Denabled(false);             break;

 		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(false);       break;

 		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;

-		case GL_COLOR_LOGIC_OP:           UNIMPLEMENTED(); break;

-		case GL_POINT_SMOOTH:             UNIMPLEMENTED(); break;

-		case GL_LINE_SMOOTH:              UNIMPLEMENTED(); break;

-		case GL_COLOR_MATERIAL:           UNIMPLEMENTED(); break;

-		case GL_NORMALIZE:                UNIMPLEMENTED(); break;

-		case GL_RESCALE_NORMAL:           UNIMPLEMENTED(); break;

-		case GL_VERTEX_ARRAY:             UNIMPLEMENTED(); break;

-		case GL_NORMAL_ARRAY:             UNIMPLEMENTED(); break;

-		case GL_COLOR_ARRAY:              UNIMPLEMENTED(); break;

-		case GL_TEXTURE_COORD_ARRAY:      UNIMPLEMENTED(); break;

-		case GL_MULTISAMPLE:              UNIMPLEMENTED(); break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      UNIMPLEMENTED(); break;

-		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, false); break;

-		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, false); break;

-		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, false); break;

-		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, false); break;

-		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, false); break;

-		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, false); break;

+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;

+		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(false);           break;

+		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(false);            break;

+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;

+		case GL_NORMALIZE:                context->setNormalizeEnabled(false);             break;

+		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(false);         break;

+		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(false);           break;

+		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(false);           break;

+		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(false);            break;

+		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(false);        break;

+		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(false);     break;

+		case GL_MULTISAMPLE:              context->setMultisampleEnabled(false);           break;

+		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(false);      break;

+		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, false);          break;

+		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, false);          break;

+		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, false);          break;

+		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, false);          break;

+		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, false);          break;

+		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, false);          break;

+		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(false);           break;

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -1244,19 +1246,32 @@
 {

 	TRACE("(GLenum array = 0x%X)", array);

 

+	switch(array)

+	{

+	case GL_VERTEX_ARRAY:

+	case GL_NORMAL_ARRAY:

+	case GL_COLOR_ARRAY:

+	case GL_POINT_SIZE_ARRAY_OES:

+	case GL_TEXTURE_COORD_ARRAY:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

 	es1::Context *context = es1::getContext();

 

-	if (context)

+	if(context)

 	{

 		GLenum texture = context->getClientActiveTexture();

 

-		switch (array)

+		switch(array)

 		{

-		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, false);                            break;

-		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;

-		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;

-		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;

-		default:                     UNIMPLEMENTED();

+		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, false);                            break;

+		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;

+		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;

+		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false);                           break;

+		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;

+		default:                      UNREACHABLE(array);

 		}

 	}

 }

@@ -1334,28 +1349,30 @@
 		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;

 		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;

 		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;

-		case GL_FOG:                      context->setFogEnabled(true);				      break;

+		case GL_FOG:                      context->setFogEnabled(true);                   break;

 		case GL_TEXTURE_2D:               context->setTexture2Denabled(true);             break;

 		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(true);       break;

 		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;

-		case GL_COLOR_LOGIC_OP:           UNIMPLEMENTED(); break;

-		case GL_POINT_SMOOTH:             UNIMPLEMENTED(); break;

-		case GL_LINE_SMOOTH:              UNIMPLEMENTED(); break;

-		case GL_COLOR_MATERIAL:           UNIMPLEMENTED(); break;

-		case GL_NORMALIZE:                UNIMPLEMENTED(); break;

-		case GL_RESCALE_NORMAL:           UNIMPLEMENTED(); break;

-		case GL_VERTEX_ARRAY:             UNIMPLEMENTED(); break;

-		case GL_NORMAL_ARRAY:             UNIMPLEMENTED(); break;

-		case GL_COLOR_ARRAY:              UNIMPLEMENTED(); break;

-		case GL_TEXTURE_COORD_ARRAY:      UNIMPLEMENTED(); break;

-		case GL_MULTISAMPLE:              UNIMPLEMENTED(); break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      UNIMPLEMENTED(); break;

-		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, true); break;

-		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, true); break;

-		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, true); break;

-		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, true); break;

-		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, true); break;

-		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, true); break;

+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;

+		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(true);           break;

+		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(true);            break;

+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;

+		case GL_NORMALIZE:                context->setNormalizeEnabled(true);             break;

+		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(true);         break;

+		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(true);           break;

+		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(true);           break;

+		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(true);            break;

+		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(true);        break;

+		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(true);     break;

+		case GL_MULTISAMPLE:              context->setMultisampleEnabled(true);           break;

+		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(true);      break;

+		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, true);          break;

+		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, true);          break;

+		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, true);          break;

+		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, true);          break;

+		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, true);          break;

+		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, true);          break;

+		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(true);           break;

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -1366,6 +1383,18 @@
 {

 	TRACE("(GLenum array = 0x%X)", array);

 

+	switch(array)

+	{

+	case GL_VERTEX_ARRAY:

+	case GL_NORMAL_ARRAY:

+	case GL_COLOR_ARRAY:

+	case GL_POINT_SIZE_ARRAY_OES:

+	case GL_TEXTURE_COORD_ARRAY:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

 	es1::Context *context = es1::getContext();

 

 	if(context)

@@ -1374,11 +1403,12 @@
 

 		switch(array)

 		{

-		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, true);                            break;

-		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;

-		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;

-		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;

-		default:                     UNIMPLEMENTED();

+		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, true);                            break;

+		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;

+		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;

+		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true);                           break;

+		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;

+		default:                      UNREACHABLE(array);

 		}

 	}

 }

@@ -1528,6 +1558,7 @@
 	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

 

 	es1::Context *context = es1::getContext();

+

 	if(context)

 	{

 		switch(pname)

@@ -1544,25 +1575,21 @@
 				return error(GL_INVALID_ENUM);

 			}

 			break;

-

 		case GL_FOG_DENSITY:

 			if(param < 0)

 			{

 				return error(GL_INVALID_VALUE);

 			}

-

 			context->setFogDensity(param);

 			break;

-

 		case GL_FOG_START:

 			context->setFogStart(param);

 			break;

-

 		case GL_FOG_END:

 			context->setFogEnd(param);

 			break;

-

 		case GL_FOG_COLOR:

+			return error(GL_INVALID_ENUM);   // Need four values, should call glFogfv() instead

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -1591,28 +1618,22 @@
 				return error(GL_INVALID_ENUM);

 			}

 			break;

-

 		case GL_FOG_DENSITY:

 			if(params[0] < 0)

 			{

 				return error(GL_INVALID_VALUE);

 			}

-

 			context->setFogDensity(params[0]);

 			break;

-

 		case GL_FOG_START:

 			context->setFogStart(params[0]);

 			break;

-

 		case GL_FOG_END:

 			context->setFogEnd(params[0]);

 			break;

-

 		case GL_FOG_COLOR:

 			context->setFogColor(params[0], params[1], params[2], params[3]);

 			break;

-

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -1874,6 +1895,7 @@
 

 				delete [] intParams;

 			}

+			else UNREACHABLE(pname);

 		}

 	}

 }

@@ -2002,6 +2024,7 @@
 

 				delete [] intParams;

 			}

+			else UNREACHABLE(pname);

 		}

 	}

 }

@@ -2149,6 +2172,7 @@
 

 				delete [] floatParams;

 			}

+			else UNREACHABLE(pname);

 		}

 	}

 }

@@ -2374,6 +2398,9 @@
 		case GL_PERSPECTIVE_CORRECTION_HINT:

 			context->setPerspectiveCorrectionHint(mode);

 			break;

+		case GL_FOG_HINT:

+			context->setFogHint(mode);

+			break;

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -2409,22 +2436,48 @@
 	{

 		switch(cap)

 		{

-		case GL_CULL_FACE:                return context->isCullFaceEnabled();

-		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();

-		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();

-		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();

-		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();

-		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();

-		case GL_BLEND:                    return context->isBlendEnabled();

-		case GL_DITHER:                   return context->isDitherEnabled();

-		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();

-		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);

-		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);

-		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);

-		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);

-		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);

-		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);

+		case GL_CULL_FACE:                return context->isCullFaceEnabled();              break;

+		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();     break;

+		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;

+		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();        break;

+		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();           break;

+		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();           break;

+		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();             break;

+		case GL_BLEND:                    return context->isBlendEnabled();                 break;

+		case GL_DITHER:                   return context->isDitherEnabled();                break;

+		case GL_LIGHTING:                 return context->isLightingEnabled();              break;

+		case GL_LIGHT0:                   return context->isLightEnabled(0);                break;

+		case GL_LIGHT1:                   return context->isLightEnabled(1);                break;

+		case GL_LIGHT2:                   return context->isLightEnabled(2);                break;

+		case GL_LIGHT3:                   return context->isLightEnabled(3);                break;

+		case GL_LIGHT4:                   return context->isLightEnabled(4);                break;

+		case GL_LIGHT5:                   return context->isLightEnabled(5);                break;

+		case GL_LIGHT6:                   return context->isLightEnabled(6);                break;

+		case GL_LIGHT7:                   return context->isLightEnabled(7);                break;

+		case GL_FOG:                      return context->isFogEnabled();                   break;

+		case GL_TEXTURE_2D:               return context->isTexture2Denabled();             break;

+		case GL_TEXTURE_EXTERNAL_OES:     return context->isTextureExternalEnabled();       break;

+		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();             break;

+		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();          break;

+		case GL_POINT_SMOOTH:             return context->isPointSmoothEnabled();           break;

+		case GL_LINE_SMOOTH:              return context->isLineSmoothEnabled();            break;

+		case GL_COLOR_MATERIAL:           return context->isColorMaterialEnabled();         break;

+		case GL_NORMALIZE:                return context->isNormalizeEnabled();             break;

+		case GL_RESCALE_NORMAL:           return context->isRescaleNormalEnabled();         break;

+		case GL_VERTEX_ARRAY:             return context->isVertexArrayEnabled();           break;

+		case GL_NORMAL_ARRAY:             return context->isNormalArrayEnabled();           break;

+		case GL_COLOR_ARRAY:              return context->isColorArrayEnabled();            break;

+		case GL_POINT_SIZE_ARRAY_OES:     return context->isPointSizeArrayEnabled();        break;

+		case GL_TEXTURE_COORD_ARRAY:      return context->isTextureCoordArrayEnabled();     break;

+		case GL_MULTISAMPLE:              return context->isMultisampleEnabled();           break;

+		case GL_SAMPLE_ALPHA_TO_ONE:      return context->isSampleAlphaToOneEnabled();      break;

+		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);            break;

+		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);            break;

+		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);            break;

+		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);            break;

+		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);            break;

+		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);            break;

+		case GL_POINT_SPRITE_OES:         return context->isPointSpriteEnabled();           break;

 		default:

 			return error(GL_INVALID_ENUM, GL_FALSE);

 		}

@@ -2492,7 +2545,23 @@
 

 void LightModelf(GLenum pname, GLfloat param)

 {

-	UNIMPLEMENTED();

+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

+

+	es1::Context *context = es1::getContext();

+

+	if(context)

+	{

+		switch(pname)

+		{

+		case GL_LIGHT_MODEL_TWO_SIDE:

+			context->setLightModelTwoSide(param != 0.0f);

+			break;

+		case GL_LIGHT_MODEL_AMBIENT:

+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelfv() instead

+		default:

+			return error(GL_INVALID_ENUM);

+		}

+	}

 }

 

 void LightModelfv(GLenum pname, const GLfloat *params)

@@ -2509,7 +2578,7 @@
 			context->setGlobalAmbient(params[0], params[1], params[2], params[3]);

 			break;

 		case GL_LIGHT_MODEL_TWO_SIDE:

-			UNIMPLEMENTED();

+			context->setLightModelTwoSide(params[0] != 0.0f);

 			break;

 		default:

 			return error(GL_INVALID_ENUM);

@@ -2544,11 +2613,47 @@
 	{

 		switch(pname)

 		{

-		case GL_SPOT_EXPONENT:         UNIMPLEMENTED(); break;

-		case GL_SPOT_CUTOFF:           UNIMPLEMENTED(); break;

-		case GL_CONSTANT_ATTENUATION:  context->setLightAttenuationConstant(index, param);                       break;

-		case GL_LINEAR_ATTENUATION:    context->setLightAttenuationLinear(index, param);                         break;

-		case GL_QUADRATIC_ATTENUATION: context->setLightAttenuationQuadratic(index, param);                      break;

+		case GL_SPOT_EXPONENT:

+			if(param < 0.0f || param > 128.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setSpotLightExponent(index, param);

+			break;

+		case GL_SPOT_CUTOFF:

+			if((param < 0.0f || param > 90.0f) && param != 180.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setSpotLightCutoff(index, param);

+			break;

+		case GL_CONSTANT_ATTENUATION:

+			if(param < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setLightAttenuationConstant(index, param);

+			break;

+		case GL_LINEAR_ATTENUATION:

+			if(param < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setLightAttenuationLinear(index, param);

+			break;

+		case GL_QUADRATIC_ATTENUATION:

+			if(param < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setLightAttenuationQuadratic(index, param);

+			break;

+		case GL_AMBIENT:

+		case GL_DIFFUSE:

+		case GL_SPECULAR:

+		case GL_POSITION:

+		case GL_SPOT_DIRECTION:

+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightfv() instead

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -2577,11 +2682,41 @@
 		case GL_SPECULAR:              context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;

 		case GL_POSITION:              context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;

 		case GL_SPOT_DIRECTION:        context->setLightDirection(index, params[0], params[1], params[2]);           break;

-		case GL_SPOT_EXPONENT:         UNIMPLEMENTED(); break;

-		case GL_SPOT_CUTOFF:           UNIMPLEMENTED(); break;

-		case GL_CONSTANT_ATTENUATION:  context->setLightAttenuationConstant(index, params[0]);                       break;

-		case GL_LINEAR_ATTENUATION:    context->setLightAttenuationLinear(index, params[0]);                         break;

-		case GL_QUADRATIC_ATTENUATION: context->setLightAttenuationQuadratic(index, params[0]);                      break;

+		case GL_SPOT_EXPONENT:

+			if(params[0] < 0.0f || params[0] > 128.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setSpotLightExponent(index, params[0]);

+			break;

+		case GL_SPOT_CUTOFF:

+			if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setSpotLightCutoff(index, params[0]);

+			break;

+		case GL_CONSTANT_ATTENUATION:

+			if(params[0] < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setLightAttenuationConstant(index, params[0]);

+			break;

+		case GL_LINEAR_ATTENUATION:

+			if(params[0] < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setLightAttenuationLinear(index, params[0]);

+			break;

+		case GL_QUADRATIC_ATTENUATION:

+			if(params[0] < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setLightAttenuationQuadratic(index, params[0]);

+			break;

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -2651,7 +2786,37 @@
 

 void LogicOp(GLenum opcode)

 {

-	UNIMPLEMENTED();

+	TRACE("(GLenum opcode = 0x%X)", opcode);

+

+	switch(opcode)

+	{

+	case GL_CLEAR:

+	case GL_SET:

+	case GL_COPY:

+	case GL_COPY_INVERTED:

+	case GL_NOOP:

+	case GL_INVERT:

+	case GL_AND:

+	case GL_NAND:

+	case GL_OR:

+	case GL_NOR:

+	case GL_XOR:

+	case GL_EQUIV:

+	case GL_AND_REVERSE:

+	case GL_AND_INVERTED:

+	case GL_OR_REVERSE:

+	case GL_OR_INVERTED:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

+	es1::Context *context = es1::getContext();

+

+	if(context)

+	{

+		context->setLogicalOperation(opcode);

+	}

 }

 

 void Materialf(GLenum face, GLenum pname, GLfloat param)

@@ -2670,8 +2835,18 @@
 		switch(pname)

 		{

 		case GL_SHININESS:

+			if(param < 0.0f || param > 128.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

 			context->setMaterialShininess(param);

 			break;

+		case GL_AMBIENT:

+		case GL_DIFFUSE:

+		case GL_AMBIENT_AND_DIFFUSE:

+		case GL_SPECULAR:

+		case GL_EMISSION:

+			return error(GL_INVALID_ENUM);   // Need four values, should call glMaterialfv() instead

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -2840,12 +3015,81 @@
 

 void PointParameterf(GLenum pname, GLfloat param)

 {

-	UNIMPLEMENTED();

+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

+

+	es1::Context *context = es1::getContext();

+

+	if(context)

+	{

+		switch(pname)

+		{

+		case GL_POINT_SIZE_MIN:

+			if(param < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setPointSizeMin(param);

+			break;

+		case GL_POINT_SIZE_MAX:

+			if(param < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setPointSizeMax(param);

+			break;

+		case GL_POINT_FADE_THRESHOLD_SIZE:

+			if(param < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setPointFadeThresholdSize(param);

+			break;

+		case GL_POINT_DISTANCE_ATTENUATION:

+			return error(GL_INVALID_ENUM);   // Needs three values, should call glPointParameterfv() instead

+		default:

+			return error(GL_INVALID_ENUM);

+		}

+	}

 }

 

 void PointParameterfv(GLenum pname, const GLfloat *params)

 {

-	UNIMPLEMENTED();

+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

+

+	es1::Context *context = es1::getContext();

+

+	if(context)

+	{

+		switch(pname)

+		{

+		case GL_POINT_SIZE_MIN:

+			if(params[0] < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setPointSizeMin(params[0]);

+			break;

+		case GL_POINT_SIZE_MAX:

+			if(params[0] < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setPointSizeMax(params[0]);

+			break;

+		case GL_POINT_DISTANCE_ATTENUATION:

+			context->setPointDistanceAttenuation(params[0], params[1], params[2]);

+			break;

+		case GL_POINT_FADE_THRESHOLD_SIZE:

+			if(params[0] < 0.0f)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+			context->setPointFadeThresholdSize(params[0]);

+			break;

+		default:

+			return error(GL_INVALID_ENUM);

+		}

+	}

 }

 

 void PointParameterx(GLenum pname, GLfixed param)

@@ -3925,6 +4169,8 @@
 		case GL_GENERATE_MIPMAP:

 			texture->setGenerateMipmap((GLboolean)param);

 			break;

+		case GL_TEXTURE_CROP_RECT_OES:

+			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameterfv() instead

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -3993,6 +4239,8 @@
 		case GL_GENERATE_MIPMAP:

 			texture->setGenerateMipmap((GLboolean)param);

 			break;

+		case GL_TEXTURE_CROP_RECT_OES:

+			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameteriv() instead

 		default:

 			return error(GL_INVALID_ENUM);

 		}

diff --git a/src/OpenGL/libGLES_CM/utilities.cpp b/src/OpenGL/libGLES_CM/utilities.cpp
index 42ee1af..ca3d892 100644
--- a/src/OpenGL/libGLES_CM/utilities.cpp
+++ b/src/OpenGL/libGLES_CM/utilities.cpp
@@ -174,7 +174,7 @@
 		switch(texFormat)

 		{

 		case GL_LUMINANCE:

-		case GL_RGB:
+		case GL_RGB:

 		case GL_RGB565_OES:   // GL_OES_framebuffer_object

 		case GL_RGB8_OES:     // GL_OES_rgb8_rgba8

 			return true;

@@ -190,7 +190,7 @@
 		case GL_LUMINANCE_ALPHA:

 		case GL_RGBA:

 		case GL_BGRA_EXT:      // GL_EXT_texture_format_BGRA8888

-		case GL_RGBA4_OES:     // GL_OES_framebuffer_object
+		case GL_RGBA4_OES:     // GL_OES_framebuffer_object

 		case GL_RGB5_A1_OES:   // GL_OES_framebuffer_object

 		case GL_RGBA8_OES:     // GL_OES_rgb8_rgba8

 			return true;

@@ -297,6 +297,32 @@
 		return sw::BLENDOP_ADD;

 	}

 

+	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)

+	{

+		switch(logicalOperation)

+		{

+		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;

+		case GL_SET:           return sw::LOGICALOP_SET;

+		case GL_COPY:          return sw::LOGICALOP_COPY;

+		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;

+		case GL_NOOP:          return sw::LOGICALOP_NOOP;

+		case GL_INVERT:        return sw::LOGICALOP_INVERT;

+		case GL_AND:           return sw::LOGICALOP_AND;

+		case GL_NAND:          return sw::LOGICALOP_NAND;

+		case GL_OR:            return sw::LOGICALOP_OR;

+		case GL_NOR:           return sw::LOGICALOP_NOR;

+		case GL_XOR:           return sw::LOGICALOP_XOR;

+		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;

+		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;

+		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;

+		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;

+		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;

+		default: UNREACHABLE(logicalOperation);

+		}

+

+		return sw::LOGICALOP_COPY;

+	}

+

 	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)

 	{

 		switch(stencilOp)

diff --git a/src/Renderer/Context.cpp b/src/Renderer/Context.cpp
index c41401c..fd8a307 100644
--- a/src/Renderer/Context.cpp
+++ b/src/Renderer/Context.cpp
@@ -304,7 +304,7 @@
 		sampleMask = 0xFFFFFFFF;
 
 		colorLogicOpEnabled = false;
-		logicalOperation = LogicalOperation::LOGICALOP_COPY;
+		logicalOperation = LOGICALOP_COPY;
 	}
 
 	const float &Context::exp2Bias()
@@ -750,7 +750,7 @@
 
 	LogicalOperation Context::colorLogicOp()
 	{
-		return colorLogicOpEnabled ? logicalOperation : LogicalOperation::LOGICALOP_COPY;
+		return colorLogicOpEnabled ? logicalOperation : LOGICALOP_COPY;
 	}
 
 	BlendFactor Context::sourceBlendFactor()
diff --git a/src/Shader/PixelRoutine.cpp b/src/Shader/PixelRoutine.cpp
index b53c031..442c512 100644
--- a/src/Shader/PixelRoutine.cpp
+++ b/src/Shader/PixelRoutine.cpp
@@ -1285,7 +1285,7 @@
 
 	void PixelRoutine::logicOperation(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x)
 	{
-		if(state.logicalOperation == LogicalOperation::LOGICALOP_COPY)
+		if(state.logicalOperation == LOGICALOP_COPY)
 		{
 			return;
 		}
@@ -1303,9 +1303,9 @@
 			current.z = 0;
 			break;
 		case LOGICALOP_SET:
-			current.x = 0xFFFF;
-			current.y = 0xFFFF;
-			current.z = 0xFFFF;
+			current.x = 0xFFFFu;
+			current.y = 0xFFFFu;
+			current.z = 0xFFFFu;
 			break;
 		case LOGICALOP_COPY:
 			ASSERT(false);   // Optimized out