Adding Texture3D support.

Bug 19126833

Added Texture3D argument verifications.
Added the basic API and functions. A few are still unimplemented:
- Image::loadCompressedData() (for depth other than 1)
- Texture3D::copyImage()
- Texture3D::generateMipmaps()
Added colour grading test for 3D texture

Change-Id: I9e52afa7213999f94c5916c2f301fc6fa4b42c0d
Reviewed-on: https://swiftshader-review.googlesource.com/1730
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/compiler/BaseTypes.h b/src/OpenGL/compiler/BaseTypes.h
index 60a838d..4406760 100644
--- a/src/OpenGL/compiler/BaseTypes.h
+++ b/src/OpenGL/compiler/BaseTypes.h
@@ -43,7 +43,8 @@
     EbtSampler2D,
     EbtSamplerCube,
     EbtSamplerExternalOES,
-    EbtGuardSamplerEnd,    // non type:  see implementation of IsSampler()
+	EbtSampler3D,
+	EbtGuardSamplerEnd,    // non type:  see implementation of IsSampler()
     EbtStruct,
     EbtAddress,            // should be deprecated??
     EbtInvariant           // used as a type when qualifying a previously declared variable as being invariant
@@ -60,6 +61,7 @@
     case EbtSampler2D:          return "sampler2D";
     case EbtSamplerCube:        return "samplerCube";
     case EbtSamplerExternalOES: return "samplerExternalOES";
+	case EbtSampler3D:			return "sampler3D";
     case EbtStruct:             return "structure";
     default:                    return "unknown type";
     }
diff --git a/src/OpenGL/compiler/Initialize.cpp b/src/OpenGL/compiler/Initialize.cpp
index 9350fbd..4d81959 100644
--- a/src/OpenGL/compiler/Initialize.cpp
+++ b/src/OpenGL/compiler/Initialize.cpp
@@ -255,11 +255,13 @@
 
 	TType *sampler2D = new TType(EbtSampler2D, EbpUndefined, EvqGlobal, 1);
 	TType *samplerCube = new TType(EbtSamplerCube, EbpUndefined, EvqGlobal, 1);
+	TType *sampler3D = new TType(EbtSampler3D, EbpUndefined, EvqGlobal, 1);
 
     symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2);
     symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float3);
     symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float4);
     symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, float3);
+	symbolTable.insertBuiltIn(float4, "texture3D", sampler3D, float3);
 
 	if(type == SH_FRAGMENT_SHADER)
 	{
@@ -267,6 +269,7 @@
 		symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float3, float1);
 	    symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float4, float1);
 		symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, float3, float1);
+		symbolTable.insertBuiltIn(float4, "texture3D", sampler3D, float3, float1);
 
 		if (resources.OES_standard_derivatives)
 		{
@@ -293,6 +296,7 @@
 		symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float3, float1);
 	    symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float4, float1);
 		symbolTable.insertBuiltIn(float4, "textureCubeLod", samplerCube, float3, float1);
+		symbolTable.insertBuiltIn(float4, "texture3DLod", sampler3D, float3, float1);
 	}
 
     TType *samplerExternalOES = new TType(EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1);
@@ -302,6 +306,7 @@
         symbolTable.insertBuiltIn(float4, "texture2D", samplerExternalOES, float2);
         symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float3);
         symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float4);
+		symbolTable.insertBuiltIn(float4, "texture3D", samplerExternalOES, float3);
     }
 
 	TTypeList *members = NewPoolTTypeList();
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 64fb951..f6f9da7 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -768,7 +768,7 @@
 				{

 					TString name = TFunction::unmangleName(node->getName());

 

-					if(name == "texture2D" || name == "textureCube")

+					if(name == "texture2D" || name == "textureCube" || name == "texture3D")

 					{

 						if(argumentCount == 2)

 						{	

@@ -2391,6 +2391,10 @@
 		{

 			return GL_SAMPLER_EXTERNAL_OES;

 		}

+		else if(type.getBasicType() == EbtSampler3D)

+		{

+			return GL_SAMPLER_3D_OES;

+		}

 		else UNREACHABLE();

 

 		return GL_NONE;

diff --git a/src/OpenGL/compiler/SymbolTable.cpp b/src/OpenGL/compiler/SymbolTable.cpp
index 2502332..873fda5 100644
--- a/src/OpenGL/compiler/SymbolTable.cpp
+++ b/src/OpenGL/compiler/SymbolTable.cpp
@@ -53,7 +53,8 @@
     case EbtSampler2D:          mangledName += "s2";     break;
     case EbtSamplerCube:        mangledName += "sC";     break;
     case EbtSamplerExternalOES: mangledName += "sE";     break;
-    case EbtStruct:
+	case EbtSampler3D:          mangledName += "s3";     break;
+	case EbtStruct:
         mangledName += "struct-";
         if (typeName)
             mangledName += *typeName;
diff --git a/src/OpenGL/compiler/glslang.l b/src/OpenGL/compiler/glslang.l
index 0aa4e89..6b4914f 100644
--- a/src/OpenGL/compiler/glslang.l
+++ b/src/OpenGL/compiler/glslang.l
@@ -134,6 +134,7 @@
 "sampler2D"       { context->lexAfterType = true; return SAMPLER2D; }
 "samplerCube"     { context->lexAfterType = true; return SAMPLERCUBE; }
 "samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
+"sampler3D"       { context->lexAfterType = true; return SAMPLER3D; }
 
 "struct"       { context->lexAfterType = true; return(STRUCT); }
 
@@ -183,7 +184,6 @@
 "fvec4"        { return reserved_word(yyscanner); }
 
 "sampler1D"    { return reserved_word(yyscanner); }
-"sampler3D"    { return reserved_word(yyscanner); }
 
 "sampler1DShadow" { return reserved_word(yyscanner); }
 "sampler2DShadow" { return reserved_word(yyscanner); }
diff --git a/src/OpenGL/compiler/glslang.y b/src/OpenGL/compiler/glslang.y
index 77a0e1b..5b34853 100644
--- a/src/OpenGL/compiler/glslang.y
+++ b/src/OpenGL/compiler/glslang.y
@@ -113,7 +113,7 @@
 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
 %token <lex> STRUCT VOID_TYPE WHILE
-%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES
+%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER3D
 
 %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
 %token <lex> FIELD_SELECTION
@@ -1665,6 +1665,11 @@
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtSamplerExternalOES, qual, $1.line);
     }
+    | SAMPLER3D {
+        FRAG_VERT_ONLY("sampler3D", $1.line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler3D, qual, $1.line);
+    }
     | struct_specifier {
         FRAG_VERT_ONLY("struct", $1.line);
         $$ = $1;
diff --git a/src/OpenGL/compiler/glslang_lex.cpp b/src/OpenGL/compiler/glslang_lex.cpp
index ef0a9a6..ac05e4c 100644
--- a/src/OpenGL/compiler/glslang_lex.cpp
+++ b/src/OpenGL/compiler/glslang_lex.cpp
@@ -420,7 +420,7 @@
        98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
        98,   98,   98,   98,   98,   98,   98,  115,  119,    5,
       151,    0,    1,  104,    0,    0,  103,   99,  111,  112,
-       49,   98,   98,   98,   98,   98,   98,   98,   98,   98,
+       50,   98,   98,   98,   98,   98,   98,   98,   98,   98,
        98,   98,   98,   98,   98,   98,   98,   98,   98,   18,
        98,   98,   98,   98,   98,   98,   98,   98,   26,   98,
        98,   98,   98,   98,   98,   98,   98,   23,   98,   98,
@@ -428,27 +428,27 @@
        98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
        98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
        98,    0,  105,    0,  104,   98,   28,   98,   98,   95,
-       98,   98,   98,   98,   98,   98,   98,   21,   52,   98,
-       98,   98,   68,   98,   98,   57,   72,   98,   98,   98,
-       98,   98,   98,   98,   98,   69,    9,   33,   34,   35,
+       98,   98,   98,   98,   98,   98,   98,   21,   53,   98,
+       98,   98,   69,   98,   98,   58,   73,   98,   98,   98,
+       98,   98,   98,   98,   98,   70,    9,   33,   34,   35,
        98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
-       98,   98,   98,   98,   98,   98,   55,   29,   98,   98,
+       98,   98,   98,   98,   98,   98,   56,   29,   98,   98,
        98,   98,   98,   98,   36,   37,   38,   27,   98,   98,
-       98,   15,   42,   43,   44,   50,   12,   98,   98,   98,
+       98,   15,   42,   43,   44,   51,   12,   98,   98,   98,
 
-       98,   81,   82,   83,   98,   30,   73,   25,   84,   85,
-       86,    7,   78,   79,   80,   98,   24,   76,   98,   98,
+       98,   82,   83,   84,   98,   30,   74,   25,   85,   86,
+       87,    7,   79,   80,   81,   98,   24,   77,   98,   98,
        39,   40,   41,   98,   98,   98,   98,   98,   98,   98,
-       98,   98,   70,   98,   98,   98,   98,   98,   98,   98,
-       98,   51,   98,   97,   98,   98,   19,   98,   98,   98,
-       98,   71,   65,   60,   98,   98,   98,   98,   98,   77,
-       56,   98,   63,   32,   98,   94,   64,   48,   75,   58,
-       98,   98,   98,   98,   98,   98,   98,   98,   59,   31,
-       98,   98,   98,    8,   98,   98,   98,   98,   98,   53,
-       13,   98,   14,   98,   98,   16,   66,   98,   98,   98,
+       98,   98,   71,   98,   98,   98,   98,   98,   98,   98,
+       98,   52,   98,   97,   98,   98,   19,   98,   98,   98,
+       98,   72,   66,   61,   98,   98,   98,   98,   98,   78,
+       57,   98,   64,   32,   98,   94,   65,   49,   76,   59,
+       98,   98,   98,   98,   98,   98,   98,   98,   60,   31,
+       98,   98,   98,    8,   98,   98,   98,   98,   98,   54,
+       13,   98,   14,   98,   98,   16,   67,   98,   98,   98,
 
-       61,   98,   98,   98,   98,   98,   98,   54,   74,   62,
-       11,   67,    6,   96,   10,   87,   45,   88,   98,   98,
+       62,   98,   98,   98,   98,   98,   98,   55,   75,   63,
+       11,   68,    6,   96,   10,   88,   45,   48,   98,   98,
        98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
        46,   98,   98,   98,   98,   98,   98,   98,   91,   98,
        92,   98,   98,   98,   98,   98,   89,   98,   90,   98,
@@ -1349,11 +1349,11 @@
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-{ context->lexAfterType = true; return(STRUCT); }
+{ context->lexAfterType = true; return SAMPLER3D; }
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-{ return reserved_word(yyscanner); }
+{ context->lexAfterType = true; return(STRUCT); }
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
diff --git a/src/OpenGL/compiler/glslang_tab.cpp b/src/OpenGL/compiler/glslang_tab.cpp
index f2f061b..3164461 100644
--- a/src/OpenGL/compiler/glslang_tab.cpp
+++ b/src/OpenGL/compiler/glslang_tab.cpp
@@ -165,57 +165,58 @@
      SAMPLER2D = 296,
      SAMPLERCUBE = 297,
      SAMPLER_EXTERNAL_OES = 298,
-     IDENTIFIER = 299,
-     TYPE_NAME = 300,
-     FLOATCONSTANT = 301,
-     INTCONSTANT = 302,
-     BOOLCONSTANT = 303,
-     FIELD_SELECTION = 304,
-     LEFT_OP = 305,
-     RIGHT_OP = 306,
-     INC_OP = 307,
-     DEC_OP = 308,
-     LE_OP = 309,
-     GE_OP = 310,
-     EQ_OP = 311,
-     NE_OP = 312,
-     AND_OP = 313,
-     OR_OP = 314,
-     XOR_OP = 315,
-     MUL_ASSIGN = 316,
-     DIV_ASSIGN = 317,
-     ADD_ASSIGN = 318,
-     MOD_ASSIGN = 319,
-     LEFT_ASSIGN = 320,
-     RIGHT_ASSIGN = 321,
-     AND_ASSIGN = 322,
-     XOR_ASSIGN = 323,
-     OR_ASSIGN = 324,
-     SUB_ASSIGN = 325,
-     LEFT_PAREN = 326,
-     RIGHT_PAREN = 327,
-     LEFT_BRACKET = 328,
-     RIGHT_BRACKET = 329,
-     LEFT_BRACE = 330,
-     RIGHT_BRACE = 331,
-     DOT = 332,
-     COMMA = 333,
-     COLON = 334,
-     EQUAL = 335,
-     SEMICOLON = 336,
-     BANG = 337,
-     DASH = 338,
-     TILDE = 339,
-     PLUS = 340,
-     STAR = 341,
-     SLASH = 342,
-     PERCENT = 343,
-     LEFT_ANGLE = 344,
-     RIGHT_ANGLE = 345,
-     VERTICAL_BAR = 346,
-     CARET = 347,
-     AMPERSAND = 348,
-     QUESTION = 349
+     SAMPLER3D = 299,
+     IDENTIFIER = 300,
+     TYPE_NAME = 301,
+     FLOATCONSTANT = 302,
+     INTCONSTANT = 303,
+     BOOLCONSTANT = 304,
+     FIELD_SELECTION = 305,
+     LEFT_OP = 306,
+     RIGHT_OP = 307,
+     INC_OP = 308,
+     DEC_OP = 309,
+     LE_OP = 310,
+     GE_OP = 311,
+     EQ_OP = 312,
+     NE_OP = 313,
+     AND_OP = 314,
+     OR_OP = 315,
+     XOR_OP = 316,
+     MUL_ASSIGN = 317,
+     DIV_ASSIGN = 318,
+     ADD_ASSIGN = 319,
+     MOD_ASSIGN = 320,
+     LEFT_ASSIGN = 321,
+     RIGHT_ASSIGN = 322,
+     AND_ASSIGN = 323,
+     XOR_ASSIGN = 324,
+     OR_ASSIGN = 325,
+     SUB_ASSIGN = 326,
+     LEFT_PAREN = 327,
+     RIGHT_PAREN = 328,
+     LEFT_BRACKET = 329,
+     RIGHT_BRACKET = 330,
+     LEFT_BRACE = 331,
+     RIGHT_BRACE = 332,
+     DOT = 333,
+     COMMA = 334,
+     COLON = 335,
+     EQUAL = 336,
+     SEMICOLON = 337,
+     BANG = 338,
+     DASH = 339,
+     TILDE = 340,
+     PLUS = 341,
+     STAR = 342,
+     SLASH = 343,
+     PERCENT = 344,
+     LEFT_ANGLE = 345,
+     RIGHT_ANGLE = 346,
+     VERTICAL_BAR = 347,
+     CARET = 348,
+     AMPERSAND = 349,
+     QUESTION = 350
    };
 #endif
 
@@ -506,22 +507,22 @@
 #endif
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  70
+#define YYFINAL  71
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1404
+#define YYLAST   1416
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  95
+#define YYNTOKENS  96
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  83
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  200
+#define YYNRULES  201
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  303
+#define YYNSTATES  304
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   349
+#define YYMAXUTOK   350
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -563,7 +564,8 @@
       55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
       65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
       75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
-      85,    86,    87,    88,    89,    90,    91,    92,    93,    94
+      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
+      95
 };
 
 #if YYDEBUG
@@ -584,76 +586,76 @@
      298,   303,   306,   308,   311,   313,   315,   317,   320,   322,
      324,   327,   329,   331,   333,   335,   340,   342,   344,   346,
      348,   350,   352,   354,   356,   358,   360,   362,   364,   366,
-     368,   370,   372,   374,   376,   378,   380,   382,   383,   390,
-     391,   397,   399,   402,   406,   408,   412,   414,   419,   421,
-     423,   425,   427,   429,   431,   433,   435,   437,   440,   441,
-     442,   448,   450,   452,   453,   456,   457,   460,   463,   467,
-     469,   472,   474,   477,   483,   487,   489,   491,   496,   497,
-     504,   505,   514,   515,   523,   525,   527,   529,   530,   533,
-     537,   540,   543,   546,   550,   553,   555,   558,   560,   562,
-     563
+     368,   370,   372,   374,   376,   378,   380,   382,   384,   385,
+     392,   393,   399,   401,   404,   408,   410,   414,   416,   421,
+     423,   425,   427,   429,   431,   433,   435,   437,   439,   442,
+     443,   444,   450,   452,   454,   455,   458,   459,   462,   465,
+     469,   471,   474,   476,   479,   485,   489,   491,   493,   498,
+     499,   506,   507,   516,   517,   525,   527,   529,   531,   532,
+     535,   539,   542,   545,   548,   552,   555,   557,   560,   562,
+     564,   565
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int16 yyrhs[] =
 {
-     174,     0,    -1,    44,    -1,    96,    -1,    47,    -1,    46,
-      -1,    48,    -1,    71,   123,    72,    -1,    97,    -1,    98,
-      73,    99,    74,    -1,   100,    -1,    98,    77,    49,    -1,
-      98,    52,    -1,    98,    53,    -1,   123,    -1,   101,    -1,
-     102,    -1,    98,    77,   102,    -1,   104,    72,    -1,   103,
-      72,    -1,   105,    39,    -1,   105,    -1,   105,   121,    -1,
-     104,    78,   121,    -1,   106,    71,    -1,   141,    -1,    44,
-      -1,    49,    -1,    98,    -1,    52,   107,    -1,    53,   107,
-      -1,   108,   107,    -1,    85,    -1,    83,    -1,    82,    -1,
-     107,    -1,   109,    86,   107,    -1,   109,    87,   107,    -1,
-     109,    -1,   110,    85,   109,    -1,   110,    83,   109,    -1,
-     110,    -1,   111,    -1,   112,    89,   111,    -1,   112,    90,
-     111,    -1,   112,    54,   111,    -1,   112,    55,   111,    -1,
-     112,    -1,   113,    56,   112,    -1,   113,    57,   112,    -1,
-     113,    -1,   114,    -1,   115,    -1,   116,    -1,   117,    58,
-     116,    -1,   117,    -1,   118,    60,   117,    -1,   118,    -1,
-     119,    59,   118,    -1,   119,    -1,   119,    94,   123,    79,
-     121,    -1,   120,    -1,   107,   122,   121,    -1,    80,    -1,
-      61,    -1,    62,    -1,    63,    -1,    70,    -1,   121,    -1,
-     123,    78,   121,    -1,   120,    -1,   126,    81,    -1,   134,
-      81,    -1,     7,   139,   140,    81,    -1,   127,    72,    -1,
-     129,    -1,   128,    -1,   129,   131,    -1,   128,    78,   131,
-      -1,   136,    44,    71,    -1,   138,    44,    -1,   138,    44,
-      73,   124,    74,    -1,   137,   132,   130,    -1,   132,   130,
-      -1,   137,   132,   133,    -1,   132,   133,    -1,    -1,    33,
-      -1,    34,    -1,    35,    -1,   138,    -1,   135,    -1,   134,
-      78,    44,    -1,   134,    78,    44,    73,    74,    -1,   134,
-      78,    44,    73,   124,    74,    -1,   134,    78,    44,    80,
-     149,    -1,   136,    -1,   136,    44,    -1,   136,    44,    73,
-      74,    -1,   136,    44,    73,   124,    74,    -1,   136,    44,
-      80,   149,    -1,     3,    44,    -1,   138,    -1,   137,   138,
+     175,     0,    -1,    45,    -1,    97,    -1,    48,    -1,    47,
+      -1,    49,    -1,    72,   124,    73,    -1,    98,    -1,    99,
+      74,   100,    75,    -1,   101,    -1,    99,    78,    50,    -1,
+      99,    53,    -1,    99,    54,    -1,   124,    -1,   102,    -1,
+     103,    -1,    99,    78,   103,    -1,   105,    73,    -1,   104,
+      73,    -1,   106,    39,    -1,   106,    -1,   106,   122,    -1,
+     105,    79,   122,    -1,   107,    72,    -1,   142,    -1,    45,
+      -1,    50,    -1,    99,    -1,    53,   108,    -1,    54,   108,
+      -1,   109,   108,    -1,    86,    -1,    84,    -1,    83,    -1,
+     108,    -1,   110,    87,   108,    -1,   110,    88,   108,    -1,
+     110,    -1,   111,    86,   110,    -1,   111,    84,   110,    -1,
+     111,    -1,   112,    -1,   113,    90,   112,    -1,   113,    91,
+     112,    -1,   113,    55,   112,    -1,   113,    56,   112,    -1,
+     113,    -1,   114,    57,   113,    -1,   114,    58,   113,    -1,
+     114,    -1,   115,    -1,   116,    -1,   117,    -1,   118,    59,
+     117,    -1,   118,    -1,   119,    61,   118,    -1,   119,    -1,
+     120,    60,   119,    -1,   120,    -1,   120,    95,   124,    80,
+     122,    -1,   121,    -1,   108,   123,   122,    -1,    81,    -1,
+      62,    -1,    63,    -1,    64,    -1,    71,    -1,   122,    -1,
+     124,    79,   122,    -1,   121,    -1,   127,    82,    -1,   135,
+      82,    -1,     7,   140,   141,    82,    -1,   128,    73,    -1,
+     130,    -1,   129,    -1,   130,   132,    -1,   129,    79,   132,
+      -1,   137,    45,    72,    -1,   139,    45,    -1,   139,    45,
+      74,   125,    75,    -1,   138,   133,   131,    -1,   133,   131,
+      -1,   138,   133,   134,    -1,   133,   134,    -1,    -1,    33,
+      -1,    34,    -1,    35,    -1,   139,    -1,   136,    -1,   135,
+      79,    45,    -1,   135,    79,    45,    74,    75,    -1,   135,
+      79,    45,    74,   125,    75,    -1,   135,    79,    45,    81,
+     150,    -1,   137,    -1,   137,    45,    -1,   137,    45,    74,
+      75,    -1,   137,    45,    74,   125,    75,    -1,   137,    45,
+      81,   150,    -1,     3,    45,    -1,   139,    -1,   138,   139,
       -1,     9,    -1,     8,    -1,    37,    -1,     3,    37,    -1,
-      36,    -1,   140,    -1,   139,   140,    -1,     4,    -1,     5,
-      -1,     6,    -1,   141,    -1,   141,    73,   124,    74,    -1,
+      36,    -1,   141,    -1,   140,   141,    -1,     4,    -1,     5,
+      -1,     6,    -1,   142,    -1,   142,    74,   125,    75,    -1,
       39,    -1,    11,    -1,    12,    -1,    10,    -1,    27,    -1,
       28,    -1,    29,    -1,    21,    -1,    22,    -1,    23,    -1,
       24,    -1,    25,    -1,    26,    -1,    30,    -1,    31,    -1,
-      32,    -1,    41,    -1,    42,    -1,    43,    -1,   142,    -1,
-      45,    -1,    -1,    38,    44,    75,   143,   145,    76,    -1,
-      -1,    38,    75,   144,   145,    76,    -1,   146,    -1,   145,
-     146,    -1,   138,   147,    81,    -1,   148,    -1,   147,    78,
-     148,    -1,    44,    -1,    44,    73,   124,    74,    -1,   121,
-      -1,   125,    -1,   153,    -1,   152,    -1,   150,    -1,   162,
-      -1,   163,    -1,   166,    -1,   173,    -1,    75,    76,    -1,
-      -1,    -1,    75,   154,   161,   155,    76,    -1,   160,    -1,
-     152,    -1,    -1,   158,   160,    -1,    -1,   159,   152,    -1,
-      75,    76,    -1,    75,   161,    76,    -1,   151,    -1,   161,
-     151,    -1,    81,    -1,   123,    81,    -1,    18,    71,   123,
-      72,   164,    -1,   157,    16,   157,    -1,   157,    -1,   123,
-      -1,   136,    44,    80,   149,    -1,    -1,    40,    71,   167,
-     165,    72,   156,    -1,    -1,    15,   168,   157,    40,    71,
-     123,    72,    81,    -1,    -1,    17,    71,   169,   170,   172,
-      72,   156,    -1,   162,    -1,   150,    -1,   165,    -1,    -1,
-     171,    81,    -1,   171,    81,   123,    -1,    14,    81,    -1,
-      13,    81,    -1,    20,    81,    -1,    20,   123,    81,    -1,
-      19,    81,    -1,   175,    -1,   174,   175,    -1,   176,    -1,
-     125,    -1,    -1,   126,   177,   160,    -1
+      32,    -1,    41,    -1,    42,    -1,    43,    -1,    44,    -1,
+     143,    -1,    46,    -1,    -1,    38,    45,    76,   144,   146,
+      77,    -1,    -1,    38,    76,   145,   146,    77,    -1,   147,
+      -1,   146,   147,    -1,   139,   148,    82,    -1,   149,    -1,
+     148,    79,   149,    -1,    45,    -1,    45,    74,   125,    75,
+      -1,   122,    -1,   126,    -1,   154,    -1,   153,    -1,   151,
+      -1,   163,    -1,   164,    -1,   167,    -1,   174,    -1,    76,
+      77,    -1,    -1,    -1,    76,   155,   162,   156,    77,    -1,
+     161,    -1,   153,    -1,    -1,   159,   161,    -1,    -1,   160,
+     153,    -1,    76,    77,    -1,    76,   162,    77,    -1,   152,
+      -1,   162,   152,    -1,    82,    -1,   124,    82,    -1,    18,
+      72,   124,    73,   165,    -1,   158,    16,   158,    -1,   158,
+      -1,   124,    -1,   137,    45,    81,   150,    -1,    -1,    40,
+      72,   168,   166,    73,   157,    -1,    -1,    15,   169,   158,
+      40,    72,   124,    73,    82,    -1,    -1,    17,    72,   170,
+     171,   173,    73,   157,    -1,   163,    -1,   151,    -1,   166,
+      -1,    -1,   172,    82,    -1,   172,    82,   124,    -1,    14,
+      82,    -1,    13,    82,    -1,    20,    82,    -1,    20,   124,
+      82,    -1,    19,    82,    -1,   176,    -1,   175,   176,    -1,
+     177,    -1,   126,    -1,    -1,   127,   178,   161,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
@@ -672,14 +674,14 @@
     1345,  1365,  1453,  1462,  1485,  1488,  1494,  1502,  1510,  1518,
     1528,  1535,  1538,  1541,  1547,  1550,  1565,  1569,  1573,  1577,
     1586,  1591,  1596,  1601,  1606,  1611,  1616,  1621,  1626,  1631,
-    1637,  1643,  1649,  1654,  1659,  1668,  1673,  1686,  1686,  1700,
-    1700,  1709,  1712,  1727,  1763,  1767,  1773,  1781,  1797,  1801,
-    1805,  1806,  1812,  1813,  1814,  1815,  1816,  1820,  1821,  1821,
-    1821,  1831,  1832,  1836,  1836,  1837,  1837,  1842,  1845,  1855,
-    1858,  1864,  1865,  1869,  1877,  1881,  1891,  1896,  1913,  1913,
-    1918,  1918,  1925,  1925,  1933,  1936,  1942,  1945,  1951,  1955,
-    1962,  1969,  1976,  1983,  1994,  2003,  2007,  2014,  2017,  2023,
-    2023
+    1637,  1643,  1649,  1654,  1659,  1668,  1673,  1678,  1691,  1691,
+    1705,  1705,  1714,  1717,  1732,  1768,  1772,  1778,  1786,  1802,
+    1806,  1810,  1811,  1817,  1818,  1819,  1820,  1821,  1825,  1826,
+    1826,  1826,  1836,  1837,  1841,  1841,  1842,  1842,  1847,  1850,
+    1860,  1863,  1869,  1870,  1874,  1882,  1886,  1896,  1901,  1918,
+    1918,  1923,  1923,  1930,  1930,  1938,  1941,  1947,  1950,  1956,
+    1960,  1967,  1974,  1981,  1988,  1999,  2008,  2012,  2019,  2022,
+    2028,  2028
 };
 #endif
 
@@ -695,16 +697,16 @@
   "BVEC4", "IVEC2", "IVEC3", "IVEC4", "VEC2", "VEC3", "VEC4", "MATRIX2",
   "MATRIX3", "MATRIX4", "IN_QUAL", "OUT_QUAL", "INOUT_QUAL", "UNIFORM",
   "VARYING", "STRUCT", "VOID_TYPE", "WHILE", "SAMPLER2D", "SAMPLERCUBE",
-  "SAMPLER_EXTERNAL_OES", "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT",
-  "INTCONSTANT", "BOOLCONSTANT", "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP",
-  "INC_OP", "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP",
-  "OR_OP", "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN",
-  "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN",
-  "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACKET",
-  "RIGHT_BRACKET", "LEFT_BRACE", "RIGHT_BRACE", "DOT", "COMMA", "COLON",
-  "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", "STAR", "SLASH",
-  "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", "CARET",
-  "AMPERSAND", "QUESTION", "$accept", "variable_identifier",
+  "SAMPLER_EXTERNAL_OES", "SAMPLER3D", "IDENTIFIER", "TYPE_NAME",
+  "FLOATCONSTANT", "INTCONSTANT", "BOOLCONSTANT", "FIELD_SELECTION",
+  "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", "GE_OP", "EQ_OP",
+  "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN",
+  "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN",
+  "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", "RIGHT_PAREN",
+  "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE", "RIGHT_BRACE", "DOT",
+  "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS",
+  "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR",
+  "CARET", "AMPERSAND", "QUESTION", "$accept", "variable_identifier",
   "primary_expression", "postfix_expression", "integer_expression",
   "function_call", "function_call_or_method", "function_call_generic",
   "function_call_header_no_parameters",
@@ -750,34 +752,34 @@
      315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
      325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
      335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
-     345,   346,   347,   348,   349
+     345,   346,   347,   348,   349,   350
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    95,    96,    97,    97,    97,    97,    97,    98,    98,
-      98,    98,    98,    98,    99,   100,   101,   101,   102,   102,
-     103,   103,   104,   104,   105,   106,   106,   106,   107,   107,
-     107,   107,   108,   108,   108,   109,   109,   109,   110,   110,
-     110,   111,   112,   112,   112,   112,   112,   113,   113,   113,
-     114,   115,   116,   117,   117,   118,   118,   119,   119,   120,
-     120,   121,   121,   122,   122,   122,   122,   122,   123,   123,
-     124,   125,   125,   125,   126,   127,   127,   128,   128,   129,
-     130,   130,   131,   131,   131,   131,   132,   132,   132,   132,
-     133,   134,   134,   134,   134,   134,   135,   135,   135,   135,
-     135,   135,   136,   136,   137,   137,   137,   137,   137,   138,
-     138,   139,   139,   139,   140,   140,   141,   141,   141,   141,
-     141,   141,   141,   141,   141,   141,   141,   141,   141,   141,
-     141,   141,   141,   141,   141,   141,   141,   143,   142,   144,
-     142,   145,   145,   146,   147,   147,   148,   148,   149,   150,
-     151,   151,   152,   152,   152,   152,   152,   153,   154,   155,
-     153,   156,   156,   158,   157,   159,   157,   160,   160,   161,
-     161,   162,   162,   163,   164,   164,   165,   165,   167,   166,
-     168,   166,   169,   166,   170,   170,   171,   171,   172,   172,
-     173,   173,   173,   173,   173,   174,   174,   175,   175,   177,
-     176
+       0,    96,    97,    98,    98,    98,    98,    98,    99,    99,
+      99,    99,    99,    99,   100,   101,   102,   102,   103,   103,
+     104,   104,   105,   105,   106,   107,   107,   107,   108,   108,
+     108,   108,   109,   109,   109,   110,   110,   110,   111,   111,
+     111,   112,   113,   113,   113,   113,   113,   114,   114,   114,
+     115,   116,   117,   118,   118,   119,   119,   120,   120,   121,
+     121,   122,   122,   123,   123,   123,   123,   123,   124,   124,
+     125,   126,   126,   126,   127,   128,   128,   129,   129,   130,
+     131,   131,   132,   132,   132,   132,   133,   133,   133,   133,
+     134,   135,   135,   135,   135,   135,   136,   136,   136,   136,
+     136,   136,   137,   137,   138,   138,   138,   138,   138,   139,
+     139,   140,   140,   140,   141,   141,   142,   142,   142,   142,
+     142,   142,   142,   142,   142,   142,   142,   142,   142,   142,
+     142,   142,   142,   142,   142,   142,   142,   142,   144,   143,
+     145,   143,   146,   146,   147,   148,   148,   149,   149,   150,
+     151,   152,   152,   153,   153,   153,   153,   153,   154,   155,
+     156,   154,   157,   157,   159,   158,   160,   158,   161,   161,
+     162,   162,   163,   163,   164,   165,   165,   166,   166,   168,
+     167,   169,   167,   170,   167,   171,   171,   172,   172,   173,
+     173,   174,   174,   174,   174,   174,   175,   175,   176,   176,
+     178,   177
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -796,14 +798,14 @@
        4,     2,     1,     2,     1,     1,     1,     2,     1,     1,
        2,     1,     1,     1,     1,     4,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     0,     6,     0,
-       5,     1,     2,     3,     1,     3,     1,     4,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     2,     0,     0,
-       5,     1,     1,     0,     2,     0,     2,     2,     3,     1,
-       2,     1,     2,     5,     3,     1,     1,     4,     0,     6,
-       0,     8,     0,     7,     1,     1,     1,     0,     2,     3,
-       2,     2,     2,     3,     2,     1,     2,     1,     1,     0,
-       3
+       1,     1,     1,     1,     1,     1,     1,     1,     0,     6,
+       0,     5,     1,     2,     3,     1,     3,     1,     4,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     2,     0,
+       0,     5,     1,     1,     0,     2,     0,     2,     2,     3,
+       1,     2,     1,     2,     5,     3,     1,     1,     4,     0,
+       6,     0,     8,     0,     7,     1,     1,     1,     0,     2,
+       3,     2,     2,     2,     3,     2,     1,     2,     1,     1,
+       0,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -814,395 +816,397 @@
        0,     0,   111,   112,   113,     0,   105,   104,   119,   117,
      118,   123,   124,   125,   126,   127,   128,   120,   121,   122,
      129,   130,   131,   108,   106,     0,   116,   132,   133,   134,
-     136,   198,   199,     0,    76,    86,     0,    91,    96,     0,
-     102,     0,   109,   114,   135,     0,   195,   197,   107,   101,
-       0,     0,   139,    71,     0,    74,    86,     0,    87,    88,
-      89,    77,     0,    86,     0,    72,    97,   103,   110,     0,
-       1,   196,     0,   137,     0,     0,   200,    78,    83,    85,
-      90,     0,    92,    79,     0,     0,     2,     5,     4,     6,
-      27,     0,     0,     0,    34,    33,    32,     3,     8,    28,
-      10,    15,    16,     0,     0,    21,     0,    35,     0,    38,
-      41,    42,    47,    50,    51,    52,    53,    55,    57,    59,
-      70,     0,    25,    73,     0,     0,     0,   141,     0,     0,
-     180,     0,     0,     0,     0,     0,   158,   167,   171,    35,
-      61,    68,     0,   149,     0,   114,   152,   169,   151,   150,
-       0,   153,   154,   155,   156,    80,    82,    84,     0,     0,
-      98,     0,   148,   100,    29,    30,     0,    12,    13,     0,
-       0,    19,    18,     0,    20,    22,    24,    31,     0,     0,
+     135,   137,   199,   200,     0,    76,    86,     0,    91,    96,
+       0,   102,     0,   109,   114,   136,     0,   196,   198,   107,
+     101,     0,     0,   140,    71,     0,    74,    86,     0,    87,
+      88,    89,    77,     0,    86,     0,    72,    97,   103,   110,
+       0,     1,   197,     0,   138,     0,     0,   201,    78,    83,
+      85,    90,     0,    92,    79,     0,     0,     2,     5,     4,
+       6,    27,     0,     0,     0,    34,    33,    32,     3,     8,
+      28,    10,    15,    16,     0,     0,    21,     0,    35,     0,
+      38,    41,    42,    47,    50,    51,    52,    53,    55,    57,
+      59,    70,     0,    25,    73,     0,     0,     0,   142,     0,
+       0,   181,     0,     0,     0,     0,     0,   159,   168,   172,
+      35,    61,    68,     0,   150,     0,   114,   153,   170,   152,
+     151,     0,   154,   155,   156,   157,    80,    82,    84,     0,
+       0,    98,     0,   149,   100,    29,    30,     0,    12,    13,
+       0,     0,    19,    18,     0,    20,    22,    24,    31,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   115,     0,   146,     0,   144,   140,   142,   191,
-     190,   165,   182,     0,   194,   192,     0,   178,   157,     0,
-      64,    65,    66,    67,    63,     0,     0,   172,   168,   170,
-       0,    93,     0,    95,    99,     7,     0,    14,    26,    11,
-      17,    23,    36,    37,    40,    39,    45,    46,    43,    44,
-      48,    49,    54,    56,    58,     0,   138,     0,     0,   143,
-       0,     0,     0,     0,     0,   193,     0,   159,    62,    69,
-       0,    94,     9,     0,     0,   145,     0,   164,   166,   185,
-     184,   187,   165,   176,     0,     0,     0,    81,    60,   147,
-       0,   186,     0,     0,   175,   173,     0,     0,   160,     0,
-     188,     0,   165,     0,   162,   179,   161,     0,   189,   183,
-     174,   177,   181
+       0,     0,     0,   115,     0,   147,     0,   145,   141,   143,
+     192,   191,   166,   183,     0,   195,   193,     0,   179,   158,
+       0,    64,    65,    66,    67,    63,     0,     0,   173,   169,
+     171,     0,    93,     0,    95,    99,     7,     0,    14,    26,
+      11,    17,    23,    36,    37,    40,    39,    45,    46,    43,
+      44,    48,    49,    54,    56,    58,     0,   139,     0,     0,
+     144,     0,     0,     0,     0,     0,   194,     0,   160,    62,
+      69,     0,    94,     9,     0,     0,   146,     0,   165,   167,
+     186,   185,   188,   166,   177,     0,     0,     0,    81,    60,
+     148,     0,   187,     0,     0,   176,   174,     0,     0,   161,
+       0,   189,     0,   166,     0,   163,   180,   162,     0,   190,
+     184,   175,   178,   182
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    97,    98,    99,   226,   100,   101,   102,   103,   104,
-     105,   106,   139,   108,   109,   110,   111,   112,   113,   114,
-     115,   116,   117,   118,   119,   140,   141,   215,   142,   121,
-     143,   144,    33,    34,    35,    78,    61,    62,    79,    36,
-      37,    38,    39,    40,    41,    42,   122,    44,   124,    74,
-     126,   127,   195,   196,   163,   146,   147,   148,   149,   209,
-     276,   295,   250,   251,   252,   296,   150,   151,   152,   285,
-     275,   153,   256,   201,   253,   271,   282,   283,   154,    45,
-      46,    47,    54
+      -1,    98,    99,   100,   227,   101,   102,   103,   104,   105,
+     106,   107,   140,   109,   110,   111,   112,   113,   114,   115,
+     116,   117,   118,   119,   120,   141,   142,   216,   143,   122,
+     144,   145,    34,    35,    36,    79,    62,    63,    80,    37,
+      38,    39,    40,    41,    42,    43,   123,    45,   125,    75,
+     127,   128,   196,   197,   164,   147,   148,   149,   150,   210,
+     277,   296,   251,   252,   253,   297,   151,   152,   153,   286,
+     276,   154,   257,   202,   254,   272,   283,   284,   155,    46,
+      47,    48,    55
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -256
+#define YYPACT_NINF -266
 static const yytype_int16 yypact[] =
 {
-    1256,   -17,  -256,  -256,  -256,   147,  -256,  -256,  -256,  -256,
-    -256,  -256,  -256,  -256,  -256,  -256,  -256,  -256,  -256,  -256,
-    -256,  -256,  -256,  -256,  -256,   -32,  -256,  -256,  -256,  -256,
-    -256,  -256,   -60,   -64,   -29,    20,   -43,  -256,   -10,  1298,
-    -256,  1359,  -256,   -27,  -256,  1213,  -256,  -256,  -256,  -256,
-    1359,    56,  -256,  -256,    74,  -256,    70,    51,  -256,  -256,
-    -256,  -256,  1298,   123,   110,  -256,     9,  -256,  -256,   982,
-    -256,  -256,    86,  -256,  1298,   289,  -256,  -256,  -256,  -256,
-     126,  1298,    35,  -256,   194,   982,   100,  -256,  -256,  -256,
-    -256,   982,   982,   982,  -256,  -256,  -256,  -256,  -256,    18,
-    -256,  -256,  -256,   101,   -62,  1047,   104,  -256,   982,   -19,
-      76,  -256,   -24,    41,  -256,  -256,  -256,   114,   117,   -33,
-    -256,   107,  -256,  -256,  1298,   134,  1115,  -256,   102,   103,
-    -256,   115,   116,   108,   852,   119,   109,  -256,  -256,    39,
-    -256,  -256,     5,  -256,   -60,    89,  -256,  -256,  -256,  -256,
-     372,  -256,  -256,  -256,  -256,   118,  -256,  -256,   917,   982,
-    -256,   120,  -256,  -256,  -256,  -256,    38,  -256,  -256,   982,
-    1323,  -256,  -256,   982,   121,  -256,  -256,  -256,   982,   982,
-     982,   982,   982,   982,   982,   982,   982,   982,   982,   982,
-     982,   982,  -256,  1157,   122,     6,  -256,  -256,  -256,  -256,
-    -256,   124,  -256,   982,  -256,  -256,    44,  -256,  -256,   455,
-    -256,  -256,  -256,  -256,  -256,   982,   982,  -256,  -256,  -256,
-     982,  -256,   127,  -256,  -256,  -256,   128,   129,  -256,   125,
-    -256,  -256,  -256,  -256,   -19,   -19,  -256,  -256,  -256,  -256,
-     -24,   -24,  -256,   114,   117,    42,  -256,   982,   134,  -256,
-     157,    74,   621,   704,    40,  -256,   787,   455,  -256,  -256,
-     137,  -256,  -256,   982,   138,  -256,   142,  -256,  -256,  -256,
-    -256,   787,   124,   129,   164,   155,   152,  -256,  -256,  -256,
-     982,  -256,   133,   158,   213,  -256,   151,   538,  -256,    45,
-     982,   538,   124,   982,  -256,  -256,  -256,   153,   129,  -256,
-    -256,  -256,  -256
+    1253,   -20,  -266,  -266,  -266,   148,  -266,  -266,  -266,  -266,
+    -266,  -266,  -266,  -266,  -266,  -266,  -266,  -266,  -266,  -266,
+    -266,  -266,  -266,  -266,  -266,   -39,  -266,  -266,  -266,  -266,
+    -266,  -266,  -266,   -18,    -2,     6,    21,   -61,  -266,    51,
+    1296,  -266,  1370,  -266,    25,  -266,  1209,  -266,  -266,  -266,
+    -266,  1370,    42,  -266,  -266,    50,  -266,    71,    95,  -266,
+    -266,  -266,  -266,  1296,   123,   105,  -266,     9,  -266,  -266,
+     974,  -266,  -266,    81,  -266,  1296,   290,  -266,  -266,  -266,
+    -266,   125,  1296,   -13,  -266,   776,   974,    99,  -266,  -266,
+    -266,  -266,   974,   974,   974,  -266,  -266,  -266,  -266,  -266,
+      35,  -266,  -266,  -266,   100,    -6,  1040,   104,  -266,   974,
+      36,   -64,  -266,   -21,   102,  -266,  -266,  -266,   113,   117,
+     -51,  -266,   108,  -266,  -266,  1296,   129,  1109,  -266,    97,
+     103,  -266,   112,   114,   106,   842,   115,   116,  -266,  -266,
+      39,  -266,  -266,   -43,  -266,   -18,    47,  -266,  -266,  -266,
+    -266,   374,  -266,  -266,  -266,  -266,   118,  -266,  -266,   908,
+     974,  -266,   120,  -266,  -266,  -266,  -266,    19,  -266,  -266,
+     974,  1333,  -266,  -266,   974,   119,  -266,  -266,  -266,   974,
+     974,   974,   974,   974,   974,   974,   974,   974,   974,   974,
+     974,   974,   974,  -266,  1152,   122,   -29,  -266,  -266,  -266,
+    -266,  -266,   121,  -266,   974,  -266,  -266,     5,  -266,  -266,
+     458,  -266,  -266,  -266,  -266,  -266,   974,   974,  -266,  -266,
+    -266,   974,  -266,   137,  -266,  -266,  -266,   138,   111,  -266,
+     142,  -266,  -266,  -266,  -266,    36,    36,  -266,  -266,  -266,
+    -266,   -21,   -21,  -266,   113,   117,    82,  -266,   974,   129,
+    -266,   175,    50,   626,   710,    38,  -266,   197,   458,  -266,
+    -266,   141,  -266,  -266,   974,   155,  -266,   145,  -266,  -266,
+    -266,  -266,   197,   121,   111,   186,   159,   160,  -266,  -266,
+    -266,   974,  -266,   166,   176,   236,  -266,   174,   542,  -266,
+      43,   974,   542,   121,   974,  -266,  -266,  -266,   177,   111,
+    -266,  -266,  -266,  -266
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -256,  -256,  -256,  -256,  -256,  -256,  -256,    75,  -256,  -256,
-    -256,  -256,   -44,  -256,   -15,  -256,   -55,   -18,  -256,  -256,
-    -256,    60,    55,    59,  -256,   -65,   -83,  -256,   -92,   -73,
-       7,    13,  -256,  -256,  -256,   169,   195,   191,   174,  -256,
-    -256,  -238,   -20,   -30,   253,    19,     0,  -256,  -256,  -256,
-     135,  -121,  -256,    12,  -145,     8,  -144,  -228,  -256,  -256,
-    -256,   -28,  -255,  -256,  -256,   -51,    53,    11,  -256,  -256,
-      -5,  -256,  -256,  -256,  -256,  -256,  -256,  -256,  -256,  -256,
-     222,  -256,  -256
+    -266,  -266,  -266,  -266,  -266,  -266,  -266,    85,  -266,  -266,
+    -266,  -266,   -44,  -266,   -15,  -266,   -55,   -19,  -266,  -266,
+    -266,    72,    70,    73,  -266,   -66,   -83,  -266,   -92,   -73,
+      13,    14,  -266,  -266,  -266,   180,   206,   201,   184,  -266,
+    -266,  -241,   -25,   -30,   262,    -4,     0,  -266,  -266,  -266,
+     143,  -122,  -266,    22,  -145,    16,  -144,  -226,  -266,  -266,
+    -266,   -17,  -265,  -266,  -266,   -54,    63,    20,  -266,  -266,
+       4,  -266,  -266,  -266,  -266,  -266,  -266,  -266,  -266,  -266,
+     231,  -266,  -266
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -164
+#define YYTABLE_NINF -165
 static const yytype_int16 yytable[] =
 {
-      43,   166,   162,    76,   120,   198,   219,    31,    55,    67,
-     172,   161,    51,    32,   223,    63,   173,   284,   274,   120,
-      48,    53,   175,    57,   268,   107,   190,    49,     6,     7,
-     182,   183,    80,   274,    66,    64,    63,   300,    65,    43,
-     107,    43,   206,    52,   125,    43,    69,   164,   165,    56,
-      43,    80,    31,    58,    59,    60,    23,    24,    32,   294,
-      68,   191,    43,   294,   177,   184,   185,   178,   179,    72,
-     167,   168,   198,    57,    43,   145,   162,   227,     6,     7,
-      83,    43,    84,   216,   248,   222,   217,   249,    48,    85,
-     231,   169,   -75,   120,   125,   170,   125,   186,   187,   245,
-     210,   211,   212,    58,    59,    60,    23,    24,   158,   213,
-     225,   254,   272,   219,   107,   159,   216,   297,   216,   214,
-     216,   263,   216,   216,    43,   255,    43,   236,   237,   238,
-     239,    73,   258,   259,   232,   233,   107,   107,   107,   107,
-     107,   107,   107,   107,   107,   107,   107,   260,   301,    75,
-     145,     2,     3,     4,    82,   120,    58,    59,    60,   180,
-     -25,   181,    69,   125,   273,   234,   235,   123,   240,   241,
-     155,   -26,   188,   171,   264,   176,   107,   189,   194,   273,
-     278,   192,   120,   199,   200,   208,   202,   203,   289,   204,
-     207,   220,  -116,    43,   224,   247,   -27,   266,   298,  -163,
-     267,   261,   262,   107,     8,     9,    10,   216,   286,   145,
-     162,   277,   279,   280,   290,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,   287,   288,   292,
-     291,   293,    25,    26,   302,    27,    28,    29,    86,    30,
-      87,    88,    89,    90,   243,   230,    91,    92,   242,   244,
-     156,    77,   145,   145,    81,   157,   145,   145,    50,   193,
-     265,   269,   257,   299,   270,    93,   281,    71,   160,     0,
-       0,   145,     0,     0,     0,     0,    94,    95,     0,    96,
-       0,     0,     0,     0,     0,     0,     0,   145,     0,     0,
-       0,   145,     1,     2,     3,     4,     5,     6,     7,     8,
-       9,    10,   128,   129,   130,     0,   131,   132,   133,   134,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,     0,     0,     0,    23,    24,    25,    26,   135,
-      27,    28,    29,    86,    30,    87,    88,    89,    90,     0,
-       0,    91,    92,     0,     0,     0,     0,     0,     0,     0,
+      44,    77,   167,   163,   121,   199,    52,   220,   285,   191,
+      68,    64,   162,    32,    33,   224,   275,    49,    65,   121,
+     181,    66,   182,   176,    58,    50,   108,   269,   301,     6,
+       7,   275,    64,    81,   183,   184,   217,    53,    69,   218,
+      44,   108,    44,   207,   192,   126,    44,    73,   165,   166,
+     249,    44,    81,   250,    59,    60,    61,    23,    24,    32,
+      33,   159,   295,    44,    54,   178,   295,   173,   160,   185,
+     186,    56,   199,   174,    58,    44,   146,   163,   228,     6,
+       7,    84,    44,    85,   217,    57,   223,   256,   168,   169,
+      86,   232,   226,   121,   -75,   126,    67,   126,   217,    70,
+     246,   211,   212,   213,    59,    60,    61,    23,    24,   170,
+     214,   273,   255,   171,   220,   108,   298,   217,    74,   -25,
+     215,    70,   217,   179,   180,    44,    76,    44,   237,   238,
+     239,   240,    49,   259,   260,   233,   234,   108,   108,   108,
+     108,   108,   108,   108,   108,   108,   108,   108,   261,   302,
+      83,   146,     2,     3,     4,   121,    59,    60,    61,   187,
+     188,   217,   264,   124,   126,   274,   235,   236,   241,   242,
+     156,   -26,   189,   172,   195,   265,   177,   108,   190,   200,
+     274,   279,   121,   193,   203,   201,   204,   208,   205,   290,
+     217,  -116,   221,   209,    44,   225,   248,  -164,   268,   299,
+      58,     2,     3,     4,   108,     6,     7,     8,     9,    10,
+     146,   163,   262,   263,   -27,   267,   278,   281,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+     280,   287,   288,    23,    24,    25,    26,   289,    27,    28,
+      29,    30,    87,    31,    88,    89,    90,    91,   291,   292,
+      92,    93,   293,   146,   146,   294,   231,   146,   146,   303,
+     244,   243,   157,    78,   245,    82,   158,    51,   194,    94,
+     270,   266,   146,   258,   271,   300,   282,    72,     0,     0,
+      95,    96,     0,    97,     0,     0,     0,     0,   146,     0,
+       0,     0,   146,     1,     2,     3,     4,     5,     6,     7,
+       8,     9,    10,   129,   130,   131,     0,   132,   133,   134,
+     135,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,     0,     0,     0,    23,    24,    25,    26,
+     136,    27,    28,    29,    30,    87,    31,    88,    89,    90,
+      91,     0,     0,    92,    93,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      93,     0,     0,     0,   136,   137,     0,     0,     0,     0,
-     138,    94,    95,     0,    96,     1,     2,     3,     4,     5,
-       6,     7,     8,     9,    10,   128,   129,   130,     0,   131,
-     132,   133,   134,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,     0,     0,     0,    23,    24,
-      25,    26,   135,    27,    28,    29,    86,    30,    87,    88,
-      89,    90,     0,     0,    91,    92,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    93,     0,     0,     0,   136,   218,     0,
-       0,     0,     0,   138,    94,    95,     0,    96,     1,     2,
-       3,     4,     5,     6,     7,     8,     9,    10,   128,   129,
-     130,     0,   131,   132,   133,   134,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,     0,     0,
-       0,    23,    24,    25,    26,   135,    27,    28,    29,    86,
-      30,    87,    88,    89,    90,     0,     0,    91,    92,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    93,     0,     0,     0,
-     136,     0,     0,     0,     0,     0,   138,    94,    95,     0,
-      96,     1,     2,     3,     4,     5,     6,     7,     8,     9,
-      10,   128,   129,   130,     0,   131,   132,   133,   134,    11,
-      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,     0,     0,     0,    23,    24,    25,    26,   135,    27,
-      28,    29,    86,    30,    87,    88,    89,    90,     0,     0,
-      91,    92,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    93,
-       0,     0,     0,    75,     0,     0,     0,     0,     0,   138,
-      94,    95,     0,    96,     1,     2,     3,     4,     5,     6,
-       7,     8,     9,    10,   128,   129,   130,     0,   131,   132,
-     133,   134,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,     0,     0,     0,    23,    24,    25,
-      26,   135,    27,    28,    29,    86,    30,    87,    88,    89,
-      90,     0,     0,    91,    92,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    93,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   138,    94,    95,     0,    96,     1,     2,     3,
-       4,     5,     6,     7,     8,     9,    10,     0,     0,     0,
-       0,     0,     0,     0,     0,    11,    12,    13,    14,    15,
+       0,     0,    94,     0,     0,     0,   137,   138,     0,     0,
+       0,     0,   139,    95,    96,     0,    97,     1,     2,     3,
+       4,     5,     6,     7,     8,     9,    10,   129,   130,   131,
+       0,   132,   133,   134,   135,    11,    12,    13,    14,    15,
       16,    17,    18,    19,    20,    21,    22,     0,     0,     0,
-      23,    24,    25,    26,     0,    27,    28,    29,    86,    30,
-      87,    88,    89,    90,     0,     0,    91,    92,     0,     0,
+      23,    24,    25,    26,   136,    27,    28,    29,    30,    87,
+      31,    88,    89,    90,    91,     0,     0,    92,    93,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    93,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   138,    94,    95,     0,    96,
-      57,     2,     3,     4,     0,     6,     7,     8,     9,    10,
-       0,     0,     0,     0,     0,     0,     0,     0,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-       0,     0,     0,    23,    24,    25,    26,     0,    27,    28,
-      29,    86,    30,    87,    88,    89,    90,     0,     0,    91,
-      92,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    93,     0,
-       0,     0,     8,     9,    10,     0,     0,     0,     0,    94,
-      95,     0,    96,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,     0,     0,     0,     0,     0,
-      25,    26,     0,    27,    28,    29,    86,    30,    87,    88,
-      89,    90,     0,     0,    91,    92,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    93,     0,     0,     0,     8,     9,    10,
-       0,     0,     0,   205,    94,    95,     0,    96,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-       0,     0,     0,     0,     0,    25,    26,     0,    27,    28,
-      29,    86,    30,    87,    88,    89,    90,     0,     0,    91,
-      92,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    93,     0,
-       0,   221,     8,     9,    10,     0,     0,     0,     0,    94,
-      95,     0,    96,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,     0,     0,     0,     0,     0,
-      25,    26,     0,    27,    28,    29,    86,    30,    87,    88,
-      89,    90,     0,     0,    91,    92,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    93,     0,     0,     0,     8,     9,    10,
-       0,     0,     0,     0,    94,    95,     0,    96,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-       0,     0,     0,     0,     0,    25,   174,     0,    27,    28,
-      29,    86,    30,    87,    88,    89,    90,     0,     0,    91,
-      92,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    93,     2,
-       3,     4,     0,     0,     0,     8,     9,    10,     0,    94,
-      95,     0,    96,     0,     0,     0,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,     0,     0,
-       0,     0,     0,    25,    26,     0,    27,    28,    29,     0,
-      30,     2,     3,     4,     0,     0,     0,     8,     9,    10,
-       0,     0,     0,     0,     0,     0,     0,     0,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-       0,   197,     0,     0,     0,    25,    26,     0,    27,    28,
-      29,     0,    30,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    70,     0,     0,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,     0,     0,     0,     0,
-       0,     0,     0,   246,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,    20,    21,    22,     0,     0,     0,    23,
-      24,    25,    26,     0,    27,    28,    29,     0,    30,     1,
-       2,     3,     4,     5,     6,     7,     8,     9,    10,     0,
-       0,     0,     0,     0,     0,     0,     0,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
-       0,     0,    23,    24,    25,    26,     0,    27,    28,    29,
-       0,    30,     2,     3,     4,     0,     0,     0,     8,     9,
-      10,     0,     0,     0,     0,     0,     0,     0,     0,    11,
+       0,     0,     0,     0,     0,     0,    94,     0,     0,     0,
+     137,   219,     0,     0,     0,     0,   139,    95,    96,     0,
+      97,     1,     2,     3,     4,     5,     6,     7,     8,     9,
+      10,   129,   130,   131,     0,   132,   133,   134,   135,    11,
       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,     0,     0,     8,     9,    10,    25,    26,     0,    27,
-      28,    29,     0,    30,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,    20,    21,    22,     0,     0,     0,     0,
-       0,    25,    26,     0,    27,    28,    29,   228,    30,     8,
-       9,    10,   229,     0,     0,     0,     0,     0,     0,     0,
+      22,     0,     0,     0,    23,    24,    25,    26,   136,    27,
+      28,    29,    30,    87,    31,    88,    89,    90,    91,     0,
+       0,    92,    93,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      94,     0,     0,     0,   137,     0,     0,     0,     0,     0,
+     139,    95,    96,     0,    97,     1,     2,     3,     4,     5,
+       6,     7,     8,     9,    10,   129,   130,   131,     0,   132,
+     133,   134,   135,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,     0,     0,     0,    23,    24,
+      25,    26,   136,    27,    28,    29,    30,    87,    31,    88,
+      89,    90,    91,     0,     0,    92,    93,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    94,     0,     0,     0,    76,     0,
+       0,     0,     0,     0,   139,    95,    96,     0,    97,     1,
+       2,     3,     4,     5,     6,     7,     8,     9,    10,   129,
+     130,   131,     0,   132,   133,   134,   135,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,    23,    24,    25,    26,   136,    27,    28,    29,
+      30,    87,    31,    88,    89,    90,    91,     0,     0,    92,
+      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    94,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   139,    95,
+      96,     0,    97,     1,     2,     3,     4,     5,     6,     7,
+       8,     9,    10,     0,     0,     0,     0,     0,     0,     0,
+       0,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,     0,     0,     0,    23,    24,    25,    26,
+       0,    27,    28,    29,    30,    87,    31,    88,    89,    90,
+      91,     0,     0,    92,    93,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    94,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,   139,    95,    96,     0,    97,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+      30,    87,    31,    88,    89,    90,    91,     0,     0,    92,
+      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    94,     0,
+       0,   161,     8,     9,    10,     0,     0,     0,     0,    95,
+      96,     0,    97,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,     0,     0,     0,     0,     0,
+      25,    26,     0,    27,    28,    29,    30,    87,    31,    88,
+      89,    90,    91,     0,     0,    92,    93,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    94,     0,     0,     0,     8,     9,
+      10,     0,     0,     0,   206,    95,    96,     0,    97,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,     0,     0,     0,     0,     0,    25,    26,     0,    27,
+      28,    29,    30,    87,    31,    88,    89,    90,    91,     0,
+       0,    92,    93,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      94,     0,     0,   222,     8,     9,    10,     0,     0,     0,
+       0,    95,    96,     0,    97,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,     0,     0,     0,
+       0,     0,    25,    26,     0,    27,    28,    29,    30,    87,
+      31,    88,    89,    90,    91,     0,     0,    92,    93,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    94,     0,     0,     0,
+       8,     9,    10,     0,     0,     0,     0,    95,    96,     0,
+      97,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,     0,     0,     0,     0,     0,    25,   175,
+       0,    27,    28,    29,    30,    87,    31,    88,    89,    90,
+      91,     0,     0,    92,    93,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    94,     2,     3,     4,     0,     0,     0,     8,
+       9,    10,     0,    95,    96,     0,    97,     0,     0,     0,
       11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
       21,    22,     0,     0,     0,     0,     0,    25,    26,     0,
-      27,    28,    29,     0,    30
+      27,    28,    29,    30,     0,    31,     2,     3,     4,     0,
+       0,     0,     8,     9,    10,     0,     0,     0,     0,     0,
+       0,     0,     0,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,     0,   198,     0,     0,     0,
+      25,    26,     0,    27,    28,    29,    30,     0,    31,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    71,
+       0,     0,     1,     2,     3,     4,     5,     6,     7,     8,
+       9,    10,     0,     0,     0,     0,     0,     0,     0,   247,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,     0,     0,     0,    23,    24,    25,    26,     0,
+      27,    28,    29,    30,     0,    31,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,     0,     0,     0,     0,
+       0,     0,     0,     0,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,     0,     0,     0,    23,
+      24,    25,    26,     0,    27,    28,    29,    30,     0,    31,
+       2,     3,     4,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,     0,     0,     0,     0,     0,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+      30,     0,    31,     8,     9,    10,     0,     0,     0,     0,
+       0,     0,     0,     0,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,     0,     0,     0,     0,
+       0,    25,    26,     0,    27,    28,    29,    30,   229,    31,
+       8,     9,    10,   230,     0,     0,     0,     0,     0,     0,
+       0,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,     0,     0,     0,     0,     0,    25,    26,
+       0,    27,    28,    29,    30,     0,    31
 };
 
 static const yytype_int16 yycheck[] =
 {
-       0,    93,    85,    54,    69,   126,   150,     0,    72,    39,
-      72,    84,    44,     0,   159,    35,    78,   272,   256,    84,
-      37,    81,   105,     3,   252,    69,    59,    44,     8,     9,
-      54,    55,    62,   271,    44,    78,    56,   292,    81,    39,
-      84,    41,   134,    75,    74,    45,    73,    91,    92,    78,
-      50,    81,    45,    33,    34,    35,    36,    37,    45,   287,
-      41,    94,    62,   291,   108,    89,    90,    86,    87,    50,
-      52,    53,   193,     3,    74,    75,   159,   169,     8,     9,
-      71,    81,    73,    78,    78,   158,    81,    81,    37,    80,
-     173,    73,    72,   158,   124,    77,   126,    56,    57,   191,
-      61,    62,    63,    33,    34,    35,    36,    37,    73,    70,
-      72,   203,    72,   257,   158,    80,    78,    72,    78,    80,
-      78,    79,    78,    78,   124,    81,   126,   182,   183,   184,
-     185,    75,   215,   216,   178,   179,   180,   181,   182,   183,
-     184,   185,   186,   187,   188,   189,   190,   220,   293,    75,
-     150,     4,     5,     6,    44,   220,    33,    34,    35,    83,
-      71,    85,    73,   193,   256,   180,   181,    81,   186,   187,
-      44,    71,    58,    72,   247,    71,   220,    60,    44,   271,
-     263,    74,   247,    81,    81,    76,    71,    71,   280,    81,
-      71,    73,    71,   193,    74,    73,    71,    40,   290,    75,
-     251,    74,    74,   247,    10,    11,    12,    78,    44,   209,
-     293,    74,    74,    71,    81,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    30,    31,    32,    72,    76,    16,
-      72,    80,    38,    39,    81,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,   189,   170,    52,    53,   188,   190,
-      81,    56,   252,   253,    63,    81,   256,   257,     5,   124,
-     248,   253,   209,   291,   253,    71,   271,    45,    74,    -1,
-      -1,   271,    -1,    -1,    -1,    -1,    82,    83,    -1,    85,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,   287,    -1,    -1,
-      -1,   291,     3,     4,     5,     6,     7,     8,     9,    10,
-      11,    12,    13,    14,    15,    -1,    17,    18,    19,    20,
-      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
-      31,    32,    -1,    -1,    -1,    36,    37,    38,    39,    40,
-      41,    42,    43,    44,    45,    46,    47,    48,    49,    -1,
-      -1,    52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+       0,    55,    94,    86,    70,   127,    45,   151,   273,    60,
+      40,    36,    85,     0,     0,   160,   257,    37,    79,    85,
+      84,    82,    86,   106,     3,    45,    70,   253,   293,     8,
+       9,   272,    57,    63,    55,    56,    79,    76,    42,    82,
+      40,    85,    42,   135,    95,    75,    46,    51,    92,    93,
+      79,    51,    82,    82,    33,    34,    35,    36,    37,    46,
+      46,    74,   288,    63,    82,   109,   292,    73,    81,    90,
+      91,    73,   194,    79,     3,    75,    76,   160,   170,     8,
+       9,    72,    82,    74,    79,    79,   159,    82,    53,    54,
+      81,   174,    73,   159,    73,   125,    45,   127,    79,    74,
+     192,    62,    63,    64,    33,    34,    35,    36,    37,    74,
+      71,    73,   204,    78,   258,   159,    73,    79,    76,    72,
+      81,    74,    79,    87,    88,   125,    76,   127,   183,   184,
+     185,   186,    37,   216,   217,   179,   180,   181,   182,   183,
+     184,   185,   186,   187,   188,   189,   190,   191,   221,   294,
+      45,   151,     4,     5,     6,   221,    33,    34,    35,    57,
+      58,    79,    80,    82,   194,   257,   181,   182,   187,   188,
+      45,    72,    59,    73,    45,   248,    72,   221,    61,    82,
+     272,   264,   248,    75,    72,    82,    72,    72,    82,   281,
+      79,    72,    74,    77,   194,    75,    74,    76,   252,   291,
+       3,     4,     5,     6,   248,     8,     9,    10,    11,    12,
+     210,   294,    75,    75,    72,    40,    75,    72,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      75,    45,    73,    36,    37,    38,    39,    77,    41,    42,
+      43,    44,    45,    46,    47,    48,    49,    50,    82,    73,
+      53,    54,    16,   253,   254,    81,   171,   257,   258,    82,
+     190,   189,    82,    57,   191,    64,    82,     5,   125,    72,
+     254,   249,   272,   210,   254,   292,   272,    46,    -1,    -1,
+      83,    84,    -1,    86,    -1,    -1,    -1,    -1,   288,    -1,
+      -1,    -1,   292,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    -1,    17,    18,    19,
+      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    -1,    -1,    -1,    36,    37,    38,    39,
+      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
+      50,    -1,    -1,    53,    54,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      71,    -1,    -1,    -1,    75,    76,    -1,    -1,    -1,    -1,
-      81,    82,    83,    -1,    85,     3,     4,     5,     6,     7,
+      -1,    -1,    72,    -1,    -1,    -1,    76,    77,    -1,    -1,
+      -1,    -1,    82,    83,    84,    -1,    86,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+      -1,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
+      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+      46,    47,    48,    49,    50,    -1,    -1,    53,    54,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    72,    -1,    -1,    -1,
+      76,    77,    -1,    -1,    -1,    -1,    82,    83,    84,    -1,
+      86,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,    14,    15,    -1,    17,    18,    19,    20,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    -1,    -1,    -1,    36,    37,    38,    39,    40,    41,
+      42,    43,    44,    45,    46,    47,    48,    49,    50,    -1,
+      -1,    53,    54,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      72,    -1,    -1,    -1,    76,    -1,    -1,    -1,    -1,    -1,
+      82,    83,    84,    -1,    86,     3,     4,     5,     6,     7,
        8,     9,    10,    11,    12,    13,    14,    15,    -1,    17,
       18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
       28,    29,    30,    31,    32,    -1,    -1,    -1,    36,    37,
       38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
-      48,    49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,
+      48,    49,    50,    -1,    -1,    53,    54,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    71,    -1,    -1,    -1,    75,    76,    -1,
-      -1,    -1,    -1,    81,    82,    83,    -1,    85,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    -1,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
-      -1,    36,    37,    38,    39,    40,    41,    42,    43,    44,
-      45,    46,    47,    48,    49,    -1,    -1,    52,    53,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,
-      75,    -1,    -1,    -1,    -1,    -1,    81,    82,    83,    -1,
-      85,     3,     4,     5,     6,     7,     8,     9,    10,    11,
-      12,    13,    14,    15,    -1,    17,    18,    19,    20,    21,
-      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
-      32,    -1,    -1,    -1,    36,    37,    38,    39,    40,    41,
-      42,    43,    44,    45,    46,    47,    48,    49,    -1,    -1,
-      52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,
-      -1,    -1,    -1,    75,    -1,    -1,    -1,    -1,    -1,    81,
-      82,    83,    -1,    85,     3,     4,     5,     6,     7,     8,
-       9,    10,    11,    12,    13,    14,    15,    -1,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,    32,    -1,    -1,    -1,    36,    37,    38,
-      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
-      49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    81,    82,    83,    -1,    85,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
-      36,    37,    38,    39,    -1,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,    -1,    -1,    52,    53,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    81,    82,    83,    -1,    85,
-       3,     4,     5,     6,    -1,     8,     9,    10,    11,    12,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,
-      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
-      -1,    -1,    -1,    36,    37,    38,    39,    -1,    41,    42,
-      43,    44,    45,    46,    47,    48,    49,    -1,    -1,    52,
-      53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,
-      -1,    -1,    10,    11,    12,    -1,    -1,    -1,    -1,    82,
-      83,    -1,    85,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
-      38,    39,    -1,    41,    42,    43,    44,    45,    46,    47,
-      48,    49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,
-      -1,    -1,    -1,    81,    82,    83,    -1,    85,    21,    22,
-      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
-      -1,    -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,
-      43,    44,    45,    46,    47,    48,    49,    -1,    -1,    52,
-      53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,
-      -1,    74,    10,    11,    12,    -1,    -1,    -1,    -1,    82,
-      83,    -1,    85,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
-      38,    39,    -1,    41,    42,    43,    44,    45,    46,    47,
-      48,    49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,
-      -1,    -1,    -1,    -1,    82,    83,    -1,    85,    21,    22,
-      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
-      -1,    -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,
-      43,    44,    45,    46,    47,    48,    49,    -1,    -1,    52,
-      53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,     4,
-       5,     6,    -1,    -1,    -1,    10,    11,    12,    -1,    82,
-      83,    -1,    85,    -1,    -1,    -1,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
-      -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,    -1,
-      45,     4,     5,     6,    -1,    -1,    -1,    10,    11,    12,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,
-      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
-      -1,    76,    -1,    -1,    -1,    38,    39,    -1,    41,    42,
-      43,    -1,    45,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,     0,    -1,    -1,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    76,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    36,
-      37,    38,    39,    -1,    41,    42,    43,    -1,    45,     3,
-       4,     5,     6,     7,     8,     9,    10,    11,    12,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,
+      -1,    -1,    -1,    -1,    72,    -1,    -1,    -1,    76,    -1,
+      -1,    -1,    -1,    -1,    82,    83,    84,    -1,    86,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,    -1,    17,    18,    19,    20,    21,    22,    23,
       24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
-      -1,    -1,    36,    37,    38,    39,    -1,    41,    42,    43,
-      -1,    45,     4,     5,     6,    -1,    -1,    -1,    10,    11,
-      12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,
+      -1,    -1,    36,    37,    38,    39,    40,    41,    42,    43,
+      44,    45,    46,    47,    48,    49,    50,    -1,    -1,    53,
+      54,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    72,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    82,    83,
+      84,    -1,    86,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    -1,    -1,    -1,    36,    37,    38,    39,
+      -1,    41,    42,    43,    44,    45,    46,    47,    48,    49,
+      50,    -1,    -1,    53,    54,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    72,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    82,    83,    84,    -1,    86,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
+      44,    45,    46,    47,    48,    49,    50,    -1,    -1,    53,
+      54,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    72,    -1,
+      -1,    75,    10,    11,    12,    -1,    -1,    -1,    -1,    83,
+      84,    -1,    86,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
+      38,    39,    -1,    41,    42,    43,    44,    45,    46,    47,
+      48,    49,    50,    -1,    -1,    53,    54,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    72,    -1,    -1,    -1,    10,    11,
+      12,    -1,    -1,    -1,    82,    83,    84,    -1,    86,    21,
       22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
-      32,    -1,    -1,    10,    11,    12,    38,    39,    -1,    41,
-      42,    43,    -1,    45,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,
-      -1,    38,    39,    -1,    41,    42,    43,    44,    45,    10,
-      11,    12,    49,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      32,    -1,    -1,    -1,    -1,    -1,    38,    39,    -1,    41,
+      42,    43,    44,    45,    46,    47,    48,    49,    50,    -1,
+      -1,    53,    54,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      72,    -1,    -1,    75,    10,    11,    12,    -1,    -1,    -1,
+      -1,    83,    84,    -1,    86,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
+      -1,    -1,    38,    39,    -1,    41,    42,    43,    44,    45,
+      46,    47,    48,    49,    50,    -1,    -1,    53,    54,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    72,    -1,    -1,    -1,
+      10,    11,    12,    -1,    -1,    -1,    -1,    83,    84,    -1,
+      86,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,
+      -1,    41,    42,    43,    44,    45,    46,    47,    48,    49,
+      50,    -1,    -1,    53,    54,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    72,     4,     5,     6,    -1,    -1,    -1,    10,
+      11,    12,    -1,    83,    84,    -1,    86,    -1,    -1,    -1,
       21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
       31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,    -1,
-      41,    42,    43,    -1,    45
+      41,    42,    43,    44,    -1,    46,     4,     5,     6,    -1,
+      -1,    -1,    10,    11,    12,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    -1,    77,    -1,    -1,    -1,
+      38,    39,    -1,    41,    42,    43,    44,    -1,    46,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     0,
+      -1,    -1,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    77,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    -1,    -1,    -1,    36,    37,    38,    39,    -1,
+      41,    42,    43,    44,    -1,    46,     3,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    36,
+      37,    38,    39,    -1,    41,    42,    43,    44,    -1,    46,
+       4,     5,     6,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,
+      44,    -1,    46,    10,    11,    12,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,
+      -1,    38,    39,    -1,    41,    42,    43,    44,    45,    46,
+      10,    11,    12,    50,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,
+      -1,    41,    42,    43,    44,    -1,    46
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1212,34 +1216,34 @@
        0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
       12,    21,    22,    23,    24,    25,    26,    27,    28,    29,
       30,    31,    32,    36,    37,    38,    39,    41,    42,    43,
-      45,   125,   126,   127,   128,   129,   134,   135,   136,   137,
-     138,   139,   140,   141,   142,   174,   175,   176,    37,    44,
-     139,    44,    75,    81,   177,    72,    78,     3,    33,    34,
-      35,   131,   132,   137,    78,    81,    44,   138,   140,    73,
-       0,   175,   140,    75,   144,    75,   160,   131,   130,   133,
-     138,   132,    44,    71,    73,    80,    44,    46,    47,    48,
-      49,    52,    53,    71,    82,    83,    85,    96,    97,    98,
-     100,   101,   102,   103,   104,   105,   106,   107,   108,   109,
+      44,    46,   126,   127,   128,   129,   130,   135,   136,   137,
+     138,   139,   140,   141,   142,   143,   175,   176,   177,    37,
+      45,   140,    45,    76,    82,   178,    73,    79,     3,    33,
+      34,    35,   132,   133,   138,    79,    82,    45,   139,   141,
+      74,     0,   176,   141,    76,   145,    76,   161,   132,   131,
+     134,   139,   133,    45,    72,    74,    81,    45,    47,    48,
+      49,    50,    53,    54,    72,    83,    84,    86,    97,    98,
+      99,   101,   102,   103,   104,   105,   106,   107,   108,   109,
      110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
-     120,   124,   141,    81,   143,   138,   145,   146,    13,    14,
-      15,    17,    18,    19,    20,    40,    75,    76,    81,   107,
-     120,   121,   123,   125,   126,   141,   150,   151,   152,   153,
-     161,   162,   163,   166,   173,    44,   130,   133,    73,    80,
-      74,   124,   121,   149,   107,   107,   123,    52,    53,    73,
-      77,    72,    72,    78,    39,   121,    71,   107,    86,    87,
-      83,    85,    54,    55,    89,    90,    56,    57,    58,    60,
-      59,    94,    74,   145,    44,   147,   148,    76,   146,    81,
-      81,   168,    71,    71,    81,    81,   123,    71,    76,   154,
-      61,    62,    63,    70,    80,   122,    78,    81,    76,   151,
-      73,    74,   124,   149,    74,    72,    99,   123,    44,    49,
-     102,   121,   107,   107,   109,   109,   111,   111,   111,   111,
-     112,   112,   116,   117,   118,   123,    76,    73,    78,    81,
-     157,   158,   159,   169,   123,    81,   167,   161,   121,   121,
-     124,    74,    74,    79,   124,   148,    40,   160,   152,   150,
-     162,   170,    72,   123,   136,   165,   155,    74,   121,    74,
-      71,   165,   171,   172,   157,   164,    44,    72,    76,   123,
-      81,    72,    16,    80,   152,   156,   160,    72,   123,   156,
-     157,   149,    81
+     120,   121,   125,   142,    82,   144,   139,   146,   147,    13,
+      14,    15,    17,    18,    19,    20,    40,    76,    77,    82,
+     108,   121,   122,   124,   126,   127,   142,   151,   152,   153,
+     154,   162,   163,   164,   167,   174,    45,   131,   134,    74,
+      81,    75,   125,   122,   150,   108,   108,   124,    53,    54,
+      74,    78,    73,    73,    79,    39,   122,    72,   108,    87,
+      88,    84,    86,    55,    56,    90,    91,    57,    58,    59,
+      61,    60,    95,    75,   146,    45,   148,   149,    77,   147,
+      82,    82,   169,    72,    72,    82,    82,   124,    72,    77,
+     155,    62,    63,    64,    71,    81,   123,    79,    82,    77,
+     152,    74,    75,   125,   150,    75,    73,   100,   124,    45,
+      50,   103,   122,   108,   108,   110,   110,   112,   112,   112,
+     112,   113,   113,   117,   118,   119,   124,    77,    74,    79,
+      82,   158,   159,   160,   170,   124,    82,   168,   162,   122,
+     122,   125,    75,    75,    80,   125,   149,    40,   161,   153,
+     151,   163,   171,    73,   124,   137,   166,   156,    75,   122,
+      75,    72,   166,   172,   173,   158,   165,    45,    73,    77,
+     124,    82,    73,    16,    81,   153,   157,   161,    73,   124,
+     157,   158,   150,    82
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -3865,13 +3869,22 @@
   case 135:
 
     {
+        FRAG_VERT_ONLY("sampler3D", (yyvsp[(1) - (1)].lex).line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtSampler3D, qual, (yyvsp[(1) - (1)].lex).line);
+    }
+    break;
+
+  case 136:
+
+    {
         FRAG_VERT_ONLY("struct", (yyvsp[(1) - (1)].interm.type).line);
         (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
         (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
     }
     break;
 
-  case 136:
+  case 137:
 
     {
         //
@@ -3885,12 +3898,12 @@
     }
     break;
 
-  case 137:
+  case 138:
 
     { if (context->enterStructDeclaration((yyvsp[(2) - (3)].lex).line, *(yyvsp[(2) - (3)].lex).string)) context->recover(); }
     break;
 
-  case 138:
+  case 139:
 
     {
         if (context->reservedErrorCheck((yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].lex).string))
@@ -3908,12 +3921,12 @@
     }
     break;
 
-  case 139:
+  case 140:
 
     { if (context->enterStructDeclaration((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string)) context->recover(); }
     break;
 
-  case 140:
+  case 141:
 
     {
         TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), TString(""));
@@ -3923,14 +3936,14 @@
     }
     break;
 
-  case 141:
+  case 142:
 
     {
         (yyval.interm.typeList) = (yyvsp[(1) - (1)].interm.typeList);
     }
     break;
 
-  case 142:
+  case 143:
 
     {
         (yyval.interm.typeList) = (yyvsp[(1) - (2)].interm.typeList);
@@ -3946,7 +3959,7 @@
     }
     break;
 
-  case 143:
+  case 144:
 
     {
         (yyval.interm.typeList) = (yyvsp[(2) - (3)].interm.typeList);
@@ -3983,7 +3996,7 @@
     }
     break;
 
-  case 144:
+  case 145:
 
     {
         (yyval.interm.typeList) = NewPoolTTypeList();
@@ -3991,14 +4004,14 @@
     }
     break;
 
-  case 145:
+  case 146:
 
     {
         (yyval.interm.typeList)->push_back((yyvsp[(3) - (3)].interm.typeLine));
     }
     break;
 
-  case 146:
+  case 147:
 
     {
         if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
@@ -4010,7 +4023,7 @@
     }
     break;
 
-  case 147:
+  case 148:
 
     {
         if (context->reservedErrorCheck((yyvsp[(1) - (4)].lex).line, *(yyvsp[(1) - (4)].lex).string))
@@ -4027,24 +4040,19 @@
     }
     break;
 
-  case 148:
+  case 149:
 
     { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
     break;
 
-  case 149:
-
-    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
-    break;
-
   case 150:
 
-    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); }
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
     break;
 
   case 151:
 
-    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); }
     break;
 
   case 152:
@@ -4074,21 +4082,26 @@
 
   case 157:
 
-    { (yyval.interm.intermAggregate) = 0; }
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
     break;
 
   case 158:
 
-    { context->symbolTable.push(); }
+    { (yyval.interm.intermAggregate) = 0; }
     break;
 
   case 159:
 
-    { context->symbolTable.pop(); }
+    { context->symbolTable.push(); }
     break;
 
   case 160:
 
+    { context->symbolTable.pop(); }
+    break;
+
+  case 161:
+
     {
         if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) {
             (yyvsp[(3) - (5)].interm.intermAggregate)->setOp(EOpSequence);
@@ -4098,11 +4111,6 @@
     }
     break;
 
-  case 161:
-
-    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
-    break;
-
   case 162:
 
     { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
@@ -4110,32 +4118,37 @@
 
   case 163:
 
-    { context->symbolTable.push(); }
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
     break;
 
   case 164:
 
-    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); }
+    { context->symbolTable.push(); }
     break;
 
   case 165:
 
-    { context->symbolTable.push(); }
+    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); }
     break;
 
   case 166:
 
-    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); }
+    { context->symbolTable.push(); }
     break;
 
   case 167:
 
+    { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); }
+    break;
+
+  case 168:
+
     {
         (yyval.interm.intermNode) = 0;
     }
     break;
 
-  case 168:
+  case 169:
 
     {
         if ((yyvsp[(2) - (3)].interm.intermAggregate)) {
@@ -4146,31 +4159,31 @@
     }
     break;
 
-  case 169:
+  case 170:
 
     {
         (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), 0);
     }
     break;
 
-  case 170:
+  case 171:
 
     {
         (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), 0);
     }
     break;
 
-  case 171:
+  case 172:
 
     { (yyval.interm.intermNode) = 0; }
     break;
 
-  case 172:
+  case 173:
 
     { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[(1) - (2)].interm.intermTypedNode)); }
     break;
 
-  case 173:
+  case 174:
 
     {
         if (context->boolErrorCheck((yyvsp[(1) - (5)].lex).line, (yyvsp[(3) - (5)].interm.intermTypedNode)))
@@ -4179,7 +4192,7 @@
     }
     break;
 
-  case 174:
+  case 175:
 
     {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermNode);
@@ -4187,7 +4200,7 @@
     }
     break;
 
-  case 175:
+  case 176:
 
     {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (1)].interm.intermNode);
@@ -4195,7 +4208,7 @@
     }
     break;
 
-  case 176:
+  case 177:
 
     {
         (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
@@ -4204,7 +4217,7 @@
     }
     break;
 
-  case 177:
+  case 178:
 
     {
         TIntermNode* intermNode;
@@ -4222,12 +4235,12 @@
     }
     break;
 
-  case 178:
+  case 179:
 
     { context->symbolTable.push(); ++context->loopNestingLevel; }
     break;
 
-  case 179:
+  case 180:
 
     {
         context->symbolTable.pop();
@@ -4236,12 +4249,12 @@
     }
     break;
 
-  case 180:
+  case 181:
 
     { ++context->loopNestingLevel; }
     break;
 
-  case 181:
+  case 182:
 
     {
         if (context->boolErrorCheck((yyvsp[(8) - (8)].lex).line, (yyvsp[(6) - (8)].interm.intermTypedNode)))
@@ -4252,24 +4265,17 @@
     }
     break;
 
-  case 182:
-
-    { context->symbolTable.push(); ++context->loopNestingLevel; }
-    break;
-
   case 183:
 
-    {
-        context->symbolTable.pop();
-        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yyvsp[(1) - (7)].lex).line);
-        --context->loopNestingLevel;
-    }
+    { context->symbolTable.push(); ++context->loopNestingLevel; }
     break;
 
   case 184:
 
     {
-        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+        context->symbolTable.pop();
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yyvsp[(1) - (7)].lex).line);
+        --context->loopNestingLevel;
     }
     break;
 
@@ -4283,26 +4289,33 @@
   case 186:
 
     {
-        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
     }
     break;
 
   case 187:
 
     {
-        (yyval.interm.intermTypedNode) = 0;
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
     }
     break;
 
   case 188:
 
     {
+        (yyval.interm.intermTypedNode) = 0;
+    }
+    break;
+
+  case 189:
+
+    {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (2)].interm.intermTypedNode);
         (yyval.interm.nodePair).node2 = 0;
     }
     break;
 
-  case 189:
+  case 190:
 
     {
         (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermTypedNode);
@@ -4310,7 +4323,7 @@
     }
     break;
 
-  case 190:
+  case 191:
 
     {
         if (context->loopNestingLevel <= 0) {
@@ -4321,7 +4334,7 @@
     }
     break;
 
-  case 191:
+  case 192:
 
     {
         if (context->loopNestingLevel <= 0) {
@@ -4332,7 +4345,7 @@
     }
     break;
 
-  case 192:
+  case 193:
 
     {
         (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line);
@@ -4343,7 +4356,7 @@
     }
     break;
 
-  case 193:
+  case 194:
 
     {
         (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line);
@@ -4358,7 +4371,7 @@
     }
     break;
 
-  case 194:
+  case 195:
 
     {
         FRAG_ONLY("discard", (yyvsp[(1) - (2)].lex).line);
@@ -4366,18 +4379,10 @@
     }
     break;
 
-  case 195:
-
-    {
-        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
-        context->treeRoot = (yyval.interm.intermNode);
-    }
-    break;
-
   case 196:
 
     {
-        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0);
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
         context->treeRoot = (yyval.interm.intermNode);
     }
     break;
@@ -4385,7 +4390,8 @@
   case 197:
 
     {
-        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0);
+        context->treeRoot = (yyval.interm.intermNode);
     }
     break;
 
@@ -4399,6 +4405,13 @@
   case 199:
 
     {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    }
+    break;
+
+  case 200:
+
+    {
         TFunction* function = (yyvsp[(1) - (1)].interm).function;
         
         const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName());
@@ -4485,7 +4498,7 @@
     }
     break;
 
-  case 200:
+  case 201:
 
     {
         //?? Check that all paths return a value if return type != void ?
diff --git a/src/OpenGL/compiler/glslang_tab.h b/src/OpenGL/compiler/glslang_tab.h
index eb3237c..33e493b 100644
--- a/src/OpenGL/compiler/glslang_tab.h
+++ b/src/OpenGL/compiler/glslang_tab.h
@@ -80,57 +80,58 @@
      SAMPLER2D = 296,
      SAMPLERCUBE = 297,
      SAMPLER_EXTERNAL_OES = 298,
-     IDENTIFIER = 299,
-     TYPE_NAME = 300,
-     FLOATCONSTANT = 301,
-     INTCONSTANT = 302,
-     BOOLCONSTANT = 303,
-     FIELD_SELECTION = 304,
-     LEFT_OP = 305,
-     RIGHT_OP = 306,
-     INC_OP = 307,
-     DEC_OP = 308,
-     LE_OP = 309,
-     GE_OP = 310,
-     EQ_OP = 311,
-     NE_OP = 312,
-     AND_OP = 313,
-     OR_OP = 314,
-     XOR_OP = 315,
-     MUL_ASSIGN = 316,
-     DIV_ASSIGN = 317,
-     ADD_ASSIGN = 318,
-     MOD_ASSIGN = 319,
-     LEFT_ASSIGN = 320,
-     RIGHT_ASSIGN = 321,
-     AND_ASSIGN = 322,
-     XOR_ASSIGN = 323,
-     OR_ASSIGN = 324,
-     SUB_ASSIGN = 325,
-     LEFT_PAREN = 326,
-     RIGHT_PAREN = 327,
-     LEFT_BRACKET = 328,
-     RIGHT_BRACKET = 329,
-     LEFT_BRACE = 330,
-     RIGHT_BRACE = 331,
-     DOT = 332,
-     COMMA = 333,
-     COLON = 334,
-     EQUAL = 335,
-     SEMICOLON = 336,
-     BANG = 337,
-     DASH = 338,
-     TILDE = 339,
-     PLUS = 340,
-     STAR = 341,
-     SLASH = 342,
-     PERCENT = 343,
-     LEFT_ANGLE = 344,
-     RIGHT_ANGLE = 345,
-     VERTICAL_BAR = 346,
-     CARET = 347,
-     AMPERSAND = 348,
-     QUESTION = 349
+     SAMPLER3D = 299,
+     IDENTIFIER = 300,
+     TYPE_NAME = 301,
+     FLOATCONSTANT = 302,
+     INTCONSTANT = 303,
+     BOOLCONSTANT = 304,
+     FIELD_SELECTION = 305,
+     LEFT_OP = 306,
+     RIGHT_OP = 307,
+     INC_OP = 308,
+     DEC_OP = 309,
+     LE_OP = 310,
+     GE_OP = 311,
+     EQ_OP = 312,
+     NE_OP = 313,
+     AND_OP = 314,
+     OR_OP = 315,
+     XOR_OP = 316,
+     MUL_ASSIGN = 317,
+     DIV_ASSIGN = 318,
+     ADD_ASSIGN = 319,
+     MOD_ASSIGN = 320,
+     LEFT_ASSIGN = 321,
+     RIGHT_ASSIGN = 322,
+     AND_ASSIGN = 323,
+     XOR_ASSIGN = 324,
+     OR_ASSIGN = 325,
+     SUB_ASSIGN = 326,
+     LEFT_PAREN = 327,
+     RIGHT_PAREN = 328,
+     LEFT_BRACKET = 329,
+     RIGHT_BRACKET = 330,
+     LEFT_BRACE = 331,
+     RIGHT_BRACE = 332,
+     DOT = 333,
+     COMMA = 334,
+     COLON = 335,
+     EQUAL = 336,
+     SEMICOLON = 337,
+     BANG = 338,
+     DASH = 339,
+     TILDE = 340,
+     PLUS = 341,
+     STAR = 342,
+     SLASH = 343,
+     PERCENT = 344,
+     LEFT_ANGLE = 345,
+     RIGHT_ANGLE = 346,
+     VERTICAL_BAR = 347,
+     CARET = 348,
+     AMPERSAND = 349,
+     QUESTION = 350
    };
 #endif
 
diff --git a/src/OpenGL/libEGL/Image.hpp b/src/OpenGL/libEGL/Image.hpp
index 862162a..f612c57 100644
--- a/src/OpenGL/libEGL/Image.hpp
+++ b/src/OpenGL/libEGL/Image.hpp
@@ -18,50 +18,52 @@
 class Image : public sw::Surface

 {

 public:

-	Image(sw::Resource *resource, GLsizei width, GLsizei height, GLenum format, GLenum type, sw::Format internalFormat)

-		: width(width), height(height), format(format), type(type), internalFormat(internalFormat), multiSampleDepth(1)

-		, sw::Surface(resource, width, height, 1, internalFormat, true, true)

+	Image(sw::Resource *resource, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, sw::Format internalFormat)

+		: width(width), height(height), format(format), type(type), internalFormat(internalFormat), depth(depth)

+		, sw::Surface(resource, width, height, depth, internalFormat, true, true)

 	{

 		shared = false;

 	}

 

 	Image(sw::Resource *resource, int width, int height, int depth, sw::Format internalFormat, bool lockable, bool renderTarget)

-		: width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), multiSampleDepth(depth)

+		: width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(depth)

 		, sw::Surface(resource, width, height, depth, internalFormat, lockable, renderTarget)

 	{

 		shared = false;

 	}

 

-	GLsizei getWidth()

+	GLsizei getWidth() const

 	{

 		return width;

 	}

 

-	GLsizei getHeight()

+	GLsizei getHeight() const

 	{

 		return height;

 	}

 

-	GLenum getFormat()

+	int getDepth() const

+	{

+		// FIXME: add member if the depth dimension (for 3D textures or 2D testure arrays)

+		// and multi sample depth are ever simultaneously required.

+		return depth;

+	}

+

+	GLenum getFormat() const

 	{

 		return format;

 	}

 

-	GLenum getType()

+	GLenum getType() const

 	{

 		return type;

 	}

 

-	sw::Format getInternalFormat()

+	sw::Format getInternalFormat() const

 	{

 		return internalFormat;

 	}

 

-	int getMultiSampleDepth()

-	{

-		return multiSampleDepth;

-	}

-

 	bool isShared() const

     {

         return shared;

@@ -98,8 +100,8 @@
 		release();

     }

 

-	virtual void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input) = 0;

-	virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) = 0;

+	virtual void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input) = 0;

+	virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;

 

 protected:

 	virtual ~Image()

@@ -111,7 +113,7 @@
 	const GLenum format;

 	const GLenum type;

 	const sw::Format internalFormat;

-	const int multiSampleDepth;

+	const int depth;

 

 	bool shared;   // Used as an EGLImage

 };

diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index b8ce563..921b79d 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -867,7 +867,7 @@
 		return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);

 	}

 

-	if(image->getMultiSampleDepth() > 1)

+	if(image->getDepth() > 1)

 	{

 		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);

 	}

diff --git a/src/OpenGL/libGL/Image.cpp b/src/OpenGL/libGL/Image.cpp
index 9e98db2..4168d82 100644
--- a/src/OpenGL/libGL/Image.cpp
+++ b/src/OpenGL/libGL/Image.cpp
@@ -32,7 +32,7 @@
 
 	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
 		: parentTexture(parentTexture)
-		, egl::Image(getParentResource(parentTexture), width, height, format, type, selectInternalFormat(format, type))
+		, egl::Image(getParentResource(parentTexture), width, height, 1, format, type, selectInternalFormat(format, type))
 	{
 		referenceCount = 1;
 	}
@@ -176,7 +176,7 @@
 		return sw::FORMAT_A8R8G8B8;
 	}
 
-	void Image::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
+	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
 	{
 		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
 		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
@@ -644,7 +644,7 @@
 		}
 	}
 
-	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
 	{
 		int inputPitch = ComputeCompressedPitch(width, format);
 		int rows = imageSize / inputPitch;
diff --git a/src/OpenGL/libGL/Image.hpp b/src/OpenGL/libGL/Image.hpp
index 28d04d8..039d2d0 100644
--- a/src/OpenGL/libGL/Image.hpp
+++ b/src/OpenGL/libGL/Image.hpp
@@ -28,8 +28,8 @@
 		Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
 		Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget);
 
-		void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
-		void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+		void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
+		void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
 
 		virtual void addRef();
 		virtual void release();
diff --git a/src/OpenGL/libGL/Program.cpp b/src/OpenGL/libGL/Program.cpp
index a66a19d..97eb6f4 100644
--- a/src/OpenGL/libGL/Program.cpp
+++ b/src/OpenGL/libGL/Program.cpp
@@ -591,7 +591,8 @@
 		if(targetUniform->type == GL_INT ||

 		   targetUniform->type == GL_SAMPLER_2D ||

 		   targetUniform->type == GL_SAMPLER_CUBE ||

-           targetUniform->type == GL_SAMPLER_EXTERNAL_OES)

+		   targetUniform->type == GL_SAMPLER_EXTERNAL_OES ||

+		   targetUniform->type == GL_SAMPLER_3D_OES)

 		{

 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),

 				   v, sizeof(GLint) * count);

@@ -925,6 +926,7 @@
 				  case GL_SAMPLER_2D:

 				  case GL_SAMPLER_CUBE:

                   case GL_SAMPLER_EXTERNAL_OES:

+				  case GL_SAMPLER_3D_OES:

 				  case GL_INT:        applyUniform1iv(location, size, i);       break;

 				  case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;

 				  case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;

@@ -1315,7 +1317,7 @@
 

 	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex)

 	{

-		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES)

+		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_3D_OES)

 	    {

 			int index = registerIndex;

 			

@@ -1737,7 +1739,8 @@
 		{

             if(targetUniform->type == GL_SAMPLER_2D ||

                targetUniform->type == GL_SAMPLER_CUBE ||

-               targetUniform->type == GL_SAMPLER_EXTERNAL_OES)

+			   targetUniform->type == GL_SAMPLER_EXTERNAL_OES ||

+			   targetUniform->type == GL_SAMPLER_3D_OES)

 			{

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

 				{

@@ -1760,7 +1763,8 @@
 		{

 			if(targetUniform->type == GL_SAMPLER_2D ||

                targetUniform->type == GL_SAMPLER_CUBE ||

-               targetUniform->type == GL_SAMPLER_EXTERNAL_OES)

+               targetUniform->type == GL_SAMPLER_EXTERNAL_OES ||

+			   targetUniform->type == GL_SAMPLER_3D_OES)

 			{

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

 				{

diff --git a/src/OpenGL/libGL/Renderbuffer.cpp b/src/OpenGL/libGL/Renderbuffer.cpp
index 81fcd45..6e1e04b 100644
--- a/src/OpenGL/libGL/Renderbuffer.cpp
+++ b/src/OpenGL/libGL/Renderbuffer.cpp
@@ -361,7 +361,7 @@
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
 		format = sw2es::ConvertBackBufferFormat(internalFormat);
-		mSamples = renderTarget->getMultiSampleDepth() & ~1;
+		mSamples = renderTarget->getDepth() & ~1;
 	}
 }
 
@@ -438,7 +438,7 @@
 		mHeight = depthStencil->getHeight();
 		internalFormat = depthStencil->getInternalFormat();
 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
-		mSamples = depthStencil->getMultiSampleDepth() & ~1;
+		mSamples = depthStencil->getDepth() & ~1;
 	}
 }
 
diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
index 732b018..f7dcbfa 100644
--- a/src/OpenGL/libGL/Texture.cpp
+++ b/src/OpenGL/libGL/Texture.cpp
@@ -185,7 +185,7 @@
 {

     if(pixels && image)

     {

-		image->loadImageData(0, 0, image->getWidth(), image->getHeight(), format, type, unpackAlignment, pixels);

+		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackAlignment, pixels);

     }

 }

 

@@ -193,7 +193,7 @@
 {

     if(pixels && image)

     {

-		image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), imageSize, pixels);

+		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);

     }

 }

 

@@ -221,7 +221,7 @@
 

     if(pixels)

     {

-        image->loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels);

+        image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackAlignment, pixels);

     }

 }

 

@@ -244,7 +244,7 @@
 

     if(pixels)

     {

-		image->loadCompressedData(xoffset, yoffset, width, height, imageSize, pixels);

+		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);

     }

 }

 

diff --git a/src/OpenGL/libGL/utilities.cpp b/src/OpenGL/libGL/utilities.cpp
index ef6eeed..0305085 100644
--- a/src/OpenGL/libGL/utilities.cpp
+++ b/src/OpenGL/libGL/utilities.cpp
@@ -32,6 +32,7 @@
 		case GL_SAMPLER_2D:

 		case GL_SAMPLER_CUBE:

         case GL_SAMPLER_EXTERNAL_OES:

+		case GL_SAMPLER_3D_OES:

 			return 1;

 		case GL_BOOL_VEC2:

 		case GL_FLOAT_VEC2:

@@ -78,6 +79,7 @@
 		case GL_SAMPLER_2D:

 		case GL_SAMPLER_CUBE:

         case GL_SAMPLER_EXTERNAL_OES:

+		case GL_SAMPLER_3D_OES:

 		case GL_INT_VEC2:

 		case GL_INT_VEC3:

 		case GL_INT_VEC4:

@@ -122,6 +124,7 @@
 		case GL_SAMPLER_2D:

 		case GL_SAMPLER_CUBE:

         case GL_SAMPLER_EXTERNAL_OES:

+		case GL_SAMPLER_3D_OES:

 			return 1;

 		case GL_FLOAT_MAT2:

 			return 2;

diff --git a/src/OpenGL/libGLES_CM/Image.cpp b/src/OpenGL/libGLES_CM/Image.cpp
index 162ac30..416b6b4 100644
--- a/src/OpenGL/libGLES_CM/Image.cpp
+++ b/src/OpenGL/libGLES_CM/Image.cpp
@@ -33,7 +33,7 @@
 
 	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
 		: parentTexture(parentTexture)
-		, egl::Image(getParentResource(parentTexture), width, height, format, type, selectInternalFormat(format, type))
+		, egl::Image(getParentResource(parentTexture), width, height, 1, format, type, selectInternalFormat(format, type))
 	{
 		referenceCount = 1;
 	}
@@ -157,8 +157,10 @@
 		return sw::FORMAT_A8R8G8B8;
 	}
 
-	void Image::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
+	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
 	{
+		ASSERT(zoffset == 0 && depth == 1);
+
 		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
 		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
 		
@@ -524,8 +526,10 @@
 		}
 	}
 
-	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
 	{
+		ASSERT(zoffset == 0 && depth == 1);
+
 		int inputPitch = ComputeCompressedPitch(width, format);
 		int rows = imageSize / inputPitch;
 		void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
diff --git a/src/OpenGL/libGLES_CM/Image.hpp b/src/OpenGL/libGLES_CM/Image.hpp
index 440705f..a5b0251 100644
--- a/src/OpenGL/libGLES_CM/Image.hpp
+++ b/src/OpenGL/libGLES_CM/Image.hpp
@@ -28,8 +28,8 @@
 		Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
 		Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget);
 
-		void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
-		void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+		void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
+		void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
 
 		virtual void addRef();
 		virtual void release();
diff --git a/src/OpenGL/libGLES_CM/Renderbuffer.cpp b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
index 4d3dd9b..e4bdaca 100644
--- a/src/OpenGL/libGLES_CM/Renderbuffer.cpp
+++ b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
@@ -293,7 +293,7 @@
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
 		format = sw2es::ConvertBackBufferFormat(internalFormat);
-		mSamples = renderTarget->getMultiSampleDepth() & ~1;
+		mSamples = renderTarget->getDepth() & ~1;
 	}
 }
 
@@ -370,7 +370,7 @@
 		mHeight = depthStencil->getHeight();
 		internalFormat = depthStencil->getInternalFormat();
 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
-		mSamples = depthStencil->getMultiSampleDepth() & ~1;
+		mSamples = depthStencil->getDepth() & ~1;
 	}
 }
 
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index 3f1fa7f..d33c63e 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -185,7 +185,7 @@
 {

     if(pixels && image)

     {

-		image->loadImageData(0, 0, image->getWidth(), image->getHeight(), format, type, unpackAlignment, pixels);

+		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackAlignment, pixels);

     }

 }

 

@@ -193,7 +193,7 @@
 {

     if(pixels && image)

     {

-		image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), imageSize, pixels);

+		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);

     }

 }

 

@@ -221,7 +221,7 @@
 

     if(pixels)

     {

-        image->loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels);

+        image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackAlignment, pixels);

     }

 }

 

@@ -244,7 +244,7 @@
 

     if(pixels)

     {

-		image->loadCompressedData(xoffset, yoffset, width, height, imageSize, pixels);

+		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);

     }

 }

 

diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index da05a8a..d228d29 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -131,6 +131,7 @@
     // objects all of whose names are 0.

 

     mTexture2DZero.set(new Texture2D(0));

+	mTexture3DZero.set(new Texture3D(0));

     mTextureCubeMapZero.set(new TextureCubeMap(0));

     mTextureExternalZero.set(new TextureExternal(0));

 

@@ -212,6 +213,7 @@
     mState.renderbuffer.set(NULL);

 

     mTexture2DZero.set(NULL);

+	mTexture3DZero.set(NULL);

     mTextureCubeMapZero.set(NULL);

     mTextureExternalZero.set(NULL);

 

@@ -951,6 +953,13 @@
     mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].set(getTexture(texture));

 }

 

+void Context::bindTexture3D(GLuint texture)

+{

+	mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);

+

+	mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture));

+}

+

 void Context::bindReadFramebuffer(GLuint framebuffer)

 {

     if(!getFramebuffer(framebuffer))

@@ -1162,7 +1171,12 @@
 

 Texture2D *Context::getTexture2D()

 {

-    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));

+	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));

+}

+

+Texture3D *Context::getTexture3D()

+{

+	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));

 }

 

 TextureCubeMap *Context::getTextureCubeMap()

@@ -1184,6 +1198,7 @@
         switch (type)

         {

         case TEXTURE_2D: return mTexture2DZero.get();

+		case TEXTURE_3D: return mTexture3DZero.get();

         case TEXTURE_CUBE: return mTextureCubeMapZero.get();

         case TEXTURE_EXTERNAL: return mTextureExternalZero.get();

         default: UNREACHABLE();

@@ -1486,7 +1501,18 @@
             *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].id();

         }

         break;

-    default:

+	case GL_TEXTURE_BINDING_3D_OES:

+		{

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

+			{

+				error(GL_INVALID_OPERATION);

+				return false;

+			}

+

+			*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].id();

+	}

+		break;

+	default:

         return false;

     }

 

@@ -1576,6 +1602,7 @@
       case GL_TEXTURE_BINDING_2D:

       case GL_TEXTURE_BINDING_CUBE_MAP:

       case GL_TEXTURE_BINDING_EXTERNAL_OES:

+	  case GL_TEXTURE_BINDING_3D_OES:

         {

             *type = GL_INT;

             *numParams = 1;

@@ -2028,12 +2055,14 @@
             {

                 GLenum wrapS = texture->getWrapS();

                 GLenum wrapT = texture->getWrapT();

+				GLenum wrapR = texture->getWrapR();

                 GLenum texFilter = texture->getMinFilter();

                 GLenum magFilter = texture->getMagFilter();

 				GLfloat maxAnisotropy = texture->getMaxAnisotropy();

 

 				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));

-                device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));

+				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));

+				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));

 

 				sw::FilterType minFilter;

 				sw::MipmapType mipFilter;

@@ -2109,6 +2138,27 @@
 				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);

 			}

 		}

+		else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES)

+		{

+			Texture3D *texture = static_cast<Texture3D*>(baseTexture);

+

+			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)

+			{

+				int surfaceLevel = mipmapLevel;

+

+				if(surfaceLevel < 0)

+				{

+					surfaceLevel = 0;

+				}

+				else if(surfaceLevel >= levelCount)

+				{

+					surfaceLevel = levelCount - 1;

+				}

+

+				egl::Image *surface = texture->getImage(surfaceLevel);

+				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);

+			}

+		}

 		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)

 		{

 			for(int face = 0; face < 6; face++)

diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 42c8c19..5331af3 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -49,6 +49,7 @@
 class Program;

 class Texture;

 class Texture2D;

+class Texture3D;

 class TextureCubeMap;

 class TextureExternal;

 class Framebuffer;

@@ -370,6 +371,7 @@
     void bindTexture2D(GLuint texture);

     void bindTextureCubeMap(GLuint texture);

     void bindTextureExternal(GLuint texture);

+	void bindTexture3D(GLuint texture);

     void bindReadFramebuffer(GLuint framebuffer);

     void bindDrawFramebuffer(GLuint framebuffer);

     void bindRenderbuffer(GLuint renderbuffer);

@@ -397,7 +399,8 @@
     Buffer *getElementArrayBuffer();

     Program *getCurrentProgram();

     Texture2D *getTexture2D();

-    TextureCubeMap *getTextureCubeMap();

+	Texture3D *getTexture3D();

+	TextureCubeMap *getTextureCubeMap();

     TextureExternal *getTextureExternal();

     Texture *getSamplerTexture(unsigned int sampler, TextureType type);

     Framebuffer *getReadFramebuffer();

@@ -460,8 +463,9 @@
 

     State mState;

 

-    gl::BindingPointer<Texture2D> mTexture2DZero;

-    gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero;

+	gl::BindingPointer<Texture2D> mTexture2DZero;

+	gl::BindingPointer<Texture3D> mTexture3DZero;

+	gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero;

     gl::BindingPointer<TextureExternal> mTextureExternalZero;

 

     typedef std::map<GLint, Framebuffer*> FramebufferMap;

diff --git a/src/OpenGL/libGLESv2/Image.cpp b/src/OpenGL/libGLESv2/Image.cpp
index a78694c..6a36db5 100644
--- a/src/OpenGL/libGLESv2/Image.cpp
+++ b/src/OpenGL/libGLESv2/Image.cpp
@@ -22,28 +22,28 @@
 {
 	enum DataType
 	{
-		Alpha,

-		AlphaFloat,

-		AlphaHalfFloat,

-		Luminance,

-		LuminanceFloat,

-		LuminanceHalfFloat,

-		LuminanceAlpha,

-		LuminanceAlphaFloat,

-		LuminanceAlphaHalfFloat,

-		RGBUByte,

-		RGB565,

-		RGBFloat,

-		RGBHalfFloat,

-		RGBAUByte,

-		RGBA4444,

-		RGBA5551,

-		RGBAFloat,

-		RGBAHalfFloat,

-		BGRA,

-		D16,

-		D24,

-		D32,

+		Alpha,
+		AlphaFloat,
+		AlphaHalfFloat,
+		Luminance,
+		LuminanceFloat,
+		LuminanceHalfFloat,
+		LuminanceAlpha,
+		LuminanceAlphaFloat,
+		LuminanceAlphaHalfFloat,
+		RGBUByte,
+		RGB565,
+		RGBFloat,
+		RGBHalfFloat,
+		RGBAUByte,
+		RGBA4444,
+		RGBA5551,
+		RGBAFloat,
+		RGBAHalfFloat,
+		BGRA,
+		D16,
+		D24,
+		D32,
 		S8,
 	};
 
@@ -53,13 +53,13 @@
 		UNIMPLEMENTED();
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<Alpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset, source, width);
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<AlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const float *sourceF = reinterpret_cast<const float*>(source);
@@ -74,7 +74,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<AlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
@@ -89,13 +89,13 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<Luminance>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset, source, width);
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<LuminanceFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const float *sourceF = reinterpret_cast<const float*>(source);
@@ -110,7 +110,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<LuminanceHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
@@ -125,13 +125,13 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<LuminanceAlpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset * 2, source, width * 2);
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<LuminanceAlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const float *sourceF = reinterpret_cast<const float*>(source);
@@ -146,7 +146,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<LuminanceAlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
@@ -161,7 +161,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBUByte>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		unsigned char *destB = dest + xoffset * 4;
@@ -175,7 +175,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGB565>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *source565 = reinterpret_cast<const unsigned short*>(source);
@@ -191,7 +191,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const float *sourceF = reinterpret_cast<const float*>(source);
@@ -206,7 +206,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
@@ -221,7 +221,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBAUByte>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
@@ -234,7 +234,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBA4444>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
@@ -250,7 +250,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBA5551>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source);
@@ -266,25 +266,25 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBAFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset * 16, source, width * 16);
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<RGBAHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset * 8, source, width * 8);
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<BGRA>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset * 4, source, width * 4);
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<D16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
@@ -296,7 +296,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<D24>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source);
@@ -308,7 +308,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<D32>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source);
@@ -320,7 +320,7 @@
 		}
 	}
 
-	template<>
+	template<>

 	void LoadImageRow<S8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
@@ -339,7 +339,7 @@
 		{
 			const unsigned char *inputStart = static_cast<const unsigned char*>(input)+(z * inputPitch * height);
 			unsigned char *destStart = static_cast<unsigned char*>(buffer)+((zoffset + z) * destPitch * destHeight);
-			for(int y = 0; y < height; y++)
+			for(int y = 0; y < height; ++y)
 			{
 				const unsigned char *source = inputStart + y * inputPitch;
 				unsigned char *dest = destStart + (y + yoffset) * destPitch;
@@ -364,7 +364,14 @@
 
 	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
 		: parentTexture(parentTexture)
-		, egl::Image(getParentResource(parentTexture), width, height, format, type, selectInternalFormat(format, type))
+		, egl::Image(getParentResource(parentTexture), width, height, 1, format, type, selectInternalFormat(format, type))
+	{
+		referenceCount = 1;
+	}
+
+	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
+		: parentTexture(parentTexture)
+		, egl::Image(getParentResource(parentTexture), width, height, depth, format, type, selectInternalFormat(format, type))
 	{
 		referenceCount = 1;
 	}
@@ -508,13 +515,11 @@
 		return sw::FORMAT_A8R8G8B8;
 	}
 
-	void Image::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
+	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
 	{
 		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
 		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
-		GLint zoffset = 0;
-		GLsizei depth = 1;
-
+		
 		if(buffer)
 		{
 			switch(type)
@@ -621,7 +626,7 @@
 				LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, getPitch(), getHeight(), input, buffer);
 				break;
 			case GL_UNSIGNED_INT_24_8_OES:
-				loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
+				loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, input, buffer);
 				break;
 			default: UNREACHABLE();
 			}
@@ -630,22 +635,27 @@
 		unlock();
 	}
 
-	void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer)
+	void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, const void *input, void *buffer)
 	{
-		LoadImageData<D24>(xoffset, yoffset, 0, width, height, 1, inputPitch, getPitch(), getHeight(), input, buffer);
+		LoadImageData<D24>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, getPitch(), getHeight(), input, buffer);
 
 		unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, sw::PUBLIC));
 
 		if(stencil)
 		{
-			LoadImageData<S8>(xoffset, yoffset, 0, width, height, 1, inputPitch, getStencilPitchB(), getHeight(), input, stencil);
+			LoadImageData<S8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, getStencilPitchB(), getHeight(), input, stencil);
 
 			unlockStencil();
 		}
 	}
 
-	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
 	{
+		if(zoffset != 0 || depth != 1)
+		{
+			UNIMPLEMENTED(); // FIXME
+		}
+
 		int inputPitch = ComputeCompressedPitch(width, format);
 		int rows = imageSize / inputPitch;
 		void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
diff --git a/src/OpenGL/libGLESv2/Image.hpp b/src/OpenGL/libGLESv2/Image.hpp
index 4c1a1ac..3824a8f 100644
--- a/src/OpenGL/libGLESv2/Image.hpp
+++ b/src/OpenGL/libGLESv2/Image.hpp
@@ -26,10 +26,11 @@
 	{
 	public:
 		Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
+		Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type);
 		Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget);
 
-		void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
-		void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+		void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
+		void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
 
 		virtual void addRef();
 		virtual void release();
@@ -40,7 +41,7 @@
 	private:
 		virtual ~Image();
 
-		void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer);
+		void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, const void *input, void *buffer);
 
 		egl::Texture *parentTexture;
 
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index 3ffb06b..7599be5 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -591,7 +591,8 @@
 		if(targetUniform->type == GL_INT ||

 		   targetUniform->type == GL_SAMPLER_2D ||

 		   targetUniform->type == GL_SAMPLER_CUBE ||

-           targetUniform->type == GL_SAMPLER_EXTERNAL_OES)

+           targetUniform->type == GL_SAMPLER_EXTERNAL_OES ||

+		   targetUniform->type == GL_SAMPLER_3D_OES)

 		{

 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),

 				   v, sizeof(GLint) * count);

@@ -924,7 +925,8 @@
 				  case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, size, f); break;

 				  case GL_SAMPLER_2D:

 				  case GL_SAMPLER_CUBE:

-                  case GL_SAMPLER_EXTERNAL_OES:

+				  case GL_SAMPLER_EXTERNAL_OES:

+				  case GL_SAMPLER_3D_OES:

 				  case GL_INT:        applyUniform1iv(location, size, i);       break;

 				  case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;

 				  case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;

@@ -1315,7 +1317,7 @@
 

 	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex)

 	{

-		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES)

+		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_3D_OES)

 	    {

 			int index = registerIndex;

 			

@@ -1326,7 +1328,17 @@
 					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)

 					{

 						samplersVS[index].active = true;

-						samplersVS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;

+						switch(type) {

+						case GL_SAMPLER_CUBE:

+							samplersVS[index].textureType = TEXTURE_CUBE;

+							break;

+						case GL_SAMPLER_3D_OES:

+							samplersVS[index].textureType = TEXTURE_3D;

+							break;

+						default:

+							samplersVS[index].textureType = TEXTURE_2D;

+							break;

+						}

 						samplersVS[index].logicalTextureUnit = 0;

 					}

 					else

@@ -1340,7 +1352,17 @@
 					if(index < MAX_TEXTURE_IMAGE_UNITS)

 					{

 						samplersPS[index].active = true;

-						samplersPS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;

+						switch(type) {

+						case GL_SAMPLER_CUBE:

+							samplersPS[index].textureType = TEXTURE_CUBE;

+							break;

+						case GL_SAMPLER_3D_OES:

+							samplersPS[index].textureType = TEXTURE_3D;

+							break;

+						default:

+							samplersPS[index].textureType = TEXTURE_2D;

+							break;

+						}

 						samplersPS[index].logicalTextureUnit = 0;

 					}

 					else

@@ -1737,7 +1759,8 @@
 		{

             if(targetUniform->type == GL_SAMPLER_2D ||

                targetUniform->type == GL_SAMPLER_CUBE ||

-               targetUniform->type == GL_SAMPLER_EXTERNAL_OES)

+			   targetUniform->type == GL_SAMPLER_EXTERNAL_OES ||

+			   targetUniform->type == GL_SAMPLER_3D_OES)

 			{

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

 				{

@@ -1760,7 +1783,8 @@
 		{

 			if(targetUniform->type == GL_SAMPLER_2D ||

                targetUniform->type == GL_SAMPLER_CUBE ||

-               targetUniform->type == GL_SAMPLER_EXTERNAL_OES)

+			   targetUniform->type == GL_SAMPLER_EXTERNAL_OES ||

+			   targetUniform->type == GL_SAMPLER_3D_OES)

 			{

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

 				{

diff --git a/src/OpenGL/libGLESv2/Renderbuffer.cpp b/src/OpenGL/libGLESv2/Renderbuffer.cpp
index a88d222..58f5f57 100644
--- a/src/OpenGL/libGLESv2/Renderbuffer.cpp
+++ b/src/OpenGL/libGLESv2/Renderbuffer.cpp
@@ -82,12 +82,12 @@
 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
 {
-    mTexture2D->addProxyRef(proxy);
+	mTexture2D->addProxyRef(proxy);
 }
 
 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
 {
-    mTexture2D->releaseProxy(proxy);
+	mTexture2D->releaseProxy(proxy);
 }
 
 // Increments refcount on image.
@@ -101,12 +101,12 @@
 // caller must release() the returned image
 egl::Image *RenderbufferTexture2D::createSharedImage()
 {
-    return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
+	return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
 }
 
 bool RenderbufferTexture2D::isShared() const
 {
-    return mTexture2D->isShared(GL_TEXTURE_2D, 0);
+	return mTexture2D->isShared(GL_TEXTURE_2D, 0);
 }
 
 GLsizei RenderbufferTexture2D::getWidth() const
@@ -134,6 +134,74 @@
 	return 0;
 }
 
+///// RenderbufferTexture3D Implementation ////////
+
+RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture)
+{
+	mTexture3D.set(texture);
+}
+
+RenderbufferTexture3D::~RenderbufferTexture3D()
+{
+	mTexture3D.set(NULL);
+}
+
+// Textures need to maintain their own reference count for references via
+// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
+void RenderbufferTexture3D::addProxyRef(const Renderbuffer *proxy)
+{
+	mTexture3D->addProxyRef(proxy);
+}
+
+void RenderbufferTexture3D::releaseProxy(const Renderbuffer *proxy)
+{
+	mTexture3D->releaseProxy(proxy);
+}
+
+// Increments refcount on image.
+// caller must release() the returned image
+egl::Image *RenderbufferTexture3D::getRenderTarget()
+{
+	return mTexture3D->getRenderTarget(GL_TEXTURE_3D_OES, 0);
+}
+
+// Increments refcount on image.
+// caller must release() the returned image
+egl::Image *RenderbufferTexture3D::createSharedImage()
+{
+	return mTexture3D->createSharedImage(GL_TEXTURE_3D_OES, 0);
+}
+
+bool RenderbufferTexture3D::isShared() const
+{
+	return mTexture3D->isShared(GL_TEXTURE_3D_OES, 0);
+}
+
+GLsizei RenderbufferTexture3D::getWidth() const
+{
+	return mTexture3D->getWidth(GL_TEXTURE_3D_OES, 0);
+}
+
+GLsizei RenderbufferTexture3D::getHeight() const
+{
+	return mTexture3D->getHeight(GL_TEXTURE_3D_OES, 0);
+}
+
+GLenum RenderbufferTexture3D::getFormat() const
+{
+	return mTexture3D->getFormat(GL_TEXTURE_3D_OES, 0);
+}
+
+sw::Format RenderbufferTexture3D::getInternalFormat() const
+{
+	return mTexture3D->getInternalFormat(GL_TEXTURE_3D_OES, 0);
+}
+
+GLsizei RenderbufferTexture3D::getSamples() const
+{
+	return 0;
+}
+
 ///// RenderbufferTextureCubeMap Implementation ////////
 
 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
@@ -361,7 +429,7 @@
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
 		format = sw2es::ConvertBackBufferFormat(internalFormat);
-		mSamples = renderTarget->getMultiSampleDepth() & ~1;
+		mSamples = renderTarget->getDepth() & ~1;
 	}
 }
 
@@ -438,7 +506,7 @@
 		mHeight = depthStencil->getHeight();
 		internalFormat = depthStencil->getInternalFormat();
 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
-		mSamples = depthStencil->getMultiSampleDepth() & ~1;
+		mSamples = depthStencil->getDepth() & ~1;
 	}
 }
 
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.h b/src/OpenGL/libGLESv2/Renderbuffer.h
index b8e9d0d..bd322e7 100644
--- a/src/OpenGL/libGLESv2/Renderbuffer.h
+++ b/src/OpenGL/libGLESv2/Renderbuffer.h
@@ -26,6 +26,7 @@
 namespace es2

 {

 class Texture2D;

+class Texture3D;

 class TextureCubeMap;

 class Renderbuffer;

 class Colorbuffer;

@@ -83,6 +84,30 @@
 	gl::BindingPointer<Texture2D> mTexture2D;

 };

 

+class RenderbufferTexture3D : public RenderbufferInterface

+{

+public:

+	RenderbufferTexture3D(Texture3D *texture);

+

+	virtual ~RenderbufferTexture3D();

+

+	virtual void addProxyRef(const Renderbuffer *proxy);

+	virtual void releaseProxy(const Renderbuffer *proxy);

+

+	virtual egl::Image *getRenderTarget();

+	virtual egl::Image *createSharedImage();

+	virtual bool isShared() const;

+

+	virtual GLsizei getWidth() const;

+	virtual GLsizei getHeight() const;

+	virtual GLenum getFormat() const;

+	virtual sw::Format getInternalFormat() const;

+	virtual GLsizei getSamples() const;

+

+private:

+	gl::BindingPointer<Texture3D> mTexture3D;

+};

+

 class RenderbufferTextureCubeMap : public RenderbufferInterface

 {

 public:

diff --git a/src/OpenGL/libGLESv2/ResourceManager.cpp b/src/OpenGL/libGLESv2/ResourceManager.cpp
index e3be9bc..2f6fd74 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.cpp
+++ b/src/OpenGL/libGLESv2/ResourceManager.cpp
@@ -307,11 +307,15 @@
         {
             textureObject = new TextureCubeMap(texture);
         }
-        else if(type == TEXTURE_EXTERNAL)
-        {
-            textureObject = new TextureExternal(texture);
-        }
-        else
+		else if(type == TEXTURE_EXTERNAL)
+		{
+			textureObject = new TextureExternal(texture);
+		}
+		else if(type == TEXTURE_3D)
+		{
+			textureObject = new Texture3D(texture);
+		}
+		else
         {
             UNREACHABLE();
             return;
diff --git a/src/OpenGL/libGLESv2/ResourceManager.h b/src/OpenGL/libGLESv2/ResourceManager.h
index 699944f..d7d626d 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.h
+++ b/src/OpenGL/libGLESv2/ResourceManager.h
@@ -33,6 +33,7 @@
 enum TextureType

 {

     TEXTURE_2D,

+	TEXTURE_3D,

     TEXTURE_CUBE,

     TEXTURE_EXTERNAL,

 

diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index 4964bce..982c7c8 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -10,7 +10,7 @@
 //

 

 // Texture.cpp: Implements the Texture class and its derived classes

-// Texture2D and TextureCubeMap. Implements GL texture objects and related

+// Texture2D, TextureCubeMap and Texture3D. Implements GL texture objects and related

 // functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

 

 #include "Texture.h"

@@ -34,6 +34,7 @@
     mMagFilter = GL_LINEAR;

     mWrapS = GL_REPEAT;

     mWrapT = GL_REPEAT;

+	mWrapR = GL_REPEAT;

 	mMaxAnisotropy = 1.0f;

 

 	resource = new sw::Resource(0);

@@ -109,21 +110,41 @@
 // Returns true on successful wrap state update (valid enum parameter)

 bool Texture::setWrapT(GLenum wrap)

 {

-    switch(wrap)

-    {

-    case GL_REPEAT:

-    case GL_MIRRORED_REPEAT:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_CLAMP_TO_EDGE:

-         mWrapT = wrap;

-         return true;

-    default:

-        return false;

-    }

+	switch(wrap)

+	{

+	case GL_REPEAT:

+	case GL_MIRRORED_REPEAT:

+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

+		{

+			return false;

+		}

+		// Fall through

+	case GL_CLAMP_TO_EDGE:

+		mWrapT = wrap;

+		return true;

+	default:

+		return false;

+	}

+}

+

+// Returns true on successful wrap state update (valid enum parameter)

+bool Texture::setWrapR(GLenum wrap)

+{

+	switch(wrap)

+	{

+	case GL_REPEAT:

+	case GL_MIRRORED_REPEAT:

+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

+		{

+			return false;

+		}

+		// Fall through

+	case GL_CLAMP_TO_EDGE:

+		mWrapR = wrap;

+		return true;

+	default:

+		return false;

+	}

 }

 

 // Returns true on successful max anisotropy update (valid anisotropy value)

@@ -161,7 +182,12 @@
 

 GLenum Texture::getWrapT() const

 {

-    return mWrapT;

+	return mWrapT;

+}

+

+GLenum Texture::getWrapR() const

+{

+	return mWrapR;

 }

 

 GLfloat Texture::getMaxAnisotropy() const

@@ -169,6 +195,11 @@
     return mMaxAnisotropy;

 }

 

+GLsizei Texture::getDepth(GLenum target, GLint level) const

+{

+	return 1;

+}

+

 egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)

 {

     egl::Image *image = getRenderTarget(target, level);   // Increments reference count

@@ -185,7 +216,8 @@
 {

     if(pixels && image)

     {

-		image->loadImageData(0, 0, image->getWidth(), image->getHeight(), format, type, unpackAlignment, pixels);

+		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES) ? image->getDepth() : 1;

+		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), depth, format, type, unpackAlignment, pixels);

     }

 }

 

@@ -193,18 +225,19 @@
 {

     if(pixels && image)

     {

-		image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), imageSize, pixels);

+		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES) ? image->getDepth() : 1;

+		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), depth, imageSize, pixels);

     }

 }

 

-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)

+void Texture::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)

 {

 	if(!image)

 	{

 		return error(GL_INVALID_OPERATION);

 	}

 

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())

     {

         return error(GL_INVALID_VALUE);

     }

@@ -221,18 +254,18 @@
 

     if(pixels)

     {

-        image->loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels);

+        image->loadImageData(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackAlignment, pixels);

     }

 }

 

-void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)

+void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)

 {

 	if(!image)

 	{

 		return error(GL_INVALID_OPERATION);

 	}

 

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

+    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())

     {

         return error(GL_INVALID_VALUE);

     }

@@ -244,7 +277,7 @@
 

     if(pixels)

     {

-		image->loadCompressedData(xoffset, yoffset, width, height, imageSize, pixels);

+		image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels);

     }

 }

 

@@ -467,12 +500,12 @@
 

 void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

 {

-	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);

+	Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackAlignment, pixels, image[level]);

 }

 

 void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

 {

-    Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);

+    Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[level]);

 }

 

 void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

@@ -508,7 +541,7 @@
 	renderTarget->release();

 }

 

-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

 {

 	if(!image[level])

 	{

@@ -847,12 +880,12 @@
 

 void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

 {

-    Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[CubeFaceIndex(target)][level]);

+    Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackAlignment, pixels, image[CubeFaceIndex(target)][level]);

 }

 

 void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

 {

-    Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);

+    Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);

 }

 

 // Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.

@@ -1031,7 +1064,7 @@
     return image[CubeFaceIndex(face)][level];

 }

 

-void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

+void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

 {

 	int face = CubeFaceIndex(target);

 

@@ -1140,12 +1173,402 @@
     return image[face][level]->isShared();

 }

 

+Texture3D::Texture3D(GLuint id) : Texture(id)

+{

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

+	{

+		image[i] = 0;

+	}

+

+	mSurface = NULL;

+

+	mColorbufferProxy = NULL;

+	mProxyRefs = 0;

+}

+

+Texture3D::~Texture3D()

+{

+	resource->lock(sw::DESTRUCT);

+

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

+	{

+		if(image[i])

+		{

+			image[i]->unbind(this);

+			image[i] = 0;

+		}

+	}

+

+	resource->unlock();

+

+	if(mSurface)

+	{

+		mSurface->setBoundTexture(NULL);

+		mSurface = NULL;

+	}

+

+	mColorbufferProxy = NULL;

+}

+

+// We need to maintain a count of references to renderbuffers acting as 

+// proxies for this texture, so that we do not attempt to use a pointer 

+// to a renderbuffer proxy which has been deleted.

+void Texture3D::addProxyRef(const Renderbuffer *proxy)

+{

+	mProxyRefs++;

+}

+

+void Texture3D::releaseProxy(const Renderbuffer *proxy)

+{

+	if(mProxyRefs > 0)

+	{

+		mProxyRefs--;

+	}

+

+	if(mProxyRefs == 0)

+	{

+		mColorbufferProxy = NULL;

+	}

+}

+

+GLenum Texture3D::getTarget() const

+{

+	return GL_TEXTURE_3D_OES;

+}

+

+GLsizei Texture3D::getWidth(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	return image[level] ? image[level]->getWidth() : 0;

+}

+

+GLsizei Texture3D::getHeight(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	return image[level] ? image[level]->getHeight() : 0;

+}

+

+GLsizei Texture3D::getDepth(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	return image[level] ? image[level]->getDepth() : 0;

+}

+

+GLenum Texture3D::getFormat(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	return image[level] ? image[level]->getFormat() : 0;

+}

+

+GLenum Texture3D::getType(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	return image[level] ? image[level]->getType() : 0;

+}

+

+sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;

+}

+

+int Texture3D::getLevelCount() const

+{

+	ASSERT(isSamplerComplete());

+	int levels = 0;

+

+	while(levels < MIPMAP_LEVELS && image[levels])

+	{

+		levels++;

+	}

+

+	return levels;

+}

+

+void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

+{

+	if(image[level])

+	{

+		image[level]->unbind(this);

+	}

+

+	image[level] = new Image(this, width, height, depth, format, type);

+

+	if(!image[level])

+	{

+		return error(GL_OUT_OF_MEMORY);

+	}

+

+	Texture::setImage(format, type, unpackAlignment, pixels, image[level]);

+}

+

+void Texture3D::bindTexImage(egl::Surface *surface)

+{

+	GLenum format;

+

+	switch(surface->getInternalFormat())

+	{

+	case sw::FORMAT_A8R8G8B8:

+		format = GL_RGBA;

+		break;

+	case sw::FORMAT_X8R8G8B8:

+		format = GL_RGB;

+		break;

+	default:

+		UNIMPLEMENTED();

+		return;

+	}

+

+	for(int level = 0; level < MIPMAP_LEVELS; level++)

+	{

+		if(image[level])

+		{

+			image[level]->unbind(this);

+			image[level] = 0;

+		}

+	}

+

+	image[0] = surface->getRenderTarget();

+

+	mSurface = surface;

+	mSurface->setBoundTexture(this);

+}

+

+void Texture3D::releaseTexImage()

+{

+	for(int level = 0; level < MIPMAP_LEVELS; level++)

+	{

+		if(image[level])

+		{

+			image[level]->unbind(this);

+			image[level] = 0;

+		}

+	}

+}

+

+void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)

+{

+	if(image[level])

+	{

+		image[level]->unbind(this);

+	}

+

+	image[level] = new Image(this, width, height, depth, format, GL_UNSIGNED_BYTE);

+

+	if(!image[level])

+	{

+		return error(GL_OUT_OF_MEMORY);

+	}

+

+	Texture::setCompressedImage(imageSize, pixels, image[level]);

+}

+

+void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

+{

+	Texture::subImage(xoffset, yoffset, zoffset, width, height, format, depth, type, unpackAlignment, pixels, image[level]);

+}

+

+void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)

+{

+	Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, image[level]);

+}

+

+void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source)

+{

+	UNIMPLEMENTED();

+}

+

+void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

+{

+	if(zoffset != 0)

+	{

+		UNIMPLEMENTED(); // FIXME: add support for copying into a layer other than layer 0

+	}

+

+	if(!image[level])

+	{

+		return error(GL_INVALID_OPERATION);

+	}

+

+	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	egl::Image *renderTarget = source->getRenderTarget();

+

+	if(!renderTarget)

+	{

+		ERR("Failed to retrieve the render target.");

+		return error(GL_OUT_OF_MEMORY);

+	}

+

+	sw::Rect sourceRect = { x, y, x + width, y + height };

+	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

+

+	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);

+

+	renderTarget->release();

+}

+

+void Texture3D::setImage(egl::Image *sharedImage)

+{

+	sharedImage->addRef();

+

+	if(image[0])

+	{

+		image[0]->unbind(this);

+	}

+

+	image[0] = sharedImage;

+}

+

+// Tests for 3D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.

+bool Texture3D::isSamplerComplete() const

+{

+	if(!image[0])

+	{

+		return false;

+	}

+

+	GLsizei width = image[0]->getWidth();

+	GLsizei height = image[0]->getHeight();

+	GLsizei depth = image[0]->getDepth();

+

+	if(width <= 0 || height <= 0 || depth <= 0)

+	{

+		return false;

+	}

+

+	if(isMipmapFiltered())

+	{

+		if(!isMipmapComplete())

+		{

+			return false;

+		}

+	}

+

+	return true;

+}

+

+// Tests for 3D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.

+bool Texture3D::isMipmapComplete() const

+{

+	GLsizei width = image[0]->getWidth();

+	GLsizei height = image[0]->getHeight();

+	GLsizei depth = image[0]->getDepth();

+

+	int q = log2(std::max(std::max(width, height), depth));

+

+	for(int level = 1; level <= q; level++)

+	{

+		if(!image[level])

+		{

+			return false;

+		}

+

+		if(image[level]->getFormat() != image[0]->getFormat())

+		{

+			return false;

+		}

+

+		if(image[level]->getType() != image[0]->getType())

+		{

+			return false;

+		}

+

+		if(image[level]->getWidth() != std::max(1, width >> level))

+		{

+			return false;

+		}

+

+		if(image[level]->getHeight() != std::max(1, height >> level))

+		{

+			return false;

+		}

+

+		if(image[level]->getDepth() != std::max(1, depth >> level))

+		{

+			return false;

+		}

+	}

+

+	return true;

+}

+

+bool Texture3D::isCompressed(GLenum target, GLint level) const

+{

+	return IsCompressed(getFormat(target, level));

+}

+

+bool Texture3D::isDepth(GLenum target, GLint level) const

+{

+	return IsDepthTexture(getFormat(target, level));

+}

+

+void Texture3D::generateMipmaps()

+{

+	UNIMPLEMENTED();

+}

+

+egl::Image *Texture3D::getImage(unsigned int level)

+{

+	return image[level];

+}

+

+Renderbuffer *Texture3D::getRenderbuffer(GLenum target)

+{

+	if(target != GL_TEXTURE_3D_OES)

+	{

+		return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);

+	}

+

+	if(mColorbufferProxy == NULL)

+	{

+		mColorbufferProxy = new Renderbuffer(id(), new RenderbufferTexture3D(this));

+	}

+

+	return mColorbufferProxy;

+}

+

+egl::Image *Texture3D::getRenderTarget(GLenum target, unsigned int level)

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

+

+	if(image[level])

+	{

+		image[level]->addRef();

+	}

+

+	return image[level];

+}

+

+bool Texture3D::isShared(GLenum target, unsigned int level) const

+{

+	ASSERT(target == GL_TEXTURE_3D_OES);

+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

+

+	if(mSurface)   // Bound to an EGLSurface

+	{

+		return true;

+	}

+

+	if(!image[level])

+	{

+		return false;

+	}

+

+	return image[level]->isShared();

+}

+

 TextureExternal::TextureExternal(GLuint id) : Texture2D(id)

 {

     mMinFilter = GL_LINEAR;

     mMagFilter = GL_LINEAR;

     mWrapS = GL_CLAMP_TO_EDGE;

-    mWrapT = GL_CLAMP_TO_EDGE;

+	mWrapT = GL_CLAMP_TO_EDGE;

+	mWrapR = GL_CLAMP_TO_EDGE;

 }

 

 TextureExternal::~TextureExternal()

diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index 100cf01..ae0ec86 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -63,17 +63,20 @@
     bool setMinFilter(GLenum filter);

     bool setMagFilter(GLenum filter);

     bool setWrapS(GLenum wrap);

-    bool setWrapT(GLenum wrap);

+	bool setWrapT(GLenum wrap);

+	bool setWrapR(GLenum wrap);

 	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);

 

     GLenum getMinFilter() const;

     GLenum getMagFilter() const;

     GLenum getWrapS() const;

-    GLenum getWrapT() const;

+	GLenum getWrapT() const;

+	GLenum getWrapR() const;

 	GLfloat getMaxAnisotropy() const;

 

     virtual GLsizei getWidth(GLenum target, GLint level) const = 0;

-    virtual GLsizei getHeight(GLenum target, GLint level) const = 0;

+	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;

+	virtual GLsizei getDepth(GLenum target, GLint level) const;

     virtual GLenum getFormat(GLenum target, GLint level) const = 0;

     virtual GLenum getType(GLenum target, GLint level) const = 0;

     virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;

@@ -89,13 +92,13 @@
     virtual bool isShared(GLenum target, unsigned int level) const = 0;

 

     virtual void generateMipmaps() = 0;

-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

 

 protected:

     void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

-    void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

+    void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

     void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);

-    void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);

+    void subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);

 

 	bool copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest);

 

@@ -105,6 +108,7 @@
     GLenum mMagFilter;

     GLenum mWrapS;

     GLenum mWrapT;

+    GLenum mWrapR;

 	GLfloat mMaxAnisotropy;

 

 	sw::Resource *resource;

@@ -134,7 +138,7 @@
     void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

     void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

+	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

 

 	void setImage(egl::Image *image);

 

@@ -193,7 +197,7 @@
     void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

     void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

     void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

 

     virtual bool isSamplerComplete() const;

     virtual bool isCompressed(GLenum target, GLint level) const;

@@ -226,6 +230,65 @@
 	unsigned int mFaceProxyRefs[6];

 };

 

+class Texture3D : public Texture

+{

+public:

+	explicit Texture3D(GLuint id);

+

+	virtual ~Texture3D();

+

+	void addProxyRef(const Renderbuffer *proxy);

+	void releaseProxy(const Renderbuffer *proxy);

+

+	virtual GLenum getTarget() const;

+

+	virtual GLsizei getWidth(GLenum target, GLint level) const;

+	virtual GLsizei getHeight(GLenum target, GLint level) const;

+	virtual GLsizei getDepth(GLenum target, GLint level) const;

+	virtual GLenum getFormat(GLenum target, GLint level) const;

+	virtual GLenum getType(GLenum target, GLint level) const;

+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

+	virtual int getLevelCount() const;

+

+	void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

+	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);

+	void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

+	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);

+	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source);

+	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

+

+	void setImage(egl::Image *image);

+

+	virtual bool isSamplerComplete() const;

+	virtual bool isCompressed(GLenum target, GLint level) const;

+	virtual bool isDepth(GLenum target, GLint level) const;

+	virtual void bindTexImage(egl::Surface *surface);

+	virtual void releaseTexImage();

+

+	virtual void generateMipmaps();

+

+	virtual Renderbuffer *getRenderbuffer(GLenum target);

+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);

+	virtual bool isShared(GLenum target, unsigned int level) const;

+

+	egl::Image *getImage(unsigned int level);

+

+protected:

+	bool isMipmapComplete() const;

+

+	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

+

+	egl::Surface *mSurface;

+

+	// A specific internal reference count is kept for colorbuffer proxy references,

+	// because, as the renderbuffer acting as proxy will maintain a binding pointer

+	// back to this texture, there would be a circular reference if we used a binding

+	// pointer here. This reference count will cause the pointer to be set to NULL if

+	// the count drops to zero, but will not cause deletion of the Renderbuffer.

+	Renderbuffer *mColorbufferProxy;

+	unsigned int mProxyRefs;

+};

+

 class TextureExternal : public Texture2D

 {

 public:

diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 7f289dc..f354579 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -33,6 +33,15 @@
 #include <exception>

 #include <limits>

 

+typedef std::pair<GLenum, GLenum> InternalFormatTypePair;

+typedef std::map<InternalFormatTypePair, GLenum> FormatMap;

+

+// A helper function to insert data into the format map with fewer characters.

+static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)

+{

+	map[InternalFormatTypePair(internalformat, type)] = format;

+}

+

 static bool validImageSize(GLint level, GLsizei width, GLsizei height)

 {

 	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)

@@ -63,14 +72,14 @@
 	if(compressed)

 	{

 		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-		   (height % 4 != 0 && height != texture->getHeight(target, 0)))

+			(height % 4 != 0 && height != texture->getHeight(target, 0)))

 		{

 			return error(GL_INVALID_OPERATION, false);

 		}

 	}

 

 	if(xoffset + width > texture->getWidth(target, level) ||

-	   yoffset + height > texture->getHeight(target, level))

+		yoffset + height > texture->getHeight(target, level))

 	{

 		return error(GL_INVALID_VALUE, false);

 	}

@@ -78,6 +87,200 @@
 	return true;

 }

 

+static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)

+{

+	if(!texture)

+	{

+		return error(GL_INVALID_OPERATION, false);

+	}

+

+	if(compressed != texture->isCompressed(target, level))

+	{

+		return error(GL_INVALID_OPERATION, false);

+	}

+

+	if(format != GL_NONE && format != texture->getFormat(target, level))

+	{

+		return error(GL_INVALID_OPERATION, false);

+	}

+

+	if(compressed)

+	{

+		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

+		   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||

+		   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))

+		{

+			return error(GL_INVALID_OPERATION, false);

+		}

+	}

+

+	if(xoffset + width > texture->getWidth(target, level) ||

+	   yoffset + height > texture->getHeight(target, level) ||

+	   zoffset + depth > texture->getDepth(target, level))

+	{

+		return error(GL_INVALID_VALUE, false);

+	}

+

+	return true;

+}

+

+static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)

+{

+	// [OpenGL ES 2.0.24] table 3.9

+	switch(textureFormat)

+	{

+	case GL_ALPHA:

+		if(colorbufferFormat != GL_ALPHA &&

+			colorbufferFormat != GL_RGBA &&

+			colorbufferFormat != GL_RGBA4 &&

+			colorbufferFormat != GL_RGB5_A1 &&

+			colorbufferFormat != GL_RGBA8_OES)

+		{

+			return error(GL_INVALID_OPERATION, false);

+		}

+		break;

+	case GL_LUMINANCE:

+	case GL_RGB:

+		if(colorbufferFormat != GL_RGB &&

+			colorbufferFormat != GL_RGB565 &&

+			colorbufferFormat != GL_RGB8_OES &&

+			colorbufferFormat != GL_RGBA &&

+			colorbufferFormat != GL_RGBA4 &&

+			colorbufferFormat != GL_RGB5_A1 &&

+			colorbufferFormat != GL_RGBA8_OES)

+		{

+			return error(GL_INVALID_OPERATION, false);

+		}

+		break;

+	case GL_LUMINANCE_ALPHA:

+	case GL_RGBA:

+		if(colorbufferFormat != GL_RGBA &&

+			colorbufferFormat != GL_RGBA4 &&

+			colorbufferFormat != GL_RGB5_A1 &&

+			colorbufferFormat != GL_RGBA8_OES)

+		{

+			return error(GL_INVALID_OPERATION, false);

+		}

+		break;

+	case GL_ETC1_RGB8_OES:

+		return error(GL_INVALID_OPERATION, false);

+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

+	case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

+	case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

+		if(S3TC_SUPPORT)

+		{

+			return error(GL_INVALID_OPERATION, false);

+		}

+		else

+		{

+			return error(GL_INVALID_ENUM, false);

+		}

+	case GL_DEPTH_COMPONENT:

+	case GL_DEPTH_STENCIL_OES:

+		return error(GL_INVALID_OPERATION, false);

+	default:

+		return error(GL_INVALID_ENUM, false);

+	}

+	return true;

+}

+

+static FormatMap BuildFormatMap3D()

+{

+	FormatMap map;

+

+	//                       Internal format | Format | Type

+	InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);

+	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);

+	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);

+	InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_R8_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);

+	InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);

+	InsertFormatMapping(map, GL_R32F_EXT, GL_RED_EXT, GL_FLOAT);

+	InsertFormatMapping(map, GL_RG8_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);

+	InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);

+	InsertFormatMapping(map, GL_RG32F_EXT, GL_RG_EXT, GL_FLOAT);

+	InsertFormatMapping(map, GL_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_SRGB8_NV, GL_RGB, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);

+	InsertFormatMapping(map, GL_RGB16F_EXT, GL_HALF_FLOAT_OES, GL_FLOAT);

+	InsertFormatMapping(map, GL_RGB32F_EXT, GL_RGB, GL_FLOAT);

+	InsertFormatMapping(map, GL_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);

+	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);

+	InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);

+	InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);

+	InsertFormatMapping(map, GL_RGB10_A2_EXT, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);

+	InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);

+	InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_FLOAT);

+	InsertFormatMapping(map, GL_RGBA32F_EXT, GL_RGBA, GL_FLOAT);

+

+	return map;

+}

+

+static bool ValidateType3D(GLenum type)

+{

+	switch(type)

+	{

+	case GL_UNSIGNED_BYTE:

+	case GL_BYTE:

+	case GL_UNSIGNED_SHORT:

+	case GL_SHORT:

+	case GL_UNSIGNED_INT:

+	case GL_INT:

+	case GL_HALF_FLOAT_OES:

+	case GL_FLOAT:

+	case GL_UNSIGNED_SHORT_5_6_5:

+	case GL_UNSIGNED_SHORT_4_4_4_4:

+	case GL_UNSIGNED_SHORT_5_5_5_1:

+	case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:

+		return true;

+	default:

+		break;

+	}

+	return false;

+}

+

+static bool ValidateFormat3D(GLenum format)

+{

+	switch(format)

+	{

+	case GL_RED_EXT:

+	case GL_RG_EXT:

+	case GL_RGB:

+	case GL_RGBA:

+	case GL_DEPTH_COMPONENT:

+	case GL_DEPTH_STENCIL_OES:

+	case GL_LUMINANCE_ALPHA:

+	case GL_LUMINANCE:

+	case GL_ALPHA:

+		return true;

+	default:

+		break;

+	}

+	return false;

+}

+

+static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)

+{

+	static const FormatMap formatMap = BuildFormatMap3D();

+	FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));

+	if(iter != formatMap.end())

+	{

+		return iter->second == format;

+	}

+	return false;

+}

+

 extern "C"

 {

 

@@ -301,6 +504,9 @@
 		case GL_TEXTURE_EXTERNAL_OES:

 			context->bindTextureExternal(texture);

 			return;

+		case GL_TEXTURE_3D_OES:

+			context->bindTexture3D(texture);

+			return;

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -730,7 +936,7 @@
 

 	if(context)

 	{

-		if(level > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

+		if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

 		{

 			return error(GL_INVALID_VALUE);

 		}

@@ -850,7 +1056,7 @@
 

 	if(context)

 	{

-		if(level > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

+		if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

 		{

 			return error(GL_INVALID_VALUE);

 		}

@@ -956,58 +1162,9 @@
 		es2::Renderbuffer *source = framebuffer->getColorbuffer();

 		GLenum colorbufferFormat = source->getFormat();

 

-		// [OpenGL ES 2.0.24] table 3.9

-		switch(internalformat)

+		if(!validateColorBufferFormat(internalformat, colorbufferFormat))

 		{

-		case GL_ALPHA:

-			if(colorbufferFormat != GL_ALPHA &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE:

-		case GL_RGB:

-			if(colorbufferFormat != GL_RGB &&

-			   colorbufferFormat != GL_RGB565 &&

-			   colorbufferFormat != GL_RGB8_OES &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE_ALPHA:

-		case GL_RGBA:

-			if(colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_ETC1_RGB8_OES:

-			return error(GL_INVALID_OPERATION);

-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

-		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

-			if(S3TC_SUPPORT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-		default:

-			return error(GL_INVALID_ENUM);

+			return;

 		}

 

 		if(target == GL_TEXTURE_2D)

@@ -1066,7 +1223,7 @@
 

 	if(context)

 	{

-		if(level > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

+		if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

 		{

 			return error(GL_INVALID_VALUE);

 		}

@@ -1104,64 +1261,12 @@
 

 		GLenum textureFormat = texture->getFormat(target, level);

 

-		// [OpenGL ES 2.0.24] table 3.9

-		switch(textureFormat)

+		if(!validateColorBufferFormat(textureFormat, colorbufferFormat))

 		{

-		case GL_ALPHA:

-			if(colorbufferFormat != GL_ALPHA &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE:

-		case GL_RGB:

-			if(colorbufferFormat != GL_RGB &&

-			   colorbufferFormat != GL_RGB565 &&

-			   colorbufferFormat != GL_RGB8_OES &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE_ALPHA:

-		case GL_RGBA:

-			if(colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_ETC1_RGB8_OES:

-			return error(GL_INVALID_OPERATION);

-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

-		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

-			if(S3TC_SUPPORT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-		case GL_DEPTH_COMPONENT:

-		case GL_DEPTH_STENCIL_OES:

-			return error(GL_INVALID_OPERATION);

-		default:

-			return error(GL_INVALID_ENUM);

+			return;

 		}

 

-		texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);

+		texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);

 	}

 }

 

@@ -2861,6 +2966,7 @@
 			"GL_OES_texture_half_float "

 			"GL_OES_texture_half_float_linear "

 			"GL_OES_texture_npot "

+			"GL_OES_texture_3D "

 			"GL_EXT_blend_minmax "

 			"GL_EXT_occlusion_query_boolean "

 			"GL_EXT_read_format_bgra "

@@ -2920,6 +3026,9 @@
 		case GL_TEXTURE_WRAP_T:

 			*params = (GLfloat)texture->getWrapT();

 			break;

+		case GL_TEXTURE_WRAP_R_OES:

+			*params = (GLfloat)texture->getWrapR();

+			break;

 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

 			*params = texture->getMaxAnisotropy();

 			break;

@@ -2971,6 +3080,9 @@
 		case GL_TEXTURE_WRAP_T:

 			*params = texture->getWrapT();

 			break;

+		case GL_TEXTURE_WRAP_R_OES:

+			*params = texture->getWrapR();

+			break;

 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

 			*params = (GLint)texture->getMaxAnisotropy();

 			break;

@@ -4144,6 +4256,9 @@
 		case GL_TEXTURE_2D:

 			texture = context->getTexture2D();

 			break;

+		case GL_TEXTURE_3D_OES:

+			texture = context->getTexture3D();

+			break;

 		case GL_TEXTURE_CUBE_MAP:

 			texture = context->getTextureCubeMap();

 			break;

@@ -4168,6 +4283,12 @@
 				return error(GL_INVALID_ENUM);

 			}

 			break;

+		case GL_TEXTURE_WRAP_R_OES:

+			if(!texture->setWrapR((GLenum)param))

+			{

+				return error(GL_INVALID_ENUM);

+			}

+			break;

 		case GL_TEXTURE_MIN_FILTER:

 			if(!texture->setMinFilter((GLenum)param))

 			{

@@ -4212,6 +4333,9 @@
 		case GL_TEXTURE_2D:

 			texture = context->getTexture2D();

 			break;

+		case GL_TEXTURE_3D_OES:

+			texture = context->getTexture3D();

+			break;

 		case GL_TEXTURE_CUBE_MAP:

 			texture = context->getTextureCubeMap();

 			break;

@@ -4236,6 +4360,12 @@
 				return error(GL_INVALID_ENUM);

 			}

 			break;

+		case GL_TEXTURE_WRAP_R_OES:

+			if(!texture->setWrapR((GLenum)param))

+			{

+				return error(GL_INVALID_ENUM);

+			}

+			break;

 		case GL_TEXTURE_MIN_FILTER:

 			if(!texture->setMinFilter((GLenum)param))

 			{

@@ -4302,7 +4432,7 @@
 

 	if(context)

 	{

-		if(level > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

+		if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

 		{

 			return error(GL_INVALID_VALUE);

 		}

@@ -5047,9 +5177,373 @@
 	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",

 	      target, level, internalformat, width, height, depth, border, format, type, pixels);

 

-	UNIMPLEMENTED();   // FIXME

+	switch(target)

+	{

+	case GL_TEXTURE_3D_OES:

+		switch(format)

+		{

+		case GL_DEPTH_COMPONENT:

+		case GL_DEPTH_STENCIL_OES:

+			return error(GL_INVALID_OPERATION);

+		default:

+			break;

+		}

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

+	if(!ValidateType3D(type) || !ValidateFormat3D(format))

+	{

+		return error(GL_INVALID_ENUM);

+	}

+

+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;

+	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	if(border != 0)

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	if(!ValidateInternalFormat3D(internalformat, format, type))

+	{

+		return error(GL_INVALID_OPERATION);

+	}

+

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

+

+	if(context)

+	{

+		es2::Texture3D *texture = context->getTexture3D();

+

+		if(!texture)

+		{

+			return error(GL_INVALID_OPERATION);

+		}

+

+		texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackAlignment(), pixels);

+	}

 }

 

+void GL_APIENTRY glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

+		"GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "

+		"GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",

+		target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+
+	switch(target)

+	{

+	case GL_TEXTURE_3D_OES:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

+	if(!ValidateType3D(type) || !ValidateFormat3D(format))

+	{

+		return error(GL_INVALID_ENUM);

+	}

+

+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	if((width < 0) || (height < 0) || (depth < 0))

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

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

+

+	if(context)

+	{

+		es2::Texture3D *texture = context->getTexture3D();

+

+		if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))

+		{

+			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackAlignment(), pixels);

+		}

+	}
+}
+
+void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

+		"GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",

+		target, level, xoffset, yoffset, zoffset, x, y, width, height);
+
+	switch(target)

+	{

+	case GL_TEXTURE_3D_OES:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

+	{

+		return error(GL_INVALID_VALUE);

+	}
+
+	es2::Context *context = es2::getContext();

+

+	if(context)

+	{

+		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

+

+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

+		{

+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);

+		}

+

+		if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)

+		{

+			return error(GL_INVALID_OPERATION);

+		}

+

+		es2::Renderbuffer *source = framebuffer->getColorbuffer();

+		GLenum colorbufferFormat = source->getFormat();

+		es2::Texture3D *texture = context->getTexture3D();

+

+		if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))

+		{

+			return;

+		}

+

+		GLenum textureFormat = texture->getFormat(target, level);

+

+		if(!validateColorBufferFormat(textureFormat, colorbufferFormat))

+		{

+			return;

+		}

+		

+		texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);

+	}
+}
+
+void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "

+		"GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",

+		target, level, internalformat, width, height, depth, border, imageSize, data);

+

+	switch(target)

+	{

+	case GL_TEXTURE_3D_OES:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}
+

+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;

+	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	switch(internalformat)

+	{

+	case GL_ETC1_RGB8_OES:

+		break;

+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

+	case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

+	case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

+		if(!S3TC_SUPPORT)

+		{

+			return error(GL_INVALID_ENUM);

+		}

+		break;

+	case GL_DEPTH_COMPONENT:

+	case GL_DEPTH_COMPONENT16:

+	case GL_DEPTH_COMPONENT32_OES:

+	case GL_DEPTH_STENCIL_OES:

+	case GL_DEPTH24_STENCIL8_OES:

+		return error(GL_INVALID_OPERATION);

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

+	if(imageSize != es2::ComputeCompressedSize(width, height, internalformat) * depth)

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

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

+

+	if(context)

+	{

+		es2::Texture3D *texture = context->getTexture3D();

+

+		if(!texture)

+		{

+			return error(GL_INVALID_OPERATION);

+		}

+

+		texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);

+	}
+}
+
+void GL_APIENTRY glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

+		"GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "

+		"GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = 0x%0.8p)",

+		target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+
+	switch(target)

+	{

+	case GL_TEXTURE_3D_OES:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}
+

+	if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)

+	{

+		return error(GL_INVALID_VALUE);

+	}

+

+	switch(format)

+	{

+	case GL_ETC1_RGB8_OES:

+		break;

+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

+	case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

+	case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

+		if(!S3TC_SUPPORT)

+		{

+			return error(GL_INVALID_ENUM);

+		}

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

+	if(width == 0 || height == 0 || depth == 0 || data == NULL)

+	{

+		return;

+	}
+
+	es2::Context *context = es2::getContext();

+

+	if(context)

+	{
+		es2::Texture3D *texture = context->getTexture3D();

+

+		if(!texture)

+		{

+			return error(GL_INVALID_OPERATION);

+		}

+

+		texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);

+	}

+}
+
+void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "

+		"GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);

+

+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)

+	{

+		return error(GL_INVALID_ENUM);

+	}

+

+	switch(attachment)

+	{

+	case GL_COLOR_ATTACHMENT0:

+	case GL_DEPTH_ATTACHMENT:

+	case GL_STENCIL_ATTACHMENT:

+		break;

+	default:

+		return error(GL_INVALID_ENUM);

+	}

+

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

+

+	if(context)

+	{

+		if(texture == 0)

+		{

+			textarget = GL_NONE;

+		}

+		else

+		{

+			es2::Texture *tex = context->getTexture(texture);

+

+			if(tex == NULL)

+			{

+				return error(GL_INVALID_OPERATION);

+			}

+

+			if(tex->isCompressed(textarget, level))

+			{

+				return error(GL_INVALID_OPERATION);

+			}

+

+			switch(textarget)

+			{

+			case GL_TEXTURE_3D_OES:

+				if(tex->getTarget() != GL_TEXTURE_3D_OES)

+				{

+					return error(GL_INVALID_OPERATION);

+				}

+				break;

+			default:

+				return error(GL_INVALID_ENUM);

+			}

+

+			if(level != 0)

+			{

+				return error(GL_INVALID_VALUE);

+			}

+		}

+

+		es2::Framebuffer *framebuffer = NULL;

+		GLuint framebufferHandle = 0;

+		if(target == GL_READ_FRAMEBUFFER_ANGLE)

+		{

+			framebuffer = context->getReadFramebuffer();

+			framebufferHandle = context->getReadFramebufferHandle();

+		}

+		else

+		{

+			framebuffer = context->getDrawFramebuffer();

+			framebufferHandle = context->getDrawFramebufferHandle();

+		}

+

+		if(framebufferHandle == 0 || !framebuffer)

+		{

+			return error(GL_INVALID_OPERATION);

+		}

+

+		switch(attachment)

+		{

+		case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;

+		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;

+		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;

+		}

+	}
+}
+

 void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)

 {

 	if(egl::getClientVersion() == 1)

diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index 8ebcb16..acfa903 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -32,6 +32,7 @@
 		case GL_SAMPLER_2D:

 		case GL_SAMPLER_CUBE:

         case GL_SAMPLER_EXTERNAL_OES:

+		case GL_SAMPLER_3D_OES:

 			return 1;

 		case GL_BOOL_VEC2:

 		case GL_FLOAT_VEC2:

@@ -77,7 +78,8 @@
 		case GL_INT:

 		case GL_SAMPLER_2D:

 		case GL_SAMPLER_CUBE:

-        case GL_SAMPLER_EXTERNAL_OES:

+		case GL_SAMPLER_EXTERNAL_OES:

+		case GL_SAMPLER_3D_OES:

 		case GL_INT_VEC2:

 		case GL_INT_VEC3:

 		case GL_INT_VEC4:

@@ -122,6 +124,7 @@
 		case GL_SAMPLER_2D:

 		case GL_SAMPLER_CUBE:

         case GL_SAMPLER_EXTERNAL_OES:

+		case GL_SAMPLER_3D_OES:

 			return 1;

 		case GL_FLOAT_MAT2:

 			return 2;