compiler: Import Mesa compiler components
Merciliess removal of gl_context state
compiler: Bring glslang and LunarGLASS into CMake process
compiler: Progress (?) towards standalone xglCompiler
diff --git a/icd/intel/compiler/mesa-utils/src/glsl/builtin_type_macros.h b/icd/intel/compiler/mesa-utils/src/glsl/builtin_type_macros.h
new file mode 100644
index 0000000..236e1ce
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/glsl/builtin_type_macros.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file builtin_type_macros.h
+ *
+ * This contains definitions for all GLSL built-in types, regardless of what
+ * language version or extension might provide them.
+ */
+
+#include "glsl_types.h"
+
+DECL_TYPE(error, GL_INVALID_ENUM, GLSL_TYPE_ERROR, 0, 0)
+DECL_TYPE(void, GL_INVALID_ENUM, GLSL_TYPE_VOID, 0, 0)
+
+DECL_TYPE(bool, GL_BOOL, GLSL_TYPE_BOOL, 1, 1)
+DECL_TYPE(bvec2, GL_BOOL_VEC2, GLSL_TYPE_BOOL, 2, 1)
+DECL_TYPE(bvec3, GL_BOOL_VEC3, GLSL_TYPE_BOOL, 3, 1)
+DECL_TYPE(bvec4, GL_BOOL_VEC4, GLSL_TYPE_BOOL, 4, 1)
+
+DECL_TYPE(int, GL_INT, GLSL_TYPE_INT, 1, 1)
+DECL_TYPE(ivec2, GL_INT_VEC2, GLSL_TYPE_INT, 2, 1)
+DECL_TYPE(ivec3, GL_INT_VEC3, GLSL_TYPE_INT, 3, 1)
+DECL_TYPE(ivec4, GL_INT_VEC4, GLSL_TYPE_INT, 4, 1)
+
+DECL_TYPE(uint, GL_UNSIGNED_INT, GLSL_TYPE_UINT, 1, 1)
+DECL_TYPE(uvec2, GL_UNSIGNED_INT_VEC2, GLSL_TYPE_UINT, 2, 1)
+DECL_TYPE(uvec3, GL_UNSIGNED_INT_VEC3, GLSL_TYPE_UINT, 3, 1)
+DECL_TYPE(uvec4, GL_UNSIGNED_INT_VEC4, GLSL_TYPE_UINT, 4, 1)
+
+DECL_TYPE(float, GL_FLOAT, GLSL_TYPE_FLOAT, 1, 1)
+DECL_TYPE(vec2, GL_FLOAT_VEC2, GLSL_TYPE_FLOAT, 2, 1)
+DECL_TYPE(vec3, GL_FLOAT_VEC3, GLSL_TYPE_FLOAT, 3, 1)
+DECL_TYPE(vec4, GL_FLOAT_VEC4, GLSL_TYPE_FLOAT, 4, 1)
+
+DECL_TYPE(mat2, GL_FLOAT_MAT2, GLSL_TYPE_FLOAT, 2, 2)
+DECL_TYPE(mat3, GL_FLOAT_MAT3, GLSL_TYPE_FLOAT, 3, 3)
+DECL_TYPE(mat4, GL_FLOAT_MAT4, GLSL_TYPE_FLOAT, 4, 4)
+
+DECL_TYPE(mat2x3, GL_FLOAT_MAT2x3, GLSL_TYPE_FLOAT, 3, 2)
+DECL_TYPE(mat2x4, GL_FLOAT_MAT2x4, GLSL_TYPE_FLOAT, 4, 2)
+DECL_TYPE(mat3x2, GL_FLOAT_MAT3x2, GLSL_TYPE_FLOAT, 2, 3)
+DECL_TYPE(mat3x4, GL_FLOAT_MAT3x4, GLSL_TYPE_FLOAT, 4, 3)
+DECL_TYPE(mat4x2, GL_FLOAT_MAT4x2, GLSL_TYPE_FLOAT, 2, 4)
+DECL_TYPE(mat4x3, GL_FLOAT_MAT4x3, GLSL_TYPE_FLOAT, 3, 4)
+
+DECL_TYPE(sampler1D, GL_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2D, GL_SAMPLER_2D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler3D, GL_SAMPLER_3D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCube, GL_SAMPLER_CUBE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler1DArray, GL_SAMPLER_1D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DArray, GL_SAMPLER_2D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCubeArray, GL_SAMPLER_CUBE_MAP_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DRect, GL_SAMPLER_2D_RECT, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerBuffer, GL_SAMPLER_BUFFER, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DMS, GL_SAMPLER_2D_MULTISAMPLE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DMSArray, GL_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT)
+
+DECL_TYPE(isampler1D, GL_INT_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler2D, GL_INT_SAMPLER_2D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler3D, GL_INT_SAMPLER_3D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isamplerCube, GL_INT_SAMPLER_CUBE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler1DArray, GL_INT_SAMPLER_1D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DArray, GL_INT_SAMPLER_2D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT)
+DECL_TYPE(isamplerCubeArray, GL_INT_SAMPLER_CUBE_MAP_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DRect, GL_INT_SAMPLER_2D_RECT, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isamplerBuffer, GL_INT_SAMPLER_BUFFER, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DMS, GL_INT_SAMPLER_2D_MULTISAMPLE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DMSArray, GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT)
+
+DECL_TYPE(usampler1D, GL_UNSIGNED_INT_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2D, GL_UNSIGNED_INT_SAMPLER_2D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler3D, GL_UNSIGNED_INT_SAMPLER_3D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usamplerCube, GL_UNSIGNED_INT_SAMPLER_CUBE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler1DArray, GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DArray, GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT)
+DECL_TYPE(usamplerCubeArray, GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DRect, GL_UNSIGNED_INT_SAMPLER_2D_RECT, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usamplerBuffer, GL_UNSIGNED_INT_SAMPLER_BUFFER, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DMS, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DMSArray, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT)
+
+DECL_TYPE(sampler1DShadow, GL_SAMPLER_1D_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DShadow, GL_SAMPLER_2D_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCubeShadow, GL_SAMPLER_CUBE_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler1DArrayShadow, GL_SAMPLER_1D_ARRAY_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DArrayShadow, GL_SAMPLER_2D_ARRAY_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCubeArrayShadow, GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 1, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DRectShadow, GL_SAMPLER_2D_RECT_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 1, 0, GLSL_TYPE_FLOAT)
+
+DECL_TYPE(samplerExternalOES, GL_SAMPLER_EXTERNAL_OES, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_EXTERNAL, 0, 0, GLSL_TYPE_FLOAT)
+
+DECL_TYPE(image1D, GL_IMAGE_1D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2D, GL_IMAGE_2D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image3D, GL_IMAGE_3D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DRect, GL_IMAGE_2D_RECT, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(imageCube, GL_IMAGE_CUBE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(imageBuffer, GL_IMAGE_BUFFER, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image1DArray, GL_IMAGE_1D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DArray, GL_IMAGE_2D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(imageCubeArray, GL_IMAGE_CUBE_MAP_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DMS, GL_IMAGE_2D_MULTISAMPLE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DMSArray, GL_IMAGE_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(iimage1D, GL_INT_IMAGE_1D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage2D, GL_INT_IMAGE_2D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage3D, GL_INT_IMAGE_3D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DRect, GL_INT_IMAGE_2D_RECT, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimageCube, GL_INT_IMAGE_CUBE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimageBuffer, GL_INT_IMAGE_BUFFER, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage1DArray, GL_INT_IMAGE_1D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DArray, GL_INT_IMAGE_2D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(iimageCubeArray, GL_INT_IMAGE_CUBE_MAP_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DMS, GL_INT_IMAGE_2D_MULTISAMPLE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DMSArray, GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(uimage1D, GL_UNSIGNED_INT_IMAGE_1D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2D, GL_UNSIGNED_INT_IMAGE_2D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage3D, GL_UNSIGNED_INT_IMAGE_3D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DRect, GL_UNSIGNED_INT_IMAGE_2D_RECT, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimageCube, GL_UNSIGNED_INT_IMAGE_CUBE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimageBuffer, GL_UNSIGNED_INT_IMAGE_BUFFER, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage1DArray, GL_UNSIGNED_INT_IMAGE_1D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DArray, GL_UNSIGNED_INT_IMAGE_2D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT);
+DECL_TYPE(uimageCubeArray, GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DMS, GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DMSArray, GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT);
+
+DECL_TYPE(atomic_uint, GL_UNSIGNED_INT_ATOMIC_COUNTER, GLSL_TYPE_ATOMIC_UINT, 1, 1)
+
+STRUCT_TYPE(gl_DepthRangeParameters)
+STRUCT_TYPE(gl_PointParameters)
+STRUCT_TYPE(gl_MaterialParameters)
+STRUCT_TYPE(gl_LightSourceParameters)
+STRUCT_TYPE(gl_LightModelParameters)
+STRUCT_TYPE(gl_LightModelProducts)
+STRUCT_TYPE(gl_LightProducts)
+STRUCT_TYPE(gl_FogParameters)
diff --git a/icd/intel/compiler/shader/glsl_types.h b/icd/intel/compiler/mesa-utils/src/glsl/glsl_types.h
similarity index 100%
rename from icd/intel/compiler/shader/glsl_types.h
rename to icd/intel/compiler/mesa-utils/src/glsl/glsl_types.h
diff --git a/icd/intel/compiler/mesa-utils/src/glsl/ir_uniform.h b/icd/intel/compiler/mesa-utils/src/glsl/ir_uniform.h
new file mode 100644
index 0000000..3508509
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/glsl/ir_uniform.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+#ifndef IR_UNIFORM_H
+#define IR_UNIFORM_H
+
+
+/* stdbool.h is necessary because this file is included in both C and C++ code.
+ */
+#include <stdbool.h>
+
+#include "program/prog_parameter.h" /* For union gl_constant_value. */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum gl_uniform_driver_format {
+ uniform_native = 0, /**< Store data in the native format. */
+ uniform_int_float, /**< Store integer data as floats. */
+ uniform_bool_float, /**< Store boolean data as floats. */
+
+ /**
+ * Store boolean data as integer using 1 for \c true.
+ */
+ uniform_bool_int_0_1,
+
+ /**
+ * Store boolean data as integer using ~0 for \c true.
+ */
+ uniform_bool_int_0_not0
+};
+
+struct gl_uniform_driver_storage {
+ /**
+ * Number of bytes from one array element to the next.
+ */
+ uint8_t element_stride;
+
+ /**
+ * Number of bytes from one vector in a matrix to the next.
+ */
+ uint8_t vector_stride;
+
+ /**
+ * Base format of the stored data.
+ *
+ * This field must have a value from \c GLSL_TYPE_UINT through \c
+ * GLSL_TYPE_SAMPLER.
+ */
+ uint8_t format;
+
+ /**
+ * Pointer to the base of the data.
+ */
+ void *data;
+};
+
+struct gl_opaque_uniform_index {
+ /**
+ * Base opaque uniform index
+ *
+ * If \c gl_uniform_storage::base_type is an opaque type, this
+ * represents its uniform index. If \c
+ * gl_uniform_storage::array_elements is not zero, the array will
+ * use opaque uniform indices \c index through \c index + \c
+ * gl_uniform_storage::array_elements - 1, inclusive.
+ *
+ * Note that the index may be different in each shader stage.
+ */
+ uint8_t index;
+
+ /**
+ * Whether this opaque uniform is used in this shader stage.
+ */
+ bool active;
+};
+
+struct gl_uniform_storage {
+ char *name;
+ /** Type of this uniform data stored.
+ *
+ * In the case of an array, it's the type of a single array element.
+ */
+ const struct glsl_type *type;
+
+ /**
+ * The number of elements in this uniform.
+ *
+ * For non-arrays, this is always 0. For arrays, the value is the size of
+ * the array.
+ */
+ unsigned array_elements;
+
+ /**
+ * Has this uniform ever been set?
+ */
+ bool initialized;
+
+ struct gl_opaque_uniform_index sampler[MESA_SHADER_STAGES];
+
+ struct gl_opaque_uniform_index image[MESA_SHADER_STAGES];
+
+ /**
+ * Storage used by the driver for the uniform
+ */
+ unsigned num_driver_storage;
+ struct gl_uniform_driver_storage *driver_storage;
+
+ /**
+ * Storage used by Mesa for the uniform
+ *
+ * This form of the uniform is used by Mesa's implementation of \c
+ * glGetUniform. It can also be used by drivers to obtain the value of the
+ * uniform if the \c ::driver_storage interface is not used.
+ */
+ union gl_constant_value *storage;
+
+ /** Fields for GL_ARB_uniform_buffer_object
+ * @{
+ */
+
+ /**
+ * GL_UNIFORM_BLOCK_INDEX: index of the uniform block containing
+ * the uniform, or -1 for the default uniform block. Note that the
+ * index is into the linked program's UniformBlocks[] array, not
+ * the linked shader's.
+ */
+ int block_index;
+
+ /** GL_UNIFORM_OFFSET: byte offset within the uniform block, or -1. */
+ int offset;
+
+ /**
+ * GL_UNIFORM_MATRIX_STRIDE: byte stride between columns or rows of
+ * a matrix. Set to 0 for non-matrices in UBOs, or -1 for uniforms
+ * in the default uniform block.
+ */
+ int matrix_stride;
+
+ /**
+ * GL_UNIFORM_ARRAY_STRIDE: byte stride between elements of the
+ * array. Set to zero for non-arrays in UBOs, or -1 for uniforms
+ * in the default uniform block.
+ */
+ int array_stride;
+
+ /** GL_UNIFORM_ROW_MAJOR: true iff it's a row-major matrix in a UBO */
+ bool row_major;
+
+ /** @} */
+
+ /**
+ * Index within gl_shader_program::AtomicBuffers[] of the atomic
+ * counter buffer this uniform is stored in, or -1 if this is not
+ * an atomic counter.
+ */
+ int atomic_buffer_index;
+
+ /**
+ * The 'base location' for this uniform in the uniform remap table. For
+ * arrays this is the first element in the array.
+ */
+ unsigned remap_location;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IR_UNIFORM_H */
diff --git a/icd/intel/compiler/mesa-utils/src/glsl/memory_map.h b/icd/intel/compiler/mesa-utils/src/glsl/memory_map.h
new file mode 100644
index 0000000..f950fdb
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/glsl/memory_map.h
@@ -0,0 +1,237 @@
+/* -*- c++ -*- */
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+#ifndef MEMORY_MAP_H
+#define MEMORY_MAP_H
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef _POSIX_MAPPED_FILES
+#include <sys/mman.h>
+#include <sys/stat.h>
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include "ralloc.h"
+
+#ifdef __cplusplus
+
+/**
+ * Helper class to read data
+ *
+ * Class can read either from user given memory or from a file. On Linux
+ * file reading wraps around the Posix functions for mapping a file into
+ * the process's address space. Other OS may need different implementation.
+ */
+class memory_map
+{
+public:
+ memory_map() :
+ error(false),
+ mode(memory_map::READ_MEM),
+ cache_size(0),
+ cache_mmap(NULL),
+ cache_mmap_p(NULL)
+ {
+ mem_ctx = ralloc_context(NULL);
+ }
+
+ /* read from disk */
+ int map(const char *path)
+ {
+#ifdef _POSIX_MAPPED_FILES
+ struct stat stat_info;
+ if (stat(path, &stat_info) != 0)
+ return -1;
+
+ mode = memory_map::READ_MAP;
+ cache_size = stat_info.st_size;
+
+ int fd = open(path, O_RDONLY);
+ if (fd) {
+ cache_mmap_p = cache_mmap = (char *)
+ mmap(NULL, cache_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+ return (cache_mmap == MAP_FAILED) ? -1 : 0;
+ }
+#else
+ /* Implementation for systems without mmap(). */
+ FILE *in = fopen(path, "r");
+ if (in) {
+ fseek(in, 0, SEEK_END);
+ cache_size = ftell(in);
+ rewind(in);
+
+ cache_mmap = ralloc_array(mem_ctx, char, cache_size);
+
+ if (!cache_mmap)
+ return -1;
+
+ if (fread(cache_mmap, cache_size, 1, in) != 1) {
+ ralloc_free(cache_mmap);
+ cache_mmap = NULL;
+ }
+ cache_mmap_p = cache_mmap;
+ fclose(in);
+
+ return (cache_mmap == NULL) ? -1 : 0;
+ }
+#endif
+ return -1;
+ }
+
+ /* read from memory */
+ void map(const void *memory, size_t size)
+ {
+ cache_mmap_p = cache_mmap = (char *) memory;
+ cache_size = size;
+ }
+
+ ~memory_map() {
+#ifdef _POSIX_MAPPED_FILES
+ if (cache_mmap && mode == READ_MAP) {
+ munmap(cache_mmap, cache_size);
+ }
+#endif
+ ralloc_free(mem_ctx);
+ }
+
+ /* move read pointer forward */
+ inline void ffwd(int len)
+ {
+ cache_mmap_p += len;
+ }
+
+ inline void jump(unsigned pos)
+ {
+ cache_mmap_p = cache_mmap + pos;
+ }
+
+ /**
+ * safety check to avoid reading over cache_size,
+ * returns bool if it is safe to continue reading
+ */
+ bool safe_read(unsigned size)
+ {
+ if (position() + size > cache_size)
+ error = true;
+ return !error;
+ }
+
+ /* position of read pointer */
+ inline uint32_t position()
+ {
+ return cache_mmap_p - cache_mmap;
+ }
+
+ inline char *read_string()
+ {
+ uint32_t len = read_uint32_t();
+
+ /* NULL pointer is supported */
+ if (len == 0)
+ return NULL;
+
+ /* don't read off the end of cache */
+ /* TODO: Understand how this can happen and fix */
+ if (len + position() > cache_size) {
+ error = true;
+ return NULL;
+ }
+
+ /* verify that last character is terminator */
+ if (*(cache_mmap_p + len - 1) != '\0') {
+ error = true;
+ return NULL;
+ }
+
+ char *str = ralloc_array(mem_ctx, char, len);
+ memcpy(str, cache_mmap_p, len);
+ ffwd(len);
+ return str;
+ }
+
+/**
+ * read functions per type
+ */
+#define DECL_READER(type) type read_ ##type () {\
+ if (!safe_read(sizeof(type)))\
+ return 0;\
+ ffwd(sizeof(type));\
+ return *(type *) (cache_mmap_p - sizeof(type));\
+}
+
+ DECL_READER(int32_t);
+ DECL_READER(int64_t);
+ DECL_READER(uint8_t);
+ DECL_READER(uint32_t);
+
+ inline uint8_t read_bool()
+ {
+ return read_uint8_t();
+ }
+
+ inline void read(void *dst, size_t size)
+ {
+ if (!safe_read(size))
+ return;
+ memcpy(dst, cache_mmap_p, size);
+ ffwd(size);
+ }
+
+ /* total size of mapped memory */
+ inline int32_t size()
+ {
+ return cache_size;
+ }
+
+ inline bool errors()
+ {
+ return error;
+ }
+
+private:
+
+ void *mem_ctx;
+
+ /* if errors have occured during reading */
+ bool error;
+
+ /* specifies if we are reading mapped memory or user passed mem */
+ enum read_mode {
+ READ_MEM = 0,
+ READ_MAP
+ };
+
+ int32_t mode;
+ unsigned cache_size;
+ char *cache_mmap;
+ char *cache_mmap_p;
+};
+#endif /* ifdef __cplusplus */
+
+#endif /* MEMORY_MAP_H */
diff --git a/icd/intel/compiler/mesa-utils/src/glsl/memory_writer.h b/icd/intel/compiler/mesa-utils/src/glsl/memory_writer.h
new file mode 100644
index 0000000..f98d118
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/glsl/memory_writer.h
@@ -0,0 +1,204 @@
+/* -*- c++ -*- */
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+#ifndef MEMORY_WRITER_H
+#define MEMORY_WRITER_H
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "main/hash_table.h"
+
+#ifdef __cplusplus
+/**
+ * Helper class for writing data to memory
+ *
+ * This class maintains a dynamically-sized memory buffer and allows
+ * for data to be efficiently appended to it with automatic resizing.
+ */
+class memory_writer
+{
+public:
+ memory_writer() :
+ memory(NULL),
+ curr_size(0),
+ pos(0),
+ unique_id_counter(0)
+ {
+ data_hash = _mesa_hash_table_create(0, int_equal);
+ hash_value = _mesa_hash_data(this, sizeof(memory_writer));
+ }
+
+ ~memory_writer()
+ {
+ free(memory);
+ _mesa_hash_table_destroy(data_hash, NULL);
+ }
+
+ /* user wants to claim the memory */
+ char *release_memory(size_t *size)
+ {
+ /* final realloc to free allocated but unused memory */
+ char *result = (char *) realloc(memory, pos);
+ *size = pos;
+ memory = NULL;
+ curr_size = 0;
+ pos = 0;
+ return result;
+ }
+
+/**
+ * write functions per type
+ */
+#define DECL_WRITER(type) void write_ ##type (const type data) {\
+ write(&data, sizeof(type));\
+}
+
+ DECL_WRITER(int32_t);
+ DECL_WRITER(int64_t);
+ DECL_WRITER(uint8_t);
+ DECL_WRITER(uint32_t);
+
+ void write_bool(bool data)
+ {
+ uint8_t val = data;
+ write_uint8_t(val);
+ }
+
+ /* write function that reallocates more memory if required */
+ void write(const void *data, int size)
+ {
+ if (!memory || pos > (curr_size - size))
+ if (!grow(size)) {
+ assert(!"Out of memory while serializing a shader");
+ return;
+ }
+
+ memcpy(memory + pos, data, size);
+
+ pos += size;
+ }
+
+ void overwrite(const void *data, int size, int offset)
+ {
+ if (offset < 0 || offset + size > pos) {
+ assert(!"Attempt to write out of bounds while serializing a shader");
+ return;
+ }
+
+ memcpy(memory + offset, data, size);
+ }
+
+ /* length is written to make reading safe, we write len + 1 to be
+ * able to make distinction between "" and NULL
+ */
+ void write_string(const char *str)
+ {
+ uint32_t len = str ? strlen(str) + 1 : 0;
+ write_uint32_t(len);
+
+ /* serialize string + terminator for more convinient parsing. */
+ if (str)
+ write(str, len);
+ }
+
+ unsigned position()
+ {
+ return pos;
+ }
+
+ /**
+ * Convert the given pointer into a small integer unique ID. In other
+ * words, if make_unique_id() has previously been called with this pointer,
+ * return the same ID that was returned last time. If this is the first
+ * call to make_unique_id() with this pointer, return a fresh ID.
+ *
+ * Return value is true if the pointer has been seen before, false
+ * otherwise.
+ */
+ bool make_unique_id(const void *ptr, uint32_t *id_out)
+ {
+ hash_entry *entry =
+ _mesa_hash_table_search(data_hash, _mesa_hash_pointer(ptr), ptr);
+ if (entry != NULL) {
+ *id_out = (uint32_t) (intptr_t) entry->data;
+ return true;
+ } else {
+ /* Note: hashtable uses 0 to represent "entry not found" so our
+ * unique ID's need to start at 1. Hence, preincrement
+ * unique_id_counter.
+ */
+ *id_out = ++this->unique_id_counter;
+ _mesa_hash_table_insert(data_hash, _mesa_hash_pointer(ptr), ptr,
+ (void *) (intptr_t) *id_out);
+ return false;
+ }
+ }
+
+private:
+
+ /* reallocate more memory */
+ bool grow(int size)
+ {
+ unsigned new_size = 2 * (curr_size + size);
+ char *more_mem = (char *) realloc(memory, new_size);
+ if (more_mem == NULL) {
+ free(memory);
+ memory = NULL;
+ return false;
+ } else {
+ memory = more_mem;
+ curr_size = new_size;
+ return true;
+ }
+ }
+
+ /* allocated memory */
+ char *memory;
+
+ /* current size of the whole allocation */
+ int curr_size;
+
+ /* write position / size of the data written */
+ int pos;
+
+ /* this hash can be used to refer to data already written
+ * to skip sequential writes of the same data
+ */
+ struct hash_table *data_hash;
+ uint32_t hash_value;
+ unsigned unique_id_counter;
+
+ static bool int_equal(const void *a, const void *b)
+ {
+ return a == b;
+ }
+
+};
+
+#endif /* ifdef __cplusplus */
+
+#endif /* MEMORY_WRITER_H */
diff --git a/icd/intel/compiler/shader/ralloc.c b/icd/intel/compiler/mesa-utils/src/glsl/ralloc.c
similarity index 100%
rename from icd/intel/compiler/shader/ralloc.c
rename to icd/intel/compiler/mesa-utils/src/glsl/ralloc.c
diff --git a/icd/intel/compiler/shader/ralloc.h b/icd/intel/compiler/mesa-utils/src/glsl/ralloc.h
similarity index 100%
rename from icd/intel/compiler/shader/ralloc.h
rename to icd/intel/compiler/mesa-utils/src/glsl/ralloc.h
diff --git a/icd/intel/compiler/shader/threadpool.h b/icd/intel/compiler/mesa-utils/src/glsl/threadpool.h
similarity index 100%
rename from icd/intel/compiler/shader/threadpool.h
rename to icd/intel/compiler/mesa-utils/src/glsl/threadpool.h
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/accum.c b/icd/intel/compiler/mesa-utils/src/mesa/main/accum.c
new file mode 100644
index 0000000..ef74468
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/accum.c
@@ -0,0 +1,491 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "accum.h"
+#include "condrender.h"
+#include "context.h"
+#include "format_unpack.h"
+#include "format_pack.h"
+#include "imports.h"
+#include "macros.h"
+#include "state.h"
+#include "mtypes.h"
+#include "main/dispatch.h"
+
+
+void GLAPIENTRY
+_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
+{
+ GLfloat tmp[4];
+ GET_CURRENT_CONTEXT(ctx);
+
+ tmp[0] = CLAMP( red, -1.0F, 1.0F );
+ tmp[1] = CLAMP( green, -1.0F, 1.0F );
+ tmp[2] = CLAMP( blue, -1.0F, 1.0F );
+ tmp[3] = CLAMP( alpha, -1.0F, 1.0F );
+
+ if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor))
+ return;
+
+ COPY_4FV( ctx->Accum.ClearColor, tmp );
+}
+
+
+void GLAPIENTRY
+_mesa_Accum( GLenum op, GLfloat value )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+
+ switch (op) {
+ case GL_ADD:
+ case GL_MULT:
+ case GL_ACCUM:
+ case GL_LOAD:
+ case GL_RETURN:
+ /* OK */
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glAccum(op)");
+ return;
+ }
+
+ if (ctx->DrawBuffer->Visual.haveAccumBuffer == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glAccum(no accum buffer)");
+ return;
+ }
+
+ if (ctx->DrawBuffer != ctx->ReadBuffer) {
+ /* See GLX_SGI_make_current_read or WGL_ARB_make_current_read,
+ * or GL_EXT_framebuffer_blit.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glAccum(different read/draw buffers)");
+ return;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glAccum(incomplete framebuffer)");
+ return;
+ }
+
+ if (ctx->RasterDiscard)
+ return;
+
+ if (ctx->RenderMode == GL_RENDER) {
+ _mesa_accum(ctx, op, value);
+ }
+}
+
+
+/**
+ * Clear the accumulation buffer by mapping the renderbuffer and
+ * writing the clear color to it. Called by the driver's implementation
+ * of the glClear function.
+ */
+void
+_mesa_clear_accum_buffer(struct gl_context *ctx)
+{
+ GLuint x, y, width, height;
+ GLubyte *accMap;
+ GLint accRowStride;
+ struct gl_renderbuffer *accRb;
+
+ if (!ctx->DrawBuffer)
+ return;
+
+ accRb = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer;
+ if (!accRb)
+ return; /* missing accum buffer, not an error */
+
+ /* bounds, with scissor */
+ x = ctx->DrawBuffer->_Xmin;
+ y = ctx->DrawBuffer->_Ymin;
+ width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
+ height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
+
+ ctx->Driver.MapRenderbuffer(ctx, accRb, x, y, width, height,
+ GL_MAP_WRITE_BIT, &accMap, &accRowStride);
+
+ if (!accMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ return;
+ }
+
+ if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) {
+ const GLshort clearR = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]);
+ const GLshort clearG = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]);
+ const GLshort clearB = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]);
+ const GLshort clearA = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
+ GLuint i, j;
+
+ for (j = 0; j < height; j++) {
+ GLshort *row = (GLshort *) accMap;
+
+ for (i = 0; i < width; i++) {
+ row[i * 4 + 0] = clearR;
+ row[i * 4 + 1] = clearG;
+ row[i * 4 + 2] = clearB;
+ row[i * 4 + 3] = clearA;
+ }
+ accMap += accRowStride;
+ }
+ }
+ else {
+ /* other types someday? */
+ _mesa_warning(ctx, "unexpected accum buffer type");
+ }
+
+ ctx->Driver.UnmapRenderbuffer(ctx, accRb);
+}
+
+
+/**
+ * if (bias)
+ * Accum += value
+ * else
+ * Accum *= value
+ */
+static void
+accum_scale_or_bias(struct gl_context *ctx, GLfloat value,
+ GLint xpos, GLint ypos, GLint width, GLint height,
+ GLboolean bias)
+{
+ struct gl_renderbuffer *accRb =
+ ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer;
+ GLubyte *accMap;
+ GLint accRowStride;
+
+ assert(accRb);
+
+ ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height,
+ GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
+ &accMap, &accRowStride);
+
+ if (!accMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ return;
+ }
+
+ if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) {
+ const GLshort incr = (GLshort) (value * 32767.0f);
+ GLint i, j;
+ if (bias) {
+ for (j = 0; j < height; j++) {
+ GLshort *acc = (GLshort *) accMap;
+ for (i = 0; i < 4 * width; i++) {
+ acc[i] += incr;
+ }
+ accMap += accRowStride;
+ }
+ }
+ else {
+ /* scale */
+ for (j = 0; j < height; j++) {
+ GLshort *acc = (GLshort *) accMap;
+ for (i = 0; i < 4 * width; i++) {
+ acc[i] = (GLshort) (acc[i] * value);
+ }
+ accMap += accRowStride;
+ }
+ }
+ }
+ else {
+ /* other types someday? */
+ }
+
+ ctx->Driver.UnmapRenderbuffer(ctx, accRb);
+}
+
+
+/**
+ * if (load)
+ * Accum = ColorBuf * value
+ * else
+ * Accum += ColorBuf * value
+ */
+static void
+accum_or_load(struct gl_context *ctx, GLfloat value,
+ GLint xpos, GLint ypos, GLint width, GLint height,
+ GLboolean load)
+{
+ struct gl_renderbuffer *accRb =
+ ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer;
+ struct gl_renderbuffer *colorRb = ctx->ReadBuffer->_ColorReadBuffer;
+ GLubyte *accMap, *colorMap;
+ GLint accRowStride, colorRowStride;
+ GLbitfield mappingFlags;
+
+ if (!colorRb) {
+ /* no read buffer - OK */
+ return;
+ }
+
+ assert(accRb);
+
+ mappingFlags = GL_MAP_WRITE_BIT;
+ if (!load) /* if we're accumulating */
+ mappingFlags |= GL_MAP_READ_BIT;
+
+ /* Map accum buffer */
+ ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height,
+ mappingFlags, &accMap, &accRowStride);
+ if (!accMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ return;
+ }
+
+ /* Map color buffer */
+ ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
+ GL_MAP_READ_BIT,
+ &colorMap, &colorRowStride);
+ if (!colorMap) {
+ ctx->Driver.UnmapRenderbuffer(ctx, accRb);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ return;
+ }
+
+ if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) {
+ const GLfloat scale = value * 32767.0f;
+ GLint i, j;
+ GLfloat (*rgba)[4];
+
+ rgba = malloc(width * 4 * sizeof(GLfloat));
+ if (rgba) {
+ for (j = 0; j < height; j++) {
+ GLshort *acc = (GLshort *) accMap;
+
+ /* read colors from source color buffer */
+ _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, rgba);
+
+ if (load) {
+ for (i = 0; i < width; i++) {
+ acc[i * 4 + 0] = (GLshort) (rgba[i][RCOMP] * scale);
+ acc[i * 4 + 1] = (GLshort) (rgba[i][GCOMP] * scale);
+ acc[i * 4 + 2] = (GLshort) (rgba[i][BCOMP] * scale);
+ acc[i * 4 + 3] = (GLshort) (rgba[i][ACOMP] * scale);
+ }
+ }
+ else {
+ /* accumulate */
+ for (i = 0; i < width; i++) {
+ acc[i * 4 + 0] += (GLshort) (rgba[i][RCOMP] * scale);
+ acc[i * 4 + 1] += (GLshort) (rgba[i][GCOMP] * scale);
+ acc[i * 4 + 2] += (GLshort) (rgba[i][BCOMP] * scale);
+ acc[i * 4 + 3] += (GLshort) (rgba[i][ACOMP] * scale);
+ }
+ }
+
+ colorMap += colorRowStride;
+ accMap += accRowStride;
+ }
+
+ free(rgba);
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ }
+ }
+ else {
+ /* other types someday? */
+ }
+
+ ctx->Driver.UnmapRenderbuffer(ctx, accRb);
+ ctx->Driver.UnmapRenderbuffer(ctx, colorRb);
+}
+
+
+/**
+ * ColorBuffer = Accum * value
+ */
+static void
+accum_return(struct gl_context *ctx, GLfloat value,
+ GLint xpos, GLint ypos, GLint width, GLint height)
+{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ struct gl_renderbuffer *accRb = fb->Attachment[BUFFER_ACCUM].Renderbuffer;
+ GLubyte *accMap, *colorMap;
+ GLint accRowStride, colorRowStride;
+ GLuint buffer;
+
+ /* Map accum buffer */
+ ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height,
+ GL_MAP_READ_BIT,
+ &accMap, &accRowStride);
+ if (!accMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ return;
+ }
+
+ /* Loop over destination buffers */
+ for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) {
+ struct gl_renderbuffer *colorRb = fb->_ColorDrawBuffers[buffer];
+ const GLboolean masking = (!ctx->Color.ColorMask[buffer][RCOMP] ||
+ !ctx->Color.ColorMask[buffer][GCOMP] ||
+ !ctx->Color.ColorMask[buffer][BCOMP] ||
+ !ctx->Color.ColorMask[buffer][ACOMP]);
+ GLbitfield mappingFlags = GL_MAP_WRITE_BIT;
+
+ if (masking)
+ mappingFlags |= GL_MAP_READ_BIT;
+
+ /* Map color buffer */
+ ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
+ mappingFlags, &colorMap, &colorRowStride);
+ if (!colorMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ continue;
+ }
+
+ if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) {
+ const GLfloat scale = value / 32767.0f;
+ GLint i, j;
+ GLfloat (*rgba)[4], (*dest)[4];
+
+ rgba = malloc(width * 4 * sizeof(GLfloat));
+ dest = malloc(width * 4 * sizeof(GLfloat));
+
+ if (rgba && dest) {
+ for (j = 0; j < height; j++) {
+ GLshort *acc = (GLshort *) accMap;
+
+ for (i = 0; i < width; i++) {
+ rgba[i][0] = acc[i * 4 + 0] * scale;
+ rgba[i][1] = acc[i * 4 + 1] * scale;
+ rgba[i][2] = acc[i * 4 + 2] * scale;
+ rgba[i][3] = acc[i * 4 + 3] * scale;
+ }
+
+ if (masking) {
+
+ /* get existing colors from dest buffer */
+ _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, dest);
+
+ /* use the dest colors where mask[channel] = 0 */
+ if (ctx->Color.ColorMask[buffer][RCOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][RCOMP] = dest[i][RCOMP];
+ }
+ if (ctx->Color.ColorMask[buffer][GCOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][GCOMP] = dest[i][GCOMP];
+ }
+ if (ctx->Color.ColorMask[buffer][BCOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][BCOMP] = dest[i][BCOMP];
+ }
+ if (ctx->Color.ColorMask[buffer][ACOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][ACOMP] = dest[i][ACOMP];
+ }
+ }
+
+ _mesa_pack_float_rgba_row(colorRb->Format, width,
+ (const GLfloat (*)[4]) rgba, colorMap);
+
+ accMap += accRowStride;
+ colorMap += colorRowStride;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ }
+ free(rgba);
+ free(dest);
+ }
+ else {
+ /* other types someday? */
+ }
+
+ ctx->Driver.UnmapRenderbuffer(ctx, colorRb);
+ }
+
+ ctx->Driver.UnmapRenderbuffer(ctx, accRb);
+}
+
+
+
+/**
+ * Software fallback for glAccum. A hardware driver that supports
+ * signed 16-bit color channels could implement hardware accumulation
+ * operations, but no driver does so at this time.
+ */
+void
+_mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value)
+{
+ GLint xpos, ypos, width, height;
+
+ if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) {
+ _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer");
+ return;
+ }
+
+ if (!_mesa_check_conditional_render(ctx))
+ return;
+
+ xpos = ctx->DrawBuffer->_Xmin;
+ ypos = ctx->DrawBuffer->_Ymin;
+ width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
+ height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
+
+ switch (op) {
+ case GL_ADD:
+ if (value != 0.0F) {
+ accum_scale_or_bias(ctx, value, xpos, ypos, width, height, GL_TRUE);
+ }
+ break;
+ case GL_MULT:
+ if (value != 1.0F) {
+ accum_scale_or_bias(ctx, value, xpos, ypos, width, height, GL_FALSE);
+ }
+ break;
+ case GL_ACCUM:
+ if (value != 0.0F) {
+ accum_or_load(ctx, value, xpos, ypos, width, height, GL_FALSE);
+ }
+ break;
+ case GL_LOAD:
+ accum_or_load(ctx, value, xpos, ypos, width, height, GL_TRUE);
+ break;
+ case GL_RETURN:
+ accum_return(ctx, value, xpos, ypos, width, height);
+ break;
+ default:
+ _mesa_problem(ctx, "invalid mode in _mesa_accum()");
+ break;
+ }
+}
+
+
+void
+_mesa_init_accum( struct gl_context *ctx )
+{
+ /* Accumulate buffer group */
+ ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/accum.h b/icd/intel/compiler/mesa-utils/src/mesa/main/accum.h
new file mode 100644
index 0000000..a5665c7
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/accum.h
@@ -0,0 +1,60 @@
+/**
+ * \file accum.h
+ * Accumulation buffer operations.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef ACCUM_H
+#define ACCUM_H
+
+#include "main/glheader.h"
+
+struct _glapi_table;
+struct gl_context;
+struct gl_renderbuffer;
+
+extern void GLAPIENTRY
+_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha );
+void GLAPIENTRY
+_mesa_Accum( GLenum op, GLfloat value );
+
+extern void
+_mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value);
+
+extern void
+_mesa_clear_accum_buffer(struct gl_context *ctx);
+
+extern void
+_mesa_init_accum( struct gl_context *ctx );
+
+#endif /* ACCUM_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/context.c b/icd/intel/compiler/mesa-utils/src/mesa/main/context.c
new file mode 100644
index 0000000..877b267
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/context.c
@@ -0,0 +1,1988 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file context.c
+ * Mesa context/visual/framebuffer management functions.
+ * \author Brian Paul
+ */
+
+/**
+ * \mainpage Mesa Main Module
+ *
+ * \section MainIntroduction Introduction
+ *
+ * The Mesa Main module consists of all the files in the main/ directory.
+ * Among the features of this module are:
+ * <UL>
+ * <LI> Structures to represent most GL state </LI>
+ * <LI> State set/get functions </LI>
+ * <LI> Display lists </LI>
+ * <LI> Texture unit, object and image handling </LI>
+ * <LI> Matrix and attribute stacks </LI>
+ * </UL>
+ *
+ * Other modules are responsible for API dispatch, vertex transformation,
+ * point/line/triangle setup, rasterization, vertex array caching,
+ * vertex/fragment programs/shaders, etc.
+ *
+ *
+ * \section AboutDoxygen About Doxygen
+ *
+ * If you're viewing this information as Doxygen-generated HTML you'll
+ * see the documentation index at the top of this page.
+ *
+ * The first line lists the Mesa source code modules.
+ * The second line lists the indexes available for viewing the documentation
+ * for each module.
+ *
+ * Selecting the <b>Main page</b> link will display a summary of the module
+ * (this page).
+ *
+ * Selecting <b>Data Structures</b> will list all C structures.
+ *
+ * Selecting the <b>File List</b> link will list all the source files in
+ * the module.
+ * Selecting a filename will show a list of all functions defined in that file.
+ *
+ * Selecting the <b>Data Fields</b> link will display a list of all
+ * documented structure members.
+ *
+ * Selecting the <b>Globals</b> link will display a list
+ * of all functions, structures, global variables and macros in the module.
+ *
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "accum.h"
+#include "api_exec.h"
+#include "api_loopback.h"
+#include "arrayobj.h"
+#include "attrib.h"
+#include "blend.h"
+#include "buffers.h"
+#include "bufferobj.h"
+#include "context.h"
+#include "cpuinfo.h"
+#include "debug.h"
+#include "depth.h"
+#include "dlist.h"
+#include "eval.h"
+#include "extensions.h"
+#include "fbobject.h"
+#include "feedback.h"
+#include "fog.h"
+#include "formats.h"
+#include "framebuffer.h"
+#include "hint.h"
+#include "hash.h"
+#include "light.h"
+#include "lines.h"
+#include "macros.h"
+#include "matrix.h"
+#include "multisample.h"
+#include "performance_monitor.h"
+#include "pipelineobj.h"
+#include "pixel.h"
+#include "pixelstore.h"
+#include "points.h"
+#include "polygon.h"
+#include "queryobj.h"
+#include "shaderapi.h"
+#include "syncobj.h"
+#include "rastpos.h"
+#include "remap.h"
+#include "scissor.h"
+#include "shared.h"
+#include "shaderobj.h"
+#include "simple_list.h"
+#include "state.h"
+#include "stencil.h"
+#include "texcompress_s3tc.h"
+#include "texstate.h"
+#include "transformfeedback.h"
+#include "mtypes.h"
+#include "varray.h"
+#include "version.h"
+#include "viewport.h"
+#include "vtxfmt.h"
+#include "program/program.h"
+#include "program/prog_print.h"
+#include "program/prog_diskcache.h"
+#include "math/m_matrix.h"
+#include "main/dispatch.h" /* for _gloffset_COUNT */
+
+#ifdef USE_SPARC_ASM
+#include "sparc/sparc.h"
+#endif
+
+#include "glsl_parser_extras.h"
+#include "threadpool.h"
+#include <stdbool.h>
+
+
+#ifndef MESA_VERBOSE
+int MESA_VERBOSE = 0;
+#endif
+
+#ifndef MESA_DEBUG_FLAGS
+int MESA_DEBUG_FLAGS = 0;
+#endif
+
+
+/* ubyte -> float conversion */
+GLfloat _mesa_ubyte_to_float_color_tab[256];
+
+
+
+/**
+ * Swap buffers notification callback.
+ *
+ * \param ctx GL context.
+ *
+ * Called by window system just before swapping buffers.
+ * We have to finish any pending rendering.
+ */
+void
+_mesa_notifySwapBuffers(struct gl_context *ctx)
+{
+ if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS)
+ _mesa_debug(ctx, "SwapBuffers\n");
+ FLUSH_CURRENT( ctx, 0 );
+ if (ctx->Driver.Flush) {
+ ctx->Driver.Flush(ctx);
+ }
+}
+
+
+/**********************************************************************/
+/** \name GL Visual allocation/destruction */
+/**********************************************************************/
+/*@{*/
+
+/**
+ * Allocates a struct gl_config structure and initializes it via
+ * _mesa_initialize_visual().
+ *
+ * \param dbFlag double buffering
+ * \param stereoFlag stereo buffer
+ * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
+ * is acceptable but the actual depth type will be GLushort or GLuint as
+ * needed.
+ * \param stencilBits requested minimum bits per stencil buffer value
+ * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number
+ * of bits per color component in accum buffer.
+ * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
+ * \param redBits number of bits per color component in frame buffer for RGB(A)
+ * mode. We always use 8 in core Mesa though.
+ * \param greenBits same as above.
+ * \param blueBits same as above.
+ * \param alphaBits same as above.
+ * \param numSamples not really used.
+ *
+ * \return pointer to new struct gl_config or NULL if requested parameters
+ * can't be met.
+ *
+ * \note Need to add params for level and numAuxBuffers (at least)
+ */
+struct gl_config *
+_mesa_create_visual( GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples )
+{
+ struct gl_config *vis = CALLOC_STRUCT(gl_config);
+ if (vis) {
+ if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag,
+ redBits, greenBits, blueBits, alphaBits,
+ depthBits, stencilBits,
+ accumRedBits, accumGreenBits,
+ accumBlueBits, accumAlphaBits,
+ numSamples)) {
+ free(vis);
+ return NULL;
+ }
+ }
+ return vis;
+}
+
+
+/**
+ * Makes some sanity checks and fills in the fields of the struct
+ * gl_config object with the given parameters. If the caller needs to
+ * set additional fields, he should just probably init the whole
+ * gl_config object himself.
+ *
+ * \return GL_TRUE on success, or GL_FALSE on failure.
+ *
+ * \sa _mesa_create_visual() above for the parameter description.
+ */
+GLboolean
+_mesa_initialize_visual( struct gl_config *vis,
+ GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples )
+{
+ assert(vis);
+
+ if (depthBits < 0 || depthBits > 32) {
+ return GL_FALSE;
+ }
+ if (stencilBits < 0 || stencilBits > 8) {
+ return GL_FALSE;
+ }
+ assert(accumRedBits >= 0);
+ assert(accumGreenBits >= 0);
+ assert(accumBlueBits >= 0);
+ assert(accumAlphaBits >= 0);
+
+ vis->rgbMode = GL_TRUE;
+ vis->doubleBufferMode = dbFlag;
+ vis->stereoMode = stereoFlag;
+
+ vis->redBits = redBits;
+ vis->greenBits = greenBits;
+ vis->blueBits = blueBits;
+ vis->alphaBits = alphaBits;
+ vis->rgbBits = redBits + greenBits + blueBits;
+
+ vis->indexBits = 0;
+ vis->depthBits = depthBits;
+ vis->stencilBits = stencilBits;
+
+ vis->accumRedBits = accumRedBits;
+ vis->accumGreenBits = accumGreenBits;
+ vis->accumBlueBits = accumBlueBits;
+ vis->accumAlphaBits = accumAlphaBits;
+
+ vis->haveAccumBuffer = accumRedBits > 0;
+ vis->haveDepthBuffer = depthBits > 0;
+ vis->haveStencilBuffer = stencilBits > 0;
+
+ vis->numAuxBuffers = 0;
+ vis->level = 0;
+ vis->sampleBuffers = numSamples > 0 ? 1 : 0;
+ vis->samples = numSamples;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Destroy a visual and free its memory.
+ *
+ * \param vis visual.
+ *
+ * Frees the visual structure.
+ */
+void
+_mesa_destroy_visual( struct gl_config *vis )
+{
+ free(vis);
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Context allocation, initialization, destroying
+ *
+ * The purpose of the most initialization functions here is to provide the
+ * default state values according to the OpenGL specification.
+ */
+/**********************************************************************/
+/*@{*/
+
+
+/**
+ * This is lame. gdb only seems to recognize enum types that are
+ * actually used somewhere. We want to be able to print/use enum
+ * values such as TEXTURE_2D_INDEX in gdb. But we don't actually use
+ * the gl_texture_index type anywhere. Thus, this lame function.
+ */
+static void
+dummy_enum_func(void)
+{
+ gl_buffer_index bi = BUFFER_FRONT_LEFT;
+ gl_face_index fi = FACE_POS_X;
+ gl_frag_result fr = FRAG_RESULT_DEPTH;
+ gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX;
+ gl_vert_attrib va = VERT_ATTRIB_POS;
+ gl_varying_slot vs = VARYING_SLOT_POS;
+
+ (void) bi;
+ (void) fi;
+ (void) fr;
+ (void) ti;
+ (void) va;
+ (void) vs;
+}
+
+
+/**
+ * One-time initialization mutex lock.
+ *
+ * \sa Used by one_time_init().
+ */
+mtx_t OneTimeLock = _MTX_INITIALIZER_NP;
+
+
+
+/**
+ * Calls all the various one-time-init functions in Mesa.
+ *
+ * While holding a global mutex lock, calls several initialization functions,
+ * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
+ * defined.
+ *
+ * \sa _math_init().
+ */
+static void
+one_time_init( struct gl_context *ctx )
+{
+ static GLbitfield api_init_mask = 0x0;
+
+ mtx_lock(&OneTimeLock);
+
+ /* truly one-time init */
+ if (!api_init_mask) {
+ GLuint i;
+
+ /* do some implementation tests */
+ assert( sizeof(GLbyte) == 1 );
+ assert( sizeof(GLubyte) == 1 );
+ assert( sizeof(GLshort) == 2 );
+ assert( sizeof(GLushort) == 2 );
+ assert( sizeof(GLint) == 4 );
+ assert( sizeof(GLuint) == 4 );
+
+ _mesa_get_cpu_features();
+
+ for (i = 0; i < 256; i++) {
+ _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
+ }
+
+#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
+ if (MESA_VERBOSE != 0) {
+ _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
+ PACKAGE_VERSION, __DATE__, __TIME__);
+ }
+#endif
+
+#ifdef DEBUG
+ _mesa_test_formats();
+#endif
+
+ _mesa_create_shader_compiler();
+ }
+
+ /* per-API one-time init */
+ if (!(api_init_mask & (1 << ctx->API))) {
+ _mesa_init_get_hash(ctx);
+
+ _mesa_init_remap_table();
+ }
+
+ api_init_mask |= 1 << ctx->API;
+
+ mtx_unlock(&OneTimeLock);
+
+ /* Hopefully atexit() is widely available. If not, we may need some
+ * #ifdef tests here.
+ */
+ atexit(_mesa_destroy_shader_compiler);
+
+ dummy_enum_func();
+}
+
+
+/**
+ * Initialize fields of gl_current_attrib (aka ctx->Current.*)
+ */
+static void
+_mesa_init_current(struct gl_context *ctx)
+{
+ GLuint i;
+
+ /* Init all to (0,0,0,1) */
+ for (i = 0; i < Elements(ctx->Current.Attrib); i++) {
+ ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
+ }
+
+ /* redo special cases: */
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
+}
+
+
+/**
+ * Init vertex/fragment/geometry program limits.
+ * Important: drivers should override these with actual limits.
+ */
+static void
+init_program_limits(struct gl_context *ctx, gl_shader_stage stage,
+ struct gl_program_constants *prog)
+{
+ prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS;
+ prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS;
+ prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS;
+ prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS;
+ prog->MaxTemps = MAX_PROGRAM_TEMPS;
+ prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
+ prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
+ prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS;
+
+ switch (stage) {
+ case MESA_SHADER_VERTEX:
+ prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
+ prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
+ prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+ prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
+ prog->MaxInputComponents = 0; /* value not used */
+ prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
+ break;
+ case MESA_SHADER_FRAGMENT:
+ prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
+ prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
+ prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
+ prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
+ prog->MaxOutputComponents = 0; /* value not used */
+ break;
+ case MESA_SHADER_GEOMETRY:
+ prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
+ prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
+ prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+ prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
+ prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
+ prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
+ break;
+ case MESA_SHADER_COMPUTE:
+ prog->MaxParameters = 0; /* not meaningful for compute shaders */
+ prog->MaxAttribs = 0; /* not meaningful for compute shaders */
+ prog->MaxAddressRegs = 0; /* not meaningful for compute shaders */
+ prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
+ prog->MaxInputComponents = 0; /* not meaningful for compute shaders */
+ prog->MaxOutputComponents = 0; /* not meaningful for compute shaders */
+ break;
+ default:
+ assert(0 && "Bad shader stage in init_program_limits()");
+ }
+
+ /* Set the native limits to zero. This implies that there is no native
+ * support for shaders. Let the drivers fill in the actual values.
+ */
+ prog->MaxNativeInstructions = 0;
+ prog->MaxNativeAluInstructions = 0;
+ prog->MaxNativeTexInstructions = 0;
+ prog->MaxNativeTexIndirections = 0;
+ prog->MaxNativeAttribs = 0;
+ prog->MaxNativeTemps = 0;
+ prog->MaxNativeAddressRegs = 0;
+ prog->MaxNativeParameters = 0;
+
+ /* Set GLSL datatype range/precision info assuming IEEE float values.
+ * Drivers should override these defaults as needed.
+ */
+ prog->MediumFloat.RangeMin = 127;
+ prog->MediumFloat.RangeMax = 127;
+ prog->MediumFloat.Precision = 23;
+ prog->LowFloat = prog->HighFloat = prog->MediumFloat;
+
+ /* Assume ints are stored as floats for now, since this is the least-common
+ * denominator. The OpenGL ES spec implies (page 132) that the precision
+ * of integer types should be 0. Practically speaking, IEEE
+ * single-precision floating point values can only store integers in the
+ * range [-0x01000000, 0x01000000] without loss of precision.
+ */
+ prog->MediumInt.RangeMin = 24;
+ prog->MediumInt.RangeMax = 24;
+ prog->MediumInt.Precision = 0;
+ prog->LowInt = prog->HighInt = prog->MediumInt;
+
+ prog->MaxUniformBlocks = 12;
+ prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents +
+ ctx->Const.MaxUniformBlockSize / 4 *
+ prog->MaxUniformBlocks);
+
+ prog->MaxAtomicBuffers = 0;
+ prog->MaxAtomicCounters = 0;
+}
+
+
+/**
+ * Initialize fields of gl_constants (aka ctx->Const.*).
+ * Use defaults from config.h. The device drivers will often override
+ * some of these values (such as number of texture units).
+ */
+static void
+_mesa_init_constants(struct gl_context *ctx)
+{
+ int i;
+ assert(ctx);
+
+ /* Constants, may be overriden (usually only reduced) by device drivers */
+ ctx->Const.MaxTextureMbytes = MAX_TEXTURE_MBYTES;
+ ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
+ ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
+ ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
+ ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
+ ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
+ ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
+ ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
+ ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
+ ctx->Const.MaxTextureBufferSize = 65536;
+ ctx->Const.TextureBufferOffsetAlignment = 1;
+ ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
+ ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
+ ctx->Const.MinPointSize = MIN_POINT_SIZE;
+ ctx->Const.MaxPointSize = MAX_POINT_SIZE;
+ ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
+ ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
+ ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
+ ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
+ ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
+ ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
+ ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
+ ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
+ ctx->Const.MaxClipPlanes = 6;
+ ctx->Const.MaxLights = MAX_LIGHTS;
+ ctx->Const.MaxShininess = 128.0;
+ ctx->Const.MaxSpotExponent = 128.0;
+ ctx->Const.MaxViewportWidth = MAX_VIEWPORT_WIDTH;
+ ctx->Const.MaxViewportHeight = MAX_VIEWPORT_HEIGHT;
+ ctx->Const.MinMapBufferAlignment = 64;
+
+ /* Driver must override these values if ARB_viewport_array is supported. */
+ ctx->Const.MaxViewports = 1;
+ ctx->Const.ViewportSubpixelBits = 0;
+ ctx->Const.ViewportBounds.Min = 0;
+ ctx->Const.ViewportBounds.Max = 0;
+
+ /** GL_ARB_uniform_buffer_object */
+ ctx->Const.MaxCombinedUniformBlocks = 36;
+ ctx->Const.MaxUniformBufferBindings = 36;
+ ctx->Const.MaxUniformBlockSize = 16384;
+ ctx->Const.UniformBufferOffsetAlignment = 1;
+
+ for (i = 0; i < MESA_SHADER_STAGES; i++)
+ init_program_limits(ctx, i, &ctx->Const.Program[i]);
+
+ ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
+ ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
+
+ /* CheckArrayBounds is overriden by drivers/x11 for X server */
+ ctx->Const.CheckArrayBounds = GL_FALSE;
+
+ /* GL_ARB_draw_buffers */
+ ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
+
+ ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
+ ctx->Const.MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE;
+
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+ ctx->Const.MaxVarying = 16; /* old limit not to break tnl and swrast */
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ ctx->Const.MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
+ ctx->Const.MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
+
+ /* Shading language version */
+ if (_mesa_is_desktop_gl(ctx)) {
+ ctx->Const.GLSLVersion = 120;
+ _mesa_override_glsl_version(ctx);
+ }
+ else if (ctx->API == API_OPENGLES2) {
+ ctx->Const.GLSLVersion = 100;
+ }
+ else if (ctx->API == API_OPENGLES) {
+ ctx->Const.GLSLVersion = 0; /* GLSL not supported */
+ }
+
+ /* GL_ARB_framebuffer_object */
+ ctx->Const.MaxSamples = 0;
+
+ /* GL_ARB_sync */
+ ctx->Const.MaxServerWaitTimeout = 0x1fff7fffffffULL;
+
+ /* GL_ATI_envmap_bumpmap */
+ ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
+
+ /* GL_EXT_provoking_vertex */
+ ctx->Const.QuadsFollowProvokingVertexConvention = GL_TRUE;
+
+ /* GL_EXT_transform_feedback */
+ ctx->Const.MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS;
+ ctx->Const.MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
+ ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
+ ctx->Const.MaxVertexStreams = 1;
+
+ /* GL 3.2 */
+ ctx->Const.ProfileMask = ctx->API == API_OPENGL_CORE
+ ? GL_CONTEXT_CORE_PROFILE_BIT
+ : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
+
+ /** GL_EXT_gpu_shader4 */
+ ctx->Const.MinProgramTexelOffset = -8;
+ ctx->Const.MaxProgramTexelOffset = 7;
+
+ /* GL_ARB_texture_gather */
+ ctx->Const.MinProgramTextureGatherOffset = -8;
+ ctx->Const.MaxProgramTextureGatherOffset = 7;
+
+ /* GL_ARB_robustness */
+ ctx->Const.ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB;
+
+ /* PrimitiveRestart */
+ ctx->Const.PrimitiveRestartInSoftware = GL_FALSE;
+
+ /* ES 3.0 or ARB_ES3_compatibility */
+ ctx->Const.MaxElementIndex = 0xffffffffu;
+
+ /* GL_ARB_texture_multisample */
+ ctx->Const.MaxColorTextureSamples = 1;
+ ctx->Const.MaxDepthTextureSamples = 1;
+ ctx->Const.MaxIntegerSamples = 1;
+
+ /* GL_ARB_shader_atomic_counters */
+ ctx->Const.MaxAtomicBufferBindings = MAX_COMBINED_ATOMIC_BUFFERS;
+ ctx->Const.MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE;
+ ctx->Const.MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS;
+ ctx->Const.MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS;
+
+ /* GL_ARB_vertex_attrib_binding */
+ ctx->Const.MaxVertexAttribRelativeOffset = 2047;
+ ctx->Const.MaxVertexAttribBindings = MAX_VERTEX_GENERIC_ATTRIBS;
+
+ /* GL_ARB_compute_shader */
+ ctx->Const.MaxComputeWorkGroupCount[0] = 65535;
+ ctx->Const.MaxComputeWorkGroupCount[1] = 65535;
+ ctx->Const.MaxComputeWorkGroupCount[2] = 65535;
+ ctx->Const.MaxComputeWorkGroupSize[0] = 1024;
+ ctx->Const.MaxComputeWorkGroupSize[1] = 1024;
+ ctx->Const.MaxComputeWorkGroupSize[2] = 64;
+ ctx->Const.MaxComputeWorkGroupInvocations = 1024;
+
+ /** GL_ARB_gpu_shader5 */
+ ctx->Const.MinFragmentInterpolationOffset = MIN_FRAGMENT_INTERPOLATION_OFFSET;
+ ctx->Const.MaxFragmentInterpolationOffset = MAX_FRAGMENT_INTERPOLATION_OFFSET;
+
+ ctx->Const.GlassMode = 0;
+}
+
+
+/**
+ * Do some sanity checks on the limits/constants for the given context.
+ * Only called the first time a context is bound.
+ */
+static void
+check_context_limits(struct gl_context *ctx)
+{
+ /* check that we don't exceed the size of various bitfields */
+ assert(VARYING_SLOT_MAX <=
+ (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
+ assert(VARYING_SLOT_MAX <=
+ (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
+
+ /* shader-related checks */
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+ assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+
+ /* Texture unit checks */
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits > 0);
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
+ assert(ctx->Const.MaxTextureCoordUnits > 0);
+ assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
+ assert(ctx->Const.MaxTextureUnits > 0);
+ assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
+ assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
+ assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
+ ctx->Const.MaxTextureCoordUnits));
+ assert(ctx->Const.MaxCombinedTextureImageUnits > 0);
+ assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ /* number of coord units cannot be greater than number of image units */
+ assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
+
+
+ /* Texture size checks */
+ assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS);
+ assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS);
+ assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS);
+ assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE);
+
+ /* Texture level checks */
+ assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
+ assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
+
+ /* Max texture size should be <= max viewport size (render to texture) */
+ assert((1U << (ctx->Const.MaxTextureLevels - 1))
+ <= ctx->Const.MaxViewportWidth);
+ assert((1U << (ctx->Const.MaxTextureLevels - 1))
+ <= ctx->Const.MaxViewportHeight);
+
+ assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
+
+ /* if this fails, add more enum values to gl_buffer_index */
+ assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
+
+ /* XXX probably add more tests */
+}
+
+
+/**
+ * Initialize the attribute groups in a GL context.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes all the attributes, calling the respective <tt>init*</tt>
+ * functions for the more complex data structures.
+ */
+static GLboolean
+init_attrib_groups(struct gl_context *ctx)
+{
+ assert(ctx);
+
+ /* Constants */
+ _mesa_init_constants( ctx );
+
+ /* Extensions */
+ _mesa_init_extensions( ctx );
+
+ /* Attribute Groups */
+ _mesa_init_accum( ctx );
+ _mesa_init_attrib( ctx );
+ _mesa_init_buffer_objects( ctx );
+ _mesa_init_color( ctx );
+ _mesa_init_current( ctx );
+ _mesa_init_depth( ctx );
+ _mesa_init_debug( ctx );
+ _mesa_init_display_list( ctx );
+ _mesa_init_errors( ctx );
+ _mesa_init_eval( ctx );
+ _mesa_init_fbobjects( ctx );
+ _mesa_init_feedback( ctx );
+ _mesa_init_fog( ctx );
+ _mesa_init_hint( ctx );
+ _mesa_init_line( ctx );
+ _mesa_init_lighting( ctx );
+ _mesa_init_matrix( ctx );
+ _mesa_init_multisample( ctx );
+ _mesa_init_performance_monitors( ctx );
+ _mesa_init_pipeline( ctx );
+ _mesa_init_pixel( ctx );
+ _mesa_init_pixelstore( ctx );
+ _mesa_init_point( ctx );
+ _mesa_init_polygon( ctx );
+ _mesa_init_program( ctx );
+ _mesa_init_queryobj( ctx );
+ _mesa_init_sync( ctx );
+ _mesa_init_rastpos( ctx );
+ _mesa_init_scissor( ctx );
+ _mesa_init_shader_state( ctx );
+ _mesa_init_stencil( ctx );
+ _mesa_init_transform( ctx );
+ _mesa_init_transform_feedback( ctx );
+ _mesa_init_varray( ctx );
+ _mesa_init_viewport( ctx );
+
+ if (!_mesa_init_texture( ctx ))
+ return GL_FALSE;
+
+ _mesa_init_texture_s3tc( ctx );
+
+ /* Miscellaneous */
+ ctx->NewState = _NEW_ALL;
+ ctx->NewDriverState = ~0;
+ ctx->ErrorValue = GL_NO_ERROR;
+ ctx->ShareGroupReset = false;
+ ctx->varying_vp_inputs = VERT_BIT_ALL;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Update default objects in a GL context with respect to shared state.
+ *
+ * \param ctx GL context.
+ *
+ * Removes references to old default objects, (texture objects, program
+ * objects, etc.) and changes to reference those from the current shared
+ * state.
+ */
+static GLboolean
+update_default_objects(struct gl_context *ctx)
+{
+ assert(ctx);
+
+ _mesa_update_default_objects_program(ctx);
+ _mesa_update_default_objects_texture(ctx);
+ _mesa_update_default_objects_buffer_objects(ctx);
+
+ return GL_TRUE;
+}
+
+
+/**
+ * This is the default function we plug into all dispatch table slots
+ * This helps prevents a segfault when someone calls a GL function without
+ * first checking if the extension's supported.
+ */
+int
+_mesa_generic_nop(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "unsupported function called "
+ "(unsupported extension or deprecated function?)");
+ return 0;
+}
+
+
+/**
+ * Allocate and initialize a new dispatch table.
+ */
+struct _glapi_table *
+_mesa_alloc_dispatch_table()
+{
+ /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
+ * In practice, this'll be the same for stand-alone Mesa. But for DRI
+ * Mesa we do this to accomodate different versions of libGL and various
+ * DRI drivers.
+ */
+ GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
+ struct _glapi_table *table;
+
+ table = malloc(numEntries * sizeof(_glapi_proc));
+ if (table) {
+ _glapi_proc *entry = (_glapi_proc *) table;
+ GLint i;
+ for (i = 0; i < numEntries; i++) {
+ entry[i] = (_glapi_proc) _mesa_generic_nop;
+ }
+ }
+ return table;
+}
+
+/**
+ * Creates a minimal dispatch table for use within glBegin()/glEnd().
+ *
+ * This ensures that we generate GL_INVALID_OPERATION errors from most
+ * functions, since the set of functions that are valid within Begin/End is
+ * very small.
+ *
+ * From the GL 1.0 specification section 2.6.3, "GL Commands within
+ * Begin/End"
+ *
+ * "The only GL commands that are allowed within any Begin/End pairs are
+ * the commands for specifying vertex coordinates, vertex color, normal
+ * coordinates, and texture coordinates (Vertex, Color, Index, Normal,
+ * TexCoord), EvalCoord and EvalPoint commands (see section 5.1),
+ * commands for specifying lighting material parameters (Material
+ * commands see section 2.12.2), display list invocation commands
+ * (CallList and CallLists see section 5.4), and the EdgeFlag
+ * command. Executing Begin after Begin has already been executed but
+ * before an End is issued generates the INVALID OPERATION error, as does
+ * executing End without a previous corresponding Begin. Executing any
+ * other GL command within Begin/End results in the error INVALID
+ * OPERATION."
+ *
+ * The table entries for specifying vertex attributes are set up by
+ * install_vtxfmt() and _mesa_loopback_init_api_table(), and End() and dlists
+ * are set by install_vtxfmt() as well.
+ */
+static struct _glapi_table *
+create_beginend_table(const struct gl_context *ctx)
+{
+ struct _glapi_table *table;
+
+ table = _mesa_alloc_dispatch_table();
+ if (!table)
+ return NULL;
+
+ /* Fill in functions which return a value, since they should return some
+ * specific value even if they emit a GL_INVALID_OPERATION error from them
+ * being called within glBegin()/glEnd().
+ */
+#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec))
+
+ COPY_DISPATCH(GenLists);
+ COPY_DISPATCH(IsProgram);
+ COPY_DISPATCH(IsVertexArray);
+ COPY_DISPATCH(IsBuffer);
+ COPY_DISPATCH(IsEnabled);
+ COPY_DISPATCH(IsEnabledi);
+ COPY_DISPATCH(IsRenderbuffer);
+ COPY_DISPATCH(IsFramebuffer);
+ COPY_DISPATCH(CheckFramebufferStatus);
+ COPY_DISPATCH(RenderMode);
+ COPY_DISPATCH(GetString);
+ COPY_DISPATCH(GetStringi);
+ COPY_DISPATCH(GetPointerv);
+ COPY_DISPATCH(IsQuery);
+ COPY_DISPATCH(IsSampler);
+ COPY_DISPATCH(IsSync);
+ COPY_DISPATCH(IsTexture);
+ COPY_DISPATCH(IsTransformFeedback);
+ COPY_DISPATCH(DeleteQueries);
+ COPY_DISPATCH(AreTexturesResident);
+ COPY_DISPATCH(FenceSync);
+ COPY_DISPATCH(ClientWaitSync);
+ COPY_DISPATCH(MapBuffer);
+ COPY_DISPATCH(UnmapBuffer);
+ COPY_DISPATCH(MapBufferRange);
+ COPY_DISPATCH(ObjectPurgeableAPPLE);
+ COPY_DISPATCH(ObjectUnpurgeableAPPLE);
+
+ _mesa_loopback_init_api_table(ctx, table);
+
+ return table;
+}
+
+void
+_mesa_initialize_dispatch_tables(struct gl_context *ctx)
+{
+ /* Do the code-generated setup of the exec table in api_exec.c. */
+ _mesa_initialize_exec_table(ctx);
+
+ if (ctx->Save)
+ _mesa_initialize_save_table(ctx);
+}
+
+
+/**
+ * Initialize a struct gl_context struct (rendering context).
+ *
+ * This includes allocating all the other structs and arrays which hang off of
+ * the context by pointers.
+ * Note that the driver needs to pass in its dd_function_table here since
+ * we need to at least call driverFunctions->NewTextureObject to create the
+ * default texture objects.
+ *
+ * Called by _mesa_create_context().
+ *
+ * Performs the imports and exports callback tables initialization, and
+ * miscellaneous one-time initializations. If no shared context is supplied one
+ * is allocated, and increase its reference count. Setups the GL API dispatch
+ * tables. Initialize the TNL module. Sets the maximum Z buffer depth.
+ * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
+ * for debug flags.
+ *
+ * \param ctx the context to initialize
+ * \param api the GL API type to create the context for
+ * \param visual describes the visual attributes for this context or NULL to
+ * create a configless context
+ * \param share_list points to context to share textures, display lists,
+ * etc with, or NULL
+ * \param driverFunctions table of device driver functions for this context
+ * to use
+ */
+GLboolean
+_mesa_initialize_context(struct gl_context *ctx,
+ gl_api api,
+ const struct gl_config *visual,
+ struct gl_context *share_list,
+ const struct dd_function_table *driverFunctions)
+{
+ struct gl_shared_state *shared;
+ int i;
+
+ assert(driverFunctions->NewTextureObject);
+ assert(driverFunctions->FreeTextureImageBuffer);
+
+ ctx->API = api;
+ ctx->DrawBuffer = NULL;
+ ctx->ReadBuffer = NULL;
+ ctx->WinSysDrawBuffer = NULL;
+ ctx->WinSysReadBuffer = NULL;
+
+ if (visual) {
+ ctx->Visual = *visual;
+ ctx->HasConfig = GL_TRUE;
+ }
+ else {
+ memset(&ctx->Visual, 0, sizeof ctx->Visual);
+ ctx->HasConfig = GL_FALSE;
+ }
+
+ if (_mesa_is_desktop_gl(ctx)) {
+ _mesa_override_gl_version(ctx);
+ }
+
+ /* misc one-time initializations */
+ one_time_init(ctx);
+
+ /* Plug in driver functions and context pointer here.
+ * This is important because when we call alloc_shared_state() below
+ * we'll call ctx->Driver.NewTextureObject() to create the default
+ * textures.
+ */
+ ctx->Driver = *driverFunctions;
+
+ if (share_list) {
+ /* share state with another context */
+ shared = share_list->Shared;
+ }
+ else {
+ /* allocate new, unshared state */
+ shared = _mesa_alloc_shared_state(ctx);
+ if (!shared)
+ return GL_FALSE;
+ }
+
+ _mesa_reference_shared_state(ctx, &ctx->Shared, shared);
+
+ if (!init_attrib_groups( ctx ))
+ goto fail;
+
+ /* setup the API dispatch tables with all nop functions */
+ ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table();
+ if (!ctx->OutsideBeginEnd)
+ goto fail;
+ ctx->Exec = ctx->OutsideBeginEnd;
+ ctx->CurrentDispatch = ctx->OutsideBeginEnd;
+
+ ctx->FragmentProgram._MaintainTexEnvProgram
+ = (_mesa_getenv("MESA_TEX_PROG") != NULL);
+
+ ctx->VertexProgram._MaintainTnlProgram
+ = (_mesa_getenv("MESA_TNL_PROG") != NULL);
+ if (ctx->VertexProgram._MaintainTnlProgram) {
+ /* this is required... */
+ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+ }
+
+ /* Mesa core handles all the formats that mesa core knows about.
+ * Drivers will want to override this list with just the formats
+ * they can handle, and confirm that appropriate fallbacks exist in
+ * _mesa_choose_tex_format().
+ */
+ memset(&ctx->TextureFormatSupported, GL_TRUE,
+ sizeof(ctx->TextureFormatSupported));
+
+ switch (ctx->API) {
+ case API_OPENGL_COMPAT:
+ ctx->BeginEnd = create_beginend_table(ctx);
+ ctx->Save = _mesa_alloc_dispatch_table();
+ if (!ctx->BeginEnd || !ctx->Save)
+ goto fail;
+
+ /* fall-through */
+ case API_OPENGL_CORE:
+ break;
+ case API_OPENGLES:
+ /**
+ * GL_OES_texture_cube_map says
+ * "Initially all texture generation modes are set to REFLECTION_MAP_OES"
+ */
+ for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+ texUnit->GenS.Mode = GL_REFLECTION_MAP_NV;
+ texUnit->GenT.Mode = GL_REFLECTION_MAP_NV;
+ texUnit->GenR.Mode = GL_REFLECTION_MAP_NV;
+ texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV;
+ texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV;
+ texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV;
+ }
+ break;
+ case API_OPENGLES2:
+ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+ ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
+ break;
+ }
+
+ ctx->FirstTimeCurrent = GL_TRUE;
+
+ ctx->GlslFlags =_mesa_get_shader_flags();
+
+ return GL_TRUE;
+
+fail:
+ _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
+ free(ctx->BeginEnd);
+ free(ctx->OutsideBeginEnd);
+ free(ctx->Save);
+ return GL_FALSE;
+}
+
+
+/**
+ * Allocate and initialize a struct gl_context structure.
+ * Note that the driver needs to pass in its dd_function_table here since
+ * we need to at least call driverFunctions->NewTextureObject to initialize
+ * the rendering context.
+ *
+ * \param api the GL API type to create the context for
+ * \param visual a struct gl_config pointer (we copy the struct contents) or
+ * NULL to create a configless context
+ * \param share_list another context to share display lists with or NULL
+ * \param driverFunctions points to the dd_function_table into which the
+ * driver has plugged in all its special functions.
+ *
+ * \return pointer to a new __struct gl_contextRec or NULL if error.
+ */
+struct gl_context *
+_mesa_create_context(gl_api api,
+ const struct gl_config *visual,
+ struct gl_context *share_list,
+ const struct dd_function_table *driverFunctions)
+{
+ struct gl_context *ctx;
+
+ ctx = calloc(1, sizeof(struct gl_context));
+ if (!ctx)
+ return NULL;
+
+ if (_mesa_initialize_context(ctx, api, visual, share_list,
+ driverFunctions)) {
+ return ctx;
+ }
+ else {
+ free(ctx);
+ return NULL;
+ }
+}
+
+void
+_mesa_enable_glsl_threadpool(struct gl_context *ctx, int max_threads)
+{
+ if (!ctx->ThreadPool)
+ ctx->ThreadPool = _mesa_glsl_get_threadpool(max_threads);
+}
+
+static void
+wait_shader_object_cb(GLuint id, void *data, void *userData)
+{
+ struct gl_context *ctx = (struct gl_context *) userData;
+ struct gl_shader *sh = (struct gl_shader *) data;
+
+ if (_mesa_validate_shader_target(ctx, sh->Type)) {
+ _mesa_wait_shaders(ctx, &sh, 1);
+ }
+ else {
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+ _mesa_wait_shader_program(ctx, shProg);
+ }
+}
+
+/**
+ * Free the data associated with the given context.
+ *
+ * But doesn't free the struct gl_context struct itself.
+ *
+ * \sa _mesa_initialize_context() and init_attrib_groups().
+ */
+void
+_mesa_free_context_data( struct gl_context *ctx )
+{
+ if (!_mesa_get_current_context()){
+ /* No current context, but we may need one in order to delete
+ * texture objs, etc. So temporarily bind the context now.
+ */
+ _mesa_make_current(ctx, NULL, NULL);
+ }
+
+ if (ctx->ThreadPool) {
+ _mesa_HashWalk(ctx->Shared->ShaderObjects, wait_shader_object_cb, ctx);
+ _mesa_threadpool_unref(ctx->ThreadPool);
+ ctx->ThreadPool = NULL;
+ }
+
+ /* unreference WinSysDraw/Read buffers */
+ _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
+ _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
+ _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
+ _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);
+
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
+
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
+
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
+
+ _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
+ _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
+
+ _mesa_free_attrib_data(ctx);
+ _mesa_free_buffer_objects(ctx);
+ _mesa_free_lighting_data( ctx );
+ _mesa_free_eval_data( ctx );
+ _mesa_free_texture_data( ctx );
+ _mesa_free_matrix_data( ctx );
+ _mesa_free_viewport_data( ctx );
+ _mesa_free_pipeline_data(ctx);
+ _mesa_free_program_data(ctx);
+ _mesa_free_shader_state(ctx);
+ _mesa_free_queryobj_data(ctx);
+ _mesa_free_sync_data(ctx);
+ _mesa_free_varray_data(ctx);
+ _mesa_free_transform_feedback(ctx);
+ _mesa_free_performance_monitors(ctx);
+
+ _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
+
+ /* free dispatch tables */
+ free(ctx->BeginEnd);
+ free(ctx->OutsideBeginEnd);
+ free(ctx->Save);
+
+ /* Shared context state (display lists, textures, etc) */
+ _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
+
+ /* needs to be after freeing shared state */
+ _mesa_free_display_list_data(ctx);
+
+ _mesa_free_errors_data(ctx);
+
+ free((void *)ctx->Extensions.String);
+
+ free(ctx->VersionString);
+
+ /* unbind the context if it's currently bound */
+ if (ctx == _mesa_get_current_context()) {
+ _mesa_make_current(NULL, NULL, NULL);
+ }
+}
+
+
+/**
+ * Destroy a struct gl_context structure.
+ *
+ * \param ctx GL context.
+ *
+ * Calls _mesa_free_context_data() and frees the gl_context object itself.
+ */
+void
+_mesa_destroy_context( struct gl_context *ctx )
+{
+ if (ctx) {
+ _mesa_free_context_data(ctx);
+ free( (void *) ctx );
+ }
+}
+
+
+/**
+ * Copy attribute groups from one context to another.
+ *
+ * \param src source context
+ * \param dst destination context
+ * \param mask bitwise OR of GL_*_BIT flags
+ *
+ * According to the bits specified in \p mask, copies the corresponding
+ * attributes from \p src into \p dst. For many of the attributes a simple \c
+ * memcpy is not enough due to the existence of internal pointers in their data
+ * structures.
+ */
+void
+_mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
+ GLuint mask )
+{
+ if (mask & GL_ACCUM_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Accum = src->Accum;
+ }
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Color = src->Color;
+ }
+ if (mask & GL_CURRENT_BIT) {
+ /* OK to memcpy */
+ dst->Current = src->Current;
+ }
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Depth = src->Depth;
+ }
+ if (mask & GL_ENABLE_BIT) {
+ /* no op */
+ }
+ if (mask & GL_EVAL_BIT) {
+ /* OK to memcpy */
+ dst->Eval = src->Eval;
+ }
+ if (mask & GL_FOG_BIT) {
+ /* OK to memcpy */
+ dst->Fog = src->Fog;
+ }
+ if (mask & GL_HINT_BIT) {
+ /* OK to memcpy */
+ dst->Hint = src->Hint;
+ }
+ if (mask & GL_LIGHTING_BIT) {
+ GLuint i;
+ /* begin with memcpy */
+ dst->Light = src->Light;
+ /* fixup linked lists to prevent pointer insanity */
+ make_empty_list( &(dst->Light.EnabledList) );
+ for (i = 0; i < MAX_LIGHTS; i++) {
+ if (dst->Light.Light[i].Enabled) {
+ insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
+ }
+ }
+ }
+ if (mask & GL_LINE_BIT) {
+ /* OK to memcpy */
+ dst->Line = src->Line;
+ }
+ if (mask & GL_LIST_BIT) {
+ /* OK to memcpy */
+ dst->List = src->List;
+ }
+ if (mask & GL_PIXEL_MODE_BIT) {
+ /* OK to memcpy */
+ dst->Pixel = src->Pixel;
+ }
+ if (mask & GL_POINT_BIT) {
+ /* OK to memcpy */
+ dst->Point = src->Point;
+ }
+ if (mask & GL_POLYGON_BIT) {
+ /* OK to memcpy */
+ dst->Polygon = src->Polygon;
+ }
+ if (mask & GL_POLYGON_STIPPLE_BIT) {
+ /* Use loop instead of memcpy due to problem with Portland Group's
+ * C compiler. Reported by John Stone.
+ */
+ GLuint i;
+ for (i = 0; i < 32; i++) {
+ dst->PolygonStipple[i] = src->PolygonStipple[i];
+ }
+ }
+ if (mask & GL_SCISSOR_BIT) {
+ /* OK to memcpy */
+ dst->Scissor = src->Scissor;
+ }
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Stencil = src->Stencil;
+ }
+ if (mask & GL_TEXTURE_BIT) {
+ /* Cannot memcpy because of pointers */
+ _mesa_copy_texture_state(src, dst);
+ }
+ if (mask & GL_TRANSFORM_BIT) {
+ /* OK to memcpy */
+ dst->Transform = src->Transform;
+ }
+ if (mask & GL_VIEWPORT_BIT) {
+ /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
+ unsigned i;
+ for (i = 0; i < src->Const.MaxViewports; i++) {
+ dst->ViewportArray[i].X = src->ViewportArray[i].X;
+ dst->ViewportArray[i].Y = src->ViewportArray[i].Y;
+ dst->ViewportArray[i].Width = src->ViewportArray[i].Width;
+ dst->ViewportArray[i].Height = src->ViewportArray[i].Height;
+ dst->ViewportArray[i].Near = src->ViewportArray[i].Near;
+ dst->ViewportArray[i].Far = src->ViewportArray[i].Far;
+ _math_matrix_copy(&dst->ViewportArray[i]._WindowMap,
+ &src->ViewportArray[i]._WindowMap);
+ }
+ }
+
+ /* XXX FIXME: Call callbacks?
+ */
+ dst->NewState = _NEW_ALL;
+ dst->NewDriverState = ~0;
+}
+
+
+/**
+ * Check if the given context can render into the given framebuffer
+ * by checking visual attributes.
+ *
+ * Most of these tests could go away because Mesa is now pretty flexible
+ * in terms of mixing rendering contexts with framebuffers. As long
+ * as RGB vs. CI mode agree, we're probably good.
+ *
+ * \return GL_TRUE if compatible, GL_FALSE otherwise.
+ */
+static GLboolean
+check_compatible(const struct gl_context *ctx,
+ const struct gl_framebuffer *buffer)
+{
+ const struct gl_config *ctxvis = &ctx->Visual;
+ const struct gl_config *bufvis = &buffer->Visual;
+
+ if (buffer == _mesa_get_incomplete_framebuffer())
+ return GL_TRUE;
+
+#if 0
+ /* disabling this fixes the fgl_glxgears pbuffer demo */
+ if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
+ return GL_FALSE;
+#endif
+ if (ctxvis->stereoMode && !bufvis->stereoMode)
+ return GL_FALSE;
+ if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
+ return GL_FALSE;
+ if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
+ return GL_FALSE;
+ if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
+ return GL_FALSE;
+ if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
+ return GL_FALSE;
+ if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
+ return GL_FALSE;
+ if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
+ return GL_FALSE;
+#if 0
+ /* disabled (see bug 11161) */
+ if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
+ return GL_FALSE;
+#endif
+ if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Check if the viewport/scissor size has not yet been initialized.
+ * Initialize the size if the given width and height are non-zero.
+ */
+void
+_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
+{
+ if (!ctx->ViewportInitialized && width > 0 && height > 0) {
+ unsigned i;
+
+ /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
+ * potential infinite recursion.
+ */
+ ctx->ViewportInitialized = GL_TRUE;
+
+ /* Note: ctx->Const.MaxViewports may not have been set by the driver
+ * yet, so just initialize all of them.
+ */
+ for (i = 0; i < MAX_VIEWPORTS; i++) {
+ _mesa_set_viewport(ctx, i, 0, 0, width, height);
+ _mesa_set_scissor(ctx, i, 0, 0, width, height);
+ }
+ }
+}
+
+static void
+handle_first_current(struct gl_context *ctx)
+{
+ GLenum buffer;
+ GLint bufferIndex;
+
+ assert(ctx->Version > 0);
+
+ ctx->Extensions.String = _mesa_make_extension_string(ctx);
+
+ check_context_limits(ctx);
+
+ /* According to GL_MESA_configless_context the default value of
+ * glDrawBuffers depends on the config of the first surface it is bound to.
+ * For GLES it is always GL_BACK which has a magic interpretation */
+ if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) {
+ if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) {
+ if (ctx->DrawBuffer->Visual.doubleBufferMode)
+ buffer = GL_BACK;
+ else
+ buffer = GL_FRONT;
+
+ _mesa_drawbuffers(ctx, 1, &buffer, NULL /* destMask */);
+ }
+
+ if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
+ if (ctx->ReadBuffer->Visual.doubleBufferMode) {
+ buffer = GL_BACK;
+ bufferIndex = BUFFER_BACK_LEFT;
+ }
+ else {
+ buffer = GL_FRONT;
+ bufferIndex = BUFFER_FRONT_LEFT;
+ }
+
+ _mesa_readbuffer(ctx, buffer, bufferIndex);
+ }
+ }
+
+ /* We can use this to help debug user's problems. Tell them to set
+ * the MESA_INFO env variable before running their app. Then the
+ * first time each context is made current we'll print some useful
+ * information.
+ */
+ if (_mesa_getenv("MESA_INFO")) {
+ _mesa_print_info(ctx);
+ }
+}
+
+/**
+ * Bind the given context to the given drawBuffer and readBuffer and
+ * make it the current context for the calling thread.
+ * We'll render into the drawBuffer and read pixels from the
+ * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
+ *
+ * We check that the context's and framebuffer's visuals are compatible
+ * and return immediately if they're not.
+ *
+ * \param newCtx the new GL context. If NULL then there will be no current GL
+ * context.
+ * \param drawBuffer the drawing framebuffer
+ * \param readBuffer the reading framebuffer
+ */
+GLboolean
+_mesa_make_current( struct gl_context *newCtx,
+ struct gl_framebuffer *drawBuffer,
+ struct gl_framebuffer *readBuffer )
+{
+ GET_CURRENT_CONTEXT(curCtx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(newCtx, "_mesa_make_current()\n");
+
+ /* Check that the context's and framebuffer's visuals are compatible.
+ */
+ if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
+ if (!check_compatible(newCtx, drawBuffer)) {
+ _mesa_warning(newCtx,
+ "MakeCurrent: incompatible visuals for context and drawbuffer");
+ return GL_FALSE;
+ }
+ }
+ if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
+ if (!check_compatible(newCtx, readBuffer)) {
+ _mesa_warning(newCtx,
+ "MakeCurrent: incompatible visuals for context and readbuffer");
+ return GL_FALSE;
+ }
+ }
+
+ if (curCtx &&
+ (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) &&
+ /* make sure this context is valid for flushing */
+ curCtx != newCtx)
+ _mesa_flush(curCtx);
+
+ /* We used to call _glapi_check_multithread() here. Now do it in drivers */
+ _glapi_set_context((void *) newCtx);
+ ASSERT(_mesa_get_current_context() == newCtx);
+
+ if (!newCtx) {
+ _glapi_set_dispatch(NULL); /* none current */
+ }
+ else {
+ _glapi_set_dispatch(newCtx->CurrentDispatch);
+
+ if (drawBuffer && readBuffer) {
+ ASSERT(_mesa_is_winsys_fbo(drawBuffer));
+ ASSERT(_mesa_is_winsys_fbo(readBuffer));
+ _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
+ _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
+
+ /*
+ * Only set the context's Draw/ReadBuffer fields if they're NULL
+ * or not bound to a user-created FBO.
+ */
+ if (!newCtx->DrawBuffer || _mesa_is_winsys_fbo(newCtx->DrawBuffer)) {
+ _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
+ /* Update the FBO's list of drawbuffers/renderbuffers.
+ * For winsys FBOs this comes from the GL state (which may have
+ * changed since the last time this FBO was bound).
+ */
+ _mesa_update_draw_buffers(newCtx);
+ }
+ if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) {
+ _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
+ }
+
+ /* XXX only set this flag if we're really changing the draw/read
+ * framebuffer bindings.
+ */
+ newCtx->NewState |= _NEW_BUFFERS;
+
+ if (drawBuffer) {
+ _mesa_check_init_viewport(newCtx,
+ drawBuffer->Width, drawBuffer->Height);
+ }
+ }
+
+ if (newCtx->FirstTimeCurrent) {
+ handle_first_current(newCtx);
+ newCtx->FirstTimeCurrent = GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Make context 'ctx' share the display lists, textures and programs
+ * that are associated with 'ctxToShare'.
+ * Any display lists, textures or programs associated with 'ctx' will
+ * be deleted if nobody else is sharing them.
+ */
+GLboolean
+_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
+{
+ if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
+ struct gl_shared_state *oldShared = NULL;
+
+ /* save ref to old state to prevent it from being deleted immediately */
+ _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared);
+
+ /* update ctx's Shared pointer */
+ _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared);
+
+ update_default_objects(ctx);
+
+ /* release the old shared state */
+ _mesa_reference_shared_state(ctx, &oldShared, NULL);
+
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
+/**
+ * \return pointer to the current GL context for this thread.
+ *
+ * Calls _glapi_get_context(). This isn't the fastest way to get the current
+ * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in
+ * context.h.
+ */
+struct gl_context *
+_mesa_get_current_context( void )
+{
+ return (struct gl_context *) _glapi_get_context();
+}
+
+
+/**
+ * Get context's current API dispatch table.
+ *
+ * It'll either be the immediate-mode execute dispatcher or the display list
+ * compile dispatcher.
+ *
+ * \param ctx GL context.
+ *
+ * \return pointer to dispatch_table.
+ *
+ * Simply returns __struct gl_contextRec::CurrentDispatch.
+ */
+struct _glapi_table *
+_mesa_get_dispatch(struct gl_context *ctx)
+{
+ return ctx->CurrentDispatch;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Miscellaneous functions */
+/**********************************************************************/
+/*@{*/
+
+/**
+ * Record an error.
+ *
+ * \param ctx GL context.
+ * \param error error code.
+ *
+ * Records the given error code and call the driver's dd_function_table::Error
+ * function if defined.
+ *
+ * \sa
+ * This is called via _mesa_error().
+ */
+void
+_mesa_record_error(struct gl_context *ctx, GLenum error)
+{
+ if (!ctx)
+ return;
+
+ if (ctx->ErrorValue == GL_NO_ERROR) {
+ ctx->ErrorValue = error;
+ }
+}
+
+
+/**
+ * Flush commands and wait for completion.
+ */
+void
+_mesa_finish(struct gl_context *ctx)
+{
+ FLUSH_VERTICES( ctx, 0 );
+ FLUSH_CURRENT( ctx, 0 );
+ if (ctx->Driver.Finish) {
+ ctx->Driver.Finish(ctx);
+ }
+}
+
+
+/**
+ * Flush commands.
+ */
+void
+_mesa_flush(struct gl_context *ctx)
+{
+ FLUSH_VERTICES( ctx, 0 );
+ FLUSH_CURRENT( ctx, 0 );
+ if (ctx->Driver.Flush) {
+ ctx->Driver.Flush(ctx);
+ }
+}
+
+
+
+/**
+ * Execute glFinish().
+ *
+ * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
+ * dd_function_table::Finish driver callback, if not NULL.
+ */
+void GLAPIENTRY
+_mesa_Finish(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ _mesa_finish(ctx);
+}
+
+
+/**
+ * Execute glFlush().
+ *
+ * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
+ * dd_function_table::Flush driver callback, if not NULL.
+ */
+void GLAPIENTRY
+_mesa_Flush(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ _mesa_flush(ctx);
+}
+
+
+/*
+ * ARB_blend_func_extended - ERRORS section
+ * "The error INVALID_OPERATION is generated by Begin or any procedure that
+ * implicitly calls Begin if any draw buffer has a blend function requiring the
+ * second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, SRC1_ALPHA or
+ * ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that has more than
+ * the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active color attachements."
+ */
+static GLboolean
+_mesa_check_blend_func_error(struct gl_context *ctx)
+{
+ GLuint i;
+ for (i = ctx->Const.MaxDualSourceDrawBuffers;
+ i < ctx->DrawBuffer->_NumColorDrawBuffers;
+ i++) {
+ if (ctx->Color.Blend[i]._UsesDualSrc) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "dual source blend on illegal attachment");
+ return GL_FALSE;
+ }
+ }
+ return GL_TRUE;
+}
+
+static bool
+shader_linked_or_absent(struct gl_context *ctx,
+ const struct gl_shader_program *shProg,
+ bool *shader_present, const char *where)
+{
+ if (shProg) {
+ *shader_present = true;
+
+ if (!shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(shader not linked)", where);
+ return false;
+ }
+#if 0 /* not normally enabled */
+ {
+ char errMsg[100];
+ if (!_mesa_validate_shader_program(ctx, shProg, errMsg)) {
+ _mesa_warning(ctx, "Shader program %u is invalid: %s",
+ shProg->Name, errMsg);
+ }
+ }
+#endif
+ }
+
+ return true;
+}
+
+/**
+ * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
+ * is called to see if it's valid to render. This involves checking that
+ * the current shader is valid and the framebuffer is complete.
+ * It also check the current pipeline object is valid if any.
+ * If an error is detected it'll be recorded here.
+ * \return GL_TRUE if OK to render, GL_FALSE if not
+ */
+GLboolean
+_mesa_valid_to_render(struct gl_context *ctx, const char *where)
+{
+ bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false };
+ unsigned i;
+
+ /* This depends on having up to date derived state (shaders) */
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ for (i = 0; i < MESA_SHADER_COMPUTE; i++) {
+ if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i],
+ &from_glsl_shader[i], where))
+ return GL_FALSE;
+ }
+
+ /* Any shader stages that are not supplied by the GLSL shader and have
+ * assembly shaders enabled must now be validated.
+ */
+ if (!from_glsl_shader[MESA_SHADER_VERTEX]
+ && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(vertex program not valid)", where);
+ return GL_FALSE;
+ }
+
+ /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current
+ * FINISHME: geometry program should validated here.
+ */
+ (void) from_glsl_shader[MESA_SHADER_GEOMETRY];
+
+ if (!from_glsl_shader[MESA_SHADER_FRAGMENT]) {
+ if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(fragment program not valid)", where);
+ return GL_FALSE;
+ }
+
+ /* If drawing to integer-valued color buffers, there must be an
+ * active fragment shader (GL_EXT_texture_integer).
+ */
+ if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(integer format but no fragment shader)", where);
+ return GL_FALSE;
+ }
+ }
+
+ /* A pipeline object is bound */
+ if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
+ /* Error message will be printed inside _mesa_validate_program_pipeline.
+ */
+ if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader, GL_TRUE)) {
+ return GL_FALSE;
+ }
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "%s(incomplete framebuffer)", where);
+ return GL_FALSE;
+ }
+
+ if (_mesa_check_blend_func_error(ctx) == GL_FALSE) {
+ return GL_FALSE;
+ }
+
+#ifdef DEBUG
+ if (ctx->GlslFlags & GLSL_LOG) {
+ struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram;
+ gl_shader_stage i;
+
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (shProg[i] == NULL || shProg[i]->_Used
+ || shProg[i]->_LinkedShaders[i] == NULL)
+ continue;
+
+ /* This is the first time this shader is being used.
+ * Append shader's constants/uniforms to log file.
+ *
+ * Only log data for the program target that matches the shader
+ * target. It's possible to have a program bound to the vertex
+ * shader target that also supplied a fragment shader. If that
+ * program isn't also bound to the fragment shader target we don't
+ * want to log its fragment data.
+ */
+ _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]);
+ }
+
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (shProg[i] != NULL)
+ shProg[i]->_Used = GL_TRUE;
+ }
+ }
+#endif
+
+ return GL_TRUE;
+}
+
+
+/*@}*/
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/context.h b/icd/intel/compiler/mesa-utils/src/mesa/main/context.h
new file mode 100644
index 0000000..b23f9fa
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/context.h
@@ -0,0 +1,334 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file context.h
+ * Mesa context and visual-related functions.
+ *
+ * There are three large Mesa data types/classes which are meant to be
+ * used by device drivers:
+ * - struct gl_context: this contains the Mesa rendering state
+ * - struct gl_config: this describes the color buffer (RGB vs. ci), whether
+ * or not there's a depth buffer, stencil buffer, etc.
+ * - struct gl_framebuffer: contains pointers to the depth buffer, stencil
+ * buffer, accum buffer and alpha buffers.
+ *
+ * These types should be encapsulated by corresponding device driver
+ * data types. See xmesa.h and xmesaP.h for an example.
+ *
+ * In OOP terms, struct gl_context, struct gl_config, and struct gl_framebuffer
+ * are base classes which the device driver must derive from.
+ *
+ * The following functions create and destroy these data types.
+ */
+
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+
+#include "imports.h"
+#include "mtypes.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct _glapi_table;
+
+
+/** \name Visual-related functions */
+/*@{*/
+
+extern struct gl_config *
+_mesa_create_visual( GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples );
+
+extern GLboolean
+_mesa_initialize_visual( struct gl_config *v,
+ GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples );
+
+extern void
+_mesa_destroy_visual( struct gl_config *vis );
+
+/*@}*/
+
+
+/** \name Context-related functions */
+/*@{*/
+
+extern GLboolean
+_mesa_initialize_context( struct gl_context *ctx,
+ gl_api api,
+ const struct gl_config *visual,
+ struct gl_context *share_list,
+ const struct dd_function_table *driverFunctions);
+
+extern struct gl_context *
+_mesa_create_context(gl_api api,
+ const struct gl_config *visual,
+ struct gl_context *share_list,
+ const struct dd_function_table *driverFunctions);
+
+extern void
+_mesa_enable_glsl_threadpool(struct gl_context *ctx, int max_threads);
+
+extern void
+_mesa_free_context_data( struct gl_context *ctx );
+
+extern void
+_mesa_destroy_context( struct gl_context *ctx );
+
+
+extern void
+_mesa_copy_context(const struct gl_context *src, struct gl_context *dst, GLuint mask);
+
+
+extern void
+_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height);
+
+extern GLboolean
+_mesa_make_current( struct gl_context *ctx, struct gl_framebuffer *drawBuffer,
+ struct gl_framebuffer *readBuffer );
+
+extern GLboolean
+_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare);
+
+extern struct gl_context *
+_mesa_get_current_context(void);
+
+/*@}*/
+
+extern void
+_mesa_init_get_hash(struct gl_context *ctx);
+
+extern void
+_mesa_notifySwapBuffers(struct gl_context *gc);
+
+
+extern struct _glapi_table *
+_mesa_get_dispatch(struct gl_context *ctx);
+
+
+extern GLboolean
+_mesa_valid_to_render(struct gl_context *ctx, const char *where);
+
+
+
+/** \name Miscellaneous */
+/*@{*/
+
+extern void
+_mesa_record_error( struct gl_context *ctx, GLenum error );
+
+
+extern void
+_mesa_finish(struct gl_context *ctx);
+
+extern void
+_mesa_flush(struct gl_context *ctx);
+
+extern int
+_mesa_generic_nop(void);
+
+extern void GLAPIENTRY
+_mesa_Finish( void );
+
+extern void GLAPIENTRY
+_mesa_Flush( void );
+
+/*@}*/
+
+
+/**
+ * Are we currently between glBegin and glEnd?
+ * During execution, not display list compilation.
+ */
+static inline GLboolean
+_mesa_inside_begin_end(const struct gl_context *ctx)
+{
+ return ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END;
+}
+
+
+/**
+ * Are we currently between glBegin and glEnd in a display list?
+ */
+static inline GLboolean
+_mesa_inside_dlist_begin_end(const struct gl_context *ctx)
+{
+ return ctx->Driver.CurrentSavePrimitive <= PRIM_MAX;
+}
+
+
+
+/**
+ * \name Macros for flushing buffered rendering commands before state changes,
+ * checking if inside glBegin/glEnd, etc.
+ */
+/*@{*/
+
+/**
+ * Flush vertices.
+ *
+ * \param ctx GL context.
+ * \param newstate new state.
+ *
+ * Checks if dd_function_table::NeedFlush is marked to flush stored vertices,
+ * and calls dd_function_table::FlushVertices if so. Marks
+ * __struct gl_contextRec::NewState with \p newstate.
+ */
+#define FLUSH_VERTICES(ctx, newstate) \
+do { \
+ if (MESA_VERBOSE & VERBOSE_STATE) \
+ _mesa_debug(ctx, "FLUSH_VERTICES in %s\n", MESA_FUNCTION);\
+ if (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) \
+ ctx->Driver.FlushVertices(ctx, FLUSH_STORED_VERTICES); \
+ ctx->NewState |= newstate; \
+} while (0)
+
+/**
+ * Flush current state.
+ *
+ * \param ctx GL context.
+ * \param newstate new state.
+ *
+ * Checks if dd_function_table::NeedFlush is marked to flush current state,
+ * and calls dd_function_table::FlushVertices if so. Marks
+ * __struct gl_contextRec::NewState with \p newstate.
+ */
+#define FLUSH_CURRENT(ctx, newstate) \
+do { \
+ if (MESA_VERBOSE & VERBOSE_STATE) \
+ _mesa_debug(ctx, "FLUSH_CURRENT in %s\n", MESA_FUNCTION); \
+ if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) \
+ ctx->Driver.FlushVertices(ctx, FLUSH_UPDATE_CURRENT); \
+ ctx->NewState |= newstate; \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair, with return value.
+ *
+ * \param ctx GL context.
+ * \param retval value to return in case the assertion fails.
+ */
+#define ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval) \
+do { \
+ if (_mesa_inside_begin_end(ctx)) { \
+ _mesa_error(ctx, GL_INVALID_OPERATION, "Inside glBegin/glEnd"); \
+ return retval; \
+ } \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair.
+ *
+ * \param ctx GL context.
+ */
+#define ASSERT_OUTSIDE_BEGIN_END(ctx) \
+do { \
+ if (_mesa_inside_begin_end(ctx)) { \
+ _mesa_error(ctx, GL_INVALID_OPERATION, "Inside glBegin/glEnd"); \
+ return; \
+ } \
+} while (0)
+
+/*@}*/
+
+
+/**
+ * Checks if the context is for Desktop GL (Compatibility or Core)
+ */
+static inline GLboolean
+_mesa_is_desktop_gl(const struct gl_context *ctx)
+{
+ return ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGL_CORE;
+}
+
+
+/**
+ * Checks if the context is for any GLES version
+ */
+static inline GLboolean
+_mesa_is_gles(const struct gl_context *ctx)
+{
+ return ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2;
+}
+
+
+/**
+ * Checks if the context is for GLES 3.x
+ */
+static inline GLboolean
+_mesa_is_gles3(const struct gl_context *ctx)
+{
+ return ctx->API == API_OPENGLES2 && ctx->Version >= 30;
+}
+
+
+/**
+ * Checks if the context supports geometry shaders.
+ */
+static inline GLboolean
+_mesa_has_geometry_shaders(const struct gl_context *ctx)
+{
+ return _mesa_is_desktop_gl(ctx) &&
+ (ctx->Version >= 32 || ctx->Extensions.ARB_geometry_shader4);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* CONTEXT_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/enums.c b/icd/intel/compiler/mesa-utils/src/mesa/main/enums.c
new file mode 100644
index 0000000..51651ac
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/enums.c
@@ -0,0 +1,4138 @@
+/* DO NOT EDIT - This file generated automatically by gl_enums.py (from Mesa) script */
+
+/*
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL,
+ * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "main/glheader.h"
+#include "main/enums.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+
+typedef struct PACKED {
+ uint16_t offset;
+ int n;
+} enum_elt;
+
+LONGSTRING static const char enum_string_table[] =
+ "GL_FALSE\0"
+ "GL_LINES\0"
+ "GL_LINE_LOOP\0"
+ "GL_LINE_STRIP\0"
+ "GL_TRIANGLES\0"
+ "GL_TRIANGLE_STRIP\0"
+ "GL_TRIANGLE_FAN\0"
+ "GL_QUADS\0"
+ "GL_QUAD_STRIP\0"
+ "GL_POLYGON\0"
+ "GL_LINES_ADJACENCY\0"
+ "GL_LINE_STRIP_ADJACENCY\0"
+ "GL_TRIANGLES_ADJACENCY\0"
+ "GL_TRIANGLE_STRIP_ADJACENCY\0"
+ "GL_POLYGON_STIPPLE_BIT\0"
+ "GL_PIXEL_MODE_BIT\0"
+ "GL_LIGHTING_BIT\0"
+ "GL_FOG_BIT\0"
+ "GL_ACCUM\0"
+ "GL_LOAD\0"
+ "GL_RETURN\0"
+ "GL_MULT\0"
+ "GL_ADD\0"
+ "GL_NEVER\0"
+ "GL_LESS\0"
+ "GL_EQUAL\0"
+ "GL_LEQUAL\0"
+ "GL_GREATER\0"
+ "GL_NOTEQUAL\0"
+ "GL_GEQUAL\0"
+ "GL_ALWAYS\0"
+ "GL_SRC_COLOR\0"
+ "GL_ONE_MINUS_SRC_COLOR\0"
+ "GL_SRC_ALPHA\0"
+ "GL_ONE_MINUS_SRC_ALPHA\0"
+ "GL_DST_ALPHA\0"
+ "GL_ONE_MINUS_DST_ALPHA\0"
+ "GL_DST_COLOR\0"
+ "GL_ONE_MINUS_DST_COLOR\0"
+ "GL_SRC_ALPHA_SATURATE\0"
+ "GL_FRONT_LEFT\0"
+ "GL_FRONT_RIGHT\0"
+ "GL_BACK_LEFT\0"
+ "GL_BACK_RIGHT\0"
+ "GL_FRONT\0"
+ "GL_BACK\0"
+ "GL_LEFT\0"
+ "GL_RIGHT\0"
+ "GL_FRONT_AND_BACK\0"
+ "GL_AUX0\0"
+ "GL_AUX1\0"
+ "GL_AUX2\0"
+ "GL_AUX3\0"
+ "GL_INVALID_ENUM\0"
+ "GL_INVALID_VALUE\0"
+ "GL_INVALID_OPERATION\0"
+ "GL_STACK_OVERFLOW\0"
+ "GL_STACK_UNDERFLOW\0"
+ "GL_OUT_OF_MEMORY\0"
+ "GL_INVALID_FRAMEBUFFER_OPERATION\0"
+ "GL_2D\0"
+ "GL_3D\0"
+ "GL_3D_COLOR\0"
+ "GL_3D_COLOR_TEXTURE\0"
+ "GL_4D_COLOR_TEXTURE\0"
+ "GL_PASS_THROUGH_TOKEN\0"
+ "GL_POINT_TOKEN\0"
+ "GL_LINE_TOKEN\0"
+ "GL_POLYGON_TOKEN\0"
+ "GL_BITMAP_TOKEN\0"
+ "GL_DRAW_PIXEL_TOKEN\0"
+ "GL_COPY_PIXEL_TOKEN\0"
+ "GL_LINE_RESET_TOKEN\0"
+ "GL_EXP\0"
+ "GL_EXP2\0"
+ "GL_CW\0"
+ "GL_CCW\0"
+ "GL_COEFF\0"
+ "GL_ORDER\0"
+ "GL_DOMAIN\0"
+ "GL_CURRENT_COLOR\0"
+ "GL_CURRENT_INDEX\0"
+ "GL_CURRENT_NORMAL\0"
+ "GL_CURRENT_TEXTURE_COORDS\0"
+ "GL_CURRENT_RASTER_COLOR\0"
+ "GL_CURRENT_RASTER_INDEX\0"
+ "GL_CURRENT_RASTER_TEXTURE_COORDS\0"
+ "GL_CURRENT_RASTER_POSITION\0"
+ "GL_CURRENT_RASTER_POSITION_VALID\0"
+ "GL_CURRENT_RASTER_DISTANCE\0"
+ "GL_POINT_SMOOTH\0"
+ "GL_POINT_SIZE\0"
+ "GL_POINT_SIZE_RANGE\0"
+ "GL_POINT_SIZE_GRANULARITY\0"
+ "GL_LINE_SMOOTH\0"
+ "GL_LINE_WIDTH\0"
+ "GL_LINE_WIDTH_RANGE\0"
+ "GL_LINE_WIDTH_GRANULARITY\0"
+ "GL_LINE_STIPPLE\0"
+ "GL_LINE_STIPPLE_PATTERN\0"
+ "GL_LINE_STIPPLE_REPEAT\0"
+ "GL_LIST_MODE\0"
+ "GL_MAX_LIST_NESTING\0"
+ "GL_LIST_BASE\0"
+ "GL_LIST_INDEX\0"
+ "GL_POLYGON_MODE\0"
+ "GL_POLYGON_SMOOTH\0"
+ "GL_POLYGON_STIPPLE\0"
+ "GL_EDGE_FLAG\0"
+ "GL_CULL_FACE\0"
+ "GL_CULL_FACE_MODE\0"
+ "GL_FRONT_FACE\0"
+ "GL_LIGHTING\0"
+ "GL_LIGHT_MODEL_LOCAL_VIEWER\0"
+ "GL_LIGHT_MODEL_TWO_SIDE\0"
+ "GL_LIGHT_MODEL_AMBIENT\0"
+ "GL_SHADE_MODEL\0"
+ "GL_COLOR_MATERIAL_FACE\0"
+ "GL_COLOR_MATERIAL_PARAMETER\0"
+ "GL_COLOR_MATERIAL\0"
+ "GL_FOG\0"
+ "GL_FOG_INDEX\0"
+ "GL_FOG_DENSITY\0"
+ "GL_FOG_START\0"
+ "GL_FOG_END\0"
+ "GL_FOG_MODE\0"
+ "GL_FOG_COLOR\0"
+ "GL_DEPTH_RANGE\0"
+ "GL_DEPTH_TEST\0"
+ "GL_DEPTH_WRITEMASK\0"
+ "GL_DEPTH_CLEAR_VALUE\0"
+ "GL_DEPTH_FUNC\0"
+ "GL_ACCUM_CLEAR_VALUE\0"
+ "GL_STENCIL_TEST\0"
+ "GL_STENCIL_CLEAR_VALUE\0"
+ "GL_STENCIL_FUNC\0"
+ "GL_STENCIL_VALUE_MASK\0"
+ "GL_STENCIL_FAIL\0"
+ "GL_STENCIL_PASS_DEPTH_FAIL\0"
+ "GL_STENCIL_PASS_DEPTH_PASS\0"
+ "GL_STENCIL_REF\0"
+ "GL_STENCIL_WRITEMASK\0"
+ "GL_MATRIX_MODE\0"
+ "GL_NORMALIZE\0"
+ "GL_VIEWPORT\0"
+ "GL_MODELVIEW_STACK_DEPTH\0"
+ "GL_PROJECTION_STACK_DEPTH\0"
+ "GL_TEXTURE_STACK_DEPTH\0"
+ "GL_MODELVIEW_MATRIX\0"
+ "GL_PROJECTION_MATRIX\0"
+ "GL_TEXTURE_MATRIX\0"
+ "GL_ATTRIB_STACK_DEPTH\0"
+ "GL_CLIENT_ATTRIB_STACK_DEPTH\0"
+ "GL_ALPHA_TEST\0"
+ "GL_ALPHA_TEST_FUNC\0"
+ "GL_ALPHA_TEST_REF\0"
+ "GL_DITHER\0"
+ "GL_BLEND_DST\0"
+ "GL_BLEND_SRC\0"
+ "GL_BLEND\0"
+ "GL_LOGIC_OP_MODE\0"
+ "GL_INDEX_LOGIC_OP\0"
+ "GL_COLOR_LOGIC_OP\0"
+ "GL_AUX_BUFFERS\0"
+ "GL_DRAW_BUFFER\0"
+ "GL_READ_BUFFER\0"
+ "GL_SCISSOR_BOX\0"
+ "GL_SCISSOR_TEST\0"
+ "GL_INDEX_CLEAR_VALUE\0"
+ "GL_INDEX_WRITEMASK\0"
+ "GL_COLOR_CLEAR_VALUE\0"
+ "GL_COLOR_WRITEMASK\0"
+ "GL_INDEX_MODE\0"
+ "GL_RGBA_MODE\0"
+ "GL_DOUBLEBUFFER\0"
+ "GL_STEREO\0"
+ "GL_RENDER_MODE\0"
+ "GL_PERSPECTIVE_CORRECTION_HINT\0"
+ "GL_POINT_SMOOTH_HINT\0"
+ "GL_LINE_SMOOTH_HINT\0"
+ "GL_POLYGON_SMOOTH_HINT\0"
+ "GL_FOG_HINT\0"
+ "GL_TEXTURE_GEN_S\0"
+ "GL_TEXTURE_GEN_T\0"
+ "GL_TEXTURE_GEN_R\0"
+ "GL_TEXTURE_GEN_Q\0"
+ "GL_PIXEL_MAP_I_TO_I\0"
+ "GL_PIXEL_MAP_S_TO_S\0"
+ "GL_PIXEL_MAP_I_TO_R\0"
+ "GL_PIXEL_MAP_I_TO_G\0"
+ "GL_PIXEL_MAP_I_TO_B\0"
+ "GL_PIXEL_MAP_I_TO_A\0"
+ "GL_PIXEL_MAP_R_TO_R\0"
+ "GL_PIXEL_MAP_G_TO_G\0"
+ "GL_PIXEL_MAP_B_TO_B\0"
+ "GL_PIXEL_MAP_A_TO_A\0"
+ "GL_PIXEL_MAP_I_TO_I_SIZE\0"
+ "GL_PIXEL_MAP_S_TO_S_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_R_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_G_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_B_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_A_SIZE\0"
+ "GL_PIXEL_MAP_R_TO_R_SIZE\0"
+ "GL_PIXEL_MAP_G_TO_G_SIZE\0"
+ "GL_PIXEL_MAP_B_TO_B_SIZE\0"
+ "GL_PIXEL_MAP_A_TO_A_SIZE\0"
+ "GL_UNPACK_SWAP_BYTES\0"
+ "GL_UNPACK_LSB_FIRST\0"
+ "GL_UNPACK_ROW_LENGTH\0"
+ "GL_UNPACK_SKIP_ROWS\0"
+ "GL_UNPACK_SKIP_PIXELS\0"
+ "GL_UNPACK_ALIGNMENT\0"
+ "GL_PACK_SWAP_BYTES\0"
+ "GL_PACK_LSB_FIRST\0"
+ "GL_PACK_ROW_LENGTH\0"
+ "GL_PACK_SKIP_ROWS\0"
+ "GL_PACK_SKIP_PIXELS\0"
+ "GL_PACK_ALIGNMENT\0"
+ "GL_MAP_COLOR\0"
+ "GL_MAP_STENCIL\0"
+ "GL_INDEX_SHIFT\0"
+ "GL_INDEX_OFFSET\0"
+ "GL_RED_SCALE\0"
+ "GL_RED_BIAS\0"
+ "GL_ZOOM_X\0"
+ "GL_ZOOM_Y\0"
+ "GL_GREEN_SCALE\0"
+ "GL_GREEN_BIAS\0"
+ "GL_BLUE_SCALE\0"
+ "GL_BLUE_BIAS\0"
+ "GL_ALPHA_SCALE\0"
+ "GL_ALPHA_BIAS\0"
+ "GL_DEPTH_SCALE\0"
+ "GL_DEPTH_BIAS\0"
+ "GL_MAX_EVAL_ORDER\0"
+ "GL_MAX_LIGHTS\0"
+ "GL_MAX_CLIP_DISTANCES\0"
+ "GL_MAX_TEXTURE_SIZE\0"
+ "GL_MAX_PIXEL_MAP_TABLE\0"
+ "GL_MAX_ATTRIB_STACK_DEPTH\0"
+ "GL_MAX_MODELVIEW_STACK_DEPTH\0"
+ "GL_MAX_NAME_STACK_DEPTH\0"
+ "GL_MAX_PROJECTION_STACK_DEPTH\0"
+ "GL_MAX_TEXTURE_STACK_DEPTH\0"
+ "GL_MAX_VIEWPORT_DIMS\0"
+ "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH\0"
+ "GL_SUBPIXEL_BITS\0"
+ "GL_INDEX_BITS\0"
+ "GL_RED_BITS\0"
+ "GL_GREEN_BITS\0"
+ "GL_BLUE_BITS\0"
+ "GL_ALPHA_BITS\0"
+ "GL_DEPTH_BITS\0"
+ "GL_STENCIL_BITS\0"
+ "GL_ACCUM_RED_BITS\0"
+ "GL_ACCUM_GREEN_BITS\0"
+ "GL_ACCUM_BLUE_BITS\0"
+ "GL_ACCUM_ALPHA_BITS\0"
+ "GL_NAME_STACK_DEPTH\0"
+ "GL_AUTO_NORMAL\0"
+ "GL_MAP1_COLOR_4\0"
+ "GL_MAP1_INDEX\0"
+ "GL_MAP1_NORMAL\0"
+ "GL_MAP1_TEXTURE_COORD_1\0"
+ "GL_MAP1_TEXTURE_COORD_2\0"
+ "GL_MAP1_TEXTURE_COORD_3\0"
+ "GL_MAP1_TEXTURE_COORD_4\0"
+ "GL_MAP1_VERTEX_3\0"
+ "GL_MAP1_VERTEX_4\0"
+ "GL_MAP2_COLOR_4\0"
+ "GL_MAP2_INDEX\0"
+ "GL_MAP2_NORMAL\0"
+ "GL_MAP2_TEXTURE_COORD_1\0"
+ "GL_MAP2_TEXTURE_COORD_2\0"
+ "GL_MAP2_TEXTURE_COORD_3\0"
+ "GL_MAP2_TEXTURE_COORD_4\0"
+ "GL_MAP2_VERTEX_3\0"
+ "GL_MAP2_VERTEX_4\0"
+ "GL_MAP1_GRID_DOMAIN\0"
+ "GL_MAP1_GRID_SEGMENTS\0"
+ "GL_MAP2_GRID_DOMAIN\0"
+ "GL_MAP2_GRID_SEGMENTS\0"
+ "GL_TEXTURE_1D\0"
+ "GL_TEXTURE_2D\0"
+ "GL_FEEDBACK_BUFFER_POINTER\0"
+ "GL_FEEDBACK_BUFFER_SIZE\0"
+ "GL_FEEDBACK_BUFFER_TYPE\0"
+ "GL_SELECTION_BUFFER_POINTER\0"
+ "GL_SELECTION_BUFFER_SIZE\0"
+ "GL_TEXTURE_WIDTH\0"
+ "GL_TEXTURE_HEIGHT\0"
+ "GL_TEXTURE_COMPONENTS\0"
+ "GL_TEXTURE_BORDER_COLOR\0"
+ "GL_TEXTURE_BORDER\0"
+ "GL_DONT_CARE\0"
+ "GL_FASTEST\0"
+ "GL_NICEST\0"
+ "GL_AMBIENT\0"
+ "GL_DIFFUSE\0"
+ "GL_SPECULAR\0"
+ "GL_POSITION\0"
+ "GL_SPOT_DIRECTION\0"
+ "GL_SPOT_EXPONENT\0"
+ "GL_SPOT_CUTOFF\0"
+ "GL_CONSTANT_ATTENUATION\0"
+ "GL_LINEAR_ATTENUATION\0"
+ "GL_QUADRATIC_ATTENUATION\0"
+ "GL_COMPILE\0"
+ "GL_COMPILE_AND_EXECUTE\0"
+ "GL_BYTE\0"
+ "GL_UNSIGNED_BYTE\0"
+ "GL_SHORT\0"
+ "GL_UNSIGNED_SHORT\0"
+ "GL_INT\0"
+ "GL_UNSIGNED_INT\0"
+ "GL_FLOAT\0"
+ "GL_2_BYTES\0"
+ "GL_3_BYTES\0"
+ "GL_4_BYTES\0"
+ "GL_DOUBLE\0"
+ "GL_HALF_FLOAT\0"
+ "GL_FIXED\0"
+ "GL_CLEAR\0"
+ "GL_AND\0"
+ "GL_AND_REVERSE\0"
+ "GL_COPY\0"
+ "GL_AND_INVERTED\0"
+ "GL_NOOP\0"
+ "GL_XOR\0"
+ "GL_OR\0"
+ "GL_NOR\0"
+ "GL_EQUIV\0"
+ "GL_INVERT\0"
+ "GL_OR_REVERSE\0"
+ "GL_COPY_INVERTED\0"
+ "GL_OR_INVERTED\0"
+ "GL_NAND\0"
+ "GL_SET\0"
+ "GL_EMISSION\0"
+ "GL_SHININESS\0"
+ "GL_AMBIENT_AND_DIFFUSE\0"
+ "GL_COLOR_INDEXES\0"
+ "GL_MODELVIEW\0"
+ "GL_PROJECTION\0"
+ "GL_TEXTURE\0"
+ "GL_COLOR\0"
+ "GL_DEPTH\0"
+ "GL_STENCIL\0"
+ "GL_COLOR_INDEX\0"
+ "GL_STENCIL_INDEX\0"
+ "GL_DEPTH_COMPONENT\0"
+ "GL_RED\0"
+ "GL_GREEN\0"
+ "GL_BLUE\0"
+ "GL_ALPHA\0"
+ "GL_RGB\0"
+ "GL_RGBA\0"
+ "GL_LUMINANCE\0"
+ "GL_LUMINANCE_ALPHA\0"
+ "GL_BITMAP\0"
+ "GL_POINT\0"
+ "GL_LINE\0"
+ "GL_FILL\0"
+ "GL_RENDER\0"
+ "GL_FEEDBACK\0"
+ "GL_SELECT\0"
+ "GL_FLAT\0"
+ "GL_SMOOTH\0"
+ "GL_KEEP\0"
+ "GL_REPLACE\0"
+ "GL_INCR\0"
+ "GL_DECR\0"
+ "GL_VENDOR\0"
+ "GL_RENDERER\0"
+ "GL_VERSION\0"
+ "GL_EXTENSIONS\0"
+ "GL_S\0"
+ "GL_T\0"
+ "GL_R\0"
+ "GL_Q\0"
+ "GL_MODULATE\0"
+ "GL_DECAL\0"
+ "GL_TEXTURE_ENV_MODE\0"
+ "GL_TEXTURE_ENV_COLOR\0"
+ "GL_TEXTURE_ENV\0"
+ "GL_EYE_LINEAR\0"
+ "GL_OBJECT_LINEAR\0"
+ "GL_SPHERE_MAP\0"
+ "GL_TEXTURE_GEN_MODE\0"
+ "GL_OBJECT_PLANE\0"
+ "GL_EYE_PLANE\0"
+ "GL_NEAREST\0"
+ "GL_LINEAR\0"
+ "GL_NEAREST_MIPMAP_NEAREST\0"
+ "GL_LINEAR_MIPMAP_NEAREST\0"
+ "GL_NEAREST_MIPMAP_LINEAR\0"
+ "GL_LINEAR_MIPMAP_LINEAR\0"
+ "GL_TEXTURE_MAG_FILTER\0"
+ "GL_TEXTURE_MIN_FILTER\0"
+ "GL_TEXTURE_WRAP_S\0"
+ "GL_TEXTURE_WRAP_T\0"
+ "GL_CLAMP\0"
+ "GL_REPEAT\0"
+ "GL_POLYGON_OFFSET_UNITS\0"
+ "GL_POLYGON_OFFSET_POINT\0"
+ "GL_POLYGON_OFFSET_LINE\0"
+ "GL_R3_G3_B2\0"
+ "GL_V2F\0"
+ "GL_V3F\0"
+ "GL_C4UB_V2F\0"
+ "GL_C4UB_V3F\0"
+ "GL_C3F_V3F\0"
+ "GL_N3F_V3F\0"
+ "GL_C4F_N3F_V3F\0"
+ "GL_T2F_V3F\0"
+ "GL_T4F_V4F\0"
+ "GL_T2F_C4UB_V3F\0"
+ "GL_T2F_C3F_V3F\0"
+ "GL_T2F_N3F_V3F\0"
+ "GL_T2F_C4F_N3F_V3F\0"
+ "GL_T4F_C4F_N3F_V4F\0"
+ "GL_CLIP_DISTANCE0\0"
+ "GL_CLIP_DISTANCE1\0"
+ "GL_CLIP_DISTANCE2\0"
+ "GL_CLIP_DISTANCE3\0"
+ "GL_CLIP_DISTANCE4\0"
+ "GL_CLIP_DISTANCE5\0"
+ "GL_CLIP_DISTANCE6\0"
+ "GL_CLIP_DISTANCE7\0"
+ "GL_LIGHT0\0"
+ "GL_LIGHT1\0"
+ "GL_LIGHT2\0"
+ "GL_LIGHT3\0"
+ "GL_LIGHT4\0"
+ "GL_LIGHT5\0"
+ "GL_LIGHT6\0"
+ "GL_LIGHT7\0"
+ "GL_HINT_BIT\0"
+ "GL_CONSTANT_COLOR\0"
+ "GL_ONE_MINUS_CONSTANT_COLOR\0"
+ "GL_CONSTANT_ALPHA\0"
+ "GL_ONE_MINUS_CONSTANT_ALPHA\0"
+ "GL_BLEND_COLOR\0"
+ "GL_FUNC_ADD\0"
+ "GL_MIN\0"
+ "GL_MAX\0"
+ "GL_BLEND_EQUATION\0"
+ "GL_FUNC_SUBTRACT\0"
+ "GL_FUNC_REVERSE_SUBTRACT\0"
+ "GL_CONVOLUTION_1D\0"
+ "GL_CONVOLUTION_2D\0"
+ "GL_SEPARABLE_2D\0"
+ "GL_CONVOLUTION_BORDER_MODE\0"
+ "GL_CONVOLUTION_FILTER_SCALE\0"
+ "GL_CONVOLUTION_FILTER_BIAS\0"
+ "GL_REDUCE\0"
+ "GL_CONVOLUTION_FORMAT\0"
+ "GL_CONVOLUTION_WIDTH\0"
+ "GL_CONVOLUTION_HEIGHT\0"
+ "GL_MAX_CONVOLUTION_WIDTH\0"
+ "GL_MAX_CONVOLUTION_HEIGHT\0"
+ "GL_POST_CONVOLUTION_RED_SCALE\0"
+ "GL_POST_CONVOLUTION_GREEN_SCALE\0"
+ "GL_POST_CONVOLUTION_BLUE_SCALE\0"
+ "GL_POST_CONVOLUTION_ALPHA_SCALE\0"
+ "GL_POST_CONVOLUTION_RED_BIAS\0"
+ "GL_POST_CONVOLUTION_GREEN_BIAS\0"
+ "GL_POST_CONVOLUTION_BLUE_BIAS\0"
+ "GL_POST_CONVOLUTION_ALPHA_BIAS\0"
+ "GL_HISTOGRAM\0"
+ "GL_PROXY_HISTOGRAM\0"
+ "GL_HISTOGRAM_WIDTH\0"
+ "GL_HISTOGRAM_FORMAT\0"
+ "GL_HISTOGRAM_RED_SIZE\0"
+ "GL_HISTOGRAM_GREEN_SIZE\0"
+ "GL_HISTOGRAM_BLUE_SIZE\0"
+ "GL_HISTOGRAM_ALPHA_SIZE\0"
+ "GL_HISTOGRAM_LUMINANCE_SIZE\0"
+ "GL_HISTOGRAM_SINK\0"
+ "GL_MINMAX\0"
+ "GL_MINMAX_FORMAT\0"
+ "GL_MINMAX_SINK\0"
+ "GL_TABLE_TOO_LARGE_EXT\0"
+ "GL_UNSIGNED_BYTE_3_3_2\0"
+ "GL_UNSIGNED_SHORT_4_4_4_4\0"
+ "GL_UNSIGNED_SHORT_5_5_5_1\0"
+ "GL_UNSIGNED_INT_8_8_8_8\0"
+ "GL_UNSIGNED_INT_10_10_10_2\0"
+ "GL_POLYGON_OFFSET_FILL\0"
+ "GL_POLYGON_OFFSET_FACTOR\0"
+ "GL_POLYGON_OFFSET_BIAS_EXT\0"
+ "GL_RESCALE_NORMAL\0"
+ "GL_ALPHA4\0"
+ "GL_ALPHA8\0"
+ "GL_ALPHA12\0"
+ "GL_ALPHA16\0"
+ "GL_LUMINANCE4\0"
+ "GL_LUMINANCE8\0"
+ "GL_LUMINANCE12\0"
+ "GL_LUMINANCE16\0"
+ "GL_LUMINANCE4_ALPHA4\0"
+ "GL_LUMINANCE6_ALPHA2\0"
+ "GL_LUMINANCE8_ALPHA8\0"
+ "GL_LUMINANCE12_ALPHA4\0"
+ "GL_LUMINANCE12_ALPHA12\0"
+ "GL_LUMINANCE16_ALPHA16\0"
+ "GL_INTENSITY\0"
+ "GL_INTENSITY4\0"
+ "GL_INTENSITY8\0"
+ "GL_INTENSITY12\0"
+ "GL_INTENSITY16\0"
+ "GL_RGB2_EXT\0"
+ "GL_RGB4\0"
+ "GL_RGB5\0"
+ "GL_RGB8\0"
+ "GL_RGB10\0"
+ "GL_RGB12\0"
+ "GL_RGB16\0"
+ "GL_RGBA2\0"
+ "GL_RGBA4\0"
+ "GL_RGB5_A1\0"
+ "GL_RGBA8\0"
+ "GL_RGB10_A2\0"
+ "GL_RGBA12\0"
+ "GL_RGBA16\0"
+ "GL_TEXTURE_RED_SIZE\0"
+ "GL_TEXTURE_GREEN_SIZE\0"
+ "GL_TEXTURE_BLUE_SIZE\0"
+ "GL_TEXTURE_ALPHA_SIZE\0"
+ "GL_TEXTURE_LUMINANCE_SIZE\0"
+ "GL_TEXTURE_INTENSITY_SIZE\0"
+ "GL_REPLACE_EXT\0"
+ "GL_PROXY_TEXTURE_1D\0"
+ "GL_PROXY_TEXTURE_2D\0"
+ "GL_TEXTURE_TOO_LARGE_EXT\0"
+ "GL_TEXTURE_PRIORITY\0"
+ "GL_TEXTURE_RESIDENT\0"
+ "GL_TEXTURE_BINDING_1D\0"
+ "GL_TEXTURE_BINDING_2D\0"
+ "GL_TEXTURE_BINDING_3D\0"
+ "GL_PACK_SKIP_IMAGES\0"
+ "GL_PACK_IMAGE_HEIGHT\0"
+ "GL_UNPACK_SKIP_IMAGES\0"
+ "GL_UNPACK_IMAGE_HEIGHT\0"
+ "GL_TEXTURE_3D\0"
+ "GL_PROXY_TEXTURE_3D\0"
+ "GL_TEXTURE_DEPTH\0"
+ "GL_TEXTURE_WRAP_R\0"
+ "GL_MAX_3D_TEXTURE_SIZE\0"
+ "GL_VERTEX_ARRAY\0"
+ "GL_NORMAL_ARRAY\0"
+ "GL_COLOR_ARRAY\0"
+ "GL_INDEX_ARRAY\0"
+ "GL_TEXTURE_COORD_ARRAY\0"
+ "GL_EDGE_FLAG_ARRAY\0"
+ "GL_VERTEX_ARRAY_SIZE\0"
+ "GL_VERTEX_ARRAY_TYPE\0"
+ "GL_VERTEX_ARRAY_STRIDE\0"
+ "GL_VERTEX_ARRAY_COUNT_EXT\0"
+ "GL_NORMAL_ARRAY_TYPE\0"
+ "GL_NORMAL_ARRAY_STRIDE\0"
+ "GL_NORMAL_ARRAY_COUNT_EXT\0"
+ "GL_COLOR_ARRAY_SIZE\0"
+ "GL_COLOR_ARRAY_TYPE\0"
+ "GL_COLOR_ARRAY_STRIDE\0"
+ "GL_COLOR_ARRAY_COUNT_EXT\0"
+ "GL_INDEX_ARRAY_TYPE\0"
+ "GL_INDEX_ARRAY_STRIDE\0"
+ "GL_INDEX_ARRAY_COUNT_EXT\0"
+ "GL_TEXTURE_COORD_ARRAY_SIZE\0"
+ "GL_TEXTURE_COORD_ARRAY_TYPE\0"
+ "GL_TEXTURE_COORD_ARRAY_STRIDE\0"
+ "GL_TEXTURE_COORD_ARRAY_COUNT_EXT\0"
+ "GL_EDGE_FLAG_ARRAY_STRIDE\0"
+ "GL_EDGE_FLAG_ARRAY_COUNT_EXT\0"
+ "GL_VERTEX_ARRAY_POINTER\0"
+ "GL_NORMAL_ARRAY_POINTER\0"
+ "GL_COLOR_ARRAY_POINTER\0"
+ "GL_INDEX_ARRAY_POINTER\0"
+ "GL_TEXTURE_COORD_ARRAY_POINTER\0"
+ "GL_EDGE_FLAG_ARRAY_POINTER\0"
+ "GL_MULTISAMPLE\0"
+ "GL_SAMPLE_ALPHA_TO_COVERAGE\0"
+ "GL_SAMPLE_ALPHA_TO_ONE\0"
+ "GL_SAMPLE_COVERAGE\0"
+ "GL_SAMPLE_BUFFERS\0"
+ "GL_SAMPLES\0"
+ "GL_SAMPLE_COVERAGE_VALUE\0"
+ "GL_SAMPLE_COVERAGE_INVERT\0"
+ "GL_COLOR_MATRIX\0"
+ "GL_COLOR_MATRIX_STACK_DEPTH\0"
+ "GL_MAX_COLOR_MATRIX_STACK_DEPTH\0"
+ "GL_POST_COLOR_MATRIX_RED_SCALE\0"
+ "GL_POST_COLOR_MATRIX_GREEN_SCALE\0"
+ "GL_POST_COLOR_MATRIX_BLUE_SCALE\0"
+ "GL_POST_COLOR_MATRIX_ALPHA_SCALE\0"
+ "GL_POST_COLOR_MATRIX_RED_BIAS\0"
+ "GL_POST_COLOR_MATRIX_GREEN_BIAS\0"
+ "GL_POST_COLOR_MATRIX_BLUE_BIAS\0"
+ "GL_POST_COLOR_MATRIX_ALPHA_BIAS\0"
+ "GL_TEXTURE_COLOR_TABLE_SGI\0"
+ "GL_PROXY_TEXTURE_COLOR_TABLE_SGI\0"
+ "GL_TEXTURE_COMPARE_FAIL_VALUE_ARB\0"
+ "GL_BLEND_DST_RGB\0"
+ "GL_BLEND_SRC_RGB\0"
+ "GL_BLEND_DST_ALPHA\0"
+ "GL_BLEND_SRC_ALPHA\0"
+ "GL_COLOR_TABLE\0"
+ "GL_POST_CONVOLUTION_COLOR_TABLE\0"
+ "GL_POST_COLOR_MATRIX_COLOR_TABLE\0"
+ "GL_PROXY_COLOR_TABLE\0"
+ "GL_PROXY_POST_CONVOLUTION_COLOR_TABLE\0"
+ "GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE\0"
+ "GL_COLOR_TABLE_SCALE\0"
+ "GL_COLOR_TABLE_BIAS\0"
+ "GL_COLOR_TABLE_FORMAT\0"
+ "GL_COLOR_TABLE_WIDTH\0"
+ "GL_COLOR_TABLE_RED_SIZE\0"
+ "GL_COLOR_TABLE_GREEN_SIZE\0"
+ "GL_COLOR_TABLE_BLUE_SIZE\0"
+ "GL_COLOR_TABLE_ALPHA_SIZE\0"
+ "GL_COLOR_TABLE_LUMINANCE_SIZE\0"
+ "GL_COLOR_TABLE_INTENSITY_SIZE\0"
+ "GL_BGR\0"
+ "GL_BGRA\0"
+ "GL_MAX_ELEMENTS_VERTICES\0"
+ "GL_MAX_ELEMENTS_INDICES\0"
+ "GL_TEXTURE_INDEX_SIZE_EXT\0"
+ "GL_CLIP_VOLUME_CLIPPING_HINT_EXT\0"
+ "GL_POINT_SIZE_MIN\0"
+ "GL_POINT_SIZE_MAX\0"
+ "GL_POINT_FADE_THRESHOLD_SIZE\0"
+ "GL_POINT_DISTANCE_ATTENUATION\0"
+ "GL_CLAMP_TO_BORDER\0"
+ "GL_CLAMP_TO_EDGE\0"
+ "GL_TEXTURE_MIN_LOD\0"
+ "GL_TEXTURE_MAX_LOD\0"
+ "GL_TEXTURE_BASE_LEVEL\0"
+ "GL_TEXTURE_MAX_LEVEL\0"
+ "GL_IGNORE_BORDER_HP\0"
+ "GL_CONSTANT_BORDER_HP\0"
+ "GL_REPLICATE_BORDER_HP\0"
+ "GL_CONVOLUTION_BORDER_COLOR\0"
+ "GL_OCCLUSION_TEST_HP\0"
+ "GL_OCCLUSION_TEST_RESULT_HP\0"
+ "GL_LINEAR_CLIPMAP_LINEAR_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_CENTER_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_FRAME_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_OFFSET_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_DEPTH_SGIX\0"
+ "GL_MAX_CLIPMAP_DEPTH_SGIX\0"
+ "GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX\0"
+ "GL_POST_TEXTURE_FILTER_BIAS_SGIX\0"
+ "GL_POST_TEXTURE_FILTER_SCALE_SGIX\0"
+ "GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX\0"
+ "GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX\0"
+ "GL_TEXTURE_LOD_BIAS_S_SGIX\0"
+ "GL_TEXTURE_LOD_BIAS_T_SGIX\0"
+ "GL_TEXTURE_LOD_BIAS_R_SGIX\0"
+ "GL_GENERATE_MIPMAP\0"
+ "GL_GENERATE_MIPMAP_HINT\0"
+ "GL_FOG_OFFSET_SGIX\0"
+ "GL_FOG_OFFSET_VALUE_SGIX\0"
+ "GL_TEXTURE_COMPARE_SGIX\0"
+ "GL_TEXTURE_COMPARE_OPERATOR_SGIX\0"
+ "GL_TEXTURE_LEQUAL_R_SGIX\0"
+ "GL_TEXTURE_GEQUAL_R_SGIX\0"
+ "GL_DEPTH_COMPONENT16\0"
+ "GL_DEPTH_COMPONENT24\0"
+ "GL_DEPTH_COMPONENT32\0"
+ "GL_ARRAY_ELEMENT_LOCK_FIRST_EXT\0"
+ "GL_ARRAY_ELEMENT_LOCK_COUNT_EXT\0"
+ "GL_CULL_VERTEX_EXT\0"
+ "GL_CULL_VERTEX_OBJECT_POSITION_EXT\0"
+ "GL_CULL_VERTEX_EYE_POSITION_EXT\0"
+ "GL_WRAP_BORDER_SUN\0"
+ "GL_TEXTURE_COLOR_WRITEMASK_SGIS\0"
+ "GL_LIGHT_MODEL_COLOR_CONTROL\0"
+ "GL_SINGLE_COLOR\0"
+ "GL_SEPARATE_SPECULAR_COLOR\0"
+ "GL_SHARED_TEXTURE_PALETTE_EXT\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE\0"
+ "GL_FRAMEBUFFER_DEFAULT\0"
+ "GL_FRAMEBUFFER_UNDEFINED\0"
+ "GL_DEPTH_STENCIL_ATTACHMENT\0"
+ "GL_MAJOR_VERSION\0"
+ "GL_MINOR_VERSION\0"
+ "GL_NUM_EXTENSIONS\0"
+ "GL_CONTEXT_FLAGS\0"
+ "GL_BUFFER_IMMUTABLE_STORAGE\0"
+ "GL_BUFFER_STORAGE_FLAGS\0"
+ "GL_INDEX\0"
+ "GL_DEPTH_BUFFER\0"
+ "GL_STENCIL_BUFFER\0"
+ "GL_COMPRESSED_RED\0"
+ "GL_COMPRESSED_RG\0"
+ "GL_RG\0"
+ "GL_RG_INTEGER\0"
+ "GL_R8\0"
+ "GL_R16\0"
+ "GL_RG8\0"
+ "GL_RG16\0"
+ "GL_R16F\0"
+ "GL_R32F\0"
+ "GL_RG16F\0"
+ "GL_RG32F\0"
+ "GL_R8I\0"
+ "GL_R8UI\0"
+ "GL_R16I\0"
+ "GL_R16UI\0"
+ "GL_R32I\0"
+ "GL_R32UI\0"
+ "GL_RG8I\0"
+ "GL_RG8UI\0"
+ "GL_RG16I\0"
+ "GL_RG16UI\0"
+ "GL_RG32I\0"
+ "GL_RG32UI\0"
+ "GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB\0"
+ "GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB\0"
+ "GL_DEBUG_CALLBACK_FUNCTION_ARB\0"
+ "GL_DEBUG_CALLBACK_USER_PARAM_ARB\0"
+ "GL_DEBUG_SOURCE_API_ARB\0"
+ "GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB\0"
+ "GL_DEBUG_SOURCE_SHADER_COMPILER_ARB\0"
+ "GL_DEBUG_SOURCE_THIRD_PARTY_ARB\0"
+ "GL_DEBUG_SOURCE_APPLICATION_ARB\0"
+ "GL_DEBUG_SOURCE_OTHER_ARB\0"
+ "GL_DEBUG_TYPE_ERROR_ARB\0"
+ "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB\0"
+ "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB\0"
+ "GL_DEBUG_TYPE_PORTABILITY_ARB\0"
+ "GL_DEBUG_TYPE_PERFORMANCE_ARB\0"
+ "GL_DEBUG_TYPE_OTHER_ARB\0"
+ "GL_LOSE_CONTEXT_ON_RESET_ARB\0"
+ "GL_GUILTY_CONTEXT_RESET_ARB\0"
+ "GL_INNOCENT_CONTEXT_RESET_ARB\0"
+ "GL_UNKNOWN_CONTEXT_RESET_ARB\0"
+ "GL_RESET_NOTIFICATION_STRATEGY_ARB\0"
+ "GL_PROGRAM_BINARY_RETRIEVABLE_HINT\0"
+ "GL_PROGRAM_SEPARABLE_EXT\0"
+ "GL_ACTIVE_PROGRAM_EXT\0"
+ "GL_PROGRAM_PIPELINE_BINDING_EXT\0"
+ "GL_MAX_VIEWPORTS\0"
+ "GL_VIEWPORT_SUBPIXEL_BITS\0"
+ "GL_VIEWPORT_BOUNDS_RANGE\0"
+ "GL_LAYER_PROVOKING_VERTEX\0"
+ "GL_VIEWPORT_INDEX_PROVOKING_VERTEX\0"
+ "GL_UNDEFINED_VERTEX\0"
+ "GL_NO_RESET_NOTIFICATION_ARB\0"
+ "GL_MAX_COMPUTE_SHARED_MEMORY_SIZE\0"
+ "GL_MAX_COMPUTE_UNIFORM_COMPONENTS\0"
+ "GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_MAX_COMPUTE_ATOMIC_COUNTERS\0"
+ "GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS\0"
+ "GL_COMPUTE_WORK_GROUP_SIZE\0"
+ "GL_DEBUG_TYPE_MARKER\0"
+ "GL_DEBUG_TYPE_PUSH_GROUP\0"
+ "GL_DEBUG_TYPE_POP_GROUP\0"
+ "GL_DEBUG_SEVERITY_NOTIFICATION\0"
+ "GL_MAX_DEBUG_GROUP_STACK_DEPTH\0"
+ "GL_DEBUG_GROUP_STACK_DEPTH\0"
+ "GL_VERTEX_ATTRIB_BINDING\0"
+ "GL_VERTEX_ATTRIB_RELATIVE_OFFSET\0"
+ "GL_VERTEX_BINDING_DIVISOR\0"
+ "GL_VERTEX_BINDING_OFFSET\0"
+ "GL_VERTEX_BINDING_STRIDE\0"
+ "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET\0"
+ "GL_MAX_VERTEX_ATTRIB_BINDINGS\0"
+ "GL_TEXTURE_IMMUTABLE_LEVELS\0"
+ "GL_BUFFER\0"
+ "GL_SHADER\0"
+ "GL_PROGRAM\0"
+ "GL_QUERY\0"
+ "GL_PROGRAM_PIPELINE\0"
+ "GL_SAMPLER\0"
+ "GL_DISPLAY_LIST\0"
+ "GL_MAX_LABEL_LENGTH\0"
+ "GL_UNSIGNED_BYTE_2_3_3_REV\0"
+ "GL_UNSIGNED_SHORT_5_6_5\0"
+ "GL_UNSIGNED_SHORT_5_6_5_REV\0"
+ "GL_UNSIGNED_SHORT_4_4_4_4_REV\0"
+ "GL_UNSIGNED_SHORT_1_5_5_5_REV\0"
+ "GL_UNSIGNED_INT_8_8_8_8_REV\0"
+ "GL_UNSIGNED_INT_2_10_10_10_REV\0"
+ "GL_TEXTURE_MAX_CLAMP_S_SGIX\0"
+ "GL_TEXTURE_MAX_CLAMP_T_SGIX\0"
+ "GL_TEXTURE_MAX_CLAMP_R_SGIX\0"
+ "GL_MIRRORED_REPEAT\0"
+ "GL_RGB_S3TC\0"
+ "GL_RGB4_S3TC\0"
+ "GL_RGBA_S3TC\0"
+ "GL_RGBA4_S3TC\0"
+ "GL_RGBA_DXT5_S3TC\0"
+ "GL_RGBA4_DXT5_S3TC\0"
+ "GL_COMPRESSED_RGB_S3TC_DXT1_EXT\0"
+ "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT\0"
+ "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE\0"
+ "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE\0"
+ "GL_PERFQUERY_DONOT_FLUSH_INTEL\0"
+ "GL_PERFQUERY_FLUSH_INTEL\0"
+ "GL_PERFQUERY_WAIT_INTEL\0"
+ "GL_NEAREST_CLIPMAP_NEAREST_SGIX\0"
+ "GL_NEAREST_CLIPMAP_LINEAR_SGIX\0"
+ "GL_LINEAR_CLIPMAP_NEAREST_SGIX\0"
+ "GL_FOG_COORDINATE_SOURCE\0"
+ "GL_FOG_COORD\0"
+ "GL_FRAGMENT_DEPTH\0"
+ "GL_CURRENT_FOG_COORD\0"
+ "GL_FOG_COORDINATE_ARRAY_TYPE\0"
+ "GL_FOG_COORDINATE_ARRAY_STRIDE\0"
+ "GL_FOG_COORDINATE_ARRAY_POINTER\0"
+ "GL_FOG_COORDINATE_ARRAY\0"
+ "GL_COLOR_SUM\0"
+ "GL_CURRENT_SECONDARY_COLOR\0"
+ "GL_SECONDARY_COLOR_ARRAY_SIZE\0"
+ "GL_SECONDARY_COLOR_ARRAY_TYPE\0"
+ "GL_SECONDARY_COLOR_ARRAY_STRIDE\0"
+ "GL_SECONDARY_COLOR_ARRAY_POINTER\0"
+ "GL_SECONDARY_COLOR_ARRAY\0"
+ "GL_CURRENT_RASTER_SECONDARY_COLOR\0"
+ "GL_ALIASED_POINT_SIZE_RANGE\0"
+ "GL_ALIASED_LINE_WIDTH_RANGE\0"
+ "GL_TEXTURE0\0"
+ "GL_TEXTURE1\0"
+ "GL_TEXTURE2\0"
+ "GL_TEXTURE3\0"
+ "GL_TEXTURE4\0"
+ "GL_TEXTURE5\0"
+ "GL_TEXTURE6\0"
+ "GL_TEXTURE7\0"
+ "GL_TEXTURE8\0"
+ "GL_TEXTURE9\0"
+ "GL_TEXTURE10\0"
+ "GL_TEXTURE11\0"
+ "GL_TEXTURE12\0"
+ "GL_TEXTURE13\0"
+ "GL_TEXTURE14\0"
+ "GL_TEXTURE15\0"
+ "GL_TEXTURE16\0"
+ "GL_TEXTURE17\0"
+ "GL_TEXTURE18\0"
+ "GL_TEXTURE19\0"
+ "GL_TEXTURE20\0"
+ "GL_TEXTURE21\0"
+ "GL_TEXTURE22\0"
+ "GL_TEXTURE23\0"
+ "GL_TEXTURE24\0"
+ "GL_TEXTURE25\0"
+ "GL_TEXTURE26\0"
+ "GL_TEXTURE27\0"
+ "GL_TEXTURE28\0"
+ "GL_TEXTURE29\0"
+ "GL_TEXTURE30\0"
+ "GL_TEXTURE31\0"
+ "GL_ACTIVE_TEXTURE\0"
+ "GL_CLIENT_ACTIVE_TEXTURE\0"
+ "GL_MAX_TEXTURE_UNITS\0"
+ "GL_TRANSPOSE_MODELVIEW_MATRIX\0"
+ "GL_TRANSPOSE_PROJECTION_MATRIX\0"
+ "GL_TRANSPOSE_TEXTURE_MATRIX\0"
+ "GL_TRANSPOSE_COLOR_MATRIX\0"
+ "GL_SUBTRACT\0"
+ "GL_MAX_RENDERBUFFER_SIZE\0"
+ "GL_COMPRESSED_ALPHA\0"
+ "GL_COMPRESSED_LUMINANCE\0"
+ "GL_COMPRESSED_LUMINANCE_ALPHA\0"
+ "GL_COMPRESSED_INTENSITY\0"
+ "GL_COMPRESSED_RGB\0"
+ "GL_COMPRESSED_RGBA\0"
+ "GL_TEXTURE_COMPRESSION_HINT\0"
+ "GL_TEXTURE_RECTANGLE\0"
+ "GL_TEXTURE_BINDING_RECTANGLE\0"
+ "GL_PROXY_TEXTURE_RECTANGLE\0"
+ "GL_MAX_RECTANGLE_TEXTURE_SIZE\0"
+ "GL_DEPTH_STENCIL\0"
+ "GL_UNSIGNED_INT_24_8\0"
+ "GL_MAX_TEXTURE_LOD_BIAS\0"
+ "GL_TEXTURE_MAX_ANISOTROPY_EXT\0"
+ "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT\0"
+ "GL_TEXTURE_FILTER_CONTROL\0"
+ "GL_TEXTURE_LOD_BIAS\0"
+ "GL_COMBINE4_NV\0"
+ "GL_MAX_SHININESS_NV\0"
+ "GL_MAX_SPOT_EXPONENT_NV\0"
+ "GL_INCR_WRAP\0"
+ "GL_DECR_WRAP\0"
+ "GL_MODELVIEW1_ARB\0"
+ "GL_NORMAL_MAP\0"
+ "GL_REFLECTION_MAP\0"
+ "GL_TEXTURE_CUBE_MAP\0"
+ "GL_TEXTURE_BINDING_CUBE_MAP\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_X\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_X\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_Y\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_Z\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z\0"
+ "GL_PROXY_TEXTURE_CUBE_MAP\0"
+ "GL_MAX_CUBE_MAP_TEXTURE_SIZE\0"
+ "GL_MULTISAMPLE_FILTER_HINT_NV\0"
+ "GL_PRIMITIVE_RESTART_NV\0"
+ "GL_PRIMITIVE_RESTART_INDEX_NV\0"
+ "GL_FOG_DISTANCE_MODE_NV\0"
+ "GL_EYE_RADIAL_NV\0"
+ "GL_EYE_PLANE_ABSOLUTE_NV\0"
+ "GL_COMBINE\0"
+ "GL_COMBINE_RGB\0"
+ "GL_COMBINE_ALPHA\0"
+ "GL_RGB_SCALE\0"
+ "GL_ADD_SIGNED\0"
+ "GL_INTERPOLATE\0"
+ "GL_CONSTANT\0"
+ "GL_PRIMARY_COLOR\0"
+ "GL_PREVIOUS\0"
+ "GL_SOURCE0_RGB\0"
+ "GL_SOURCE1_RGB\0"
+ "GL_SOURCE2_RGB\0"
+ "GL_SOURCE3_RGB_NV\0"
+ "GL_SOURCE0_ALPHA\0"
+ "GL_SOURCE1_ALPHA\0"
+ "GL_SOURCE2_ALPHA\0"
+ "GL_SOURCE3_ALPHA_NV\0"
+ "GL_OPERAND0_RGB\0"
+ "GL_OPERAND1_RGB\0"
+ "GL_OPERAND2_RGB\0"
+ "GL_OPERAND3_RGB_NV\0"
+ "GL_OPERAND0_ALPHA\0"
+ "GL_OPERAND1_ALPHA\0"
+ "GL_OPERAND2_ALPHA\0"
+ "GL_OPERAND3_ALPHA_NV\0"
+ "GL_BUFFER_OBJECT_APPLE\0"
+ "GL_VERTEX_ARRAY_BINDING\0"
+ "GL_TEXTURE_RANGE_LENGTH_APPLE\0"
+ "GL_TEXTURE_RANGE_POINTER_APPLE\0"
+ "GL_YCBCR_422_APPLE\0"
+ "GL_UNSIGNED_SHORT_8_8_APPLE\0"
+ "GL_UNSIGNED_SHORT_8_8_REV_APPLE\0"
+ "GL_TEXTURE_STORAGE_HINT_APPLE\0"
+ "GL_STORAGE_PRIVATE_APPLE\0"
+ "GL_STORAGE_CACHED_APPLE\0"
+ "GL_STORAGE_SHARED_APPLE\0"
+ "GL_SLICE_ACCUM_SUN\0"
+ "GL_QUAD_MESH_SUN\0"
+ "GL_TRIANGLE_MESH_SUN\0"
+ "GL_VERTEX_PROGRAM_ARB\0"
+ "GL_VERTEX_STATE_PROGRAM_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY_ENABLED\0"
+ "GL_VERTEX_ATTRIB_ARRAY_SIZE\0"
+ "GL_VERTEX_ATTRIB_ARRAY_STRIDE\0"
+ "GL_VERTEX_ATTRIB_ARRAY_TYPE\0"
+ "GL_CURRENT_VERTEX_ATTRIB\0"
+ "GL_PROGRAM_LENGTH_ARB\0"
+ "GL_PROGRAM_STRING_ARB\0"
+ "GL_MODELVIEW_PROJECTION_NV\0"
+ "GL_IDENTITY_NV\0"
+ "GL_INVERSE_NV\0"
+ "GL_TRANSPOSE_NV\0"
+ "GL_INVERSE_TRANSPOSE_NV\0"
+ "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB\0"
+ "GL_MAX_PROGRAM_MATRICES_ARB\0"
+ "GL_MATRIX0_NV\0"
+ "GL_MATRIX1_NV\0"
+ "GL_MATRIX2_NV\0"
+ "GL_MATRIX3_NV\0"
+ "GL_MATRIX4_NV\0"
+ "GL_MATRIX5_NV\0"
+ "GL_MATRIX6_NV\0"
+ "GL_MATRIX7_NV\0"
+ "GL_CURRENT_MATRIX_STACK_DEPTH_ARB\0"
+ "GL_CURRENT_MATRIX_ARB\0"
+ "GL_PROGRAM_POINT_SIZE\0"
+ "GL_VERTEX_PROGRAM_TWO_SIDE\0"
+ "GL_PROGRAM_PARAMETER_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY_POINTER\0"
+ "GL_PROGRAM_TARGET_NV\0"
+ "GL_PROGRAM_RESIDENT_NV\0"
+ "GL_TRACK_MATRIX_NV\0"
+ "GL_TRACK_MATRIX_TRANSFORM_NV\0"
+ "GL_VERTEX_PROGRAM_BINDING_NV\0"
+ "GL_PROGRAM_ERROR_POSITION_ARB\0"
+ "GL_DEPTH_CLAMP\0"
+ "GL_VERTEX_ATTRIB_ARRAY0_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY1_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY2_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY3_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY4_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY5_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY6_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY7_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY8_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY9_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY10_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY11_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY12_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY13_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY14_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY15_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB0_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB1_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB2_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB3_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB4_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB5_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB6_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB7_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB8_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB9_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB10_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB11_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB12_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB13_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB14_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB15_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB0_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB1_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB2_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB3_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB4_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB5_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB6_4_NV\0"
+ "GL_PROGRAM_BINDING_ARB\0"
+ "GL_MAP2_VERTEX_ATTRIB8_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB9_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB10_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB11_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB12_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB13_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB14_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB15_4_NV\0"
+ "GL_TEXTURE_COMPRESSED_IMAGE_SIZE\0"
+ "GL_TEXTURE_COMPRESSED\0"
+ "GL_NUM_COMPRESSED_TEXTURE_FORMATS\0"
+ "GL_COMPRESSED_TEXTURE_FORMATS\0"
+ "GL_MAX_VERTEX_UNITS_ARB\0"
+ "GL_ACTIVE_VERTEX_UNITS_ARB\0"
+ "GL_WEIGHT_SUM_UNITY_ARB\0"
+ "GL_VERTEX_BLEND_ARB\0"
+ "GL_CURRENT_WEIGHT_ARB\0"
+ "GL_WEIGHT_ARRAY_TYPE_ARB\0"
+ "GL_WEIGHT_ARRAY_STRIDE_ARB\0"
+ "GL_WEIGHT_ARRAY_SIZE_ARB\0"
+ "GL_WEIGHT_ARRAY_POINTER_ARB\0"
+ "GL_WEIGHT_ARRAY_ARB\0"
+ "GL_DOT3_RGB\0"
+ "GL_DOT3_RGBA\0"
+ "GL_COMPRESSED_RGB_FXT1_3DFX\0"
+ "GL_COMPRESSED_RGBA_FXT1_3DFX\0"
+ "GL_MULTISAMPLE_3DFX\0"
+ "GL_SAMPLE_BUFFERS_3DFX\0"
+ "GL_SAMPLES_3DFX\0"
+ "GL_SURFACE_STATE_NV\0"
+ "GL_SURFACE_REGISTERED_NV\0"
+ "GL_SURFACE_MAPPED_NV\0"
+ "GL_MODELVIEW2_ARB\0"
+ "GL_MODELVIEW3_ARB\0"
+ "GL_MODELVIEW4_ARB\0"
+ "GL_MODELVIEW5_ARB\0"
+ "GL_MODELVIEW6_ARB\0"
+ "GL_MODELVIEW7_ARB\0"
+ "GL_MODELVIEW8_ARB\0"
+ "GL_MODELVIEW9_ARB\0"
+ "GL_MODELVIEW10_ARB\0"
+ "GL_MODELVIEW11_ARB\0"
+ "GL_MODELVIEW12_ARB\0"
+ "GL_MODELVIEW13_ARB\0"
+ "GL_MODELVIEW14_ARB\0"
+ "GL_MODELVIEW15_ARB\0"
+ "GL_MODELVIEW16_ARB\0"
+ "GL_MODELVIEW17_ARB\0"
+ "GL_MODELVIEW18_ARB\0"
+ "GL_MODELVIEW19_ARB\0"
+ "GL_MODELVIEW20_ARB\0"
+ "GL_MODELVIEW21_ARB\0"
+ "GL_MODELVIEW22_ARB\0"
+ "GL_MODELVIEW23_ARB\0"
+ "GL_MODELVIEW24_ARB\0"
+ "GL_MODELVIEW25_ARB\0"
+ "GL_MODELVIEW26_ARB\0"
+ "GL_MODELVIEW27_ARB\0"
+ "GL_MODELVIEW28_ARB\0"
+ "GL_MODELVIEW29_ARB\0"
+ "GL_MODELVIEW30_ARB\0"
+ "GL_MODELVIEW31_ARB\0"
+ "GL_DOT3_RGB_EXT\0"
+ "GL_PROGRAM_BINARY_LENGTH\0"
+ "GL_MIRROR_CLAMP_EXT\0"
+ "GL_MIRROR_CLAMP_TO_EDGE_EXT\0"
+ "GL_MODULATE_ADD_ATI\0"
+ "GL_MODULATE_SIGNED_ADD_ATI\0"
+ "GL_MODULATE_SUBTRACT_ATI\0"
+ "GL_YCBCR_MESA\0"
+ "GL_PACK_INVERT_MESA\0"
+ "GL_BUFFER_SIZE\0"
+ "GL_BUFFER_USAGE\0"
+ "GL_BUMP_ROT_MATRIX_ATI\0"
+ "GL_BUMP_ROT_MATRIX_SIZE_ATI\0"
+ "GL_BUMP_NUM_TEX_UNITS_ATI\0"
+ "GL_BUMP_TEX_UNITS_ATI\0"
+ "GL_DUDV_ATI\0"
+ "GL_DU8DV8_ATI\0"
+ "GL_BUMP_ENVMAP_ATI\0"
+ "GL_BUMP_TARGET_ATI\0"
+ "GL_NUM_PROGRAM_BINARY_FORMATS\0"
+ "GL_PROGRAM_BINARY_FORMATS\0"
+ "GL_STENCIL_BACK_FUNC\0"
+ "GL_STENCIL_BACK_FAIL\0"
+ "GL_STENCIL_BACK_PASS_DEPTH_FAIL\0"
+ "GL_STENCIL_BACK_PASS_DEPTH_PASS\0"
+ "GL_FRAGMENT_PROGRAM_ARB\0"
+ "GL_PROGRAM_ALU_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_TEX_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_TEX_INDIRECTIONS_ARB\0"
+ "GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB\0"
+ "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB\0"
+ "GL_RGBA32F\0"
+ "GL_RGB32F\0"
+ "GL_ALPHA32F_ARB\0"
+ "GL_INTENSITY32F_ARB\0"
+ "GL_LUMINANCE32F_ARB\0"
+ "GL_LUMINANCE_ALPHA32F_ARB\0"
+ "GL_RGBA16F\0"
+ "GL_RGB16F\0"
+ "GL_ALPHA16F_ARB\0"
+ "GL_INTENSITY16F_ARB\0"
+ "GL_LUMINANCE16F_ARB\0"
+ "GL_LUMINANCE_ALPHA16F_ARB\0"
+ "GL_RGBA_FLOAT_MODE_ARB\0"
+ "GL_MAX_DRAW_BUFFERS\0"
+ "GL_DRAW_BUFFER0\0"
+ "GL_DRAW_BUFFER1\0"
+ "GL_DRAW_BUFFER2\0"
+ "GL_DRAW_BUFFER3\0"
+ "GL_DRAW_BUFFER4\0"
+ "GL_DRAW_BUFFER5\0"
+ "GL_DRAW_BUFFER6\0"
+ "GL_DRAW_BUFFER7\0"
+ "GL_DRAW_BUFFER8\0"
+ "GL_DRAW_BUFFER9\0"
+ "GL_DRAW_BUFFER10\0"
+ "GL_DRAW_BUFFER11\0"
+ "GL_DRAW_BUFFER12\0"
+ "GL_DRAW_BUFFER13\0"
+ "GL_DRAW_BUFFER14\0"
+ "GL_DRAW_BUFFER15\0"
+ "GL_BLEND_EQUATION_ALPHA\0"
+ "GL_MATRIX_PALETTE_ARB\0"
+ "GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB\0"
+ "GL_MAX_PALETTE_MATRICES_ARB\0"
+ "GL_CURRENT_PALETTE_MATRIX_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_ARB\0"
+ "GL_CURRENT_MATRIX_INDEX_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_SIZE_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_TYPE_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_STRIDE_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_POINTER_ARB\0"
+ "GL_TEXTURE_DEPTH_SIZE\0"
+ "GL_DEPTH_TEXTURE_MODE\0"
+ "GL_TEXTURE_COMPARE_MODE\0"
+ "GL_TEXTURE_COMPARE_FUNC\0"
+ "GL_COMPARE_REF_TO_TEXTURE\0"
+ "GL_TEXTURE_CUBE_MAP_SEAMLESS\0"
+ "GL_POINT_SPRITE\0"
+ "GL_COORD_REPLACE\0"
+ "GL_POINT_SPRITE_R_MODE_NV\0"
+ "GL_QUERY_COUNTER_BITS\0"
+ "GL_CURRENT_QUERY\0"
+ "GL_QUERY_RESULT\0"
+ "GL_QUERY_RESULT_AVAILABLE\0"
+ "GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV\0"
+ "GL_MAX_VERTEX_ATTRIBS\0"
+ "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED\0"
+ "GL_DEPTH_STENCIL_TO_RGBA_NV\0"
+ "GL_DEPTH_STENCIL_TO_BGRA_NV\0"
+ "GL_FRAGMENT_PROGRAM_NV\0"
+ "GL_MAX_TEXTURE_COORDS\0"
+ "GL_MAX_TEXTURE_IMAGE_UNITS\0"
+ "GL_FRAGMENT_PROGRAM_BINDING_NV\0"
+ "GL_PROGRAM_ERROR_STRING_ARB\0"
+ "GL_PROGRAM_FORMAT_ASCII_ARB\0"
+ "GL_PROGRAM_FORMAT_ARB\0"
+ "GL_GEOMETRY_SHADER_INVOCATIONS\0"
+ "GL_TEXTURE_UNSIGNED_REMAP_MODE_NV\0"
+ "GL_DEPTH_BOUNDS_TEST_EXT\0"
+ "GL_DEPTH_BOUNDS_EXT\0"
+ "GL_ARRAY_BUFFER\0"
+ "GL_ELEMENT_ARRAY_BUFFER\0"
+ "GL_ARRAY_BUFFER_BINDING\0"
+ "GL_ELEMENT_ARRAY_BUFFER_BINDING\0"
+ "GL_VERTEX_ARRAY_BUFFER_BINDING\0"
+ "GL_NORMAL_ARRAY_BUFFER_BINDING\0"
+ "GL_COLOR_ARRAY_BUFFER_BINDING\0"
+ "GL_INDEX_ARRAY_BUFFER_BINDING\0"
+ "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING\0"
+ "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING\0"
+ "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING\0"
+ "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING\0"
+ "GL_WEIGHT_ARRAY_BUFFER_BINDING\0"
+ "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING\0"
+ "GL_PROGRAM_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_TEMPORARIES_ARB\0"
+ "GL_MAX_PROGRAM_TEMPORARIES_ARB\0"
+ "GL_PROGRAM_NATIVE_TEMPORARIES_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB\0"
+ "GL_PROGRAM_PARAMETERS_ARB\0"
+ "GL_MAX_PROGRAM_PARAMETERS_ARB\0"
+ "GL_PROGRAM_NATIVE_PARAMETERS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB\0"
+ "GL_PROGRAM_ATTRIBS_ARB\0"
+ "GL_MAX_PROGRAM_ATTRIBS_ARB\0"
+ "GL_PROGRAM_NATIVE_ATTRIBS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB\0"
+ "GL_PROGRAM_ADDRESS_REGISTERS_ARB\0"
+ "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB\0"
+ "GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB\0"
+ "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB\0"
+ "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB\0"
+ "GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB\0"
+ "GL_TRANSPOSE_CURRENT_MATRIX_ARB\0"
+ "GL_READ_ONLY\0"
+ "GL_WRITE_ONLY\0"
+ "GL_READ_WRITE\0"
+ "GL_BUFFER_ACCESS\0"
+ "GL_BUFFER_MAPPED\0"
+ "GL_BUFFER_MAP_POINTER\0"
+ "GL_WRITE_DISCARD_NV\0"
+ "GL_TIME_ELAPSED\0"
+ "GL_MATRIX0_ARB\0"
+ "GL_MATRIX1_ARB\0"
+ "GL_MATRIX2_ARB\0"
+ "GL_MATRIX3_ARB\0"
+ "GL_MATRIX4_ARB\0"
+ "GL_MATRIX5_ARB\0"
+ "GL_MATRIX6_ARB\0"
+ "GL_MATRIX7_ARB\0"
+ "GL_MATRIX8_ARB\0"
+ "GL_MATRIX9_ARB\0"
+ "GL_MATRIX10_ARB\0"
+ "GL_MATRIX11_ARB\0"
+ "GL_MATRIX12_ARB\0"
+ "GL_MATRIX13_ARB\0"
+ "GL_MATRIX14_ARB\0"
+ "GL_MATRIX15_ARB\0"
+ "GL_MATRIX16_ARB\0"
+ "GL_MATRIX17_ARB\0"
+ "GL_MATRIX18_ARB\0"
+ "GL_MATRIX19_ARB\0"
+ "GL_MATRIX20_ARB\0"
+ "GL_MATRIX21_ARB\0"
+ "GL_MATRIX22_ARB\0"
+ "GL_MATRIX23_ARB\0"
+ "GL_MATRIX24_ARB\0"
+ "GL_MATRIX25_ARB\0"
+ "GL_MATRIX26_ARB\0"
+ "GL_MATRIX27_ARB\0"
+ "GL_MATRIX28_ARB\0"
+ "GL_MATRIX29_ARB\0"
+ "GL_MATRIX30_ARB\0"
+ "GL_MATRIX31_ARB\0"
+ "GL_STREAM_DRAW\0"
+ "GL_STREAM_READ\0"
+ "GL_STREAM_COPY\0"
+ "GL_STATIC_DRAW\0"
+ "GL_STATIC_READ\0"
+ "GL_STATIC_COPY\0"
+ "GL_DYNAMIC_DRAW\0"
+ "GL_DYNAMIC_READ\0"
+ "GL_DYNAMIC_COPY\0"
+ "GL_PIXEL_PACK_BUFFER\0"
+ "GL_PIXEL_UNPACK_BUFFER\0"
+ "GL_PIXEL_PACK_BUFFER_BINDING\0"
+ "GL_PIXEL_UNPACK_BUFFER_BINDING\0"
+ "GL_DEPTH24_STENCIL8\0"
+ "GL_TEXTURE_STENCIL_SIZE\0"
+ "GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV\0"
+ "GL_MAX_PROGRAM_CALL_DEPTH_NV\0"
+ "GL_MAX_PROGRAM_IF_DEPTH_NV\0"
+ "GL_MAX_PROGRAM_LOOP_DEPTH_NV\0"
+ "GL_MAX_PROGRAM_LOOP_COUNT_NV\0"
+ "GL_SRC1_COLOR\0"
+ "GL_ONE_MINUS_SRC1_COLOR\0"
+ "GL_ONE_MINUS_SRC1_ALPHA\0"
+ "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS\0"
+ "GL_VERTEX_ATTRIB_ARRAY_INTEGER\0"
+ "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB\0"
+ "GL_MAX_ARRAY_TEXTURE_LAYERS\0"
+ "GL_MIN_PROGRAM_TEXEL_OFFSET\0"
+ "GL_MAX_PROGRAM_TEXEL_OFFSET\0"
+ "GL_STENCIL_TEST_TWO_SIDE_EXT\0"
+ "GL_ACTIVE_STENCIL_FACE_EXT\0"
+ "GL_MIRROR_CLAMP_TO_BORDER_EXT\0"
+ "GL_SAMPLES_PASSED\0"
+ "GL_GEOMETRY_VERTICES_OUT\0"
+ "GL_GEOMETRY_INPUT_TYPE\0"
+ "GL_GEOMETRY_OUTPUT_TYPE\0"
+ "GL_SAMPLER_BINDING\0"
+ "GL_CLAMP_VERTEX_COLOR\0"
+ "GL_CLAMP_FRAGMENT_COLOR\0"
+ "GL_CLAMP_READ_COLOR\0"
+ "GL_FIXED_ONLY\0"
+ "GL_FRAGMENT_SHADER_ATI\0"
+ "GL_REG_0_ATI\0"
+ "GL_REG_1_ATI\0"
+ "GL_REG_2_ATI\0"
+ "GL_REG_3_ATI\0"
+ "GL_REG_4_ATI\0"
+ "GL_REG_5_ATI\0"
+ "GL_REG_6_ATI\0"
+ "GL_REG_7_ATI\0"
+ "GL_REG_8_ATI\0"
+ "GL_REG_9_ATI\0"
+ "GL_REG_10_ATI\0"
+ "GL_REG_11_ATI\0"
+ "GL_REG_12_ATI\0"
+ "GL_REG_13_ATI\0"
+ "GL_REG_14_ATI\0"
+ "GL_REG_15_ATI\0"
+ "GL_REG_16_ATI\0"
+ "GL_REG_17_ATI\0"
+ "GL_REG_18_ATI\0"
+ "GL_REG_19_ATI\0"
+ "GL_REG_20_ATI\0"
+ "GL_REG_21_ATI\0"
+ "GL_REG_22_ATI\0"
+ "GL_REG_23_ATI\0"
+ "GL_REG_24_ATI\0"
+ "GL_REG_25_ATI\0"
+ "GL_REG_26_ATI\0"
+ "GL_REG_27_ATI\0"
+ "GL_REG_28_ATI\0"
+ "GL_REG_29_ATI\0"
+ "GL_REG_30_ATI\0"
+ "GL_REG_31_ATI\0"
+ "GL_CON_0_ATI\0"
+ "GL_CON_1_ATI\0"
+ "GL_CON_2_ATI\0"
+ "GL_CON_3_ATI\0"
+ "GL_CON_4_ATI\0"
+ "GL_CON_5_ATI\0"
+ "GL_CON_6_ATI\0"
+ "GL_CON_7_ATI\0"
+ "GL_CON_8_ATI\0"
+ "GL_CON_9_ATI\0"
+ "GL_CON_10_ATI\0"
+ "GL_CON_11_ATI\0"
+ "GL_CON_12_ATI\0"
+ "GL_CON_13_ATI\0"
+ "GL_CON_14_ATI\0"
+ "GL_CON_15_ATI\0"
+ "GL_CON_16_ATI\0"
+ "GL_CON_17_ATI\0"
+ "GL_CON_18_ATI\0"
+ "GL_CON_19_ATI\0"
+ "GL_CON_20_ATI\0"
+ "GL_CON_21_ATI\0"
+ "GL_CON_22_ATI\0"
+ "GL_CON_23_ATI\0"
+ "GL_CON_24_ATI\0"
+ "GL_CON_25_ATI\0"
+ "GL_CON_26_ATI\0"
+ "GL_CON_27_ATI\0"
+ "GL_CON_28_ATI\0"
+ "GL_CON_29_ATI\0"
+ "GL_CON_30_ATI\0"
+ "GL_CON_31_ATI\0"
+ "GL_MOV_ATI\0"
+ "GL_ADD_ATI\0"
+ "GL_MUL_ATI\0"
+ "GL_SUB_ATI\0"
+ "GL_DOT3_ATI\0"
+ "GL_DOT4_ATI\0"
+ "GL_MAD_ATI\0"
+ "GL_LERP_ATI\0"
+ "GL_CND_ATI\0"
+ "GL_CND0_ATI\0"
+ "GL_DOT2_ADD_ATI\0"
+ "GL_SECONDARY_INTERPOLATOR_ATI\0"
+ "GL_NUM_FRAGMENT_REGISTERS_ATI\0"
+ "GL_NUM_FRAGMENT_CONSTANTS_ATI\0"
+ "GL_NUM_PASSES_ATI\0"
+ "GL_NUM_INSTRUCTIONS_PER_PASS_ATI\0"
+ "GL_NUM_INSTRUCTIONS_TOTAL_ATI\0"
+ "GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI\0"
+ "GL_NUM_LOOPBACK_COMPONENTS_ATI\0"
+ "GL_COLOR_ALPHA_PAIRING_ATI\0"
+ "GL_SWIZZLE_STR_ATI\0"
+ "GL_SWIZZLE_STQ_ATI\0"
+ "GL_SWIZZLE_STR_DR_ATI\0"
+ "GL_SWIZZLE_STQ_DQ_ATI\0"
+ "GL_SWIZZLE_STRQ_ATI\0"
+ "GL_SWIZZLE_STRQ_DQ_ATI\0"
+ "GL_POINT_SIZE_ARRAY_TYPE_OES\0"
+ "GL_POINT_SIZE_ARRAY_STRIDE_OES\0"
+ "GL_POINT_SIZE_ARRAY_POINTER_OES\0"
+ "GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES\0"
+ "GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES\0"
+ "GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES\0"
+ "GL_UNIFORM_BUFFER\0"
+ "GL_BUFFER_SERIALIZED_MODIFY_APPLE\0"
+ "GL_BUFFER_FLUSHING_UNMAP_APPLE\0"
+ "GL_RELEASED_APPLE\0"
+ "GL_VOLATILE_APPLE\0"
+ "GL_RETAINED_APPLE\0"
+ "GL_UNDEFINED_APPLE\0"
+ "GL_PURGEABLE_APPLE\0"
+ "GL_UNIFORM_BUFFER_BINDING\0"
+ "GL_UNIFORM_BUFFER_START\0"
+ "GL_UNIFORM_BUFFER_SIZE\0"
+ "GL_MAX_VERTEX_UNIFORM_BLOCKS\0"
+ "GL_MAX_GEOMETRY_UNIFORM_BLOCKS\0"
+ "GL_MAX_FRAGMENT_UNIFORM_BLOCKS\0"
+ "GL_MAX_COMBINED_UNIFORM_BLOCKS\0"
+ "GL_MAX_UNIFORM_BUFFER_BINDINGS\0"
+ "GL_MAX_UNIFORM_BLOCK_SIZE\0"
+ "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS\0"
+ "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS\0"
+ "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS\0"
+ "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT\0"
+ "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH\0"
+ "GL_ACTIVE_UNIFORM_BLOCKS\0"
+ "GL_UNIFORM_TYPE\0"
+ "GL_UNIFORM_SIZE\0"
+ "GL_UNIFORM_NAME_LENGTH\0"
+ "GL_UNIFORM_BLOCK_INDEX\0"
+ "GL_UNIFORM_OFFSET\0"
+ "GL_UNIFORM_ARRAY_STRIDE\0"
+ "GL_UNIFORM_MATRIX_STRIDE\0"
+ "GL_UNIFORM_IS_ROW_MAJOR\0"
+ "GL_UNIFORM_BLOCK_BINDING\0"
+ "GL_UNIFORM_BLOCK_DATA_SIZE\0"
+ "GL_UNIFORM_BLOCK_NAME_LENGTH\0"
+ "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS\0"
+ "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES\0"
+ "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER\0"
+ "GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER\0"
+ "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER\0"
+ "GL_TEXTURE_SRGB_DECODE_EXT\0"
+ "GL_DECODE_EXT\0"
+ "GL_SKIP_DECODE_EXT\0"
+ "GL_FRAGMENT_SHADER\0"
+ "GL_VERTEX_SHADER\0"
+ "GL_PROGRAM_OBJECT_ARB\0"
+ "GL_SHADER_OBJECT_ARB\0"
+ "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS\0"
+ "GL_MAX_VERTEX_UNIFORM_COMPONENTS\0"
+ "GL_MAX_VARYING_COMPONENTS\0"
+ "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS\0"
+ "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS\0"
+ "GL_OBJECT_TYPE_ARB\0"
+ "GL_SHADER_TYPE\0"
+ "GL_FLOAT_VEC2\0"
+ "GL_FLOAT_VEC3\0"
+ "GL_FLOAT_VEC4\0"
+ "GL_INT_VEC2\0"
+ "GL_INT_VEC3\0"
+ "GL_INT_VEC4\0"
+ "GL_BOOL\0"
+ "GL_BOOL_VEC2\0"
+ "GL_BOOL_VEC3\0"
+ "GL_BOOL_VEC4\0"
+ "GL_FLOAT_MAT2\0"
+ "GL_FLOAT_MAT3\0"
+ "GL_FLOAT_MAT4\0"
+ "GL_SAMPLER_1D\0"
+ "GL_SAMPLER_2D\0"
+ "GL_SAMPLER_3D\0"
+ "GL_SAMPLER_CUBE\0"
+ "GL_SAMPLER_1D_SHADOW\0"
+ "GL_SAMPLER_2D_SHADOW\0"
+ "GL_SAMPLER_2D_RECT\0"
+ "GL_SAMPLER_2D_RECT_SHADOW\0"
+ "GL_FLOAT_MAT2x3\0"
+ "GL_FLOAT_MAT2x4\0"
+ "GL_FLOAT_MAT3x2\0"
+ "GL_FLOAT_MAT3x4\0"
+ "GL_FLOAT_MAT4x2\0"
+ "GL_FLOAT_MAT4x3\0"
+ "GL_DELETE_STATUS\0"
+ "GL_COMPILE_STATUS\0"
+ "GL_LINK_STATUS\0"
+ "GL_VALIDATE_STATUS\0"
+ "GL_INFO_LOG_LENGTH\0"
+ "GL_ATTACHED_SHADERS\0"
+ "GL_ACTIVE_UNIFORMS\0"
+ "GL_ACTIVE_UNIFORM_MAX_LENGTH\0"
+ "GL_SHADER_SOURCE_LENGTH\0"
+ "GL_ACTIVE_ATTRIBUTES\0"
+ "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH\0"
+ "GL_FRAGMENT_SHADER_DERIVATIVE_HINT\0"
+ "GL_SHADING_LANGUAGE_VERSION\0"
+ "GL_CURRENT_PROGRAM\0"
+ "GL_PALETTE4_RGB8_OES\0"
+ "GL_PALETTE4_RGBA8_OES\0"
+ "GL_PALETTE4_R5_G6_B5_OES\0"
+ "GL_PALETTE4_RGBA4_OES\0"
+ "GL_PALETTE4_RGB5_A1_OES\0"
+ "GL_PALETTE8_RGB8_OES\0"
+ "GL_PALETTE8_RGBA8_OES\0"
+ "GL_PALETTE8_R5_G6_B5_OES\0"
+ "GL_PALETTE8_RGBA4_OES\0"
+ "GL_PALETTE8_RGB5_A1_OES\0"
+ "GL_IMPLEMENTATION_COLOR_READ_TYPE\0"
+ "GL_IMPLEMENTATION_COLOR_READ_FORMAT\0"
+ "GL_POINT_SIZE_ARRAY_OES\0"
+ "GL_TEXTURE_CROP_RECT_OES\0"
+ "GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES\0"
+ "GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES\0"
+ "GL_COUNTER_TYPE_AMD\0"
+ "GL_COUNTER_RANGE_AMD\0"
+ "GL_UNSIGNED_INT64_AMD\0"
+ "GL_PECENTAGE_AMD\0"
+ "GL_PERFMON_RESULT_AVAILABLE_AMD\0"
+ "GL_PERFMON_RESULT_SIZE_AMD\0"
+ "GL_PERFMON_RESULT_AMD\0"
+ "GL_TEXTURE_RED_TYPE\0"
+ "GL_TEXTURE_GREEN_TYPE\0"
+ "GL_TEXTURE_BLUE_TYPE\0"
+ "GL_TEXTURE_ALPHA_TYPE\0"
+ "GL_TEXTURE_LUMINANCE_TYPE\0"
+ "GL_TEXTURE_INTENSITY_TYPE\0"
+ "GL_TEXTURE_DEPTH_TYPE\0"
+ "GL_UNSIGNED_NORMALIZED\0"
+ "GL_TEXTURE_1D_ARRAY\0"
+ "GL_PROXY_TEXTURE_1D_ARRAY\0"
+ "GL_TEXTURE_2D_ARRAY\0"
+ "GL_PROXY_TEXTURE_2D_ARRAY\0"
+ "GL_TEXTURE_BINDING_1D_ARRAY\0"
+ "GL_TEXTURE_BINDING_2D_ARRAY\0"
+ "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS\0"
+ "GL_TEXTURE_BUFFER\0"
+ "GL_MAX_TEXTURE_BUFFER_SIZE\0"
+ "GL_TEXTURE_BINDING_BUFFER\0"
+ "GL_TEXTURE_BUFFER_DATA_STORE_BINDING\0"
+ "GL_TEXTURE_BUFFER_FORMAT\0"
+ "GL_ANY_SAMPLES_PASSED\0"
+ "GL_SAMPLE_SHADING\0"
+ "GL_MIN_SAMPLE_SHADING_VALUE\0"
+ "GL_R11F_G11F_B10F\0"
+ "GL_UNSIGNED_INT_10F_11F_11F_REV\0"
+ "GL_RGBA_SIGNED_COMPONENTS_EXT\0"
+ "GL_RGB9_E5\0"
+ "GL_UNSIGNED_INT_5_9_9_9_REV\0"
+ "GL_TEXTURE_SHARED_SIZE\0"
+ "GL_SRGB\0"
+ "GL_SRGB8\0"
+ "GL_SRGB_ALPHA\0"
+ "GL_SRGB8_ALPHA8\0"
+ "GL_SLUMINANCE_ALPHA\0"
+ "GL_SLUMINANCE8_ALPHA8\0"
+ "GL_SLUMINANCE\0"
+ "GL_SLUMINANCE8\0"
+ "GL_COMPRESSED_SRGB\0"
+ "GL_COMPRESSED_SRGB_ALPHA\0"
+ "GL_COMPRESSED_SLUMINANCE\0"
+ "GL_COMPRESSED_SLUMINANCE_ALPHA\0"
+ "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH\0"
+ "GL_TRANSFORM_FEEDBACK_BUFFER_MODE\0"
+ "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS\0"
+ "GL_TRANSFORM_FEEDBACK_VARYINGS\0"
+ "GL_TRANSFORM_FEEDBACK_BUFFER_START\0"
+ "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE\0"
+ "GL_PRIMITIVES_GENERATED\0"
+ "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN\0"
+ "GL_RASTERIZER_DISCARD\0"
+ "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS\0"
+ "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS\0"
+ "GL_INTERLEAVED_ATTRIBS\0"
+ "GL_SEPARATE_ATTRIBS\0"
+ "GL_TRANSFORM_FEEDBACK_BUFFER\0"
+ "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING\0"
+ "GL_POINT_SPRITE_COORD_ORIGIN\0"
+ "GL_LOWER_LEFT\0"
+ "GL_UPPER_LEFT\0"
+ "GL_STENCIL_BACK_REF\0"
+ "GL_STENCIL_BACK_VALUE_MASK\0"
+ "GL_STENCIL_BACK_WRITEMASK\0"
+ "GL_DRAW_FRAMEBUFFER_BINDING\0"
+ "GL_RENDERBUFFER_BINDING\0"
+ "GL_READ_FRAMEBUFFER\0"
+ "GL_DRAW_FRAMEBUFFER\0"
+ "GL_READ_FRAMEBUFFER_BINDING\0"
+ "GL_RENDERBUFFER_SAMPLES\0"
+ "GL_DEPTH_COMPONENT32F\0"
+ "GL_DEPTH32F_STENCIL8\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER\0"
+ "GL_FRAMEBUFFER_COMPLETE\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\0"
+ "GL_FRAMEBUFFER_UNSUPPORTED\0"
+ "GL_FRAMEBUFFER_STATUS_ERROR_EXT\0"
+ "GL_MAX_COLOR_ATTACHMENTS\0"
+ "GL_COLOR_ATTACHMENT0\0"
+ "GL_COLOR_ATTACHMENT1\0"
+ "GL_COLOR_ATTACHMENT2\0"
+ "GL_COLOR_ATTACHMENT3\0"
+ "GL_COLOR_ATTACHMENT4\0"
+ "GL_COLOR_ATTACHMENT5\0"
+ "GL_COLOR_ATTACHMENT6\0"
+ "GL_COLOR_ATTACHMENT7\0"
+ "GL_COLOR_ATTACHMENT8\0"
+ "GL_COLOR_ATTACHMENT9\0"
+ "GL_COLOR_ATTACHMENT10\0"
+ "GL_COLOR_ATTACHMENT11\0"
+ "GL_COLOR_ATTACHMENT12\0"
+ "GL_COLOR_ATTACHMENT13\0"
+ "GL_COLOR_ATTACHMENT14\0"
+ "GL_COLOR_ATTACHMENT15\0"
+ "GL_DEPTH_ATTACHMENT\0"
+ "GL_STENCIL_ATTACHMENT\0"
+ "GL_FRAMEBUFFER\0"
+ "GL_RENDERBUFFER\0"
+ "GL_RENDERBUFFER_WIDTH\0"
+ "GL_RENDERBUFFER_HEIGHT\0"
+ "GL_RENDERBUFFER_INTERNAL_FORMAT\0"
+ "GL_STENCIL_INDEX_EXT\0"
+ "GL_STENCIL_INDEX1\0"
+ "GL_STENCIL_INDEX4\0"
+ "GL_STENCIL_INDEX8\0"
+ "GL_STENCIL_INDEX16\0"
+ "GL_RENDERBUFFER_RED_SIZE\0"
+ "GL_RENDERBUFFER_GREEN_SIZE\0"
+ "GL_RENDERBUFFER_BLUE_SIZE\0"
+ "GL_RENDERBUFFER_ALPHA_SIZE\0"
+ "GL_RENDERBUFFER_DEPTH_SIZE\0"
+ "GL_RENDERBUFFER_STENCIL_SIZE\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\0"
+ "GL_MAX_SAMPLES\0"
+ "GL_TEXTURE_GEN_STR_OES\0"
+ "GL_HALF_FLOAT_OES\0"
+ "GL_RGB565\0"
+ "GL_ETC1_RGB8_OES\0"
+ "GL_TEXTURE_EXTERNAL_OES\0"
+ "GL_SAMPLER_EXTERNAL_OES\0"
+ "GL_TEXTURE_BINDING_EXTERNAL_OES\0"
+ "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES\0"
+ "GL_PRIMITIVE_RESTART_FIXED_INDEX\0"
+ "GL_ANY_SAMPLES_PASSED_CONSERVATIVE\0"
+ "GL_MAX_ELEMENT_INDEX\0"
+ "GL_RGBA32UI\0"
+ "GL_RGB32UI\0"
+ "GL_ALPHA32UI_EXT\0"
+ "GL_INTENSITY32UI_EXT\0"
+ "GL_LUMINANCE32UI_EXT\0"
+ "GL_LUMINANCE_ALPHA32UI_EXT\0"
+ "GL_RGBA16UI\0"
+ "GL_RGB16UI\0"
+ "GL_ALPHA16UI_EXT\0"
+ "GL_INTENSITY16UI_EXT\0"
+ "GL_LUMINANCE16UI_EXT\0"
+ "GL_LUMINANCE_ALPHA16UI_EXT\0"
+ "GL_RGBA8UI\0"
+ "GL_RGB8UI\0"
+ "GL_ALPHA8UI_EXT\0"
+ "GL_INTENSITY8UI_EXT\0"
+ "GL_LUMINANCE8UI_EXT\0"
+ "GL_LUMINANCE_ALPHA8UI_EXT\0"
+ "GL_RGBA32I\0"
+ "GL_RGB32I\0"
+ "GL_ALPHA32I_EXT\0"
+ "GL_INTENSITY32I_EXT\0"
+ "GL_LUMINANCE32I_EXT\0"
+ "GL_LUMINANCE_ALPHA32I_EXT\0"
+ "GL_RGBA16I\0"
+ "GL_RGB16I\0"
+ "GL_ALPHA16I_EXT\0"
+ "GL_INTENSITY16I_EXT\0"
+ "GL_LUMINANCE16I_EXT\0"
+ "GL_LUMINANCE_ALPHA16I_EXT\0"
+ "GL_RGBA8I\0"
+ "GL_RGB8I\0"
+ "GL_ALPHA8I_EXT\0"
+ "GL_INTENSITY8I_EXT\0"
+ "GL_LUMINANCE8I_EXT\0"
+ "GL_LUMINANCE_ALPHA8I_EXT\0"
+ "GL_RED_INTEGER\0"
+ "GL_GREEN_INTEGER\0"
+ "GL_BLUE_INTEGER\0"
+ "GL_ALPHA_INTEGER_EXT\0"
+ "GL_RGB_INTEGER\0"
+ "GL_RGBA_INTEGER\0"
+ "GL_BGR_INTEGER\0"
+ "GL_BGRA_INTEGER\0"
+ "GL_LUMINANCE_INTEGER_EXT\0"
+ "GL_LUMINANCE_ALPHA_INTEGER_EXT\0"
+ "GL_RGBA_INTEGER_MODE_EXT\0"
+ "GL_INT_2_10_10_10_REV\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_LAYERED\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB\0"
+ "GL_FLOAT_32_UNSIGNED_INT_24_8_REV\0"
+ "GL_FRAMEBUFFER_SRGB\0"
+ "GL_FRAMEBUFFER_SRGB_CAPABLE_EXT\0"
+ "GL_COMPRESSED_RED_RGTC1\0"
+ "GL_COMPRESSED_SIGNED_RED_RGTC1\0"
+ "GL_COMPRESSED_RG_RGTC2\0"
+ "GL_COMPRESSED_SIGNED_RG_RGTC2\0"
+ "GL_SAMPLER_1D_ARRAY\0"
+ "GL_SAMPLER_2D_ARRAY\0"
+ "GL_SAMPLER_BUFFER\0"
+ "GL_SAMPLER_1D_ARRAY_SHADOW\0"
+ "GL_SAMPLER_2D_ARRAY_SHADOW\0"
+ "GL_SAMPLER_CUBE_SHADOW\0"
+ "GL_UNSIGNED_INT_VEC2\0"
+ "GL_UNSIGNED_INT_VEC3\0"
+ "GL_UNSIGNED_INT_VEC4\0"
+ "GL_INT_SAMPLER_1D\0"
+ "GL_INT_SAMPLER_2D\0"
+ "GL_INT_SAMPLER_3D\0"
+ "GL_INT_SAMPLER_CUBE\0"
+ "GL_INT_SAMPLER_2D_RECT\0"
+ "GL_INT_SAMPLER_1D_ARRAY\0"
+ "GL_INT_SAMPLER_2D_ARRAY\0"
+ "GL_INT_SAMPLER_BUFFER\0"
+ "GL_UNSIGNED_INT_SAMPLER_1D\0"
+ "GL_UNSIGNED_INT_SAMPLER_2D\0"
+ "GL_UNSIGNED_INT_SAMPLER_3D\0"
+ "GL_UNSIGNED_INT_SAMPLER_CUBE\0"
+ "GL_UNSIGNED_INT_SAMPLER_2D_RECT\0"
+ "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY\0"
+ "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY\0"
+ "GL_UNSIGNED_INT_SAMPLER_BUFFER\0"
+ "GL_GEOMETRY_SHADER\0"
+ "GL_GEOMETRY_VERTICES_OUT_ARB\0"
+ "GL_GEOMETRY_INPUT_TYPE_ARB\0"
+ "GL_GEOMETRY_OUTPUT_TYPE_ARB\0"
+ "GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB\0"
+ "GL_MAX_VERTEX_VARYING_COMPONENTS_ARB\0"
+ "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS\0"
+ "GL_MAX_GEOMETRY_OUTPUT_VERTICES\0"
+ "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS\0"
+ "GL_LOW_FLOAT\0"
+ "GL_MEDIUM_FLOAT\0"
+ "GL_HIGH_FLOAT\0"
+ "GL_LOW_INT\0"
+ "GL_MEDIUM_INT\0"
+ "GL_HIGH_INT\0"
+ "GL_UNSIGNED_INT_10_10_10_2_OES\0"
+ "GL_INT_10_10_10_2_OES\0"
+ "GL_SHADER_BINARY_FORMATS\0"
+ "GL_NUM_SHADER_BINARY_FORMATS\0"
+ "GL_SHADER_COMPILER\0"
+ "GL_MAX_VERTEX_UNIFORM_VECTORS\0"
+ "GL_MAX_VARYING_VECTORS\0"
+ "GL_MAX_FRAGMENT_UNIFORM_VECTORS\0"
+ "GL_QUERY_WAIT\0"
+ "GL_QUERY_NO_WAIT\0"
+ "GL_QUERY_BY_REGION_WAIT\0"
+ "GL_QUERY_BY_REGION_NO_WAIT\0"
+ "GL_TRANSFORM_FEEDBACK\0"
+ "GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED\0"
+ "GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE\0"
+ "GL_TRANSFORM_FEEDBACK_BINDING\0"
+ "GL_TIMESTAMP\0"
+ "GL_TEXTURE_SWIZZLE_R\0"
+ "GL_TEXTURE_SWIZZLE_G\0"
+ "GL_TEXTURE_SWIZZLE_B\0"
+ "GL_TEXTURE_SWIZZLE_A\0"
+ "GL_TEXTURE_SWIZZLE_RGBA\0"
+ "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION\0"
+ "GL_FIRST_VERTEX_CONVENTION\0"
+ "GL_LAST_VERTEX_CONVENTION\0"
+ "GL_PROVOKING_VERTEX\0"
+ "GL_SAMPLE_POSITION\0"
+ "GL_SAMPLE_MASK\0"
+ "GL_SAMPLE_MASK_VALUE\0"
+ "GL_MAX_SAMPLE_MASK_WORDS\0"
+ "GL_MAX_GEOMETRY_SHADER_INVOCATIONS\0"
+ "GL_MIN_FRAGMENT_INTERPOLATION_OFFSET\0"
+ "GL_MAX_FRAGMENT_INTERPOLATION_OFFSET\0"
+ "GL_FRAGMENT_INTERPOLATION_OFFSET_BITS\0"
+ "GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET\0"
+ "GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET\0"
+ "GL_MAX_TRANSFORM_FEEDBACK_BUFFERS\0"
+ "GL_MAX_VERTEX_STREAMS\0"
+ "GL_COPY_READ_BUFFER\0"
+ "GL_COPY_WRITE_BUFFER\0"
+ "GL_MAX_IMAGE_UNITS\0"
+ "GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS\0"
+ "GL_IMAGE_BINDING_NAME\0"
+ "GL_IMAGE_BINDING_LEVEL\0"
+ "GL_IMAGE_BINDING_LAYERED\0"
+ "GL_IMAGE_BINDING_LAYER\0"
+ "GL_IMAGE_BINDING_ACCESS\0"
+ "GL_DRAW_INDIRECT_BUFFER\0"
+ "GL_DRAW_INDIRECT_BUFFER_BINDING\0"
+ "GL_RED_SNORM\0"
+ "GL_RG_SNORM\0"
+ "GL_RGB_SNORM\0"
+ "GL_RGBA_SNORM\0"
+ "GL_R8_SNORM\0"
+ "GL_RG8_SNORM\0"
+ "GL_RGB8_SNORM\0"
+ "GL_RGBA8_SNORM\0"
+ "GL_R16_SNORM\0"
+ "GL_RG16_SNORM\0"
+ "GL_RGB16_SNORM\0"
+ "GL_RGBA16_SNORM\0"
+ "GL_SIGNED_NORMALIZED\0"
+ "GL_PRIMITIVE_RESTART\0"
+ "GL_PRIMITIVE_RESTART_INDEX\0"
+ "GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_ARRAY_ARB\0"
+ "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB\0"
+ "GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB\0"
+ "GL_SAMPLER_CUBE_MAP_ARRAY_ARB\0"
+ "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB\0"
+ "GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB\0"
+ "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB\0"
+ "GL_IMAGE_1D\0"
+ "GL_IMAGE_2D\0"
+ "GL_IMAGE_3D\0"
+ "GL_IMAGE_2D_RECT\0"
+ "GL_IMAGE_CUBE\0"
+ "GL_IMAGE_BUFFER\0"
+ "GL_IMAGE_1D_ARRAY\0"
+ "GL_IMAGE_2D_ARRAY\0"
+ "GL_IMAGE_CUBE_MAP_ARRAY\0"
+ "GL_IMAGE_2D_MULTISAMPLE\0"
+ "GL_IMAGE_2D_MULTISAMPLE_ARRAY\0"
+ "GL_INT_IMAGE_1D\0"
+ "GL_INT_IMAGE_2D\0"
+ "GL_INT_IMAGE_3D\0"
+ "GL_INT_IMAGE_2D_RECT\0"
+ "GL_INT_IMAGE_CUBE\0"
+ "GL_INT_IMAGE_BUFFER\0"
+ "GL_INT_IMAGE_1D_ARRAY\0"
+ "GL_INT_IMAGE_2D_ARRAY\0"
+ "GL_INT_IMAGE_CUBE_MAP_ARRAY\0"
+ "GL_INT_IMAGE_2D_MULTISAMPLE\0"
+ "GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY\0"
+ "GL_UNSIGNED_INT_IMAGE_1D\0"
+ "GL_UNSIGNED_INT_IMAGE_2D\0"
+ "GL_UNSIGNED_INT_IMAGE_3D\0"
+ "GL_UNSIGNED_INT_IMAGE_2D_RECT\0"
+ "GL_UNSIGNED_INT_IMAGE_CUBE\0"
+ "GL_UNSIGNED_INT_IMAGE_BUFFER\0"
+ "GL_UNSIGNED_INT_IMAGE_1D_ARRAY\0"
+ "GL_UNSIGNED_INT_IMAGE_2D_ARRAY\0"
+ "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY\0"
+ "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE\0"
+ "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY\0"
+ "GL_MAX_IMAGE_SAMPLES\0"
+ "GL_IMAGE_BINDING_FORMAT\0"
+ "GL_RGB10_A2UI\0"
+ "GL_MIN_MAP_BUFFER_ALIGNMENT\0"
+ "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE\0"
+ "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE\0"
+ "GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS\0"
+ "GL_MAX_VERTEX_IMAGE_UNIFORMS\0"
+ "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS\0"
+ "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS\0"
+ "GL_MAX_GEOMETRY_IMAGE_UNIFORMS\0"
+ "GL_MAX_FRAGMENT_IMAGE_UNIFORMS\0"
+ "GL_MAX_COMBINED_IMAGE_UNIFORMS\0"
+ "GL_DEPTH_STENCIL_TEXTURE_MODE\0"
+ "GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS\0"
+ "GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER\0"
+ "GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER\0"
+ "GL_DISPATCH_INDIRECT_BUFFER\0"
+ "GL_DISPATCH_INDIRECT_BUFFER_BINDING\0"
+ "GL_TEXTURE_2D_MULTISAMPLE\0"
+ "GL_PROXY_TEXTURE_2D_MULTISAMPLE\0"
+ "GL_TEXTURE_2D_MULTISAMPLE_ARRAY\0"
+ "GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY\0"
+ "GL_TEXTURE_BINDING_2D_MULTISAMPLE\0"
+ "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY\0"
+ "GL_TEXTURE_SAMPLES\0"
+ "GL_TEXTURE_FIXED_SAMPLE_LOCATIONS\0"
+ "GL_SAMPLER_2D_MULTISAMPLE\0"
+ "GL_INT_SAMPLER_2D_MULTISAMPLE\0"
+ "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE\0"
+ "GL_SAMPLER_2D_MULTISAMPLE_ARRAY\0"
+ "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY\0"
+ "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY\0"
+ "GL_MAX_COLOR_TEXTURE_SAMPLES\0"
+ "GL_MAX_DEPTH_TEXTURE_SAMPLES\0"
+ "GL_MAX_INTEGER_SAMPLES\0"
+ "GL_MAX_SERVER_WAIT_TIMEOUT\0"
+ "GL_OBJECT_TYPE\0"
+ "GL_SYNC_CONDITION\0"
+ "GL_SYNC_STATUS\0"
+ "GL_SYNC_FLAGS\0"
+ "GL_SYNC_FENCE\0"
+ "GL_SYNC_GPU_COMMANDS_COMPLETE\0"
+ "GL_UNSIGNALED\0"
+ "GL_SIGNALED\0"
+ "GL_ALREADY_SIGNALED\0"
+ "GL_TIMEOUT_EXPIRED\0"
+ "GL_CONDITION_SATISFIED\0"
+ "GL_WAIT_FAILED\0"
+ "GL_BUFFER_ACCESS_FLAGS\0"
+ "GL_BUFFER_MAP_LENGTH\0"
+ "GL_BUFFER_MAP_OFFSET\0"
+ "GL_MAX_VERTEX_OUTPUT_COMPONENTS\0"
+ "GL_MAX_GEOMETRY_INPUT_COMPONENTS\0"
+ "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS\0"
+ "GL_MAX_FRAGMENT_INPUT_COMPONENTS\0"
+ "GL_CONTEXT_PROFILE_MASK\0"
+ "GL_TEXTURE_IMMUTABLE_FORMAT\0"
+ "GL_MAX_DEBUG_MESSAGE_LENGTH_ARB\0"
+ "GL_MAX_DEBUG_LOGGED_MESSAGES_ARB\0"
+ "GL_DEBUG_LOGGED_MESSAGES_ARB\0"
+ "GL_DEBUG_SEVERITY_HIGH_ARB\0"
+ "GL_DEBUG_SEVERITY_MEDIUM_ARB\0"
+ "GL_DEBUG_SEVERITY_LOW_ARB\0"
+ "GL_TEXTURE_BUFFER_OFFSET\0"
+ "GL_TEXTURE_BUFFER_SIZE\0"
+ "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT\0"
+ "GL_COMPUTE_SHADER\0"
+ "GL_MAX_COMPUTE_UNIFORM_BLOCKS\0"
+ "GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS\0"
+ "GL_MAX_COMPUTE_IMAGE_UNIFORMS\0"
+ "GL_MAX_COMPUTE_WORK_GROUP_COUNT\0"
+ "GL_MAX_COMPUTE_WORK_GROUP_SIZE\0"
+ "GL_COMPRESSED_R11_EAC\0"
+ "GL_COMPRESSED_SIGNED_R11_EAC\0"
+ "GL_COMPRESSED_RG11_EAC\0"
+ "GL_COMPRESSED_SIGNED_RG11_EAC\0"
+ "GL_COMPRESSED_RGB8_ETC2\0"
+ "GL_COMPRESSED_SRGB8_ETC2\0"
+ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2\0"
+ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2\0"
+ "GL_COMPRESSED_RGBA8_ETC2_EAC\0"
+ "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC\0"
+ "GL_ATOMIC_COUNTER_BUFFER\0"
+ "GL_ATOMIC_COUNTER_BUFFER_BINDING\0"
+ "GL_ATOMIC_COUNTER_BUFFER_START\0"
+ "GL_ATOMIC_COUNTER_BUFFER_SIZE\0"
+ "GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE\0"
+ "GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS\0"
+ "GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES\0"
+ "GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER\0"
+ "GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER\0"
+ "GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER\0"
+ "GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER\0"
+ "GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER\0"
+ "GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_MAX_VERTEX_ATOMIC_COUNTERS\0"
+ "GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS\0"
+ "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS\0"
+ "GL_MAX_GEOMETRY_ATOMIC_COUNTERS\0"
+ "GL_MAX_FRAGMENT_ATOMIC_COUNTERS\0"
+ "GL_MAX_COMBINED_ATOMIC_COUNTERS\0"
+ "GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE\0"
+ "GL_ACTIVE_ATOMIC_COUNTER_BUFFERS\0"
+ "GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX\0"
+ "GL_UNSIGNED_INT_ATOMIC_COUNTER\0"
+ "GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS\0"
+ "GL_DEBUG_OUTPUT\0"
+ "GL_NUM_SAMPLE_COUNTS\0"
+ "GL_PERFQUERY_COUNTER_EVENT_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL\0"
+ "GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL\0"
+ "GL_PERFQUERY_COUNTER_RAW_INTEL\0"
+ "GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL\0"
+ "GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL\0"
+ "GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL\0"
+ "GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL\0"
+ "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL\0"
+ "GL_EVAL_BIT\0"
+ "GL_RASTER_POSITION_UNCLIPPED_IBM\0"
+ "GL_LIST_BIT\0"
+ "GL_TEXTURE_BIT\0"
+ "GL_SCISSOR_BIT\0"
+ "GL_ALL_ATTRIB_BITS\0"
+ "GL_MULTISAMPLE_BIT\0"
+ "GL_ALL_CLIENT_ATTRIB_BITS\0"
+ ;
+
+static const enum_elt enum_string_table_offsets[2007] =
+{
+ { 0, 0x00000000 }, /* GL_FALSE */
+ { 9, 0x00000001 }, /* GL_LINES */
+ { 18, 0x00000002 }, /* GL_LINE_LOOP */
+ { 31, 0x00000003 }, /* GL_LINE_STRIP */
+ { 45, 0x00000004 }, /* GL_TRIANGLES */
+ { 58, 0x00000005 }, /* GL_TRIANGLE_STRIP */
+ { 76, 0x00000006 }, /* GL_TRIANGLE_FAN */
+ { 92, 0x00000007 }, /* GL_QUADS */
+ { 101, 0x00000008 }, /* GL_QUAD_STRIP */
+ { 115, 0x00000009 }, /* GL_POLYGON */
+ { 126, 0x0000000A }, /* GL_LINES_ADJACENCY */
+ { 145, 0x0000000B }, /* GL_LINE_STRIP_ADJACENCY */
+ { 169, 0x0000000C }, /* GL_TRIANGLES_ADJACENCY */
+ { 192, 0x0000000D }, /* GL_TRIANGLE_STRIP_ADJACENCY */
+ { 220, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
+ { 243, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
+ { 261, 0x00000040 }, /* GL_LIGHTING_BIT */
+ { 277, 0x00000080 }, /* GL_FOG_BIT */
+ { 288, 0x00000100 }, /* GL_ACCUM */
+ { 297, 0x00000101 }, /* GL_LOAD */
+ { 305, 0x00000102 }, /* GL_RETURN */
+ { 315, 0x00000103 }, /* GL_MULT */
+ { 323, 0x00000104 }, /* GL_ADD */
+ { 330, 0x00000200 }, /* GL_NEVER */
+ { 339, 0x00000201 }, /* GL_LESS */
+ { 347, 0x00000202 }, /* GL_EQUAL */
+ { 356, 0x00000203 }, /* GL_LEQUAL */
+ { 366, 0x00000204 }, /* GL_GREATER */
+ { 377, 0x00000205 }, /* GL_NOTEQUAL */
+ { 389, 0x00000206 }, /* GL_GEQUAL */
+ { 399, 0x00000207 }, /* GL_ALWAYS */
+ { 409, 0x00000300 }, /* GL_SRC_COLOR */
+ { 422, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
+ { 445, 0x00000302 }, /* GL_SRC_ALPHA */
+ { 458, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
+ { 481, 0x00000304 }, /* GL_DST_ALPHA */
+ { 494, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
+ { 517, 0x00000306 }, /* GL_DST_COLOR */
+ { 530, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
+ { 553, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
+ { 575, 0x00000400 }, /* GL_FRONT_LEFT */
+ { 589, 0x00000401 }, /* GL_FRONT_RIGHT */
+ { 604, 0x00000402 }, /* GL_BACK_LEFT */
+ { 617, 0x00000403 }, /* GL_BACK_RIGHT */
+ { 631, 0x00000404 }, /* GL_FRONT */
+ { 640, 0x00000405 }, /* GL_BACK */
+ { 648, 0x00000406 }, /* GL_LEFT */
+ { 656, 0x00000407 }, /* GL_RIGHT */
+ { 665, 0x00000408 }, /* GL_FRONT_AND_BACK */
+ { 683, 0x00000409 }, /* GL_AUX0 */
+ { 691, 0x0000040A }, /* GL_AUX1 */
+ { 699, 0x0000040B }, /* GL_AUX2 */
+ { 707, 0x0000040C }, /* GL_AUX3 */
+ { 715, 0x00000500 }, /* GL_INVALID_ENUM */
+ { 731, 0x00000501 }, /* GL_INVALID_VALUE */
+ { 748, 0x00000502 }, /* GL_INVALID_OPERATION */
+ { 769, 0x00000503 }, /* GL_STACK_OVERFLOW */
+ { 787, 0x00000504 }, /* GL_STACK_UNDERFLOW */
+ { 806, 0x00000505 }, /* GL_OUT_OF_MEMORY */
+ { 823, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+ { 856, 0x00000600 }, /* GL_2D */
+ { 862, 0x00000601 }, /* GL_3D */
+ { 868, 0x00000602 }, /* GL_3D_COLOR */
+ { 880, 0x00000603 }, /* GL_3D_COLOR_TEXTURE */
+ { 900, 0x00000604 }, /* GL_4D_COLOR_TEXTURE */
+ { 920, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
+ { 942, 0x00000701 }, /* GL_POINT_TOKEN */
+ { 957, 0x00000702 }, /* GL_LINE_TOKEN */
+ { 971, 0x00000703 }, /* GL_POLYGON_TOKEN */
+ { 988, 0x00000704 }, /* GL_BITMAP_TOKEN */
+ { 1004, 0x00000705 }, /* GL_DRAW_PIXEL_TOKEN */
+ { 1024, 0x00000706 }, /* GL_COPY_PIXEL_TOKEN */
+ { 1044, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
+ { 1064, 0x00000800 }, /* GL_EXP */
+ { 1071, 0x00000801 }, /* GL_EXP2 */
+ { 1079, 0x00000900 }, /* GL_CW */
+ { 1085, 0x00000901 }, /* GL_CCW */
+ { 1092, 0x00000A00 }, /* GL_COEFF */
+ { 1101, 0x00000A01 }, /* GL_ORDER */
+ { 1110, 0x00000A02 }, /* GL_DOMAIN */
+ { 1120, 0x00000B00 }, /* GL_CURRENT_COLOR */
+ { 1137, 0x00000B01 }, /* GL_CURRENT_INDEX */
+ { 1154, 0x00000B02 }, /* GL_CURRENT_NORMAL */
+ { 1172, 0x00000B03 }, /* GL_CURRENT_TEXTURE_COORDS */
+ { 1198, 0x00000B04 }, /* GL_CURRENT_RASTER_COLOR */
+ { 1222, 0x00000B05 }, /* GL_CURRENT_RASTER_INDEX */
+ { 1246, 0x00000B06 }, /* GL_CURRENT_RASTER_TEXTURE_COORDS */
+ { 1279, 0x00000B07 }, /* GL_CURRENT_RASTER_POSITION */
+ { 1306, 0x00000B08 }, /* GL_CURRENT_RASTER_POSITION_VALID */
+ { 1339, 0x00000B09 }, /* GL_CURRENT_RASTER_DISTANCE */
+ { 1366, 0x00000B10 }, /* GL_POINT_SMOOTH */
+ { 1382, 0x00000B11 }, /* GL_POINT_SIZE */
+ { 1396, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
+ { 1416, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
+ { 1442, 0x00000B20 }, /* GL_LINE_SMOOTH */
+ { 1457, 0x00000B21 }, /* GL_LINE_WIDTH */
+ { 1471, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
+ { 1491, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
+ { 1517, 0x00000B24 }, /* GL_LINE_STIPPLE */
+ { 1533, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
+ { 1557, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
+ { 1580, 0x00000B30 }, /* GL_LIST_MODE */
+ { 1593, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
+ { 1613, 0x00000B32 }, /* GL_LIST_BASE */
+ { 1626, 0x00000B33 }, /* GL_LIST_INDEX */
+ { 1640, 0x00000B40 }, /* GL_POLYGON_MODE */
+ { 1656, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
+ { 1674, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
+ { 1693, 0x00000B43 }, /* GL_EDGE_FLAG */
+ { 1706, 0x00000B44 }, /* GL_CULL_FACE */
+ { 1719, 0x00000B45 }, /* GL_CULL_FACE_MODE */
+ { 1737, 0x00000B46 }, /* GL_FRONT_FACE */
+ { 1751, 0x00000B50 }, /* GL_LIGHTING */
+ { 1763, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+ { 1791, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
+ { 1815, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
+ { 1838, 0x00000B54 }, /* GL_SHADE_MODEL */
+ { 1853, 0x00000B55 }, /* GL_COLOR_MATERIAL_FACE */
+ { 1876, 0x00000B56 }, /* GL_COLOR_MATERIAL_PARAMETER */
+ { 1904, 0x00000B57 }, /* GL_COLOR_MATERIAL */
+ { 1922, 0x00000B60 }, /* GL_FOG */
+ { 1929, 0x00000B61 }, /* GL_FOG_INDEX */
+ { 1942, 0x00000B62 }, /* GL_FOG_DENSITY */
+ { 1957, 0x00000B63 }, /* GL_FOG_START */
+ { 1970, 0x00000B64 }, /* GL_FOG_END */
+ { 1981, 0x00000B65 }, /* GL_FOG_MODE */
+ { 1993, 0x00000B66 }, /* GL_FOG_COLOR */
+ { 2006, 0x00000B70 }, /* GL_DEPTH_RANGE */
+ { 2021, 0x00000B71 }, /* GL_DEPTH_TEST */
+ { 2035, 0x00000B72 }, /* GL_DEPTH_WRITEMASK */
+ { 2054, 0x00000B73 }, /* GL_DEPTH_CLEAR_VALUE */
+ { 2075, 0x00000B74 }, /* GL_DEPTH_FUNC */
+ { 2089, 0x00000B80 }, /* GL_ACCUM_CLEAR_VALUE */
+ { 2110, 0x00000B90 }, /* GL_STENCIL_TEST */
+ { 2126, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
+ { 2149, 0x00000B92 }, /* GL_STENCIL_FUNC */
+ { 2165, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
+ { 2187, 0x00000B94 }, /* GL_STENCIL_FAIL */
+ { 2203, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
+ { 2230, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
+ { 2257, 0x00000B97 }, /* GL_STENCIL_REF */
+ { 2272, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
+ { 2293, 0x00000BA0 }, /* GL_MATRIX_MODE */
+ { 2308, 0x00000BA1 }, /* GL_NORMALIZE */
+ { 2321, 0x00000BA2 }, /* GL_VIEWPORT */
+ { 2333, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
+ { 2358, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
+ { 2384, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
+ { 2407, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
+ { 2427, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
+ { 2448, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
+ { 2466, 0x00000BB0 }, /* GL_ATTRIB_STACK_DEPTH */
+ { 2488, 0x00000BB1 }, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
+ { 2517, 0x00000BC0 }, /* GL_ALPHA_TEST */
+ { 2531, 0x00000BC1 }, /* GL_ALPHA_TEST_FUNC */
+ { 2550, 0x00000BC2 }, /* GL_ALPHA_TEST_REF */
+ { 2568, 0x00000BD0 }, /* GL_DITHER */
+ { 2578, 0x00000BE0 }, /* GL_BLEND_DST */
+ { 2591, 0x00000BE1 }, /* GL_BLEND_SRC */
+ { 2604, 0x00000BE2 }, /* GL_BLEND */
+ { 2613, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
+ { 2630, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
+ { 2648, 0x00000BF2 }, /* GL_COLOR_LOGIC_OP */
+ { 2666, 0x00000C00 }, /* GL_AUX_BUFFERS */
+ { 2681, 0x00000C01 }, /* GL_DRAW_BUFFER */
+ { 2696, 0x00000C02 }, /* GL_READ_BUFFER */
+ { 2711, 0x00000C10 }, /* GL_SCISSOR_BOX */
+ { 2726, 0x00000C11 }, /* GL_SCISSOR_TEST */
+ { 2742, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
+ { 2763, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
+ { 2782, 0x00000C22 }, /* GL_COLOR_CLEAR_VALUE */
+ { 2803, 0x00000C23 }, /* GL_COLOR_WRITEMASK */
+ { 2822, 0x00000C30 }, /* GL_INDEX_MODE */
+ { 2836, 0x00000C31 }, /* GL_RGBA_MODE */
+ { 2849, 0x00000C32 }, /* GL_DOUBLEBUFFER */
+ { 2865, 0x00000C33 }, /* GL_STEREO */
+ { 2875, 0x00000C40 }, /* GL_RENDER_MODE */
+ { 2890, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
+ { 2921, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
+ { 2942, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
+ { 2962, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
+ { 2985, 0x00000C54 }, /* GL_FOG_HINT */
+ { 2997, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
+ { 3014, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
+ { 3031, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
+ { 3048, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
+ { 3065, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
+ { 3085, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
+ { 3105, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
+ { 3125, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
+ { 3145, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
+ { 3165, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
+ { 3185, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
+ { 3205, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
+ { 3225, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
+ { 3245, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
+ { 3265, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+ { 3290, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+ { 3315, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+ { 3340, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+ { 3365, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+ { 3390, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+ { 3415, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+ { 3440, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+ { 3465, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+ { 3490, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+ { 3515, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
+ { 3536, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
+ { 3556, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
+ { 3577, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
+ { 3597, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
+ { 3619, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
+ { 3639, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
+ { 3658, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
+ { 3676, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
+ { 3695, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
+ { 3713, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
+ { 3733, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
+ { 3751, 0x00000D10 }, /* GL_MAP_COLOR */
+ { 3764, 0x00000D11 }, /* GL_MAP_STENCIL */
+ { 3779, 0x00000D12 }, /* GL_INDEX_SHIFT */
+ { 3794, 0x00000D13 }, /* GL_INDEX_OFFSET */
+ { 3810, 0x00000D14 }, /* GL_RED_SCALE */
+ { 3823, 0x00000D15 }, /* GL_RED_BIAS */
+ { 3835, 0x00000D16 }, /* GL_ZOOM_X */
+ { 3845, 0x00000D17 }, /* GL_ZOOM_Y */
+ { 3855, 0x00000D18 }, /* GL_GREEN_SCALE */
+ { 3870, 0x00000D19 }, /* GL_GREEN_BIAS */
+ { 3884, 0x00000D1A }, /* GL_BLUE_SCALE */
+ { 3898, 0x00000D1B }, /* GL_BLUE_BIAS */
+ { 3911, 0x00000D1C }, /* GL_ALPHA_SCALE */
+ { 3926, 0x00000D1D }, /* GL_ALPHA_BIAS */
+ { 3940, 0x00000D1E }, /* GL_DEPTH_SCALE */
+ { 3955, 0x00000D1F }, /* GL_DEPTH_BIAS */
+ { 3969, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
+ { 3987, 0x00000D31 }, /* GL_MAX_LIGHTS */
+ { 4001, 0x00000D32 }, /* GL_MAX_CLIP_DISTANCES */
+ { 4023, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
+ { 4043, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
+ { 4066, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
+ { 4092, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+ { 4121, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
+ { 4145, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
+ { 4175, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
+ { 4202, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
+ { 4223, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+ { 4256, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
+ { 4273, 0x00000D51 }, /* GL_INDEX_BITS */
+ { 4287, 0x00000D52 }, /* GL_RED_BITS */
+ { 4299, 0x00000D53 }, /* GL_GREEN_BITS */
+ { 4313, 0x00000D54 }, /* GL_BLUE_BITS */
+ { 4326, 0x00000D55 }, /* GL_ALPHA_BITS */
+ { 4340, 0x00000D56 }, /* GL_DEPTH_BITS */
+ { 4354, 0x00000D57 }, /* GL_STENCIL_BITS */
+ { 4370, 0x00000D58 }, /* GL_ACCUM_RED_BITS */
+ { 4388, 0x00000D59 }, /* GL_ACCUM_GREEN_BITS */
+ { 4408, 0x00000D5A }, /* GL_ACCUM_BLUE_BITS */
+ { 4427, 0x00000D5B }, /* GL_ACCUM_ALPHA_BITS */
+ { 4447, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
+ { 4467, 0x00000D80 }, /* GL_AUTO_NORMAL */
+ { 4482, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
+ { 4498, 0x00000D91 }, /* GL_MAP1_INDEX */
+ { 4512, 0x00000D92 }, /* GL_MAP1_NORMAL */
+ { 4527, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
+ { 4551, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
+ { 4575, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
+ { 4599, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
+ { 4623, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
+ { 4640, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
+ { 4657, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
+ { 4673, 0x00000DB1 }, /* GL_MAP2_INDEX */
+ { 4687, 0x00000DB2 }, /* GL_MAP2_NORMAL */
+ { 4702, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
+ { 4726, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
+ { 4750, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
+ { 4774, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
+ { 4798, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
+ { 4815, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
+ { 4832, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
+ { 4852, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
+ { 4874, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
+ { 4894, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
+ { 4916, 0x00000DE0 }, /* GL_TEXTURE_1D */
+ { 4930, 0x00000DE1 }, /* GL_TEXTURE_2D */
+ { 4944, 0x00000DF0 }, /* GL_FEEDBACK_BUFFER_POINTER */
+ { 4971, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */
+ { 4995, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */
+ { 5019, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
+ { 5047, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
+ { 5072, 0x00001000 }, /* GL_TEXTURE_WIDTH */
+ { 5089, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
+ { 5107, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
+ { 5129, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
+ { 5153, 0x00001005 }, /* GL_TEXTURE_BORDER */
+ { 5171, 0x00001100 }, /* GL_DONT_CARE */
+ { 5184, 0x00001101 }, /* GL_FASTEST */
+ { 5195, 0x00001102 }, /* GL_NICEST */
+ { 5205, 0x00001200 }, /* GL_AMBIENT */
+ { 5216, 0x00001201 }, /* GL_DIFFUSE */
+ { 5227, 0x00001202 }, /* GL_SPECULAR */
+ { 5239, 0x00001203 }, /* GL_POSITION */
+ { 5251, 0x00001204 }, /* GL_SPOT_DIRECTION */
+ { 5269, 0x00001205 }, /* GL_SPOT_EXPONENT */
+ { 5286, 0x00001206 }, /* GL_SPOT_CUTOFF */
+ { 5301, 0x00001207 }, /* GL_CONSTANT_ATTENUATION */
+ { 5325, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
+ { 5347, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
+ { 5372, 0x00001300 }, /* GL_COMPILE */
+ { 5383, 0x00001301 }, /* GL_COMPILE_AND_EXECUTE */
+ { 5406, 0x00001400 }, /* GL_BYTE */
+ { 5414, 0x00001401 }, /* GL_UNSIGNED_BYTE */
+ { 5431, 0x00001402 }, /* GL_SHORT */
+ { 5440, 0x00001403 }, /* GL_UNSIGNED_SHORT */
+ { 5458, 0x00001404 }, /* GL_INT */
+ { 5465, 0x00001405 }, /* GL_UNSIGNED_INT */
+ { 5481, 0x00001406 }, /* GL_FLOAT */
+ { 5490, 0x00001407 }, /* GL_2_BYTES */
+ { 5501, 0x00001408 }, /* GL_3_BYTES */
+ { 5512, 0x00001409 }, /* GL_4_BYTES */
+ { 5523, 0x0000140A }, /* GL_DOUBLE */
+ { 5533, 0x0000140B }, /* GL_HALF_FLOAT */
+ { 5547, 0x0000140C }, /* GL_FIXED */
+ { 5556, 0x00001500 }, /* GL_CLEAR */
+ { 5565, 0x00001501 }, /* GL_AND */
+ { 5572, 0x00001502 }, /* GL_AND_REVERSE */
+ { 5587, 0x00001503 }, /* GL_COPY */
+ { 5595, 0x00001504 }, /* GL_AND_INVERTED */
+ { 5611, 0x00001505 }, /* GL_NOOP */
+ { 5619, 0x00001506 }, /* GL_XOR */
+ { 5626, 0x00001507 }, /* GL_OR */
+ { 5632, 0x00001508 }, /* GL_NOR */
+ { 5639, 0x00001509 }, /* GL_EQUIV */
+ { 5648, 0x0000150A }, /* GL_INVERT */
+ { 5658, 0x0000150B }, /* GL_OR_REVERSE */
+ { 5672, 0x0000150C }, /* GL_COPY_INVERTED */
+ { 5689, 0x0000150D }, /* GL_OR_INVERTED */
+ { 5704, 0x0000150E }, /* GL_NAND */
+ { 5712, 0x0000150F }, /* GL_SET */
+ { 5719, 0x00001600 }, /* GL_EMISSION */
+ { 5731, 0x00001601 }, /* GL_SHININESS */
+ { 5744, 0x00001602 }, /* GL_AMBIENT_AND_DIFFUSE */
+ { 5767, 0x00001603 }, /* GL_COLOR_INDEXES */
+ { 5784, 0x00001700 }, /* GL_MODELVIEW */
+ { 5797, 0x00001701 }, /* GL_PROJECTION */
+ { 5811, 0x00001702 }, /* GL_TEXTURE */
+ { 5822, 0x00001800 }, /* GL_COLOR */
+ { 5831, 0x00001801 }, /* GL_DEPTH */
+ { 5840, 0x00001802 }, /* GL_STENCIL */
+ { 5851, 0x00001900 }, /* GL_COLOR_INDEX */
+ { 5866, 0x00001901 }, /* GL_STENCIL_INDEX */
+ { 5883, 0x00001902 }, /* GL_DEPTH_COMPONENT */
+ { 5902, 0x00001903 }, /* GL_RED */
+ { 5909, 0x00001904 }, /* GL_GREEN */
+ { 5918, 0x00001905 }, /* GL_BLUE */
+ { 5926, 0x00001906 }, /* GL_ALPHA */
+ { 5935, 0x00001907 }, /* GL_RGB */
+ { 5942, 0x00001908 }, /* GL_RGBA */
+ { 5950, 0x00001909 }, /* GL_LUMINANCE */
+ { 5963, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
+ { 5982, 0x00001A00 }, /* GL_BITMAP */
+ { 5992, 0x00001B00 }, /* GL_POINT */
+ { 6001, 0x00001B01 }, /* GL_LINE */
+ { 6009, 0x00001B02 }, /* GL_FILL */
+ { 6017, 0x00001C00 }, /* GL_RENDER */
+ { 6027, 0x00001C01 }, /* GL_FEEDBACK */
+ { 6039, 0x00001C02 }, /* GL_SELECT */
+ { 6049, 0x00001D00 }, /* GL_FLAT */
+ { 6057, 0x00001D01 }, /* GL_SMOOTH */
+ { 6067, 0x00001E00 }, /* GL_KEEP */
+ { 6075, 0x00001E01 }, /* GL_REPLACE */
+ { 6086, 0x00001E02 }, /* GL_INCR */
+ { 6094, 0x00001E03 }, /* GL_DECR */
+ { 6102, 0x00001F00 }, /* GL_VENDOR */
+ { 6112, 0x00001F01 }, /* GL_RENDERER */
+ { 6124, 0x00001F02 }, /* GL_VERSION */
+ { 6135, 0x00001F03 }, /* GL_EXTENSIONS */
+ { 6149, 0x00002000 }, /* GL_S */
+ { 6154, 0x00002001 }, /* GL_T */
+ { 6159, 0x00002002 }, /* GL_R */
+ { 6164, 0x00002003 }, /* GL_Q */
+ { 6169, 0x00002100 }, /* GL_MODULATE */
+ { 6181, 0x00002101 }, /* GL_DECAL */
+ { 6190, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
+ { 6210, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
+ { 6231, 0x00002300 }, /* GL_TEXTURE_ENV */
+ { 6246, 0x00002400 }, /* GL_EYE_LINEAR */
+ { 6260, 0x00002401 }, /* GL_OBJECT_LINEAR */
+ { 6277, 0x00002402 }, /* GL_SPHERE_MAP */
+ { 6291, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
+ { 6311, 0x00002501 }, /* GL_OBJECT_PLANE */
+ { 6327, 0x00002502 }, /* GL_EYE_PLANE */
+ { 6340, 0x00002600 }, /* GL_NEAREST */
+ { 6351, 0x00002601 }, /* GL_LINEAR */
+ { 6361, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
+ { 6387, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
+ { 6412, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
+ { 6437, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
+ { 6461, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
+ { 6483, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
+ { 6505, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
+ { 6523, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
+ { 6541, 0x00002900 }, /* GL_CLAMP */
+ { 6550, 0x00002901 }, /* GL_REPEAT */
+ { 6560, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
+ { 6584, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
+ { 6608, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
+ { 6631, 0x00002A10 }, /* GL_R3_G3_B2 */
+ { 6643, 0x00002A20 }, /* GL_V2F */
+ { 6650, 0x00002A21 }, /* GL_V3F */
+ { 6657, 0x00002A22 }, /* GL_C4UB_V2F */
+ { 6669, 0x00002A23 }, /* GL_C4UB_V3F */
+ { 6681, 0x00002A24 }, /* GL_C3F_V3F */
+ { 6692, 0x00002A25 }, /* GL_N3F_V3F */
+ { 6703, 0x00002A26 }, /* GL_C4F_N3F_V3F */
+ { 6718, 0x00002A27 }, /* GL_T2F_V3F */
+ { 6729, 0x00002A28 }, /* GL_T4F_V4F */
+ { 6740, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
+ { 6756, 0x00002A2A }, /* GL_T2F_C3F_V3F */
+ { 6771, 0x00002A2B }, /* GL_T2F_N3F_V3F */
+ { 6786, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
+ { 6805, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
+ { 6824, 0x00003000 }, /* GL_CLIP_DISTANCE0 */
+ { 6842, 0x00003001 }, /* GL_CLIP_DISTANCE1 */
+ { 6860, 0x00003002 }, /* GL_CLIP_DISTANCE2 */
+ { 6878, 0x00003003 }, /* GL_CLIP_DISTANCE3 */
+ { 6896, 0x00003004 }, /* GL_CLIP_DISTANCE4 */
+ { 6914, 0x00003005 }, /* GL_CLIP_DISTANCE5 */
+ { 6932, 0x00003006 }, /* GL_CLIP_DISTANCE6 */
+ { 6950, 0x00003007 }, /* GL_CLIP_DISTANCE7 */
+ { 6968, 0x00004000 }, /* GL_LIGHT0 */
+ { 6978, 0x00004001 }, /* GL_LIGHT1 */
+ { 6988, 0x00004002 }, /* GL_LIGHT2 */
+ { 6998, 0x00004003 }, /* GL_LIGHT3 */
+ { 7008, 0x00004004 }, /* GL_LIGHT4 */
+ { 7018, 0x00004005 }, /* GL_LIGHT5 */
+ { 7028, 0x00004006 }, /* GL_LIGHT6 */
+ { 7038, 0x00004007 }, /* GL_LIGHT7 */
+ { 7048, 0x00008000 }, /* GL_HINT_BIT */
+ { 7060, 0x00008001 }, /* GL_CONSTANT_COLOR */
+ { 7078, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
+ { 7106, 0x00008003 }, /* GL_CONSTANT_ALPHA */
+ { 7124, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+ { 7152, 0x00008005 }, /* GL_BLEND_COLOR */
+ { 7167, 0x00008006 }, /* GL_FUNC_ADD */
+ { 7179, 0x00008007 }, /* GL_MIN */
+ { 7186, 0x00008008 }, /* GL_MAX */
+ { 7193, 0x00008009 }, /* GL_BLEND_EQUATION */
+ { 7211, 0x0000800A }, /* GL_FUNC_SUBTRACT */
+ { 7228, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
+ { 7253, 0x00008010 }, /* GL_CONVOLUTION_1D */
+ { 7271, 0x00008011 }, /* GL_CONVOLUTION_2D */
+ { 7289, 0x00008012 }, /* GL_SEPARABLE_2D */
+ { 7305, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE */
+ { 7332, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE */
+ { 7360, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS */
+ { 7387, 0x00008016 }, /* GL_REDUCE */
+ { 7397, 0x00008017 }, /* GL_CONVOLUTION_FORMAT */
+ { 7419, 0x00008018 }, /* GL_CONVOLUTION_WIDTH */
+ { 7440, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT */
+ { 7462, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
+ { 7487, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
+ { 7513, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
+ { 7543, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+ { 7575, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+ { 7606, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+ { 7638, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
+ { 7667, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+ { 7698, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+ { 7728, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+ { 7759, 0x00008024 }, /* GL_HISTOGRAM */
+ { 7772, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
+ { 7791, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
+ { 7810, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
+ { 7830, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
+ { 7852, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
+ { 7876, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
+ { 7899, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
+ { 7923, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+ { 7951, 0x0000802D }, /* GL_HISTOGRAM_SINK */
+ { 7969, 0x0000802E }, /* GL_MINMAX */
+ { 7979, 0x0000802F }, /* GL_MINMAX_FORMAT */
+ { 7996, 0x00008030 }, /* GL_MINMAX_SINK */
+ { 8011, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
+ { 8034, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
+ { 8057, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+ { 8083, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+ { 8109, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
+ { 8133, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
+ { 8160, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
+ { 8183, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
+ { 8208, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS_EXT */
+ { 8235, 0x0000803A }, /* GL_RESCALE_NORMAL */
+ { 8253, 0x0000803B }, /* GL_ALPHA4 */
+ { 8263, 0x0000803C }, /* GL_ALPHA8 */
+ { 8273, 0x0000803D }, /* GL_ALPHA12 */
+ { 8284, 0x0000803E }, /* GL_ALPHA16 */
+ { 8295, 0x0000803F }, /* GL_LUMINANCE4 */
+ { 8309, 0x00008040 }, /* GL_LUMINANCE8 */
+ { 8323, 0x00008041 }, /* GL_LUMINANCE12 */
+ { 8338, 0x00008042 }, /* GL_LUMINANCE16 */
+ { 8353, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
+ { 8374, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
+ { 8395, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
+ { 8416, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
+ { 8438, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
+ { 8461, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
+ { 8484, 0x00008049 }, /* GL_INTENSITY */
+ { 8497, 0x0000804A }, /* GL_INTENSITY4 */
+ { 8511, 0x0000804B }, /* GL_INTENSITY8 */
+ { 8525, 0x0000804C }, /* GL_INTENSITY12 */
+ { 8540, 0x0000804D }, /* GL_INTENSITY16 */
+ { 8555, 0x0000804E }, /* GL_RGB2_EXT */
+ { 8567, 0x0000804F }, /* GL_RGB4 */
+ { 8575, 0x00008050 }, /* GL_RGB5 */
+ { 8583, 0x00008051 }, /* GL_RGB8 */
+ { 8591, 0x00008052 }, /* GL_RGB10 */
+ { 8600, 0x00008053 }, /* GL_RGB12 */
+ { 8609, 0x00008054 }, /* GL_RGB16 */
+ { 8618, 0x00008055 }, /* GL_RGBA2 */
+ { 8627, 0x00008056 }, /* GL_RGBA4 */
+ { 8636, 0x00008057 }, /* GL_RGB5_A1 */
+ { 8647, 0x00008058 }, /* GL_RGBA8 */
+ { 8656, 0x00008059 }, /* GL_RGB10_A2 */
+ { 8668, 0x0000805A }, /* GL_RGBA12 */
+ { 8678, 0x0000805B }, /* GL_RGBA16 */
+ { 8688, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
+ { 8708, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
+ { 8730, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
+ { 8751, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
+ { 8773, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
+ { 8799, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
+ { 8825, 0x00008062 }, /* GL_REPLACE_EXT */
+ { 8840, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
+ { 8860, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
+ { 8880, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
+ { 8905, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
+ { 8925, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
+ { 8945, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
+ { 8967, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
+ { 8989, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
+ { 9011, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
+ { 9031, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
+ { 9052, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
+ { 9074, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
+ { 9097, 0x0000806F }, /* GL_TEXTURE_3D */
+ { 9111, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
+ { 9131, 0x00008071 }, /* GL_TEXTURE_DEPTH */
+ { 9148, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
+ { 9166, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
+ { 9189, 0x00008074 }, /* GL_VERTEX_ARRAY */
+ { 9205, 0x00008075 }, /* GL_NORMAL_ARRAY */
+ { 9221, 0x00008076 }, /* GL_COLOR_ARRAY */
+ { 9236, 0x00008077 }, /* GL_INDEX_ARRAY */
+ { 9251, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
+ { 9274, 0x00008079 }, /* GL_EDGE_FLAG_ARRAY */
+ { 9293, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
+ { 9314, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
+ { 9335, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
+ { 9358, 0x0000807D }, /* GL_VERTEX_ARRAY_COUNT_EXT */
+ { 9384, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
+ { 9405, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
+ { 9428, 0x00008080 }, /* GL_NORMAL_ARRAY_COUNT_EXT */
+ { 9454, 0x00008081 }, /* GL_COLOR_ARRAY_SIZE */
+ { 9474, 0x00008082 }, /* GL_COLOR_ARRAY_TYPE */
+ { 9494, 0x00008083 }, /* GL_COLOR_ARRAY_STRIDE */
+ { 9516, 0x00008084 }, /* GL_COLOR_ARRAY_COUNT_EXT */
+ { 9541, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
+ { 9561, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
+ { 9583, 0x00008087 }, /* GL_INDEX_ARRAY_COUNT_EXT */
+ { 9608, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+ { 9636, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+ { 9664, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+ { 9694, 0x0000808B }, /* GL_TEXTURE_COORD_ARRAY_COUNT_EXT */
+ { 9727, 0x0000808C }, /* GL_EDGE_FLAG_ARRAY_STRIDE */
+ { 9753, 0x0000808D }, /* GL_EDGE_FLAG_ARRAY_COUNT_EXT */
+ { 9782, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
+ { 9806, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
+ { 9830, 0x00008090 }, /* GL_COLOR_ARRAY_POINTER */
+ { 9853, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
+ { 9876, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+ { 9907, 0x00008093 }, /* GL_EDGE_FLAG_ARRAY_POINTER */
+ { 9934, 0x0000809D }, /* GL_MULTISAMPLE */
+ { 9949, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+ { 9977, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
+ { 10000, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
+ { 10019, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
+ { 10037, 0x000080A9 }, /* GL_SAMPLES */
+ { 10048, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
+ { 10073, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
+ { 10099, 0x000080B1 }, /* GL_COLOR_MATRIX */
+ { 10115, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH */
+ { 10143, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+ { 10175, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+ { 10206, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+ { 10239, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+ { 10271, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+ { 10304, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+ { 10334, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+ { 10366, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+ { 10397, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+ { 10429, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
+ { 10456, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+ { 10489, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ { 10523, 0x000080C8 }, /* GL_BLEND_DST_RGB */
+ { 10540, 0x000080C9 }, /* GL_BLEND_SRC_RGB */
+ { 10557, 0x000080CA }, /* GL_BLEND_DST_ALPHA */
+ { 10576, 0x000080CB }, /* GL_BLEND_SRC_ALPHA */
+ { 10595, 0x000080D0 }, /* GL_COLOR_TABLE */
+ { 10610, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+ { 10642, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+ { 10675, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
+ { 10696, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+ { 10734, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+ { 10773, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE */
+ { 10794, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS */
+ { 10814, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT */
+ { 10836, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH */
+ { 10857, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE */
+ { 10881, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE */
+ { 10907, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE */
+ { 10932, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE */
+ { 10958, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE */
+ { 10988, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE */
+ { 11018, 0x000080E0 }, /* GL_BGR */
+ { 11025, 0x000080E1 }, /* GL_BGRA */
+ { 11033, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
+ { 11058, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
+ { 11082, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
+ { 11108, 0x000080F0 }, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
+ { 11141, 0x00008126 }, /* GL_POINT_SIZE_MIN */
+ { 11159, 0x00008127 }, /* GL_POINT_SIZE_MAX */
+ { 11177, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
+ { 11206, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
+ { 11236, 0x0000812D }, /* GL_CLAMP_TO_BORDER */
+ { 11255, 0x0000812F }, /* GL_CLAMP_TO_EDGE */
+ { 11272, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
+ { 11291, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
+ { 11310, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
+ { 11332, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
+ { 11353, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
+ { 11373, 0x00008151 }, /* GL_CONSTANT_BORDER_HP */
+ { 11395, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
+ { 11418, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR */
+ { 11446, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
+ { 11467, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
+ { 11495, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+ { 11525, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+ { 11556, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+ { 11586, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+ { 11617, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ { 11655, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+ { 11690, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+ { 11720, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+ { 11746, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ { 11780, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+ { 11813, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+ { 11847, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+ { 11886, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+ { 11926, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+ { 11953, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+ { 11980, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+ { 12007, 0x00008191 }, /* GL_GENERATE_MIPMAP */
+ { 12026, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
+ { 12050, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */
+ { 12069, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */
+ { 12094, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
+ { 12118, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+ { 12151, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
+ { 12176, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
+ { 12201, 0x000081A5 }, /* GL_DEPTH_COMPONENT16 */
+ { 12222, 0x000081A6 }, /* GL_DEPTH_COMPONENT24 */
+ { 12243, 0x000081A7 }, /* GL_DEPTH_COMPONENT32 */
+ { 12264, 0x000081A8 }, /* GL_ARRAY_ELEMENT_LOCK_FIRST_EXT */
+ { 12296, 0x000081A9 }, /* GL_ARRAY_ELEMENT_LOCK_COUNT_EXT */
+ { 12328, 0x000081AA }, /* GL_CULL_VERTEX_EXT */
+ { 12347, 0x000081AB }, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
+ { 12382, 0x000081AC }, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
+ { 12414, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
+ { 12433, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+ { 12465, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+ { 12494, 0x000081F9 }, /* GL_SINGLE_COLOR */
+ { 12510, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
+ { 12537, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+ { 12567, 0x00008210 }, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+ { 12608, 0x00008211 }, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+ { 12649, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+ { 12684, 0x00008213 }, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+ { 12721, 0x00008214 }, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+ { 12757, 0x00008215 }, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+ { 12794, 0x00008216 }, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+ { 12831, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+ { 12870, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
+ { 12893, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
+ { 12918, 0x0000821A }, /* GL_DEPTH_STENCIL_ATTACHMENT */
+ { 12946, 0x0000821B }, /* GL_MAJOR_VERSION */
+ { 12963, 0x0000821C }, /* GL_MINOR_VERSION */
+ { 12980, 0x0000821D }, /* GL_NUM_EXTENSIONS */
+ { 12998, 0x0000821E }, /* GL_CONTEXT_FLAGS */
+ { 13015, 0x0000821F }, /* GL_BUFFER_IMMUTABLE_STORAGE */
+ { 13043, 0x00008220 }, /* GL_BUFFER_STORAGE_FLAGS */
+ { 13067, 0x00008222 }, /* GL_INDEX */
+ { 13076, 0x00008223 }, /* GL_DEPTH_BUFFER */
+ { 13092, 0x00008224 }, /* GL_STENCIL_BUFFER */
+ { 13110, 0x00008225 }, /* GL_COMPRESSED_RED */
+ { 13128, 0x00008226 }, /* GL_COMPRESSED_RG */
+ { 13145, 0x00008227 }, /* GL_RG */
+ { 13151, 0x00008228 }, /* GL_RG_INTEGER */
+ { 13165, 0x00008229 }, /* GL_R8 */
+ { 13171, 0x0000822A }, /* GL_R16 */
+ { 13178, 0x0000822B }, /* GL_RG8 */
+ { 13185, 0x0000822C }, /* GL_RG16 */
+ { 13193, 0x0000822D }, /* GL_R16F */
+ { 13201, 0x0000822E }, /* GL_R32F */
+ { 13209, 0x0000822F }, /* GL_RG16F */
+ { 13218, 0x00008230 }, /* GL_RG32F */
+ { 13227, 0x00008231 }, /* GL_R8I */
+ { 13234, 0x00008232 }, /* GL_R8UI */
+ { 13242, 0x00008233 }, /* GL_R16I */
+ { 13250, 0x00008234 }, /* GL_R16UI */
+ { 13259, 0x00008235 }, /* GL_R32I */
+ { 13267, 0x00008236 }, /* GL_R32UI */
+ { 13276, 0x00008237 }, /* GL_RG8I */
+ { 13284, 0x00008238 }, /* GL_RG8UI */
+ { 13293, 0x00008239 }, /* GL_RG16I */
+ { 13302, 0x0000823A }, /* GL_RG16UI */
+ { 13312, 0x0000823B }, /* GL_RG32I */
+ { 13321, 0x0000823C }, /* GL_RG32UI */
+ { 13331, 0x00008242 }, /* GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB */
+ { 13363, 0x00008243 }, /* GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB */
+ { 13403, 0x00008244 }, /* GL_DEBUG_CALLBACK_FUNCTION_ARB */
+ { 13434, 0x00008245 }, /* GL_DEBUG_CALLBACK_USER_PARAM_ARB */
+ { 13467, 0x00008246 }, /* GL_DEBUG_SOURCE_API_ARB */
+ { 13491, 0x00008247 }, /* GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB */
+ { 13525, 0x00008248 }, /* GL_DEBUG_SOURCE_SHADER_COMPILER_ARB */
+ { 13561, 0x00008249 }, /* GL_DEBUG_SOURCE_THIRD_PARTY_ARB */
+ { 13593, 0x0000824A }, /* GL_DEBUG_SOURCE_APPLICATION_ARB */
+ { 13625, 0x0000824B }, /* GL_DEBUG_SOURCE_OTHER_ARB */
+ { 13651, 0x0000824C }, /* GL_DEBUG_TYPE_ERROR_ARB */
+ { 13675, 0x0000824D }, /* GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB */
+ { 13713, 0x0000824E }, /* GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB */
+ { 13750, 0x0000824F }, /* GL_DEBUG_TYPE_PORTABILITY_ARB */
+ { 13780, 0x00008250 }, /* GL_DEBUG_TYPE_PERFORMANCE_ARB */
+ { 13810, 0x00008251 }, /* GL_DEBUG_TYPE_OTHER_ARB */
+ { 13834, 0x00008252 }, /* GL_LOSE_CONTEXT_ON_RESET_ARB */
+ { 13863, 0x00008253 }, /* GL_GUILTY_CONTEXT_RESET_ARB */
+ { 13891, 0x00008254 }, /* GL_INNOCENT_CONTEXT_RESET_ARB */
+ { 13921, 0x00008255 }, /* GL_UNKNOWN_CONTEXT_RESET_ARB */
+ { 13950, 0x00008256 }, /* GL_RESET_NOTIFICATION_STRATEGY_ARB */
+ { 13985, 0x00008257 }, /* GL_PROGRAM_BINARY_RETRIEVABLE_HINT */
+ { 14020, 0x00008258 }, /* GL_PROGRAM_SEPARABLE_EXT */
+ { 14045, 0x00008259 }, /* GL_ACTIVE_PROGRAM_EXT */
+ { 14067, 0x0000825A }, /* GL_PROGRAM_PIPELINE_BINDING_EXT */
+ { 14099, 0x0000825B }, /* GL_MAX_VIEWPORTS */
+ { 14116, 0x0000825C }, /* GL_VIEWPORT_SUBPIXEL_BITS */
+ { 14142, 0x0000825D }, /* GL_VIEWPORT_BOUNDS_RANGE */
+ { 14167, 0x0000825E }, /* GL_LAYER_PROVOKING_VERTEX */
+ { 14193, 0x0000825F }, /* GL_VIEWPORT_INDEX_PROVOKING_VERTEX */
+ { 14228, 0x00008260 }, /* GL_UNDEFINED_VERTEX */
+ { 14248, 0x00008261 }, /* GL_NO_RESET_NOTIFICATION_ARB */
+ { 14277, 0x00008262 }, /* GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */
+ { 14311, 0x00008263 }, /* GL_MAX_COMPUTE_UNIFORM_COMPONENTS */
+ { 14345, 0x00008264 }, /* GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS */
+ { 14383, 0x00008265 }, /* GL_MAX_COMPUTE_ATOMIC_COUNTERS */
+ { 14414, 0x00008266 }, /* GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS */
+ { 14457, 0x00008267 }, /* GL_COMPUTE_WORK_GROUP_SIZE */
+ { 14484, 0x00008268 }, /* GL_DEBUG_TYPE_MARKER */
+ { 14505, 0x00008269 }, /* GL_DEBUG_TYPE_PUSH_GROUP */
+ { 14530, 0x0000826A }, /* GL_DEBUG_TYPE_POP_GROUP */
+ { 14554, 0x0000826B }, /* GL_DEBUG_SEVERITY_NOTIFICATION */
+ { 14585, 0x0000826C }, /* GL_MAX_DEBUG_GROUP_STACK_DEPTH */
+ { 14616, 0x0000826D }, /* GL_DEBUG_GROUP_STACK_DEPTH */
+ { 14643, 0x000082D4 }, /* GL_VERTEX_ATTRIB_BINDING */
+ { 14668, 0x000082D5 }, /* GL_VERTEX_ATTRIB_RELATIVE_OFFSET */
+ { 14701, 0x000082D6 }, /* GL_VERTEX_BINDING_DIVISOR */
+ { 14727, 0x000082D7 }, /* GL_VERTEX_BINDING_OFFSET */
+ { 14752, 0x000082D8 }, /* GL_VERTEX_BINDING_STRIDE */
+ { 14777, 0x000082D9 }, /* GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET */
+ { 14814, 0x000082DA }, /* GL_MAX_VERTEX_ATTRIB_BINDINGS */
+ { 14844, 0x000082DF }, /* GL_TEXTURE_IMMUTABLE_LEVELS */
+ { 14872, 0x000082E0 }, /* GL_BUFFER */
+ { 14882, 0x000082E1 }, /* GL_SHADER */
+ { 14892, 0x000082E2 }, /* GL_PROGRAM */
+ { 14903, 0x000082E3 }, /* GL_QUERY */
+ { 14912, 0x000082E4 }, /* GL_PROGRAM_PIPELINE */
+ { 14932, 0x000082E6 }, /* GL_SAMPLER */
+ { 14943, 0x000082E7 }, /* GL_DISPLAY_LIST */
+ { 14959, 0x000082E8 }, /* GL_MAX_LABEL_LENGTH */
+ { 14979, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+ { 15006, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
+ { 15030, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+ { 15058, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+ { 15088, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+ { 15118, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+ { 15146, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+ { 15177, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+ { 15205, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+ { 15233, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+ { 15261, 0x00008370 }, /* GL_MIRRORED_REPEAT */
+ { 15280, 0x000083A0 }, /* GL_RGB_S3TC */
+ { 15292, 0x000083A1 }, /* GL_RGB4_S3TC */
+ { 15305, 0x000083A2 }, /* GL_RGBA_S3TC */
+ { 15318, 0x000083A3 }, /* GL_RGBA4_S3TC */
+ { 15332, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
+ { 15350, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
+ { 15369, 0x000083F0 }, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
+ { 15401, 0x000083F1 }, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
+ { 15434, 0x000083F2 }, /* GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE */
+ { 15469, 0x000083F3 }, /* GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE */
+ { 15504, 0x000083F9 }, /* GL_PERFQUERY_DONOT_FLUSH_INTEL */
+ { 15535, 0x000083FA }, /* GL_PERFQUERY_FLUSH_INTEL */
+ { 15560, 0x000083FB }, /* GL_PERFQUERY_WAIT_INTEL */
+ { 15584, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+ { 15616, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+ { 15647, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+ { 15678, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */
+ { 15703, 0x00008451 }, /* GL_FOG_COORD */
+ { 15716, 0x00008452 }, /* GL_FRAGMENT_DEPTH */
+ { 15734, 0x00008453 }, /* GL_CURRENT_FOG_COORD */
+ { 15755, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */
+ { 15784, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
+ { 15815, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */
+ { 15847, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */
+ { 15871, 0x00008458 }, /* GL_COLOR_SUM */
+ { 15884, 0x00008459 }, /* GL_CURRENT_SECONDARY_COLOR */
+ { 15911, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+ { 15941, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+ { 15971, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+ { 16003, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+ { 16036, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
+ { 16061, 0x0000845F }, /* GL_CURRENT_RASTER_SECONDARY_COLOR */
+ { 16095, 0x0000846D }, /* GL_ALIASED_POINT_SIZE_RANGE */
+ { 16123, 0x0000846E }, /* GL_ALIASED_LINE_WIDTH_RANGE */
+ { 16151, 0x000084C0 }, /* GL_TEXTURE0 */
+ { 16163, 0x000084C1 }, /* GL_TEXTURE1 */
+ { 16175, 0x000084C2 }, /* GL_TEXTURE2 */
+ { 16187, 0x000084C3 }, /* GL_TEXTURE3 */
+ { 16199, 0x000084C4 }, /* GL_TEXTURE4 */
+ { 16211, 0x000084C5 }, /* GL_TEXTURE5 */
+ { 16223, 0x000084C6 }, /* GL_TEXTURE6 */
+ { 16235, 0x000084C7 }, /* GL_TEXTURE7 */
+ { 16247, 0x000084C8 }, /* GL_TEXTURE8 */
+ { 16259, 0x000084C9 }, /* GL_TEXTURE9 */
+ { 16271, 0x000084CA }, /* GL_TEXTURE10 */
+ { 16284, 0x000084CB }, /* GL_TEXTURE11 */
+ { 16297, 0x000084CC }, /* GL_TEXTURE12 */
+ { 16310, 0x000084CD }, /* GL_TEXTURE13 */
+ { 16323, 0x000084CE }, /* GL_TEXTURE14 */
+ { 16336, 0x000084CF }, /* GL_TEXTURE15 */
+ { 16349, 0x000084D0 }, /* GL_TEXTURE16 */
+ { 16362, 0x000084D1 }, /* GL_TEXTURE17 */
+ { 16375, 0x000084D2 }, /* GL_TEXTURE18 */
+ { 16388, 0x000084D3 }, /* GL_TEXTURE19 */
+ { 16401, 0x000084D4 }, /* GL_TEXTURE20 */
+ { 16414, 0x000084D5 }, /* GL_TEXTURE21 */
+ { 16427, 0x000084D6 }, /* GL_TEXTURE22 */
+ { 16440, 0x000084D7 }, /* GL_TEXTURE23 */
+ { 16453, 0x000084D8 }, /* GL_TEXTURE24 */
+ { 16466, 0x000084D9 }, /* GL_TEXTURE25 */
+ { 16479, 0x000084DA }, /* GL_TEXTURE26 */
+ { 16492, 0x000084DB }, /* GL_TEXTURE27 */
+ { 16505, 0x000084DC }, /* GL_TEXTURE28 */
+ { 16518, 0x000084DD }, /* GL_TEXTURE29 */
+ { 16531, 0x000084DE }, /* GL_TEXTURE30 */
+ { 16544, 0x000084DF }, /* GL_TEXTURE31 */
+ { 16557, 0x000084E0 }, /* GL_ACTIVE_TEXTURE */
+ { 16575, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE */
+ { 16600, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
+ { 16621, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+ { 16651, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+ { 16682, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+ { 16710, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
+ { 16736, 0x000084E7 }, /* GL_SUBTRACT */
+ { 16748, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE */
+ { 16773, 0x000084E9 }, /* GL_COMPRESSED_ALPHA */
+ { 16793, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE */
+ { 16817, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA */
+ { 16847, 0x000084EC }, /* GL_COMPRESSED_INTENSITY */
+ { 16871, 0x000084ED }, /* GL_COMPRESSED_RGB */
+ { 16889, 0x000084EE }, /* GL_COMPRESSED_RGBA */
+ { 16908, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
+ { 16936, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE */
+ { 16957, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE */
+ { 16986, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE */
+ { 17013, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE */
+ { 17043, 0x000084F9 }, /* GL_DEPTH_STENCIL */
+ { 17060, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
+ { 17081, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
+ { 17105, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+ { 17135, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+ { 17169, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
+ { 17195, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
+ { 17215, 0x00008503 }, /* GL_COMBINE4_NV */
+ { 17230, 0x00008504 }, /* GL_MAX_SHININESS_NV */
+ { 17250, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
+ { 17274, 0x00008507 }, /* GL_INCR_WRAP */
+ { 17287, 0x00008508 }, /* GL_DECR_WRAP */
+ { 17300, 0x0000850A }, /* GL_MODELVIEW1_ARB */
+ { 17318, 0x00008511 }, /* GL_NORMAL_MAP */
+ { 17332, 0x00008512 }, /* GL_REFLECTION_MAP */
+ { 17350, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
+ { 17370, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
+ { 17398, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+ { 17429, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+ { 17460, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+ { 17491, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+ { 17522, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+ { 17553, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+ { 17584, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
+ { 17610, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+ { 17639, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+ { 17669, 0x00008558 }, /* GL_PRIMITIVE_RESTART_NV */
+ { 17693, 0x00008559 }, /* GL_PRIMITIVE_RESTART_INDEX_NV */
+ { 17723, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */
+ { 17747, 0x0000855B }, /* GL_EYE_RADIAL_NV */
+ { 17764, 0x0000855C }, /* GL_EYE_PLANE_ABSOLUTE_NV */
+ { 17789, 0x00008570 }, /* GL_COMBINE */
+ { 17800, 0x00008571 }, /* GL_COMBINE_RGB */
+ { 17815, 0x00008572 }, /* GL_COMBINE_ALPHA */
+ { 17832, 0x00008573 }, /* GL_RGB_SCALE */
+ { 17845, 0x00008574 }, /* GL_ADD_SIGNED */
+ { 17859, 0x00008575 }, /* GL_INTERPOLATE */
+ { 17874, 0x00008576 }, /* GL_CONSTANT */
+ { 17886, 0x00008577 }, /* GL_PRIMARY_COLOR */
+ { 17903, 0x00008578 }, /* GL_PREVIOUS */
+ { 17915, 0x00008580 }, /* GL_SOURCE0_RGB */
+ { 17930, 0x00008581 }, /* GL_SOURCE1_RGB */
+ { 17945, 0x00008582 }, /* GL_SOURCE2_RGB */
+ { 17960, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
+ { 17978, 0x00008588 }, /* GL_SOURCE0_ALPHA */
+ { 17995, 0x00008589 }, /* GL_SOURCE1_ALPHA */
+ { 18012, 0x0000858A }, /* GL_SOURCE2_ALPHA */
+ { 18029, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
+ { 18049, 0x00008590 }, /* GL_OPERAND0_RGB */
+ { 18065, 0x00008591 }, /* GL_OPERAND1_RGB */
+ { 18081, 0x00008592 }, /* GL_OPERAND2_RGB */
+ { 18097, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
+ { 18116, 0x00008598 }, /* GL_OPERAND0_ALPHA */
+ { 18134, 0x00008599 }, /* GL_OPERAND1_ALPHA */
+ { 18152, 0x0000859A }, /* GL_OPERAND2_ALPHA */
+ { 18170, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
+ { 18191, 0x000085B3 }, /* GL_BUFFER_OBJECT_APPLE */
+ { 18214, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
+ { 18238, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
+ { 18268, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
+ { 18299, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
+ { 18318, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+ { 18346, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+ { 18378, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
+ { 18408, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
+ { 18433, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
+ { 18457, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
+ { 18481, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
+ { 18500, 0x00008614 }, /* GL_QUAD_MESH_SUN */
+ { 18517, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
+ { 18538, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
+ { 18560, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
+ { 18587, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
+ { 18618, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
+ { 18646, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
+ { 18676, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+ { 18704, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB */
+ { 18729, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
+ { 18751, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
+ { 18773, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
+ { 18800, 0x0000862A }, /* GL_IDENTITY_NV */
+ { 18815, 0x0000862B }, /* GL_INVERSE_NV */
+ { 18829, 0x0000862C }, /* GL_TRANSPOSE_NV */
+ { 18845, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
+ { 18869, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+ { 18907, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
+ { 18935, 0x00008630 }, /* GL_MATRIX0_NV */
+ { 18949, 0x00008631 }, /* GL_MATRIX1_NV */
+ { 18963, 0x00008632 }, /* GL_MATRIX2_NV */
+ { 18977, 0x00008633 }, /* GL_MATRIX3_NV */
+ { 18991, 0x00008634 }, /* GL_MATRIX4_NV */
+ { 19005, 0x00008635 }, /* GL_MATRIX5_NV */
+ { 19019, 0x00008636 }, /* GL_MATRIX6_NV */
+ { 19033, 0x00008637 }, /* GL_MATRIX7_NV */
+ { 19047, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
+ { 19081, 0x00008641 }, /* GL_CURRENT_MATRIX_ARB */
+ { 19103, 0x00008642 }, /* GL_PROGRAM_POINT_SIZE */
+ { 19125, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+ { 19152, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
+ { 19176, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+ { 19207, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
+ { 19228, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
+ { 19251, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
+ { 19270, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+ { 19299, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
+ { 19328, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
+ { 19358, 0x0000864F }, /* GL_DEPTH_CLAMP */
+ { 19373, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+ { 19400, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+ { 19427, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+ { 19454, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+ { 19481, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+ { 19508, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+ { 19535, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+ { 19562, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+ { 19589, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+ { 19616, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+ { 19643, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+ { 19671, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+ { 19699, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+ { 19727, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+ { 19755, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+ { 19783, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+ { 19811, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+ { 19839, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+ { 19867, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+ { 19895, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+ { 19923, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+ { 19951, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+ { 19979, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+ { 20007, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+ { 20035, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+ { 20063, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+ { 20091, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+ { 20120, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+ { 20149, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+ { 20178, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+ { 20207, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+ { 20236, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+ { 20265, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+ { 20293, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+ { 20321, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+ { 20349, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+ { 20377, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+ { 20405, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+ { 20433, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+ { 20461, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
+ { 20484, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+ { 20512, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+ { 20540, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+ { 20569, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+ { 20598, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+ { 20627, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+ { 20656, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+ { 20685, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+ { 20714, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+ { 20747, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
+ { 20769, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+ { 20803, 0x000086A3 }, /* GL_COMPRESSED_TEXTURE_FORMATS */
+ { 20833, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
+ { 20857, 0x000086A5 }, /* GL_ACTIVE_VERTEX_UNITS_ARB */
+ { 20884, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
+ { 20908, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
+ { 20928, 0x000086A8 }, /* GL_CURRENT_WEIGHT_ARB */
+ { 20950, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+ { 20975, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+ { 21002, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+ { 21027, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+ { 21055, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
+ { 21075, 0x000086AE }, /* GL_DOT3_RGB */
+ { 21087, 0x000086AF }, /* GL_DOT3_RGBA */
+ { 21100, 0x000086B0 }, /* GL_COMPRESSED_RGB_FXT1_3DFX */
+ { 21128, 0x000086B1 }, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
+ { 21157, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
+ { 21177, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
+ { 21200, 0x000086B4 }, /* GL_SAMPLES_3DFX */
+ { 21216, 0x000086EB }, /* GL_SURFACE_STATE_NV */
+ { 21236, 0x000086FD }, /* GL_SURFACE_REGISTERED_NV */
+ { 21261, 0x00008700 }, /* GL_SURFACE_MAPPED_NV */
+ { 21282, 0x00008722 }, /* GL_MODELVIEW2_ARB */
+ { 21300, 0x00008723 }, /* GL_MODELVIEW3_ARB */
+ { 21318, 0x00008724 }, /* GL_MODELVIEW4_ARB */
+ { 21336, 0x00008725 }, /* GL_MODELVIEW5_ARB */
+ { 21354, 0x00008726 }, /* GL_MODELVIEW6_ARB */
+ { 21372, 0x00008727 }, /* GL_MODELVIEW7_ARB */
+ { 21390, 0x00008728 }, /* GL_MODELVIEW8_ARB */
+ { 21408, 0x00008729 }, /* GL_MODELVIEW9_ARB */
+ { 21426, 0x0000872A }, /* GL_MODELVIEW10_ARB */
+ { 21445, 0x0000872B }, /* GL_MODELVIEW11_ARB */
+ { 21464, 0x0000872C }, /* GL_MODELVIEW12_ARB */
+ { 21483, 0x0000872D }, /* GL_MODELVIEW13_ARB */
+ { 21502, 0x0000872E }, /* GL_MODELVIEW14_ARB */
+ { 21521, 0x0000872F }, /* GL_MODELVIEW15_ARB */
+ { 21540, 0x00008730 }, /* GL_MODELVIEW16_ARB */
+ { 21559, 0x00008731 }, /* GL_MODELVIEW17_ARB */
+ { 21578, 0x00008732 }, /* GL_MODELVIEW18_ARB */
+ { 21597, 0x00008733 }, /* GL_MODELVIEW19_ARB */
+ { 21616, 0x00008734 }, /* GL_MODELVIEW20_ARB */
+ { 21635, 0x00008735 }, /* GL_MODELVIEW21_ARB */
+ { 21654, 0x00008736 }, /* GL_MODELVIEW22_ARB */
+ { 21673, 0x00008737 }, /* GL_MODELVIEW23_ARB */
+ { 21692, 0x00008738 }, /* GL_MODELVIEW24_ARB */
+ { 21711, 0x00008739 }, /* GL_MODELVIEW25_ARB */
+ { 21730, 0x0000873A }, /* GL_MODELVIEW26_ARB */
+ { 21749, 0x0000873B }, /* GL_MODELVIEW27_ARB */
+ { 21768, 0x0000873C }, /* GL_MODELVIEW28_ARB */
+ { 21787, 0x0000873D }, /* GL_MODELVIEW29_ARB */
+ { 21806, 0x0000873E }, /* GL_MODELVIEW30_ARB */
+ { 21825, 0x0000873F }, /* GL_MODELVIEW31_ARB */
+ { 21844, 0x00008740 }, /* GL_DOT3_RGB_EXT */
+ { 21860, 0x00008741 }, /* GL_PROGRAM_BINARY_LENGTH */
+ { 21885, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
+ { 21905, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+ { 21933, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
+ { 21953, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
+ { 21980, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
+ { 22005, 0x00008757 }, /* GL_YCBCR_MESA */
+ { 22019, 0x00008758 }, /* GL_PACK_INVERT_MESA */
+ { 22039, 0x00008764 }, /* GL_BUFFER_SIZE */
+ { 22054, 0x00008765 }, /* GL_BUFFER_USAGE */
+ { 22070, 0x00008775 }, /* GL_BUMP_ROT_MATRIX_ATI */
+ { 22093, 0x00008776 }, /* GL_BUMP_ROT_MATRIX_SIZE_ATI */
+ { 22121, 0x00008777 }, /* GL_BUMP_NUM_TEX_UNITS_ATI */
+ { 22147, 0x00008778 }, /* GL_BUMP_TEX_UNITS_ATI */
+ { 22169, 0x00008779 }, /* GL_DUDV_ATI */
+ { 22181, 0x0000877A }, /* GL_DU8DV8_ATI */
+ { 22195, 0x0000877B }, /* GL_BUMP_ENVMAP_ATI */
+ { 22214, 0x0000877C }, /* GL_BUMP_TARGET_ATI */
+ { 22233, 0x000087FE }, /* GL_NUM_PROGRAM_BINARY_FORMATS */
+ { 22263, 0x000087FF }, /* GL_PROGRAM_BINARY_FORMATS */
+ { 22289, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
+ { 22310, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
+ { 22331, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
+ { 22363, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+ { 22395, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */
+ { 22419, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ { 22451, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ { 22483, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+ { 22515, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ { 22554, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ { 22593, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ { 22632, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ { 22668, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ { 22704, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+ { 22740, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ { 22783, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ { 22826, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ { 22869, 0x00008814 }, /* GL_RGBA32F */
+ { 22880, 0x00008815 }, /* GL_RGB32F */
+ { 22890, 0x00008816 }, /* GL_ALPHA32F_ARB */
+ { 22906, 0x00008817 }, /* GL_INTENSITY32F_ARB */
+ { 22926, 0x00008818 }, /* GL_LUMINANCE32F_ARB */
+ { 22946, 0x00008819 }, /* GL_LUMINANCE_ALPHA32F_ARB */
+ { 22972, 0x0000881A }, /* GL_RGBA16F */
+ { 22983, 0x0000881B }, /* GL_RGB16F */
+ { 22993, 0x0000881C }, /* GL_ALPHA16F_ARB */
+ { 23009, 0x0000881D }, /* GL_INTENSITY16F_ARB */
+ { 23029, 0x0000881E }, /* GL_LUMINANCE16F_ARB */
+ { 23049, 0x0000881F }, /* GL_LUMINANCE_ALPHA16F_ARB */
+ { 23075, 0x00008820 }, /* GL_RGBA_FLOAT_MODE_ARB */
+ { 23098, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
+ { 23118, 0x00008825 }, /* GL_DRAW_BUFFER0 */
+ { 23134, 0x00008826 }, /* GL_DRAW_BUFFER1 */
+ { 23150, 0x00008827 }, /* GL_DRAW_BUFFER2 */
+ { 23166, 0x00008828 }, /* GL_DRAW_BUFFER3 */
+ { 23182, 0x00008829 }, /* GL_DRAW_BUFFER4 */
+ { 23198, 0x0000882A }, /* GL_DRAW_BUFFER5 */
+ { 23214, 0x0000882B }, /* GL_DRAW_BUFFER6 */
+ { 23230, 0x0000882C }, /* GL_DRAW_BUFFER7 */
+ { 23246, 0x0000882D }, /* GL_DRAW_BUFFER8 */
+ { 23262, 0x0000882E }, /* GL_DRAW_BUFFER9 */
+ { 23278, 0x0000882F }, /* GL_DRAW_BUFFER10 */
+ { 23295, 0x00008830 }, /* GL_DRAW_BUFFER11 */
+ { 23312, 0x00008831 }, /* GL_DRAW_BUFFER12 */
+ { 23329, 0x00008832 }, /* GL_DRAW_BUFFER13 */
+ { 23346, 0x00008833 }, /* GL_DRAW_BUFFER14 */
+ { 23363, 0x00008834 }, /* GL_DRAW_BUFFER15 */
+ { 23380, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA */
+ { 23404, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
+ { 23426, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+ { 23464, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
+ { 23492, 0x00008843 }, /* GL_CURRENT_PALETTE_MATRIX_ARB */
+ { 23522, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
+ { 23548, 0x00008845 }, /* GL_CURRENT_MATRIX_INDEX_ARB */
+ { 23576, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+ { 23607, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+ { 23638, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+ { 23671, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+ { 23705, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
+ { 23727, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE */
+ { 23749, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
+ { 23773, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
+ { 23797, 0x0000884E }, /* GL_COMPARE_REF_TO_TEXTURE */
+ { 23823, 0x0000884F }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+ { 23852, 0x00008861 }, /* GL_POINT_SPRITE */
+ { 23868, 0x00008862 }, /* GL_COORD_REPLACE */
+ { 23885, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
+ { 23911, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
+ { 23933, 0x00008865 }, /* GL_CURRENT_QUERY */
+ { 23950, 0x00008866 }, /* GL_QUERY_RESULT */
+ { 23966, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
+ { 23992, 0x00008868 }, /* GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV */
+ { 24036, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
+ { 24058, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+ { 24092, 0x0000886E }, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
+ { 24120, 0x0000886F }, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
+ { 24148, 0x00008870 }, /* GL_FRAGMENT_PROGRAM_NV */
+ { 24171, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
+ { 24193, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
+ { 24220, 0x00008873 }, /* GL_FRAGMENT_PROGRAM_BINDING_NV */
+ { 24251, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
+ { 24279, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+ { 24307, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
+ { 24329, 0x0000887F }, /* GL_GEOMETRY_SHADER_INVOCATIONS */
+ { 24360, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+ { 24394, 0x00008890 }, /* GL_DEPTH_BOUNDS_TEST_EXT */
+ { 24419, 0x00008891 }, /* GL_DEPTH_BOUNDS_EXT */
+ { 24439, 0x00008892 }, /* GL_ARRAY_BUFFER */
+ { 24455, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER */
+ { 24479, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING */
+ { 24503, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
+ { 24535, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+ { 24566, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+ { 24597, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING */
+ { 24627, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+ { 24657, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+ { 24695, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
+ { 24729, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+ { 24769, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
+ { 24808, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+ { 24839, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+ { 24877, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+ { 24905, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+ { 24937, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ { 24972, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ { 25011, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
+ { 25038, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+ { 25069, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ { 25103, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ { 25141, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
+ { 25167, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+ { 25197, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+ { 25230, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+ { 25267, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
+ { 25290, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+ { 25317, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+ { 25347, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+ { 25381, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+ { 25414, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+ { 25451, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ { 25491, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ { 25535, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+ { 25571, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+ { 25605, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+ { 25640, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+ { 25672, 0x000088B8 }, /* GL_READ_ONLY */
+ { 25685, 0x000088B9 }, /* GL_WRITE_ONLY */
+ { 25699, 0x000088BA }, /* GL_READ_WRITE */
+ { 25713, 0x000088BB }, /* GL_BUFFER_ACCESS */
+ { 25730, 0x000088BC }, /* GL_BUFFER_MAPPED */
+ { 25747, 0x000088BD }, /* GL_BUFFER_MAP_POINTER */
+ { 25769, 0x000088BE }, /* GL_WRITE_DISCARD_NV */
+ { 25789, 0x000088BF }, /* GL_TIME_ELAPSED */
+ { 25805, 0x000088C0 }, /* GL_MATRIX0_ARB */
+ { 25820, 0x000088C1 }, /* GL_MATRIX1_ARB */
+ { 25835, 0x000088C2 }, /* GL_MATRIX2_ARB */
+ { 25850, 0x000088C3 }, /* GL_MATRIX3_ARB */
+ { 25865, 0x000088C4 }, /* GL_MATRIX4_ARB */
+ { 25880, 0x000088C5 }, /* GL_MATRIX5_ARB */
+ { 25895, 0x000088C6 }, /* GL_MATRIX6_ARB */
+ { 25910, 0x000088C7 }, /* GL_MATRIX7_ARB */
+ { 25925, 0x000088C8 }, /* GL_MATRIX8_ARB */
+ { 25940, 0x000088C9 }, /* GL_MATRIX9_ARB */
+ { 25955, 0x000088CA }, /* GL_MATRIX10_ARB */
+ { 25971, 0x000088CB }, /* GL_MATRIX11_ARB */
+ { 25987, 0x000088CC }, /* GL_MATRIX12_ARB */
+ { 26003, 0x000088CD }, /* GL_MATRIX13_ARB */
+ { 26019, 0x000088CE }, /* GL_MATRIX14_ARB */
+ { 26035, 0x000088CF }, /* GL_MATRIX15_ARB */
+ { 26051, 0x000088D0 }, /* GL_MATRIX16_ARB */
+ { 26067, 0x000088D1 }, /* GL_MATRIX17_ARB */
+ { 26083, 0x000088D2 }, /* GL_MATRIX18_ARB */
+ { 26099, 0x000088D3 }, /* GL_MATRIX19_ARB */
+ { 26115, 0x000088D4 }, /* GL_MATRIX20_ARB */
+ { 26131, 0x000088D5 }, /* GL_MATRIX21_ARB */
+ { 26147, 0x000088D6 }, /* GL_MATRIX22_ARB */
+ { 26163, 0x000088D7 }, /* GL_MATRIX23_ARB */
+ { 26179, 0x000088D8 }, /* GL_MATRIX24_ARB */
+ { 26195, 0x000088D9 }, /* GL_MATRIX25_ARB */
+ { 26211, 0x000088DA }, /* GL_MATRIX26_ARB */
+ { 26227, 0x000088DB }, /* GL_MATRIX27_ARB */
+ { 26243, 0x000088DC }, /* GL_MATRIX28_ARB */
+ { 26259, 0x000088DD }, /* GL_MATRIX29_ARB */
+ { 26275, 0x000088DE }, /* GL_MATRIX30_ARB */
+ { 26291, 0x000088DF }, /* GL_MATRIX31_ARB */
+ { 26307, 0x000088E0 }, /* GL_STREAM_DRAW */
+ { 26322, 0x000088E1 }, /* GL_STREAM_READ */
+ { 26337, 0x000088E2 }, /* GL_STREAM_COPY */
+ { 26352, 0x000088E4 }, /* GL_STATIC_DRAW */
+ { 26367, 0x000088E5 }, /* GL_STATIC_READ */
+ { 26382, 0x000088E6 }, /* GL_STATIC_COPY */
+ { 26397, 0x000088E8 }, /* GL_DYNAMIC_DRAW */
+ { 26413, 0x000088E9 }, /* GL_DYNAMIC_READ */
+ { 26429, 0x000088EA }, /* GL_DYNAMIC_COPY */
+ { 26445, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
+ { 26466, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
+ { 26489, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
+ { 26518, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
+ { 26549, 0x000088F0 }, /* GL_DEPTH24_STENCIL8 */
+ { 26569, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
+ { 26593, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+ { 26629, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+ { 26658, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+ { 26685, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+ { 26714, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+ { 26743, 0x000088F9 }, /* GL_SRC1_COLOR */
+ { 26757, 0x000088FA }, /* GL_ONE_MINUS_SRC1_COLOR */
+ { 26781, 0x000088FB }, /* GL_ONE_MINUS_SRC1_ALPHA */
+ { 26805, 0x000088FC }, /* GL_MAX_DUAL_SOURCE_DRAW_BUFFERS */
+ { 26837, 0x000088FD }, /* GL_VERTEX_ATTRIB_ARRAY_INTEGER */
+ { 26868, 0x000088FE }, /* GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB */
+ { 26903, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS */
+ { 26931, 0x00008904 }, /* GL_MIN_PROGRAM_TEXEL_OFFSET */
+ { 26959, 0x00008905 }, /* GL_MAX_PROGRAM_TEXEL_OFFSET */
+ { 26987, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+ { 27016, 0x00008911 }, /* GL_ACTIVE_STENCIL_FACE_EXT */
+ { 27043, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+ { 27073, 0x00008914 }, /* GL_SAMPLES_PASSED */
+ { 27091, 0x00008916 }, /* GL_GEOMETRY_VERTICES_OUT */
+ { 27116, 0x00008917 }, /* GL_GEOMETRY_INPUT_TYPE */
+ { 27139, 0x00008918 }, /* GL_GEOMETRY_OUTPUT_TYPE */
+ { 27163, 0x00008919 }, /* GL_SAMPLER_BINDING */
+ { 27182, 0x0000891A }, /* GL_CLAMP_VERTEX_COLOR */
+ { 27204, 0x0000891B }, /* GL_CLAMP_FRAGMENT_COLOR */
+ { 27228, 0x0000891C }, /* GL_CLAMP_READ_COLOR */
+ { 27248, 0x0000891D }, /* GL_FIXED_ONLY */
+ { 27262, 0x00008920 }, /* GL_FRAGMENT_SHADER_ATI */
+ { 27285, 0x00008921 }, /* GL_REG_0_ATI */
+ { 27298, 0x00008922 }, /* GL_REG_1_ATI */
+ { 27311, 0x00008923 }, /* GL_REG_2_ATI */
+ { 27324, 0x00008924 }, /* GL_REG_3_ATI */
+ { 27337, 0x00008925 }, /* GL_REG_4_ATI */
+ { 27350, 0x00008926 }, /* GL_REG_5_ATI */
+ { 27363, 0x00008927 }, /* GL_REG_6_ATI */
+ { 27376, 0x00008928 }, /* GL_REG_7_ATI */
+ { 27389, 0x00008929 }, /* GL_REG_8_ATI */
+ { 27402, 0x0000892A }, /* GL_REG_9_ATI */
+ { 27415, 0x0000892B }, /* GL_REG_10_ATI */
+ { 27429, 0x0000892C }, /* GL_REG_11_ATI */
+ { 27443, 0x0000892D }, /* GL_REG_12_ATI */
+ { 27457, 0x0000892E }, /* GL_REG_13_ATI */
+ { 27471, 0x0000892F }, /* GL_REG_14_ATI */
+ { 27485, 0x00008930 }, /* GL_REG_15_ATI */
+ { 27499, 0x00008931 }, /* GL_REG_16_ATI */
+ { 27513, 0x00008932 }, /* GL_REG_17_ATI */
+ { 27527, 0x00008933 }, /* GL_REG_18_ATI */
+ { 27541, 0x00008934 }, /* GL_REG_19_ATI */
+ { 27555, 0x00008935 }, /* GL_REG_20_ATI */
+ { 27569, 0x00008936 }, /* GL_REG_21_ATI */
+ { 27583, 0x00008937 }, /* GL_REG_22_ATI */
+ { 27597, 0x00008938 }, /* GL_REG_23_ATI */
+ { 27611, 0x00008939 }, /* GL_REG_24_ATI */
+ { 27625, 0x0000893A }, /* GL_REG_25_ATI */
+ { 27639, 0x0000893B }, /* GL_REG_26_ATI */
+ { 27653, 0x0000893C }, /* GL_REG_27_ATI */
+ { 27667, 0x0000893D }, /* GL_REG_28_ATI */
+ { 27681, 0x0000893E }, /* GL_REG_29_ATI */
+ { 27695, 0x0000893F }, /* GL_REG_30_ATI */
+ { 27709, 0x00008940 }, /* GL_REG_31_ATI */
+ { 27723, 0x00008941 }, /* GL_CON_0_ATI */
+ { 27736, 0x00008942 }, /* GL_CON_1_ATI */
+ { 27749, 0x00008943 }, /* GL_CON_2_ATI */
+ { 27762, 0x00008944 }, /* GL_CON_3_ATI */
+ { 27775, 0x00008945 }, /* GL_CON_4_ATI */
+ { 27788, 0x00008946 }, /* GL_CON_5_ATI */
+ { 27801, 0x00008947 }, /* GL_CON_6_ATI */
+ { 27814, 0x00008948 }, /* GL_CON_7_ATI */
+ { 27827, 0x00008949 }, /* GL_CON_8_ATI */
+ { 27840, 0x0000894A }, /* GL_CON_9_ATI */
+ { 27853, 0x0000894B }, /* GL_CON_10_ATI */
+ { 27867, 0x0000894C }, /* GL_CON_11_ATI */
+ { 27881, 0x0000894D }, /* GL_CON_12_ATI */
+ { 27895, 0x0000894E }, /* GL_CON_13_ATI */
+ { 27909, 0x0000894F }, /* GL_CON_14_ATI */
+ { 27923, 0x00008950 }, /* GL_CON_15_ATI */
+ { 27937, 0x00008951 }, /* GL_CON_16_ATI */
+ { 27951, 0x00008952 }, /* GL_CON_17_ATI */
+ { 27965, 0x00008953 }, /* GL_CON_18_ATI */
+ { 27979, 0x00008954 }, /* GL_CON_19_ATI */
+ { 27993, 0x00008955 }, /* GL_CON_20_ATI */
+ { 28007, 0x00008956 }, /* GL_CON_21_ATI */
+ { 28021, 0x00008957 }, /* GL_CON_22_ATI */
+ { 28035, 0x00008958 }, /* GL_CON_23_ATI */
+ { 28049, 0x00008959 }, /* GL_CON_24_ATI */
+ { 28063, 0x0000895A }, /* GL_CON_25_ATI */
+ { 28077, 0x0000895B }, /* GL_CON_26_ATI */
+ { 28091, 0x0000895C }, /* GL_CON_27_ATI */
+ { 28105, 0x0000895D }, /* GL_CON_28_ATI */
+ { 28119, 0x0000895E }, /* GL_CON_29_ATI */
+ { 28133, 0x0000895F }, /* GL_CON_30_ATI */
+ { 28147, 0x00008960 }, /* GL_CON_31_ATI */
+ { 28161, 0x00008961 }, /* GL_MOV_ATI */
+ { 28172, 0x00008963 }, /* GL_ADD_ATI */
+ { 28183, 0x00008964 }, /* GL_MUL_ATI */
+ { 28194, 0x00008965 }, /* GL_SUB_ATI */
+ { 28205, 0x00008966 }, /* GL_DOT3_ATI */
+ { 28217, 0x00008967 }, /* GL_DOT4_ATI */
+ { 28229, 0x00008968 }, /* GL_MAD_ATI */
+ { 28240, 0x00008969 }, /* GL_LERP_ATI */
+ { 28252, 0x0000896A }, /* GL_CND_ATI */
+ { 28263, 0x0000896B }, /* GL_CND0_ATI */
+ { 28275, 0x0000896C }, /* GL_DOT2_ADD_ATI */
+ { 28291, 0x0000896D }, /* GL_SECONDARY_INTERPOLATOR_ATI */
+ { 28321, 0x0000896E }, /* GL_NUM_FRAGMENT_REGISTERS_ATI */
+ { 28351, 0x0000896F }, /* GL_NUM_FRAGMENT_CONSTANTS_ATI */
+ { 28381, 0x00008970 }, /* GL_NUM_PASSES_ATI */
+ { 28399, 0x00008971 }, /* GL_NUM_INSTRUCTIONS_PER_PASS_ATI */
+ { 28432, 0x00008972 }, /* GL_NUM_INSTRUCTIONS_TOTAL_ATI */
+ { 28462, 0x00008973 }, /* GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI */
+ { 28503, 0x00008974 }, /* GL_NUM_LOOPBACK_COMPONENTS_ATI */
+ { 28534, 0x00008975 }, /* GL_COLOR_ALPHA_PAIRING_ATI */
+ { 28561, 0x00008976 }, /* GL_SWIZZLE_STR_ATI */
+ { 28580, 0x00008977 }, /* GL_SWIZZLE_STQ_ATI */
+ { 28599, 0x00008978 }, /* GL_SWIZZLE_STR_DR_ATI */
+ { 28621, 0x00008979 }, /* GL_SWIZZLE_STQ_DQ_ATI */
+ { 28643, 0x0000897A }, /* GL_SWIZZLE_STRQ_ATI */
+ { 28663, 0x0000897B }, /* GL_SWIZZLE_STRQ_DQ_ATI */
+ { 28686, 0x0000898A }, /* GL_POINT_SIZE_ARRAY_TYPE_OES */
+ { 28715, 0x0000898B }, /* GL_POINT_SIZE_ARRAY_STRIDE_OES */
+ { 28746, 0x0000898C }, /* GL_POINT_SIZE_ARRAY_POINTER_OES */
+ { 28778, 0x0000898D }, /* GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES */
+ { 28820, 0x0000898E }, /* GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES */
+ { 28863, 0x0000898F }, /* GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES */
+ { 28903, 0x00008A11 }, /* GL_UNIFORM_BUFFER */
+ { 28921, 0x00008A12 }, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */
+ { 28955, 0x00008A13 }, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */
+ { 28986, 0x00008A19 }, /* GL_RELEASED_APPLE */
+ { 29004, 0x00008A1A }, /* GL_VOLATILE_APPLE */
+ { 29022, 0x00008A1B }, /* GL_RETAINED_APPLE */
+ { 29040, 0x00008A1C }, /* GL_UNDEFINED_APPLE */
+ { 29059, 0x00008A1D }, /* GL_PURGEABLE_APPLE */
+ { 29078, 0x00008A28 }, /* GL_UNIFORM_BUFFER_BINDING */
+ { 29104, 0x00008A29 }, /* GL_UNIFORM_BUFFER_START */
+ { 29128, 0x00008A2A }, /* GL_UNIFORM_BUFFER_SIZE */
+ { 29151, 0x00008A2B }, /* GL_MAX_VERTEX_UNIFORM_BLOCKS */
+ { 29180, 0x00008A2C }, /* GL_MAX_GEOMETRY_UNIFORM_BLOCKS */
+ { 29211, 0x00008A2D }, /* GL_MAX_FRAGMENT_UNIFORM_BLOCKS */
+ { 29242, 0x00008A2E }, /* GL_MAX_COMBINED_UNIFORM_BLOCKS */
+ { 29273, 0x00008A2F }, /* GL_MAX_UNIFORM_BUFFER_BINDINGS */
+ { 29304, 0x00008A30 }, /* GL_MAX_UNIFORM_BLOCK_SIZE */
+ { 29330, 0x00008A31 }, /* GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */
+ { 29372, 0x00008A32 }, /* GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS */
+ { 29416, 0x00008A33 }, /* GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */
+ { 29460, 0x00008A34 }, /* GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */
+ { 29495, 0x00008A35 }, /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */
+ { 29535, 0x00008A36 }, /* GL_ACTIVE_UNIFORM_BLOCKS */
+ { 29560, 0x00008A37 }, /* GL_UNIFORM_TYPE */
+ { 29576, 0x00008A38 }, /* GL_UNIFORM_SIZE */
+ { 29592, 0x00008A39 }, /* GL_UNIFORM_NAME_LENGTH */
+ { 29615, 0x00008A3A }, /* GL_UNIFORM_BLOCK_INDEX */
+ { 29638, 0x00008A3B }, /* GL_UNIFORM_OFFSET */
+ { 29656, 0x00008A3C }, /* GL_UNIFORM_ARRAY_STRIDE */
+ { 29680, 0x00008A3D }, /* GL_UNIFORM_MATRIX_STRIDE */
+ { 29705, 0x00008A3E }, /* GL_UNIFORM_IS_ROW_MAJOR */
+ { 29729, 0x00008A3F }, /* GL_UNIFORM_BLOCK_BINDING */
+ { 29754, 0x00008A40 }, /* GL_UNIFORM_BLOCK_DATA_SIZE */
+ { 29781, 0x00008A41 }, /* GL_UNIFORM_BLOCK_NAME_LENGTH */
+ { 29810, 0x00008A42 }, /* GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */
+ { 29843, 0x00008A43 }, /* GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */
+ { 29883, 0x00008A44 }, /* GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */
+ { 29928, 0x00008A45 }, /* GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER */
+ { 29975, 0x00008A46 }, /* GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */
+ { 30022, 0x00008A48 }, /* GL_TEXTURE_SRGB_DECODE_EXT */
+ { 30049, 0x00008A49 }, /* GL_DECODE_EXT */
+ { 30063, 0x00008A4A }, /* GL_SKIP_DECODE_EXT */
+ { 30082, 0x00008B30 }, /* GL_FRAGMENT_SHADER */
+ { 30101, 0x00008B31 }, /* GL_VERTEX_SHADER */
+ { 30118, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
+ { 30140, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
+ { 30161, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
+ { 30196, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
+ { 30229, 0x00008B4B }, /* GL_MAX_VARYING_COMPONENTS */
+ { 30255, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
+ { 30289, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
+ { 30325, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
+ { 30344, 0x00008B4F }, /* GL_SHADER_TYPE */
+ { 30359, 0x00008B50 }, /* GL_FLOAT_VEC2 */
+ { 30373, 0x00008B51 }, /* GL_FLOAT_VEC3 */
+ { 30387, 0x00008B52 }, /* GL_FLOAT_VEC4 */
+ { 30401, 0x00008B53 }, /* GL_INT_VEC2 */
+ { 30413, 0x00008B54 }, /* GL_INT_VEC3 */
+ { 30425, 0x00008B55 }, /* GL_INT_VEC4 */
+ { 30437, 0x00008B56 }, /* GL_BOOL */
+ { 30445, 0x00008B57 }, /* GL_BOOL_VEC2 */
+ { 30458, 0x00008B58 }, /* GL_BOOL_VEC3 */
+ { 30471, 0x00008B59 }, /* GL_BOOL_VEC4 */
+ { 30484, 0x00008B5A }, /* GL_FLOAT_MAT2 */
+ { 30498, 0x00008B5B }, /* GL_FLOAT_MAT3 */
+ { 30512, 0x00008B5C }, /* GL_FLOAT_MAT4 */
+ { 30526, 0x00008B5D }, /* GL_SAMPLER_1D */
+ { 30540, 0x00008B5E }, /* GL_SAMPLER_2D */
+ { 30554, 0x00008B5F }, /* GL_SAMPLER_3D */
+ { 30568, 0x00008B60 }, /* GL_SAMPLER_CUBE */
+ { 30584, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
+ { 30605, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
+ { 30626, 0x00008B63 }, /* GL_SAMPLER_2D_RECT */
+ { 30645, 0x00008B64 }, /* GL_SAMPLER_2D_RECT_SHADOW */
+ { 30671, 0x00008B65 }, /* GL_FLOAT_MAT2x3 */
+ { 30687, 0x00008B66 }, /* GL_FLOAT_MAT2x4 */
+ { 30703, 0x00008B67 }, /* GL_FLOAT_MAT3x2 */
+ { 30719, 0x00008B68 }, /* GL_FLOAT_MAT3x4 */
+ { 30735, 0x00008B69 }, /* GL_FLOAT_MAT4x2 */
+ { 30751, 0x00008B6A }, /* GL_FLOAT_MAT4x3 */
+ { 30767, 0x00008B80 }, /* GL_DELETE_STATUS */
+ { 30784, 0x00008B81 }, /* GL_COMPILE_STATUS */
+ { 30802, 0x00008B82 }, /* GL_LINK_STATUS */
+ { 30817, 0x00008B83 }, /* GL_VALIDATE_STATUS */
+ { 30836, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
+ { 30855, 0x00008B85 }, /* GL_ATTACHED_SHADERS */
+ { 30875, 0x00008B86 }, /* GL_ACTIVE_UNIFORMS */
+ { 30894, 0x00008B87 }, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */
+ { 30923, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
+ { 30947, 0x00008B89 }, /* GL_ACTIVE_ATTRIBUTES */
+ { 30968, 0x00008B8A }, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */
+ { 30999, 0x00008B8B }, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
+ { 31034, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
+ { 31062, 0x00008B8D }, /* GL_CURRENT_PROGRAM */
+ { 31081, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
+ { 31102, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
+ { 31124, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
+ { 31149, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
+ { 31171, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
+ { 31195, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
+ { 31216, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
+ { 31238, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
+ { 31263, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
+ { 31285, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
+ { 31309, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE */
+ { 31343, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT */
+ { 31379, 0x00008B9C }, /* GL_POINT_SIZE_ARRAY_OES */
+ { 31403, 0x00008B9D }, /* GL_TEXTURE_CROP_RECT_OES */
+ { 31428, 0x00008B9E }, /* GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES */
+ { 31469, 0x00008B9F }, /* GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES */
+ { 31508, 0x00008BC0 }, /* GL_COUNTER_TYPE_AMD */
+ { 31528, 0x00008BC1 }, /* GL_COUNTER_RANGE_AMD */
+ { 31549, 0x00008BC2 }, /* GL_UNSIGNED_INT64_AMD */
+ { 31571, 0x00008BC3 }, /* GL_PECENTAGE_AMD */
+ { 31588, 0x00008BC4 }, /* GL_PERFMON_RESULT_AVAILABLE_AMD */
+ { 31620, 0x00008BC5 }, /* GL_PERFMON_RESULT_SIZE_AMD */
+ { 31647, 0x00008BC6 }, /* GL_PERFMON_RESULT_AMD */
+ { 31669, 0x00008C10 }, /* GL_TEXTURE_RED_TYPE */
+ { 31689, 0x00008C11 }, /* GL_TEXTURE_GREEN_TYPE */
+ { 31711, 0x00008C12 }, /* GL_TEXTURE_BLUE_TYPE */
+ { 31732, 0x00008C13 }, /* GL_TEXTURE_ALPHA_TYPE */
+ { 31754, 0x00008C14 }, /* GL_TEXTURE_LUMINANCE_TYPE */
+ { 31780, 0x00008C15 }, /* GL_TEXTURE_INTENSITY_TYPE */
+ { 31806, 0x00008C16 }, /* GL_TEXTURE_DEPTH_TYPE */
+ { 31828, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
+ { 31851, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY */
+ { 31871, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY */
+ { 31897, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY */
+ { 31917, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY */
+ { 31943, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY */
+ { 31971, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY */
+ { 31999, 0x00008C29 }, /* GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS */
+ { 32035, 0x00008C2A }, /* GL_TEXTURE_BUFFER */
+ { 32053, 0x00008C2B }, /* GL_MAX_TEXTURE_BUFFER_SIZE */
+ { 32080, 0x00008C2C }, /* GL_TEXTURE_BINDING_BUFFER */
+ { 32106, 0x00008C2D }, /* GL_TEXTURE_BUFFER_DATA_STORE_BINDING */
+ { 32143, 0x00008C2E }, /* GL_TEXTURE_BUFFER_FORMAT */
+ { 32168, 0x00008C2F }, /* GL_ANY_SAMPLES_PASSED */
+ { 32190, 0x00008C36 }, /* GL_SAMPLE_SHADING */
+ { 32208, 0x00008C37 }, /* GL_MIN_SAMPLE_SHADING_VALUE */
+ { 32236, 0x00008C3A }, /* GL_R11F_G11F_B10F */
+ { 32254, 0x00008C3B }, /* GL_UNSIGNED_INT_10F_11F_11F_REV */
+ { 32286, 0x00008C3C }, /* GL_RGBA_SIGNED_COMPONENTS_EXT */
+ { 32316, 0x00008C3D }, /* GL_RGB9_E5 */
+ { 32327, 0x00008C3E }, /* GL_UNSIGNED_INT_5_9_9_9_REV */
+ { 32355, 0x00008C3F }, /* GL_TEXTURE_SHARED_SIZE */
+ { 32378, 0x00008C40 }, /* GL_SRGB */
+ { 32386, 0x00008C41 }, /* GL_SRGB8 */
+ { 32395, 0x00008C42 }, /* GL_SRGB_ALPHA */
+ { 32409, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
+ { 32425, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
+ { 32445, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
+ { 32467, 0x00008C46 }, /* GL_SLUMINANCE */
+ { 32481, 0x00008C47 }, /* GL_SLUMINANCE8 */
+ { 32496, 0x00008C48 }, /* GL_COMPRESSED_SRGB */
+ { 32515, 0x00008C49 }, /* GL_COMPRESSED_SRGB_ALPHA */
+ { 32540, 0x00008C4A }, /* GL_COMPRESSED_SLUMINANCE */
+ { 32565, 0x00008C4B }, /* GL_COMPRESSED_SLUMINANCE_ALPHA */
+ { 32596, 0x00008C76 }, /* GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH */
+ { 32637, 0x00008C7F }, /* GL_TRANSFORM_FEEDBACK_BUFFER_MODE */
+ { 32671, 0x00008C80 }, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS */
+ { 32717, 0x00008C83 }, /* GL_TRANSFORM_FEEDBACK_VARYINGS */
+ { 32748, 0x00008C84 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_START */
+ { 32783, 0x00008C85 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_SIZE */
+ { 32817, 0x00008C87 }, /* GL_PRIMITIVES_GENERATED */
+ { 32841, 0x00008C88 }, /* GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN */
+ { 32882, 0x00008C89 }, /* GL_RASTERIZER_DISCARD */
+ { 32904, 0x00008C8A }, /* GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS */
+ { 32953, 0x00008C8B }, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS */
+ { 32996, 0x00008C8C }, /* GL_INTERLEAVED_ATTRIBS */
+ { 33019, 0x00008C8D }, /* GL_SEPARATE_ATTRIBS */
+ { 33039, 0x00008C8E }, /* GL_TRANSFORM_FEEDBACK_BUFFER */
+ { 33068, 0x00008C8F }, /* GL_TRANSFORM_FEEDBACK_BUFFER_BINDING */
+ { 33105, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
+ { 33134, 0x00008CA1 }, /* GL_LOWER_LEFT */
+ { 33148, 0x00008CA2 }, /* GL_UPPER_LEFT */
+ { 33162, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
+ { 33182, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
+ { 33209, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
+ { 33235, 0x00008CA6 }, /* GL_DRAW_FRAMEBUFFER_BINDING */
+ { 33263, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING */
+ { 33287, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
+ { 33307, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER */
+ { 33327, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING */
+ { 33355, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
+ { 33379, 0x00008CAC }, /* GL_DEPTH_COMPONENT32F */
+ { 33401, 0x00008CAD }, /* GL_DEPTH32F_STENCIL8 */
+ { 33422, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+ { 33460, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+ { 33498, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+ { 33538, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+ { 33586, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+ { 33626, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
+ { 33650, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+ { 33687, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+ { 33732, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+ { 33783, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+ { 33824, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+ { 33862, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+ { 33900, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+ { 33938, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
+ { 33965, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+ { 33997, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS */
+ { 34022, 0x00008CE0 }, /* GL_COLOR_ATTACHMENT0 */
+ { 34043, 0x00008CE1 }, /* GL_COLOR_ATTACHMENT1 */
+ { 34064, 0x00008CE2 }, /* GL_COLOR_ATTACHMENT2 */
+ { 34085, 0x00008CE3 }, /* GL_COLOR_ATTACHMENT3 */
+ { 34106, 0x00008CE4 }, /* GL_COLOR_ATTACHMENT4 */
+ { 34127, 0x00008CE5 }, /* GL_COLOR_ATTACHMENT5 */
+ { 34148, 0x00008CE6 }, /* GL_COLOR_ATTACHMENT6 */
+ { 34169, 0x00008CE7 }, /* GL_COLOR_ATTACHMENT7 */
+ { 34190, 0x00008CE8 }, /* GL_COLOR_ATTACHMENT8 */
+ { 34211, 0x00008CE9 }, /* GL_COLOR_ATTACHMENT9 */
+ { 34232, 0x00008CEA }, /* GL_COLOR_ATTACHMENT10 */
+ { 34254, 0x00008CEB }, /* GL_COLOR_ATTACHMENT11 */
+ { 34276, 0x00008CEC }, /* GL_COLOR_ATTACHMENT12 */
+ { 34298, 0x00008CED }, /* GL_COLOR_ATTACHMENT13 */
+ { 34320, 0x00008CEE }, /* GL_COLOR_ATTACHMENT14 */
+ { 34342, 0x00008CEF }, /* GL_COLOR_ATTACHMENT15 */
+ { 34364, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT */
+ { 34384, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
+ { 34406, 0x00008D40 }, /* GL_FRAMEBUFFER */
+ { 34421, 0x00008D41 }, /* GL_RENDERBUFFER */
+ { 34437, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
+ { 34459, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
+ { 34482, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
+ { 34514, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
+ { 34535, 0x00008D46 }, /* GL_STENCIL_INDEX1 */
+ { 34553, 0x00008D47 }, /* GL_STENCIL_INDEX4 */
+ { 34571, 0x00008D48 }, /* GL_STENCIL_INDEX8 */
+ { 34589, 0x00008D49 }, /* GL_STENCIL_INDEX16 */
+ { 34608, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
+ { 34633, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
+ { 34660, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
+ { 34686, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
+ { 34713, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
+ { 34740, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
+ { 34769, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+ { 34807, 0x00008D57 }, /* GL_MAX_SAMPLES */
+ { 34822, 0x00008D60 }, /* GL_TEXTURE_GEN_STR_OES */
+ { 34845, 0x00008D61 }, /* GL_HALF_FLOAT_OES */
+ { 34863, 0x00008D62 }, /* GL_RGB565 */
+ { 34873, 0x00008D64 }, /* GL_ETC1_RGB8_OES */
+ { 34890, 0x00008D65 }, /* GL_TEXTURE_EXTERNAL_OES */
+ { 34914, 0x00008D66 }, /* GL_SAMPLER_EXTERNAL_OES */
+ { 34938, 0x00008D67 }, /* GL_TEXTURE_BINDING_EXTERNAL_OES */
+ { 34970, 0x00008D68 }, /* GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES */
+ { 35006, 0x00008D69 }, /* GL_PRIMITIVE_RESTART_FIXED_INDEX */
+ { 35039, 0x00008D6A }, /* GL_ANY_SAMPLES_PASSED_CONSERVATIVE */
+ { 35074, 0x00008D6B }, /* GL_MAX_ELEMENT_INDEX */
+ { 35095, 0x00008D70 }, /* GL_RGBA32UI */
+ { 35107, 0x00008D71 }, /* GL_RGB32UI */
+ { 35118, 0x00008D72 }, /* GL_ALPHA32UI_EXT */
+ { 35135, 0x00008D73 }, /* GL_INTENSITY32UI_EXT */
+ { 35156, 0x00008D74 }, /* GL_LUMINANCE32UI_EXT */
+ { 35177, 0x00008D75 }, /* GL_LUMINANCE_ALPHA32UI_EXT */
+ { 35204, 0x00008D76 }, /* GL_RGBA16UI */
+ { 35216, 0x00008D77 }, /* GL_RGB16UI */
+ { 35227, 0x00008D78 }, /* GL_ALPHA16UI_EXT */
+ { 35244, 0x00008D79 }, /* GL_INTENSITY16UI_EXT */
+ { 35265, 0x00008D7A }, /* GL_LUMINANCE16UI_EXT */
+ { 35286, 0x00008D7B }, /* GL_LUMINANCE_ALPHA16UI_EXT */
+ { 35313, 0x00008D7C }, /* GL_RGBA8UI */
+ { 35324, 0x00008D7D }, /* GL_RGB8UI */
+ { 35334, 0x00008D7E }, /* GL_ALPHA8UI_EXT */
+ { 35350, 0x00008D7F }, /* GL_INTENSITY8UI_EXT */
+ { 35370, 0x00008D80 }, /* GL_LUMINANCE8UI_EXT */
+ { 35390, 0x00008D81 }, /* GL_LUMINANCE_ALPHA8UI_EXT */
+ { 35416, 0x00008D82 }, /* GL_RGBA32I */
+ { 35427, 0x00008D83 }, /* GL_RGB32I */
+ { 35437, 0x00008D84 }, /* GL_ALPHA32I_EXT */
+ { 35453, 0x00008D85 }, /* GL_INTENSITY32I_EXT */
+ { 35473, 0x00008D86 }, /* GL_LUMINANCE32I_EXT */
+ { 35493, 0x00008D87 }, /* GL_LUMINANCE_ALPHA32I_EXT */
+ { 35519, 0x00008D88 }, /* GL_RGBA16I */
+ { 35530, 0x00008D89 }, /* GL_RGB16I */
+ { 35540, 0x00008D8A }, /* GL_ALPHA16I_EXT */
+ { 35556, 0x00008D8B }, /* GL_INTENSITY16I_EXT */
+ { 35576, 0x00008D8C }, /* GL_LUMINANCE16I_EXT */
+ { 35596, 0x00008D8D }, /* GL_LUMINANCE_ALPHA16I_EXT */
+ { 35622, 0x00008D8E }, /* GL_RGBA8I */
+ { 35632, 0x00008D8F }, /* GL_RGB8I */
+ { 35641, 0x00008D90 }, /* GL_ALPHA8I_EXT */
+ { 35656, 0x00008D91 }, /* GL_INTENSITY8I_EXT */
+ { 35675, 0x00008D92 }, /* GL_LUMINANCE8I_EXT */
+ { 35694, 0x00008D93 }, /* GL_LUMINANCE_ALPHA8I_EXT */
+ { 35719, 0x00008D94 }, /* GL_RED_INTEGER */
+ { 35734, 0x00008D95 }, /* GL_GREEN_INTEGER */
+ { 35751, 0x00008D96 }, /* GL_BLUE_INTEGER */
+ { 35767, 0x00008D97 }, /* GL_ALPHA_INTEGER_EXT */
+ { 35788, 0x00008D98 }, /* GL_RGB_INTEGER */
+ { 35803, 0x00008D99 }, /* GL_RGBA_INTEGER */
+ { 35819, 0x00008D9A }, /* GL_BGR_INTEGER */
+ { 35834, 0x00008D9B }, /* GL_BGRA_INTEGER */
+ { 35850, 0x00008D9C }, /* GL_LUMINANCE_INTEGER_EXT */
+ { 35875, 0x00008D9D }, /* GL_LUMINANCE_ALPHA_INTEGER_EXT */
+ { 35906, 0x00008D9E }, /* GL_RGBA_INTEGER_MODE_EXT */
+ { 35931, 0x00008D9F }, /* GL_INT_2_10_10_10_REV */
+ { 35953, 0x00008DA7 }, /* GL_FRAMEBUFFER_ATTACHMENT_LAYERED */
+ { 35987, 0x00008DA8 }, /* GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS */
+ { 36027, 0x00008DA9 }, /* GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB */
+ { 36069, 0x00008DAD }, /* GL_FLOAT_32_UNSIGNED_INT_24_8_REV */
+ { 36103, 0x00008DB9 }, /* GL_FRAMEBUFFER_SRGB */
+ { 36123, 0x00008DBA }, /* GL_FRAMEBUFFER_SRGB_CAPABLE_EXT */
+ { 36155, 0x00008DBB }, /* GL_COMPRESSED_RED_RGTC1 */
+ { 36179, 0x00008DBC }, /* GL_COMPRESSED_SIGNED_RED_RGTC1 */
+ { 36210, 0x00008DBD }, /* GL_COMPRESSED_RG_RGTC2 */
+ { 36233, 0x00008DBE }, /* GL_COMPRESSED_SIGNED_RG_RGTC2 */
+ { 36263, 0x00008DC0 }, /* GL_SAMPLER_1D_ARRAY */
+ { 36283, 0x00008DC1 }, /* GL_SAMPLER_2D_ARRAY */
+ { 36303, 0x00008DC2 }, /* GL_SAMPLER_BUFFER */
+ { 36321, 0x00008DC3 }, /* GL_SAMPLER_1D_ARRAY_SHADOW */
+ { 36348, 0x00008DC4 }, /* GL_SAMPLER_2D_ARRAY_SHADOW */
+ { 36375, 0x00008DC5 }, /* GL_SAMPLER_CUBE_SHADOW */
+ { 36398, 0x00008DC6 }, /* GL_UNSIGNED_INT_VEC2 */
+ { 36419, 0x00008DC7 }, /* GL_UNSIGNED_INT_VEC3 */
+ { 36440, 0x00008DC8 }, /* GL_UNSIGNED_INT_VEC4 */
+ { 36461, 0x00008DC9 }, /* GL_INT_SAMPLER_1D */
+ { 36479, 0x00008DCA }, /* GL_INT_SAMPLER_2D */
+ { 36497, 0x00008DCB }, /* GL_INT_SAMPLER_3D */
+ { 36515, 0x00008DCC }, /* GL_INT_SAMPLER_CUBE */
+ { 36535, 0x00008DCD }, /* GL_INT_SAMPLER_2D_RECT */
+ { 36558, 0x00008DCE }, /* GL_INT_SAMPLER_1D_ARRAY */
+ { 36582, 0x00008DCF }, /* GL_INT_SAMPLER_2D_ARRAY */
+ { 36606, 0x00008DD0 }, /* GL_INT_SAMPLER_BUFFER */
+ { 36628, 0x00008DD1 }, /* GL_UNSIGNED_INT_SAMPLER_1D */
+ { 36655, 0x00008DD2 }, /* GL_UNSIGNED_INT_SAMPLER_2D */
+ { 36682, 0x00008DD3 }, /* GL_UNSIGNED_INT_SAMPLER_3D */
+ { 36709, 0x00008DD4 }, /* GL_UNSIGNED_INT_SAMPLER_CUBE */
+ { 36738, 0x00008DD5 }, /* GL_UNSIGNED_INT_SAMPLER_2D_RECT */
+ { 36770, 0x00008DD6 }, /* GL_UNSIGNED_INT_SAMPLER_1D_ARRAY */
+ { 36803, 0x00008DD7 }, /* GL_UNSIGNED_INT_SAMPLER_2D_ARRAY */
+ { 36836, 0x00008DD8 }, /* GL_UNSIGNED_INT_SAMPLER_BUFFER */
+ { 36867, 0x00008DD9 }, /* GL_GEOMETRY_SHADER */
+ { 36886, 0x00008DDA }, /* GL_GEOMETRY_VERTICES_OUT_ARB */
+ { 36915, 0x00008DDB }, /* GL_GEOMETRY_INPUT_TYPE_ARB */
+ { 36942, 0x00008DDC }, /* GL_GEOMETRY_OUTPUT_TYPE_ARB */
+ { 36970, 0x00008DDD }, /* GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB */
+ { 37009, 0x00008DDE }, /* GL_MAX_VERTEX_VARYING_COMPONENTS_ARB */
+ { 37046, 0x00008DDF }, /* GL_MAX_GEOMETRY_UNIFORM_COMPONENTS */
+ { 37081, 0x00008DE0 }, /* GL_MAX_GEOMETRY_OUTPUT_VERTICES */
+ { 37113, 0x00008DE1 }, /* GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS */
+ { 37153, 0x00008DF0 }, /* GL_LOW_FLOAT */
+ { 37166, 0x00008DF1 }, /* GL_MEDIUM_FLOAT */
+ { 37182, 0x00008DF2 }, /* GL_HIGH_FLOAT */
+ { 37196, 0x00008DF3 }, /* GL_LOW_INT */
+ { 37207, 0x00008DF4 }, /* GL_MEDIUM_INT */
+ { 37221, 0x00008DF5 }, /* GL_HIGH_INT */
+ { 37233, 0x00008DF6 }, /* GL_UNSIGNED_INT_10_10_10_2_OES */
+ { 37264, 0x00008DF7 }, /* GL_INT_10_10_10_2_OES */
+ { 37286, 0x00008DF8 }, /* GL_SHADER_BINARY_FORMATS */
+ { 37311, 0x00008DF9 }, /* GL_NUM_SHADER_BINARY_FORMATS */
+ { 37340, 0x00008DFA }, /* GL_SHADER_COMPILER */
+ { 37359, 0x00008DFB }, /* GL_MAX_VERTEX_UNIFORM_VECTORS */
+ { 37389, 0x00008DFC }, /* GL_MAX_VARYING_VECTORS */
+ { 37412, 0x00008DFD }, /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */
+ { 37444, 0x00008E13 }, /* GL_QUERY_WAIT */
+ { 37458, 0x00008E14 }, /* GL_QUERY_NO_WAIT */
+ { 37475, 0x00008E15 }, /* GL_QUERY_BY_REGION_WAIT */
+ { 37499, 0x00008E16 }, /* GL_QUERY_BY_REGION_NO_WAIT */
+ { 37526, 0x00008E22 }, /* GL_TRANSFORM_FEEDBACK */
+ { 37548, 0x00008E23 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */
+ { 37584, 0x00008E24 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */
+ { 37620, 0x00008E25 }, /* GL_TRANSFORM_FEEDBACK_BINDING */
+ { 37650, 0x00008E28 }, /* GL_TIMESTAMP */
+ { 37663, 0x00008E42 }, /* GL_TEXTURE_SWIZZLE_R */
+ { 37684, 0x00008E43 }, /* GL_TEXTURE_SWIZZLE_G */
+ { 37705, 0x00008E44 }, /* GL_TEXTURE_SWIZZLE_B */
+ { 37726, 0x00008E45 }, /* GL_TEXTURE_SWIZZLE_A */
+ { 37747, 0x00008E46 }, /* GL_TEXTURE_SWIZZLE_RGBA */
+ { 37771, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+ { 37815, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION */
+ { 37842, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */
+ { 37868, 0x00008E4F }, /* GL_PROVOKING_VERTEX */
+ { 37888, 0x00008E50 }, /* GL_SAMPLE_POSITION */
+ { 37907, 0x00008E51 }, /* GL_SAMPLE_MASK */
+ { 37922, 0x00008E52 }, /* GL_SAMPLE_MASK_VALUE */
+ { 37943, 0x00008E59 }, /* GL_MAX_SAMPLE_MASK_WORDS */
+ { 37968, 0x00008E5A }, /* GL_MAX_GEOMETRY_SHADER_INVOCATIONS */
+ { 38003, 0x00008E5B }, /* GL_MIN_FRAGMENT_INTERPOLATION_OFFSET */
+ { 38040, 0x00008E5C }, /* GL_MAX_FRAGMENT_INTERPOLATION_OFFSET */
+ { 38077, 0x00008E5D }, /* GL_FRAGMENT_INTERPOLATION_OFFSET_BITS */
+ { 38115, 0x00008E5E }, /* GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET */
+ { 38152, 0x00008E5F }, /* GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET */
+ { 38189, 0x00008E70 }, /* GL_MAX_TRANSFORM_FEEDBACK_BUFFERS */
+ { 38223, 0x00008E71 }, /* GL_MAX_VERTEX_STREAMS */
+ { 38245, 0x00008F36 }, /* GL_COPY_READ_BUFFER */
+ { 38265, 0x00008F37 }, /* GL_COPY_WRITE_BUFFER */
+ { 38286, 0x00008F38 }, /* GL_MAX_IMAGE_UNITS */
+ { 38305, 0x00008F39 }, /* GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */
+ { 38354, 0x00008F3A }, /* GL_IMAGE_BINDING_NAME */
+ { 38376, 0x00008F3B }, /* GL_IMAGE_BINDING_LEVEL */
+ { 38399, 0x00008F3C }, /* GL_IMAGE_BINDING_LAYERED */
+ { 38424, 0x00008F3D }, /* GL_IMAGE_BINDING_LAYER */
+ { 38447, 0x00008F3E }, /* GL_IMAGE_BINDING_ACCESS */
+ { 38471, 0x00008F3F }, /* GL_DRAW_INDIRECT_BUFFER */
+ { 38495, 0x00008F43 }, /* GL_DRAW_INDIRECT_BUFFER_BINDING */
+ { 38527, 0x00008F90 }, /* GL_RED_SNORM */
+ { 38540, 0x00008F91 }, /* GL_RG_SNORM */
+ { 38552, 0x00008F92 }, /* GL_RGB_SNORM */
+ { 38565, 0x00008F93 }, /* GL_RGBA_SNORM */
+ { 38579, 0x00008F94 }, /* GL_R8_SNORM */
+ { 38591, 0x00008F95 }, /* GL_RG8_SNORM */
+ { 38604, 0x00008F96 }, /* GL_RGB8_SNORM */
+ { 38618, 0x00008F97 }, /* GL_RGBA8_SNORM */
+ { 38633, 0x00008F98 }, /* GL_R16_SNORM */
+ { 38646, 0x00008F99 }, /* GL_RG16_SNORM */
+ { 38660, 0x00008F9A }, /* GL_RGB16_SNORM */
+ { 38675, 0x00008F9B }, /* GL_RGBA16_SNORM */
+ { 38691, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
+ { 38712, 0x00008F9D }, /* GL_PRIMITIVE_RESTART */
+ { 38733, 0x00008F9E }, /* GL_PRIMITIVE_RESTART_INDEX */
+ { 38760, 0x00008F9F }, /* GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB */
+ { 38805, 0x00009009 }, /* GL_TEXTURE_CUBE_MAP_ARRAY_ARB */
+ { 38835, 0x0000900A }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB */
+ { 38873, 0x0000900B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB */
+ { 38909, 0x0000900C }, /* GL_SAMPLER_CUBE_MAP_ARRAY_ARB */
+ { 38939, 0x0000900D }, /* GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB */
+ { 38976, 0x0000900E }, /* GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB */
+ { 39010, 0x0000900F }, /* GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB */
+ { 39053, 0x0000904C }, /* GL_IMAGE_1D */
+ { 39065, 0x0000904D }, /* GL_IMAGE_2D */
+ { 39077, 0x0000904E }, /* GL_IMAGE_3D */
+ { 39089, 0x0000904F }, /* GL_IMAGE_2D_RECT */
+ { 39106, 0x00009050 }, /* GL_IMAGE_CUBE */
+ { 39120, 0x00009051 }, /* GL_IMAGE_BUFFER */
+ { 39136, 0x00009052 }, /* GL_IMAGE_1D_ARRAY */
+ { 39154, 0x00009053 }, /* GL_IMAGE_2D_ARRAY */
+ { 39172, 0x00009054 }, /* GL_IMAGE_CUBE_MAP_ARRAY */
+ { 39196, 0x00009055 }, /* GL_IMAGE_2D_MULTISAMPLE */
+ { 39220, 0x00009056 }, /* GL_IMAGE_2D_MULTISAMPLE_ARRAY */
+ { 39250, 0x00009057 }, /* GL_INT_IMAGE_1D */
+ { 39266, 0x00009058 }, /* GL_INT_IMAGE_2D */
+ { 39282, 0x00009059 }, /* GL_INT_IMAGE_3D */
+ { 39298, 0x0000905A }, /* GL_INT_IMAGE_2D_RECT */
+ { 39319, 0x0000905B }, /* GL_INT_IMAGE_CUBE */
+ { 39337, 0x0000905C }, /* GL_INT_IMAGE_BUFFER */
+ { 39357, 0x0000905D }, /* GL_INT_IMAGE_1D_ARRAY */
+ { 39379, 0x0000905E }, /* GL_INT_IMAGE_2D_ARRAY */
+ { 39401, 0x0000905F }, /* GL_INT_IMAGE_CUBE_MAP_ARRAY */
+ { 39429, 0x00009060 }, /* GL_INT_IMAGE_2D_MULTISAMPLE */
+ { 39457, 0x00009061 }, /* GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY */
+ { 39491, 0x00009062 }, /* GL_UNSIGNED_INT_IMAGE_1D */
+ { 39516, 0x00009063 }, /* GL_UNSIGNED_INT_IMAGE_2D */
+ { 39541, 0x00009064 }, /* GL_UNSIGNED_INT_IMAGE_3D */
+ { 39566, 0x00009065 }, /* GL_UNSIGNED_INT_IMAGE_2D_RECT */
+ { 39596, 0x00009066 }, /* GL_UNSIGNED_INT_IMAGE_CUBE */
+ { 39623, 0x00009067 }, /* GL_UNSIGNED_INT_IMAGE_BUFFER */
+ { 39652, 0x00009068 }, /* GL_UNSIGNED_INT_IMAGE_1D_ARRAY */
+ { 39683, 0x00009069 }, /* GL_UNSIGNED_INT_IMAGE_2D_ARRAY */
+ { 39714, 0x0000906A }, /* GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY */
+ { 39751, 0x0000906B }, /* GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE */
+ { 39788, 0x0000906C }, /* GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY */
+ { 39831, 0x0000906D }, /* GL_MAX_IMAGE_SAMPLES */
+ { 39852, 0x0000906E }, /* GL_IMAGE_BINDING_FORMAT */
+ { 39876, 0x0000906F }, /* GL_RGB10_A2UI */
+ { 39890, 0x000090BC }, /* GL_MIN_MAP_BUFFER_ALIGNMENT */
+ { 39918, 0x000090C7 }, /* GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */
+ { 39953, 0x000090C8 }, /* GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE */
+ { 39991, 0x000090C9 }, /* GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS */
+ { 40030, 0x000090CA }, /* GL_MAX_VERTEX_IMAGE_UNIFORMS */
+ { 40059, 0x000090CB }, /* GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS */
+ { 40094, 0x000090CC }, /* GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS */
+ { 40132, 0x000090CD }, /* GL_MAX_GEOMETRY_IMAGE_UNIFORMS */
+ { 40163, 0x000090CE }, /* GL_MAX_FRAGMENT_IMAGE_UNIFORMS */
+ { 40194, 0x000090CF }, /* GL_MAX_COMBINED_IMAGE_UNIFORMS */
+ { 40225, 0x000090EA }, /* GL_DEPTH_STENCIL_TEXTURE_MODE */
+ { 40255, 0x000090EB }, /* GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS */
+ { 40293, 0x000090EC }, /* GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER */
+ { 40339, 0x000090ED }, /* GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER */
+ { 40393, 0x000090EE }, /* GL_DISPATCH_INDIRECT_BUFFER */
+ { 40421, 0x000090EF }, /* GL_DISPATCH_INDIRECT_BUFFER_BINDING */
+ { 40457, 0x00009100 }, /* GL_TEXTURE_2D_MULTISAMPLE */
+ { 40483, 0x00009101 }, /* GL_PROXY_TEXTURE_2D_MULTISAMPLE */
+ { 40515, 0x00009102 }, /* GL_TEXTURE_2D_MULTISAMPLE_ARRAY */
+ { 40547, 0x00009103 }, /* GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */
+ { 40585, 0x00009104 }, /* GL_TEXTURE_BINDING_2D_MULTISAMPLE */
+ { 40619, 0x00009105 }, /* GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */
+ { 40659, 0x00009106 }, /* GL_TEXTURE_SAMPLES */
+ { 40678, 0x00009107 }, /* GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */
+ { 40712, 0x00009108 }, /* GL_SAMPLER_2D_MULTISAMPLE */
+ { 40738, 0x00009109 }, /* GL_INT_SAMPLER_2D_MULTISAMPLE */
+ { 40768, 0x0000910A }, /* GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */
+ { 40807, 0x0000910B }, /* GL_SAMPLER_2D_MULTISAMPLE_ARRAY */
+ { 40839, 0x0000910C }, /* GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+ { 40875, 0x0000910D }, /* GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+ { 40920, 0x0000910E }, /* GL_MAX_COLOR_TEXTURE_SAMPLES */
+ { 40949, 0x0000910F }, /* GL_MAX_DEPTH_TEXTURE_SAMPLES */
+ { 40978, 0x00009110 }, /* GL_MAX_INTEGER_SAMPLES */
+ { 41001, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */
+ { 41028, 0x00009112 }, /* GL_OBJECT_TYPE */
+ { 41043, 0x00009113 }, /* GL_SYNC_CONDITION */
+ { 41061, 0x00009114 }, /* GL_SYNC_STATUS */
+ { 41076, 0x00009115 }, /* GL_SYNC_FLAGS */
+ { 41090, 0x00009116 }, /* GL_SYNC_FENCE */
+ { 41104, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
+ { 41134, 0x00009118 }, /* GL_UNSIGNALED */
+ { 41148, 0x00009119 }, /* GL_SIGNALED */
+ { 41160, 0x0000911A }, /* GL_ALREADY_SIGNALED */
+ { 41180, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
+ { 41199, 0x0000911C }, /* GL_CONDITION_SATISFIED */
+ { 41222, 0x0000911D }, /* GL_WAIT_FAILED */
+ { 41237, 0x0000911F }, /* GL_BUFFER_ACCESS_FLAGS */
+ { 41260, 0x00009120 }, /* GL_BUFFER_MAP_LENGTH */
+ { 41281, 0x00009121 }, /* GL_BUFFER_MAP_OFFSET */
+ { 41302, 0x00009122 }, /* GL_MAX_VERTEX_OUTPUT_COMPONENTS */
+ { 41334, 0x00009123 }, /* GL_MAX_GEOMETRY_INPUT_COMPONENTS */
+ { 41367, 0x00009124 }, /* GL_MAX_GEOMETRY_OUTPUT_COMPONENTS */
+ { 41401, 0x00009125 }, /* GL_MAX_FRAGMENT_INPUT_COMPONENTS */
+ { 41434, 0x00009126 }, /* GL_CONTEXT_PROFILE_MASK */
+ { 41458, 0x0000912F }, /* GL_TEXTURE_IMMUTABLE_FORMAT */
+ { 41486, 0x00009143 }, /* GL_MAX_DEBUG_MESSAGE_LENGTH_ARB */
+ { 41518, 0x00009144 }, /* GL_MAX_DEBUG_LOGGED_MESSAGES_ARB */
+ { 41551, 0x00009145 }, /* GL_DEBUG_LOGGED_MESSAGES_ARB */
+ { 41580, 0x00009146 }, /* GL_DEBUG_SEVERITY_HIGH_ARB */
+ { 41607, 0x00009147 }, /* GL_DEBUG_SEVERITY_MEDIUM_ARB */
+ { 41636, 0x00009148 }, /* GL_DEBUG_SEVERITY_LOW_ARB */
+ { 41662, 0x0000919D }, /* GL_TEXTURE_BUFFER_OFFSET */
+ { 41687, 0x0000919E }, /* GL_TEXTURE_BUFFER_SIZE */
+ { 41710, 0x0000919F }, /* GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT */
+ { 41745, 0x000091B9 }, /* GL_COMPUTE_SHADER */
+ { 41763, 0x000091BB }, /* GL_MAX_COMPUTE_UNIFORM_BLOCKS */
+ { 41793, 0x000091BC }, /* GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS */
+ { 41828, 0x000091BD }, /* GL_MAX_COMPUTE_IMAGE_UNIFORMS */
+ { 41858, 0x000091BE }, /* GL_MAX_COMPUTE_WORK_GROUP_COUNT */
+ { 41890, 0x000091BF }, /* GL_MAX_COMPUTE_WORK_GROUP_SIZE */
+ { 41921, 0x00009270 }, /* GL_COMPRESSED_R11_EAC */
+ { 41943, 0x00009271 }, /* GL_COMPRESSED_SIGNED_R11_EAC */
+ { 41972, 0x00009272 }, /* GL_COMPRESSED_RG11_EAC */
+ { 41995, 0x00009273 }, /* GL_COMPRESSED_SIGNED_RG11_EAC */
+ { 42025, 0x00009274 }, /* GL_COMPRESSED_RGB8_ETC2 */
+ { 42049, 0x00009275 }, /* GL_COMPRESSED_SRGB8_ETC2 */
+ { 42074, 0x00009276 }, /* GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 */
+ { 42118, 0x00009277 }, /* GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 */
+ { 42163, 0x00009278 }, /* GL_COMPRESSED_RGBA8_ETC2_EAC */
+ { 42192, 0x00009279 }, /* GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC */
+ { 42228, 0x000092C0 }, /* GL_ATOMIC_COUNTER_BUFFER */
+ { 42253, 0x000092C1 }, /* GL_ATOMIC_COUNTER_BUFFER_BINDING */
+ { 42286, 0x000092C2 }, /* GL_ATOMIC_COUNTER_BUFFER_START */
+ { 42317, 0x000092C3 }, /* GL_ATOMIC_COUNTER_BUFFER_SIZE */
+ { 42347, 0x000092C4 }, /* GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE */
+ { 42382, 0x000092C5 }, /* GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS */
+ { 42430, 0x000092C6 }, /* GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES */
+ { 42485, 0x000092C7 }, /* GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER */
+ { 42538, 0x000092C8 }, /* GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER */
+ { 42597, 0x000092C9 }, /* GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER */
+ { 42659, 0x000092CA }, /* GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER */
+ { 42714, 0x000092CB }, /* GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER */
+ { 42769, 0x000092CC }, /* GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS */
+ { 42806, 0x000092CD }, /* GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS */
+ { 42849, 0x000092CE }, /* GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS */
+ { 42895, 0x000092CF }, /* GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS */
+ { 42934, 0x000092D0 }, /* GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS */
+ { 42973, 0x000092D1 }, /* GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS */
+ { 43012, 0x000092D2 }, /* GL_MAX_VERTEX_ATOMIC_COUNTERS */
+ { 43042, 0x000092D3 }, /* GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS */
+ { 43078, 0x000092D4 }, /* GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS */
+ { 43117, 0x000092D5 }, /* GL_MAX_GEOMETRY_ATOMIC_COUNTERS */
+ { 43149, 0x000092D6 }, /* GL_MAX_FRAGMENT_ATOMIC_COUNTERS */
+ { 43181, 0x000092D7 }, /* GL_MAX_COMBINED_ATOMIC_COUNTERS */
+ { 43213, 0x000092D8 }, /* GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE */
+ { 43247, 0x000092D9 }, /* GL_ACTIVE_ATOMIC_COUNTER_BUFFERS */
+ { 43280, 0x000092DA }, /* GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX */
+ { 43319, 0x000092DB }, /* GL_UNSIGNED_INT_ATOMIC_COUNTER */
+ { 43350, 0x000092DC }, /* GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS */
+ { 43388, 0x000092E0 }, /* GL_DEBUG_OUTPUT */
+ { 43404, 0x00009380 }, /* GL_NUM_SAMPLE_COUNTS */
+ { 43425, 0x000094F0 }, /* GL_PERFQUERY_COUNTER_EVENT_INTEL */
+ { 43458, 0x000094F1 }, /* GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL */
+ { 43499, 0x000094F2 }, /* GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL */
+ { 43539, 0x000094F3 }, /* GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL */
+ { 43577, 0x000094F4 }, /* GL_PERFQUERY_COUNTER_RAW_INTEL */
+ { 43608, 0x000094F5 }, /* GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL */
+ { 43645, 0x000094F8 }, /* GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL */
+ { 43684, 0x000094F9 }, /* GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL */
+ { 43723, 0x000094FA }, /* GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL */
+ { 43761, 0x000094FB }, /* GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL */
+ { 43800, 0x000094FC }, /* GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL */
+ { 43839, 0x000094FD }, /* GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL */
+ { 43880, 0x000094FE }, /* GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL */
+ { 43923, 0x000094FF }, /* GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL */
+ { 43966, 0x00009500 }, /* GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL */
+ { 44007, 0x00010000 }, /* GL_EVAL_BIT */
+ { 44019, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+ { 44052, 0x00020000 }, /* GL_LIST_BIT */
+ { 44064, 0x00040000 }, /* GL_TEXTURE_BIT */
+ { 44079, 0x00080000 }, /* GL_SCISSOR_BIT */
+ { 44094, 0x000FFFFF }, /* GL_ALL_ATTRIB_BITS */
+ { 44113, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
+ { 44132, 0xFFFFFFFF }, /* GL_ALL_CLIENT_ATTRIB_BITS */
+};
+
+
+typedef int (*cfunc)(const void *, const void *);
+
+/**
+ * Compare a key enum value to an element in the \c enum_string_table_offsets array.
+ *
+ * \c bsearch always passes the key as the first parameter and the pointer
+ * to the array element as the second parameter. We can elimiate some
+ * extra work by taking advantage of that fact.
+ *
+ * \param a Pointer to the desired enum name.
+ * \param b Pointer into the \c enum_string_table_offsets array.
+ */
+static int compar_nr( const int *a, enum_elt *b )
+{
+ return a[0] - b->n;
+}
+
+
+static char token_tmp[20];
+
+const char *_mesa_lookup_enum_by_nr( int nr )
+{
+ enum_elt *elt;
+
+ STATIC_ASSERT(sizeof(enum_string_table) < (1 << 16));
+
+ elt = _mesa_bsearch(& nr, enum_string_table_offsets,
+ Elements(enum_string_table_offsets),
+ sizeof(enum_string_table_offsets[0]),
+ (cfunc) compar_nr);
+
+ if (elt != NULL) {
+ return &enum_string_table[elt->offset];
+ }
+ else {
+ /* this is not re-entrant safe, no big deal here */
+ _mesa_snprintf(token_tmp, sizeof(token_tmp) - 1, "0x%x", nr);
+ token_tmp[sizeof(token_tmp) - 1] = '\0';
+ return token_tmp;
+ }
+}
+
+/**
+ * Primitive names
+ */
+static const char *prim_names[PRIM_MAX+3] = {
+ "GL_POINTS",
+ "GL_LINES",
+ "GL_LINE_LOOP",
+ "GL_LINE_STRIP",
+ "GL_TRIANGLES",
+ "GL_TRIANGLE_STRIP",
+ "GL_TRIANGLE_FAN",
+ "GL_QUADS",
+ "GL_QUAD_STRIP",
+ "GL_POLYGON",
+ "GL_LINES_ADJACENCY",
+ "GL_LINE_STRIP_ADJACENCY",
+ "GL_TRIANGLES_ADJACENCY",
+ "GL_TRIANGLE_STRIP_ADJACENCY",
+ "outside begin/end",
+ "unknown state"
+};
+
+
+/* Get the name of an enum given that it is a primitive type. Avoids
+ * GL_FALSE/GL_POINTS ambiguity and others.
+ */
+const char *
+_mesa_lookup_prim_by_nr(GLuint nr)
+{
+ if (nr < Elements(prim_names))
+ return prim_names[nr];
+ else
+ return "invalid mode";
+}
+
+
+
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/enums.h b/icd/intel/compiler/mesa-utils/src/mesa/main/enums.h
new file mode 100644
index 0000000..36c053d
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/enums.h
@@ -0,0 +1,47 @@
+/**
+ * \file enums.h
+ * Enumeration name/number lookup functions.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _ENUMS_H_
+#define _ENUMS_H_
+
+
+extern const char *_mesa_lookup_enum_by_nr( int nr );
+
+/* Get the name of an enum given that it is a primitive type. Avoids
+ * GL_FALSE/GL_POINTS ambiguity and others.
+ */
+const char *_mesa_lookup_prim_by_nr( unsigned nr );
+
+#endif
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/errors.c b/icd/intel/compiler/mesa-utils/src/mesa/main/errors.c
new file mode 100644
index 0000000..c75889b
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/errors.c
@@ -0,0 +1,1538 @@
+/**
+ * \file errors.c
+ * Mesa debugging and error handling functions.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "errors.h"
+#include "enums.h"
+#include "imports.h"
+#include "context.h"
+// #include "dispatch.h" // LunarG REM:
+#include "hash.h"
+#include "mtypes.h"
+#include "version.h"
+#include "hash_table.h"
+
+static mtx_t DynamicIDMutex = _MTX_INITIALIZER_NP;
+static GLuint NextDynamicID = 1;
+
+/**
+ * A namespace element.
+ */
+struct gl_debug_element
+{
+ struct simple_node link;
+
+ GLuint ID;
+ /* at which severity levels (mesa_debug_severity) is the message enabled */
+ GLbitfield State;
+};
+
+struct gl_debug_namespace
+{
+ struct simple_node Elements;
+ GLbitfield DefaultState;
+};
+
+struct gl_debug_group {
+ struct gl_debug_namespace Namespaces[MESA_DEBUG_SOURCE_COUNT][MESA_DEBUG_TYPE_COUNT];
+};
+
+/**
+ * An error, warning, or other piece of debug information for an application
+ * to consume via GL_ARB_debug_output/GL_KHR_debug.
+ */
+struct gl_debug_message
+{
+ enum mesa_debug_source source;
+ enum mesa_debug_type type;
+ GLuint id;
+ enum mesa_debug_severity severity;
+ GLsizei length;
+ GLcharARB *message;
+};
+
+/**
+ * Debug message log. It works like a ring buffer.
+ */
+struct gl_debug_log {
+ struct gl_debug_message Messages[MAX_DEBUG_LOGGED_MESSAGES];
+ GLint NextMessage;
+ GLint NumMessages;
+};
+
+struct gl_debug_state
+{
+ GLDEBUGPROC Callback;
+ const void *CallbackData;
+ GLboolean SyncOutput;
+ GLboolean DebugOutput;
+
+ struct gl_debug_group *Groups[MAX_DEBUG_GROUP_STACK_DEPTH];
+ struct gl_debug_message GroupMessages[MAX_DEBUG_GROUP_STACK_DEPTH];
+ GLint GroupStackDepth;
+
+ struct gl_debug_log Log;
+};
+
+static char out_of_memory[] = "Debugging error: out of memory";
+
+static const GLenum debug_source_enums[] = {
+ GL_DEBUG_SOURCE_API,
+ GL_DEBUG_SOURCE_WINDOW_SYSTEM,
+ GL_DEBUG_SOURCE_SHADER_COMPILER,
+ GL_DEBUG_SOURCE_THIRD_PARTY,
+ GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_SOURCE_OTHER,
+};
+
+static const GLenum debug_type_enums[] = {
+ GL_DEBUG_TYPE_ERROR,
+ GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR,
+ GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR,
+ GL_DEBUG_TYPE_PORTABILITY,
+ GL_DEBUG_TYPE_PERFORMANCE,
+ GL_DEBUG_TYPE_OTHER,
+ GL_DEBUG_TYPE_MARKER,
+ GL_DEBUG_TYPE_PUSH_GROUP,
+ GL_DEBUG_TYPE_POP_GROUP,
+};
+
+static const GLenum debug_severity_enums[] = {
+ GL_DEBUG_SEVERITY_LOW,
+ GL_DEBUG_SEVERITY_MEDIUM,
+ GL_DEBUG_SEVERITY_HIGH,
+ GL_DEBUG_SEVERITY_NOTIFICATION,
+};
+
+
+static enum mesa_debug_source
+gl_enum_to_debug_source(GLenum e)
+{
+ int i;
+
+ for (i = 0; i < Elements(debug_source_enums); i++) {
+ if (debug_source_enums[i] == e)
+ break;
+ }
+ return i;
+}
+
+static enum mesa_debug_type
+gl_enum_to_debug_type(GLenum e)
+{
+ int i;
+
+ for (i = 0; i < Elements(debug_type_enums); i++) {
+ if (debug_type_enums[i] == e)
+ break;
+ }
+ return i;
+}
+
+static enum mesa_debug_severity
+gl_enum_to_debug_severity(GLenum e)
+{
+ int i;
+
+ for (i = 0; i < Elements(debug_severity_enums); i++) {
+ if (debug_severity_enums[i] == e)
+ break;
+ }
+ return i;
+}
+
+
+/**
+ * Handles generating a GL_ARB_debug_output message ID generated by the GL or
+ * GLSL compiler.
+ *
+ * The GL API has this "ID" mechanism, where the intention is to allow a
+ * client to filter in/out messages based on source, type, and ID. Of course,
+ * building a giant enum list of all debug output messages that Mesa might
+ * generate is ridiculous, so instead we have our caller pass us a pointer to
+ * static storage where the ID should get stored. This ID will be shared
+ * across all contexts for that message (which seems like a desirable
+ * property, even if it's not expected by the spec), but note that it won't be
+ * the same between executions if messages aren't generated in the same order.
+ */
+static void
+debug_get_id(GLuint *id)
+{
+ if (!(*id)) {
+ mtx_lock(&DynamicIDMutex);
+ if (!(*id))
+ *id = NextDynamicID++;
+ mtx_unlock(&DynamicIDMutex);
+ }
+}
+
+static void
+debug_message_clear(struct gl_debug_message *msg)
+{
+ if (msg->message != (char*)out_of_memory)
+ free(msg->message);
+ msg->message = NULL;
+ msg->length = 0;
+}
+
+static void
+debug_message_store(struct gl_debug_message *msg,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type, GLuint id,
+ enum mesa_debug_severity severity,
+ GLsizei len, const char *buf)
+{
+ assert(!msg->message && !msg->length);
+
+ msg->message = malloc(len+1);
+ if (msg->message) {
+ (void) strncpy(msg->message, buf, (size_t)len);
+ msg->message[len] = '\0';
+
+ msg->length = len+1;
+ msg->source = source;
+ msg->type = type;
+ msg->id = id;
+ msg->severity = severity;
+ } else {
+ static GLuint oom_msg_id = 0;
+ debug_get_id(&oom_msg_id);
+
+ /* malloc failed! */
+ msg->message = out_of_memory;
+ msg->length = strlen(out_of_memory)+1;
+ msg->source = MESA_DEBUG_SOURCE_OTHER;
+ msg->type = MESA_DEBUG_TYPE_ERROR;
+ msg->id = oom_msg_id;
+ msg->severity = MESA_DEBUG_SEVERITY_HIGH;
+ }
+}
+
+static void
+debug_namespace_init(struct gl_debug_namespace *ns)
+{
+ make_empty_list(&ns->Elements);
+
+ /* Enable all the messages with severity HIGH or MEDIUM by default */
+ ns->DefaultState = (1 << MESA_DEBUG_SEVERITY_HIGH) |
+ (1 << MESA_DEBUG_SEVERITY_MEDIUM);
+}
+
+static void
+debug_namespace_clear(struct gl_debug_namespace *ns)
+{
+ struct simple_node *node, *tmp;
+
+ foreach_s(node, tmp, &ns->Elements)
+ free(node);
+}
+
+static bool
+debug_namespace_copy(struct gl_debug_namespace *dst,
+ const struct gl_debug_namespace *src)
+{
+ struct simple_node *node;
+
+ dst->DefaultState = src->DefaultState;
+
+ make_empty_list(&dst->Elements);
+ foreach(node, &src->Elements) {
+ const struct gl_debug_element *elem =
+ (const struct gl_debug_element *) node;
+ struct gl_debug_element *copy;
+
+ copy = malloc(sizeof(*copy));
+ if (!copy) {
+ debug_namespace_clear(dst);
+ return false;
+ }
+
+ copy->ID = elem->ID;
+ copy->State = elem->State;
+ insert_at_tail(&dst->Elements, ©->link);
+ }
+
+ return true;
+}
+
+/**
+ * Set the state of \p id in the namespace.
+ */
+static bool
+debug_namespace_set(struct gl_debug_namespace *ns,
+ GLuint id, bool enabled)
+{
+ const uint32_t state = (enabled) ?
+ ((1 << MESA_DEBUG_SEVERITY_COUNT) - 1) : 0;
+ struct gl_debug_element *elem = NULL;
+ struct simple_node *node;
+
+ /* find the element */
+ foreach(node, &ns->Elements) {
+ struct gl_debug_element *tmp = (struct gl_debug_element *) node;
+ if (tmp->ID == id) {
+ elem = tmp;
+ break;
+ }
+ }
+
+ /* we do not need the element if it has the default state */
+ if (ns->DefaultState == state) {
+ if (elem) {
+ remove_from_list(&elem->link);
+ free(elem);
+ }
+ return true;
+ }
+
+ if (!elem) {
+ elem = malloc(sizeof(*elem));
+ if (!elem)
+ return false;
+
+ elem->ID = id;
+ insert_at_tail(&ns->Elements, &elem->link);
+ }
+
+ elem->State = state;
+
+ return true;
+}
+
+/**
+ * Set the default state of the namespace for \p severity. When \p severity
+ * is MESA_DEBUG_SEVERITY_COUNT, the default values for all severities are
+ * updated.
+ */
+static void
+debug_namespace_set_all(struct gl_debug_namespace *ns,
+ enum mesa_debug_severity severity,
+ bool enabled)
+{
+ struct simple_node *node, *tmp;
+ uint32_t mask, val;
+
+ /* set all elements to the same state */
+ if (severity == MESA_DEBUG_SEVERITY_COUNT) {
+ ns->DefaultState = (enabled) ? ((1 << severity) - 1) : 0;
+ debug_namespace_clear(ns);
+ make_empty_list(&ns->Elements);
+ return;
+ }
+
+ mask = 1 << severity;
+ val = (enabled) ? mask : 0;
+
+ ns->DefaultState = (ns->DefaultState & ~mask) | val;
+
+ foreach_s(node, tmp, &ns->Elements) {
+ struct gl_debug_element *elem = (struct gl_debug_element *) node;
+
+ elem->State = (elem->State & ~mask) | val;
+ if (elem->State == ns->DefaultState) {
+ remove_from_list(node);
+ free(node);
+ }
+ }
+}
+
+/**
+ * Get the state of \p id in the namespace.
+ */
+static bool
+debug_namespace_get(const struct gl_debug_namespace *ns, GLuint id,
+ enum mesa_debug_severity severity)
+{
+ struct simple_node *node;
+ uint32_t state;
+
+ state = ns->DefaultState;
+ foreach(node, &ns->Elements) {
+ struct gl_debug_element *elem = (struct gl_debug_element *) node;
+
+ if (elem->ID == id) {
+ state = elem->State;
+ break;
+ }
+ }
+
+ return (state & (1 << severity));
+}
+
+/**
+ * Allocate and initialize context debug state.
+ */
+static struct gl_debug_state *
+debug_create(void)
+{
+ struct gl_debug_state *debug;
+ int s, t;
+
+ debug = CALLOC_STRUCT(gl_debug_state);
+ if (!debug)
+ return NULL;
+
+ debug->Groups[0] = malloc(sizeof(*debug->Groups[0]));
+ if (!debug->Groups[0]) {
+ free(debug);
+ return NULL;
+ }
+
+ /* Initialize state for filtering known debug messages. */
+ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) {
+ for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++)
+ debug_namespace_init(&debug->Groups[0]->Namespaces[s][t]);
+ }
+
+ return debug;
+}
+
+/**
+ * Return true if the top debug group points to the group below it.
+ */
+static bool
+debug_is_group_read_only(const struct gl_debug_state *debug)
+{
+ const GLint gstack = debug->GroupStackDepth;
+ return (gstack > 0 && debug->Groups[gstack] == debug->Groups[gstack - 1]);
+}
+
+/**
+ * Make the top debug group writable.
+ */
+static bool
+debug_make_group_writable(struct gl_debug_state *debug)
+{
+ const GLint gstack = debug->GroupStackDepth;
+ const struct gl_debug_group *src = debug->Groups[gstack];
+ struct gl_debug_group *dst;
+ int s, t;
+
+ if (!debug_is_group_read_only(debug))
+ return true;
+
+ dst = malloc(sizeof(*dst));
+ if (!dst)
+ return false;
+
+ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) {
+ for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) {
+ if (!debug_namespace_copy(&dst->Namespaces[s][t],
+ &src->Namespaces[s][t])) {
+ /* error path! */
+ for (t = t - 1; t >= 0; t--)
+ debug_namespace_clear(&dst->Namespaces[s][t]);
+ for (s = s - 1; s >= 0; s--) {
+ for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++)
+ debug_namespace_clear(&dst->Namespaces[s][t]);
+ }
+ free(dst);
+ return false;
+ }
+ }
+ }
+
+ debug->Groups[gstack] = dst;
+
+ return true;
+}
+
+/**
+ * Free the top debug group.
+ */
+static void
+debug_clear_group(struct gl_debug_state *debug)
+{
+ const GLint gstack = debug->GroupStackDepth;
+
+ if (!debug_is_group_read_only(debug)) {
+ struct gl_debug_group *grp = debug->Groups[gstack];
+ int s, t;
+
+ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) {
+ for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++)
+ debug_namespace_clear(&grp->Namespaces[s][t]);
+ }
+
+ free(grp);
+ }
+
+ debug->Groups[gstack] = NULL;
+}
+
+/**
+ * Loop through debug group stack tearing down states for
+ * filtering debug messages. Then free debug output state.
+ */
+static void
+debug_destroy(struct gl_debug_state *debug)
+{
+ while (debug->GroupStackDepth > 0) {
+ debug_clear_group(debug);
+ debug->GroupStackDepth--;
+ }
+
+ debug_clear_group(debug);
+ free(debug);
+}
+
+/**
+ * Sets the state of the given message source/type/ID tuple.
+ */
+static void
+debug_set_message_enable(struct gl_debug_state *debug,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type,
+ GLuint id, GLboolean enabled)
+{
+ const GLint gstack = debug->GroupStackDepth;
+ struct gl_debug_namespace *ns;
+
+ debug_make_group_writable(debug);
+ ns = &debug->Groups[gstack]->Namespaces[source][type];
+
+ debug_namespace_set(ns, id, enabled);
+}
+
+/*
+ * Set the state of all message IDs found in the given intersection of
+ * 'source', 'type', and 'severity'. The _COUNT enum can be used for
+ * GL_DONT_CARE (include all messages in the class).
+ *
+ * This requires both setting the state of all previously seen message
+ * IDs in the hash table, and setting the default state for all
+ * applicable combinations of source/type/severity, so that all the
+ * yet-unknown message IDs that may be used in the future will be
+ * impacted as if they were already known.
+ */
+static void
+debug_set_message_enable_all(struct gl_debug_state *debug,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type,
+ enum mesa_debug_severity severity,
+ GLboolean enabled)
+{
+ const GLint gstack = debug->GroupStackDepth;
+ int s, t, smax, tmax;
+
+ if (source == MESA_DEBUG_SOURCE_COUNT) {
+ source = 0;
+ smax = MESA_DEBUG_SOURCE_COUNT;
+ } else {
+ smax = source+1;
+ }
+
+ if (type == MESA_DEBUG_TYPE_COUNT) {
+ type = 0;
+ tmax = MESA_DEBUG_TYPE_COUNT;
+ } else {
+ tmax = type+1;
+ }
+
+ debug_make_group_writable(debug);
+
+ for (s = source; s < smax; s++) {
+ for (t = type; t < tmax; t++) {
+ struct gl_debug_namespace *nspace =
+ &debug->Groups[gstack]->Namespaces[s][t];
+ debug_namespace_set_all(nspace, severity, enabled);
+ }
+ }
+}
+
+/**
+ * Returns if the given message source/type/ID tuple is enabled.
+ */
+static bool
+debug_is_message_enabled(const struct gl_debug_state *debug,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type,
+ GLuint id,
+ enum mesa_debug_severity severity)
+{
+ const GLint gstack = debug->GroupStackDepth;
+ struct gl_debug_group *grp = debug->Groups[gstack];
+ struct gl_debug_namespace *nspace = &grp->Namespaces[source][type];
+
+ if (!debug->DebugOutput)
+ return false;
+
+ return debug_namespace_get(nspace, id, severity);
+}
+
+/**
+ * 'buf' is not necessarily a null-terminated string. When logging, copy
+ * 'len' characters from it, store them in a new, null-terminated string,
+ * and remember the number of bytes used by that string, *including*
+ * the null terminator this time.
+ */
+static void
+debug_log_message(struct gl_debug_state *debug,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type, GLuint id,
+ enum mesa_debug_severity severity,
+ GLsizei len, const char *buf)
+{
+ struct gl_debug_log *log = &debug->Log;
+ GLint nextEmpty;
+ struct gl_debug_message *emptySlot;
+
+ assert(len >= 0 && len < MAX_DEBUG_MESSAGE_LENGTH);
+
+ if (log->NumMessages == MAX_DEBUG_LOGGED_MESSAGES)
+ return;
+
+ nextEmpty = (log->NextMessage + log->NumMessages)
+ % MAX_DEBUG_LOGGED_MESSAGES;
+ emptySlot = &log->Messages[nextEmpty];
+
+ debug_message_store(emptySlot, source, type,
+ id, severity, len, buf);
+
+ log->NumMessages++;
+}
+
+/**
+ * Return the oldest debug message out of the log.
+ */
+static const struct gl_debug_message *
+debug_fetch_message(const struct gl_debug_state *debug)
+{
+ const struct gl_debug_log *log = &debug->Log;
+
+ return (log->NumMessages) ? &log->Messages[log->NextMessage] : NULL;
+}
+
+/**
+ * Delete the oldest debug messages out of the log.
+ */
+static void
+debug_delete_messages(struct gl_debug_state *debug, unsigned count)
+{
+ struct gl_debug_log *log = &debug->Log;
+
+ if (count > log->NumMessages)
+ count = log->NumMessages;
+
+ while (count--) {
+ struct gl_debug_message *msg = &log->Messages[log->NextMessage];
+
+ debug_message_clear(msg);
+
+ log->NumMessages--;
+ log->NextMessage++;
+ log->NextMessage %= MAX_DEBUG_LOGGED_MESSAGES;
+ }
+}
+
+static struct gl_debug_message *
+debug_get_group_message(struct gl_debug_state *debug)
+{
+ return &debug->GroupMessages[debug->GroupStackDepth];
+}
+
+static void
+debug_push_group(struct gl_debug_state *debug)
+{
+ const GLint gstack = debug->GroupStackDepth;
+
+ /* just point to the previous stack */
+ debug->Groups[gstack + 1] = debug->Groups[gstack];
+ debug->GroupStackDepth++;
+}
+
+static void
+debug_pop_group(struct gl_debug_state *debug)
+{
+ debug_clear_group(debug);
+ debug->GroupStackDepth--;
+}
+
+
+/**
+ * Lock and return debug state for the context. The debug state will be
+ * allocated and initialized upon the first call. When NULL is returned, the
+ * debug state is not locked.
+ */
+static struct gl_debug_state *
+_mesa_lock_debug_state(struct gl_context *ctx)
+{
+ mtx_lock(&ctx->DebugMutex);
+
+ if (!ctx->Debug) {
+ ctx->Debug = debug_create();
+ if (!ctx->Debug) {
+ GET_CURRENT_CONTEXT(cur);
+ mtx_unlock(&ctx->DebugMutex);
+
+ /*
+ * This function may be called from other threads. When that is the
+ * case, we cannot record this OOM error.
+ */
+ if (ctx == cur)
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "allocating debug state");
+
+ return NULL;
+ }
+ }
+
+ return ctx->Debug;
+}
+
+static void
+_mesa_unlock_debug_state(struct gl_context *ctx)
+{
+ mtx_unlock(&ctx->DebugMutex);
+}
+
+/**
+ * Set the integer debug state specified by \p pname. This can be called from
+ * _mesa_set_enable for example.
+ */
+bool
+_mesa_set_debug_state_int(struct gl_context *ctx, GLenum pname, GLint val)
+{
+ struct gl_debug_state *debug = _mesa_lock_debug_state(ctx);
+
+ if (!debug)
+ return false;
+
+ switch (pname) {
+ case GL_DEBUG_OUTPUT:
+ debug->DebugOutput = (val != 0);
+ break;
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
+ debug->SyncOutput = (val != 0);
+ break;
+ default:
+ assert(!"unknown debug output param");
+ break;
+ }
+
+ _mesa_unlock_debug_state(ctx);
+
+ return true;
+}
+
+/**
+ * Query the integer debug state specified by \p pname. This can be called
+ * _mesa_GetIntegerv for example.
+ */
+GLint
+_mesa_get_debug_state_int(struct gl_context *ctx, GLenum pname)
+{
+ struct gl_debug_state *debug;
+ GLint val;
+
+ mtx_lock(&ctx->DebugMutex);
+ debug = ctx->Debug;
+ if (!debug) {
+ mtx_unlock(&ctx->DebugMutex);
+ return 0;
+ }
+
+ switch (pname) {
+ case GL_DEBUG_OUTPUT:
+ val = debug->DebugOutput;
+ break;
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
+ val = debug->SyncOutput;
+ break;
+ case GL_DEBUG_LOGGED_MESSAGES:
+ val = debug->Log.NumMessages;
+ break;
+ case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+ val = (debug->Log.NumMessages) ?
+ debug->Log.Messages[debug->Log.NextMessage].length : 0;
+ break;
+ case GL_DEBUG_GROUP_STACK_DEPTH:
+ val = debug->GroupStackDepth;
+ break;
+ default:
+ assert(!"unknown debug output param");
+ val = 0;
+ break;
+ }
+
+ mtx_unlock(&ctx->DebugMutex);
+
+ return val;
+}
+
+/**
+ * Query the pointer debug state specified by \p pname. This can be called
+ * _mesa_GetPointerv for example.
+ */
+void *
+_mesa_get_debug_state_ptr(struct gl_context *ctx, GLenum pname)
+{
+ struct gl_debug_state *debug;
+ void *val;
+
+ mtx_lock(&ctx->DebugMutex);
+ debug = ctx->Debug;
+ if (!debug) {
+ mtx_unlock(&ctx->DebugMutex);
+ return NULL;
+ }
+
+ switch (pname) {
+ case GL_DEBUG_CALLBACK_FUNCTION_ARB:
+ val = (void *) debug->Callback;
+ break;
+ case GL_DEBUG_CALLBACK_USER_PARAM_ARB:
+ val = (void *) debug->CallbackData;
+ break;
+ default:
+ assert(!"unknown debug output param");
+ val = NULL;
+ break;
+ }
+
+ mtx_unlock(&ctx->DebugMutex);
+
+ return val;
+}
+
+/**
+ * Insert a debug message. The mutex is assumed to be locked, and will be
+ * unlocked by this call.
+ */
+static void
+log_msg_locked_and_unlock(struct gl_context *ctx,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type, GLuint id,
+ enum mesa_debug_severity severity,
+ GLint len, const char *buf)
+{
+ struct gl_debug_state *debug = ctx->Debug;
+
+ if (!debug_is_message_enabled(debug, source, type, id, severity)) {
+ _mesa_unlock_debug_state(ctx);
+ return;
+ }
+
+ if (ctx->Debug->Callback) {
+ GLenum gl_source = debug_source_enums[source];
+ GLenum gl_type = debug_type_enums[type];
+ GLenum gl_severity = debug_severity_enums[severity];
+ GLDEBUGPROC callback = ctx->Debug->Callback;
+ const void *data = ctx->Debug->CallbackData;
+
+ /*
+ * When ctx->Debug->SyncOutput is GL_FALSE, the client is prepared for
+ * unsynchronous calls. When it is GL_TRUE, we will not spawn threads.
+ * In either case, we can call the callback unlocked.
+ */
+ _mesa_unlock_debug_state(ctx);
+ callback(gl_source, gl_type, id, gl_severity, len, buf, data);
+ }
+ else {
+ debug_log_message(ctx->Debug, source, type, id, severity, len, buf);
+ _mesa_unlock_debug_state(ctx);
+ }
+}
+
+/**
+ * Log a client or driver debug message.
+ */
+static void
+log_msg(struct gl_context *ctx, enum mesa_debug_source source,
+ enum mesa_debug_type type, GLuint id,
+ enum mesa_debug_severity severity, GLint len, const char *buf)
+{
+ struct gl_debug_state *debug = _mesa_lock_debug_state(ctx);
+
+ if (!debug)
+ return;
+
+ log_msg_locked_and_unlock(ctx, source, type, id, severity, len, buf);
+}
+
+
+/**
+ * Verify that source, type, and severity are valid enums.
+ *
+ * The 'caller' param is used for handling values available
+ * only in glDebugMessageInsert or glDebugMessageControl
+ */
+static GLboolean
+validate_params(struct gl_context *ctx, unsigned caller,
+ const char *callerstr, GLenum source, GLenum type,
+ GLenum severity)
+{
+#define INSERT 1
+#define CONTROL 2
+ switch(source) {
+ case GL_DEBUG_SOURCE_APPLICATION_ARB:
+ case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
+ break;
+ case GL_DEBUG_SOURCE_API_ARB:
+ case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
+ case GL_DEBUG_SOURCE_OTHER_ARB:
+ if (caller != INSERT)
+ break;
+ else
+ goto error;
+ case GL_DONT_CARE:
+ if (caller == CONTROL)
+ break;
+ else
+ goto error;
+ default:
+ goto error;
+ }
+
+ switch(type) {
+ case GL_DEBUG_TYPE_ERROR_ARB:
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
+ case GL_DEBUG_TYPE_PERFORMANCE_ARB:
+ case GL_DEBUG_TYPE_PORTABILITY_ARB:
+ case GL_DEBUG_TYPE_OTHER_ARB:
+ case GL_DEBUG_TYPE_MARKER:
+ break;
+ case GL_DEBUG_TYPE_PUSH_GROUP:
+ case GL_DEBUG_TYPE_POP_GROUP:
+ case GL_DONT_CARE:
+ if (caller == CONTROL)
+ break;
+ else
+ goto error;
+ default:
+ goto error;
+ }
+
+ switch(severity) {
+ case GL_DEBUG_SEVERITY_HIGH_ARB:
+ case GL_DEBUG_SEVERITY_MEDIUM_ARB:
+ case GL_DEBUG_SEVERITY_LOW_ARB:
+ case GL_DEBUG_SEVERITY_NOTIFICATION:
+ break;
+ case GL_DONT_CARE:
+ if (caller == CONTROL)
+ break;
+ else
+ goto error;
+ default:
+ goto error;
+ }
+ return GL_TRUE;
+
+error:
+ _mesa_error(ctx, GL_INVALID_ENUM, "bad values passed to %s"
+ "(source=0x%x, type=0x%x, severity=0x%x)", callerstr,
+ source, type, severity);
+
+ return GL_FALSE;
+}
+
+
+static GLboolean
+validate_length(struct gl_context *ctx, const char *callerstr, GLsizei length)
+{
+ if (length >= MAX_DEBUG_MESSAGE_LENGTH) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(length=%d, which is not less than "
+ "GL_MAX_DEBUG_MESSAGE_LENGTH=%d)", callerstr, length,
+ MAX_DEBUG_MESSAGE_LENGTH);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+
+void GLAPIENTRY
+_mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLint length,
+ const GLchar *buf)
+{
+ const char *callerstr = "glDebugMessageInsert";
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!validate_params(ctx, INSERT, callerstr, source, type, severity))
+ return; /* GL_INVALID_ENUM */
+
+ if (length < 0)
+ length = strlen(buf);
+ if (!validate_length(ctx, callerstr, length))
+ return; /* GL_INVALID_VALUE */
+
+ log_msg(ctx, gl_enum_to_debug_source(source),
+ gl_enum_to_debug_type(type), id,
+ gl_enum_to_debug_severity(severity),
+ length, buf);
+}
+
+
+GLuint GLAPIENTRY
+_mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum *sources,
+ GLenum *types, GLenum *ids, GLenum *severities,
+ GLsizei *lengths, GLchar *messageLog)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_debug_state *debug;
+ GLuint ret;
+
+ if (!messageLog)
+ logSize = 0;
+
+ if (logSize < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetDebugMessageLog(logSize=%d : logSize must not be"
+ " negative)", logSize);
+ return 0;
+ }
+
+ debug = _mesa_lock_debug_state(ctx);
+ if (!debug)
+ return 0;
+
+ for (ret = 0; ret < count; ret++) {
+ const struct gl_debug_message *msg = debug_fetch_message(debug);
+
+ if (!msg)
+ break;
+
+ if (logSize < msg->length && messageLog != NULL)
+ break;
+
+ if (messageLog) {
+ assert(msg->message[msg->length-1] == '\0');
+ (void) strncpy(messageLog, msg->message, (size_t)msg->length);
+
+ messageLog += msg->length;
+ logSize -= msg->length;
+ }
+
+ if (lengths)
+ *lengths++ = msg->length;
+ if (severities)
+ *severities++ = debug_severity_enums[msg->severity];
+ if (sources)
+ *sources++ = debug_source_enums[msg->source];
+ if (types)
+ *types++ = debug_type_enums[msg->type];
+ if (ids)
+ *ids++ = msg->id;
+
+ debug_delete_messages(debug, 1);
+ }
+
+ _mesa_unlock_debug_state(ctx);
+
+ return ret;
+}
+
+
+void GLAPIENTRY
+_mesa_DebugMessageControl(GLenum gl_source, GLenum gl_type,
+ GLenum gl_severity, GLsizei count,
+ const GLuint *ids, GLboolean enabled)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ enum mesa_debug_source source = gl_enum_to_debug_source(gl_source);
+ enum mesa_debug_type type = gl_enum_to_debug_type(gl_type);
+ enum mesa_debug_severity severity = gl_enum_to_debug_severity(gl_severity);
+ const char *callerstr = "glDebugMessageControl";
+ struct gl_debug_state *debug;
+
+ if (count < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(count=%d : count must not be negative)", callerstr,
+ count);
+ return;
+ }
+
+ if (!validate_params(ctx, CONTROL, callerstr, gl_source, gl_type,
+ gl_severity))
+ return; /* GL_INVALID_ENUM */
+
+ if (count && (gl_severity != GL_DONT_CARE || gl_type == GL_DONT_CARE
+ || gl_source == GL_DONT_CARE)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(When passing an array of ids, severity must be"
+ " GL_DONT_CARE, and source and type must not be GL_DONT_CARE.",
+ callerstr);
+ return;
+ }
+
+ debug = _mesa_lock_debug_state(ctx);
+ if (!debug)
+ return;
+
+ if (count) {
+ GLsizei i;
+ for (i = 0; i < count; i++)
+ debug_set_message_enable(debug, source, type, ids[i], enabled);
+ }
+ else {
+ debug_set_message_enable_all(debug, source, type, severity, enabled);
+ }
+
+ _mesa_unlock_debug_state(ctx);
+}
+
+
+void GLAPIENTRY
+_mesa_DebugMessageCallback(GLDEBUGPROC callback, const void *userParam)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_debug_state *debug = _mesa_lock_debug_state(ctx);
+ if (debug) {
+ debug->Callback = callback;
+ debug->CallbackData = userParam;
+ _mesa_unlock_debug_state(ctx);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_PushDebugGroup(GLenum source, GLuint id, GLsizei length,
+ const GLchar *message)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *callerstr = "glPushDebugGroup";
+ struct gl_debug_state *debug;
+ struct gl_debug_message *emptySlot;
+
+ switch(source) {
+ case GL_DEBUG_SOURCE_APPLICATION:
+ case GL_DEBUG_SOURCE_THIRD_PARTY:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "bad value passed to %s"
+ "(source=0x%x)", callerstr, source);
+ return;
+ }
+
+ if (length < 0)
+ length = strlen(message);
+ if (!validate_length(ctx, callerstr, length))
+ return; /* GL_INVALID_VALUE */
+
+ debug = _mesa_lock_debug_state(ctx);
+ if (!debug)
+ return;
+
+ if (debug->GroupStackDepth >= MAX_DEBUG_GROUP_STACK_DEPTH-1) {
+ _mesa_unlock_debug_state(ctx);
+ _mesa_error(ctx, GL_STACK_OVERFLOW, "%s", callerstr);
+ return;
+ }
+
+ /* pop reuses the message details from push so we store this */
+ emptySlot = debug_get_group_message(debug);
+ debug_message_store(emptySlot,
+ gl_enum_to_debug_source(source),
+ gl_enum_to_debug_type(GL_DEBUG_TYPE_PUSH_GROUP),
+ id,
+ gl_enum_to_debug_severity(GL_DEBUG_SEVERITY_NOTIFICATION),
+ length, message);
+
+ debug_push_group(debug);
+
+ log_msg_locked_and_unlock(ctx,
+ gl_enum_to_debug_source(source),
+ MESA_DEBUG_TYPE_PUSH_GROUP, id,
+ MESA_DEBUG_SEVERITY_NOTIFICATION, length,
+ message);
+}
+
+
+void GLAPIENTRY
+_mesa_PopDebugGroup(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *callerstr = "glPopDebugGroup";
+ struct gl_debug_state *debug;
+ struct gl_debug_message *gdmessage, msg;
+
+ debug = _mesa_lock_debug_state(ctx);
+ if (!debug)
+ return;
+
+ if (debug->GroupStackDepth <= 0) {
+ _mesa_unlock_debug_state(ctx);
+ _mesa_error(ctx, GL_STACK_UNDERFLOW, "%s", callerstr);
+ return;
+ }
+
+ debug_pop_group(debug);
+
+ /* make a shallow copy */
+ gdmessage = debug_get_group_message(debug);
+ msg = *gdmessage;
+ gdmessage->message = NULL;
+ gdmessage->length = 0;
+
+ log_msg_locked_and_unlock(ctx,
+ msg.source,
+ gl_enum_to_debug_type(GL_DEBUG_TYPE_POP_GROUP),
+ msg.id,
+ gl_enum_to_debug_severity(GL_DEBUG_SEVERITY_NOTIFICATION),
+ msg.length, msg.message);
+
+ debug_message_clear(&msg);
+}
+
+
+void
+_mesa_init_errors(struct gl_context *ctx)
+{
+ mtx_init(&ctx->DebugMutex, mtx_plain);
+}
+
+
+void
+_mesa_free_errors_data(struct gl_context *ctx)
+{
+ if (ctx->Debug) {
+ debug_destroy(ctx->Debug);
+ /* set to NULL just in case it is used before context is completely gone. */
+ ctx->Debug = NULL;
+ }
+
+ mtx_destroy(&ctx->DebugMutex);
+}
+
+
+/**********************************************************************/
+/** \name Diagnostics */
+/*@{*/
+
+static void
+output_if_debug(const char *prefixString, const char *outputString,
+ GLboolean newline)
+{
+ static int debug = -1;
+ static FILE *fout = NULL;
+
+ /* Init the local 'debug' var once.
+ * Note: the _mesa_init_debug() function should have been called
+ * by now so MESA_DEBUG_FLAGS will be initialized.
+ */
+ if (debug == -1) {
+ /* If MESA_LOG_FILE env var is set, log Mesa errors, warnings,
+ * etc to the named file. Otherwise, output to stderr.
+ */
+ const char *logFile = _mesa_getenv("MESA_LOG_FILE");
+ if (logFile)
+ fout = fopen(logFile, "w");
+ if (!fout)
+ fout = stderr;
+#ifdef DEBUG
+ /* in debug builds, print messages unless MESA_DEBUG="silent" */
+ if (MESA_DEBUG_FLAGS & DEBUG_SILENT)
+ debug = 0;
+ else
+ debug = 1;
+#else
+ /* in release builds, be silent unless MESA_DEBUG is set */
+ debug = _mesa_getenv("MESA_DEBUG") != NULL;
+#endif
+ }
+
+ /* Now only print the string if we're required to do so. */
+ if (debug) {
+ fprintf(fout, "%s: %s", prefixString, outputString);
+ if (newline)
+ fprintf(fout, "\n");
+ fflush(fout);
+
+#if defined(_WIN32) && !defined(_WIN32_WCE)
+ /* stderr from windows applications without console is not usually
+ * visible, so communicate with the debugger instead */
+ {
+ char buf[4096];
+ _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
+ OutputDebugStringA(buf);
+ }
+#endif
+ }
+}
+
+
+/**
+ * When a new type of error is recorded, print a message describing
+ * previous errors which were accumulated.
+ */
+static void
+flush_delayed_errors( struct gl_context *ctx )
+{
+ char s[MAX_DEBUG_MESSAGE_LENGTH];
+
+ if (ctx->ErrorDebugCount) {
+ _mesa_snprintf(s, MAX_DEBUG_MESSAGE_LENGTH, "%d similar %s errors",
+ ctx->ErrorDebugCount,
+ _mesa_lookup_enum_by_nr(ctx->ErrorValue));
+
+ output_if_debug("Mesa", s, GL_TRUE);
+
+ ctx->ErrorDebugCount = 0;
+ }
+}
+
+
+/**
+ * Report a warning (a recoverable error condition) to stderr if
+ * either DEBUG is defined or the MESA_DEBUG env var is set.
+ *
+ * \param ctx GL context.
+ * \param fmtString printf()-like format string.
+ */
+void
+_mesa_warning( struct gl_context *ctx, const char *fmtString, ... )
+{
+ char str[MAX_DEBUG_MESSAGE_LENGTH];
+ va_list args;
+ va_start( args, fmtString );
+ (void) _mesa_vsnprintf( str, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args );
+ va_end( args );
+
+ if (ctx)
+ flush_delayed_errors( ctx );
+
+ output_if_debug("Mesa warning", str, GL_TRUE);
+}
+
+
+/**
+ * Report an internal implementation problem.
+ * Prints the message to stderr via fprintf().
+ *
+ * \param ctx GL context.
+ * \param fmtString problem description string.
+ */
+void
+_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... )
+{
+ // LunarG DEL:
+}
+
+
+static GLboolean
+should_output(struct gl_context *ctx, GLenum error, const char *fmtString)
+{
+ static GLint debug = -1;
+
+ /* Check debug environment variable only once:
+ */
+ if (debug == -1) {
+ const char *debugEnv = _mesa_getenv("MESA_DEBUG");
+
+#ifdef DEBUG
+ if (debugEnv && strstr(debugEnv, "silent"))
+ debug = GL_FALSE;
+ else
+ debug = GL_TRUE;
+#else
+ if (debugEnv)
+ debug = GL_TRUE;
+ else
+ debug = GL_FALSE;
+#endif
+ }
+
+ if (debug) {
+ if (ctx->ErrorValue != error ||
+ ctx->ErrorDebugFmtString != fmtString) {
+ flush_delayed_errors( ctx );
+ ctx->ErrorDebugFmtString = fmtString;
+ ctx->ErrorDebugCount = 0;
+ return GL_TRUE;
+ }
+ ctx->ErrorDebugCount++;
+ }
+ return GL_FALSE;
+}
+
+
+void
+_mesa_gl_debug(struct gl_context *ctx,
+ GLuint *id,
+ enum mesa_debug_type type,
+ enum mesa_debug_severity severity,
+ const char *fmtString, ...)
+{
+ char s[MAX_DEBUG_MESSAGE_LENGTH];
+ int len;
+ va_list args;
+
+ debug_get_id(id);
+
+ va_start(args, fmtString);
+ len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+ va_end(args);
+
+ log_msg(ctx, MESA_DEBUG_SOURCE_API, type, *id, severity, len, s);
+}
+
+
+/**
+ * Record an OpenGL state error. These usually occur when the user
+ * passes invalid parameters to a GL function.
+ *
+ * If debugging is enabled (either at compile-time via the DEBUG macro, or
+ * run-time via the MESA_DEBUG environment variable), report the error with
+ * _mesa_debug().
+ *
+ * \param ctx the GL context.
+ * \param error the error value.
+ * \param fmtString printf() style format string, followed by optional args
+ */
+void
+_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
+{
+ GLboolean do_output, do_log;
+ /* Ideally this would be set up by the caller, so that we had proper IDs
+ * per different message.
+ */
+ static GLuint error_msg_id = 0;
+
+ debug_get_id(&error_msg_id);
+
+ do_output = should_output(ctx, error, fmtString);
+
+ mtx_lock(&ctx->DebugMutex);
+ if (ctx->Debug) {
+ do_log = debug_is_message_enabled(ctx->Debug,
+ MESA_DEBUG_SOURCE_API,
+ MESA_DEBUG_TYPE_ERROR,
+ error_msg_id,
+ MESA_DEBUG_SEVERITY_HIGH);
+ }
+ else {
+ do_log = GL_FALSE;
+ }
+ mtx_unlock(&ctx->DebugMutex);
+
+ if (do_output || do_log) {
+ char s[MAX_DEBUG_MESSAGE_LENGTH], s2[MAX_DEBUG_MESSAGE_LENGTH];
+ int len;
+ va_list args;
+
+ va_start(args, fmtString);
+ len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+ va_end(args);
+
+ if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
+ /* Too long error message. Whoever calls _mesa_error should use
+ * shorter strings.
+ */
+ ASSERT(0);
+ return;
+ }
+
+ len = _mesa_snprintf(s2, MAX_DEBUG_MESSAGE_LENGTH, "%s in %s",
+ _mesa_lookup_enum_by_nr(error), s);
+ if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
+ /* Same as above. */
+ ASSERT(0);
+ return;
+ }
+
+ /* Print the error to stderr if needed. */
+ if (do_output) {
+ output_if_debug("Mesa: User error", s2, GL_TRUE);
+ }
+
+ /* Log the error via ARB_debug_output if needed.*/
+ if (do_log) {
+ log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_ERROR,
+ error_msg_id, MESA_DEBUG_SEVERITY_HIGH, len, s2);
+ }
+ }
+
+ /* Set the GL context error state for glGetError. */
+ _mesa_record_error(ctx, error);
+}
+
+void
+_mesa_error_no_memory(const char *caller)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "out of memory in %s", caller);
+}
+
+/**
+ * Report debug information. Print error message to stderr via fprintf().
+ * No-op if DEBUG mode not enabled.
+ *
+ * \param ctx GL context.
+ * \param fmtString printf()-style format string, followed by optional args.
+ */
+void
+_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... )
+{
+#ifdef DEBUG
+ char s[MAX_DEBUG_MESSAGE_LENGTH];
+ va_list args;
+ va_start(args, fmtString);
+ _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+ va_end(args);
+ output_if_debug("Mesa", s, GL_FALSE);
+#endif /* DEBUG */
+ (void) ctx;
+ (void) fmtString;
+}
+
+
+/**
+ * Report debug information from the shader compiler via GL_ARB_debug_output.
+ *
+ * \param ctx GL context.
+ * \param type The namespace to which this message belongs.
+ * \param id The message ID within the given namespace.
+ * \param msg The message to output. Need not be null-terminated.
+ * \param len The length of 'msg'. If negative, 'msg' must be null-terminated.
+ */
+void
+_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint *id,
+ const char *msg, int len )
+{
+ enum mesa_debug_source source = MESA_DEBUG_SOURCE_SHADER_COMPILER;
+ enum mesa_debug_severity severity = MESA_DEBUG_SEVERITY_HIGH;
+
+ debug_get_id(id);
+
+ if (len < 0)
+ len = strlen(msg);
+
+ /* Truncate the message if necessary. */
+ if (len >= MAX_DEBUG_MESSAGE_LENGTH)
+ len = MAX_DEBUG_MESSAGE_LENGTH - 1;
+
+ log_msg(ctx, source, type, *id, severity, len, msg);
+}
+
+/*@}*/
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/errors.h b/icd/intel/compiler/mesa-utils/src/mesa/main/errors.h
new file mode 100644
index 0000000..b388138
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/errors.h
@@ -0,0 +1,128 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file errors.h
+ * Mesa debugging and error handling functions.
+ *
+ * This file provides functions to record errors, warnings, and miscellaneous
+ * debug information.
+ */
+
+
+#ifndef ERRORS_H
+#define ERRORS_H
+
+
+#include "compiler.h"
+#include "glheader.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mtypes.h"
+
+struct _glapi_table;
+
+extern void
+_mesa_init_errors( struct gl_context *ctx );
+
+extern void
+_mesa_free_errors_data( struct gl_context *ctx );
+
+extern void
+_mesa_warning( struct gl_context *gc, const char *fmtString, ... ) PRINTFLIKE(2, 3);
+
+extern void
+_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
+
+extern void
+_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... ) PRINTFLIKE(3, 4);
+
+extern void
+_mesa_error_no_memory(const char *caller);
+
+extern void
+_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
+
+extern void
+_mesa_gl_debug(struct gl_context *ctx,
+ GLuint *id,
+ enum mesa_debug_type type,
+ enum mesa_debug_severity severity,
+ const char *fmtString, ...) PRINTFLIKE(5, 6);
+
+#define _mesa_perf_debug(ctx, sev, ...) do { \
+ static GLuint msg_id = 0; \
+ if (unlikely(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) { \
+ _mesa_gl_debug(ctx, &msg_id, \
+ MESA_DEBUG_TYPE_PERFORMANCE, \
+ sev, \
+ __VA_ARGS__); \
+ } \
+} while (0)
+
+bool
+_mesa_set_debug_state_int(struct gl_context *ctx, GLenum pname, GLint val);
+
+GLint
+_mesa_get_debug_state_int(struct gl_context *ctx, GLenum pname);
+
+void *
+_mesa_get_debug_state_ptr(struct gl_context *ctx, GLenum pname);
+
+extern void
+_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
+ const char *msg, int len);
+
+void GLAPIENTRY
+_mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLint length,
+ const GLchar* buf);
+GLuint GLAPIENTRY
+_mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum* sources,
+ GLenum* types, GLenum* ids, GLenum* severities,
+ GLsizei* lengths, GLchar* messageLog);
+void GLAPIENTRY
+_mesa_DebugMessageControl(GLenum source, GLenum type, GLenum severity,
+ GLsizei count, const GLuint *ids,
+ GLboolean enabled);
+void GLAPIENTRY
+_mesa_DebugMessageCallback(GLDEBUGPROC callback,
+ const void *userParam);
+void GLAPIENTRY
+_mesa_PushDebugGroup(GLenum source, GLuint id, GLsizei length,
+ const GLchar *message);
+void GLAPIENTRY
+_mesa_PopDebugGroup(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* ERRORS_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/hash.c b/icd/intel/compiler/mesa-utils/src/mesa/main/hash.c
new file mode 100644
index 0000000..23018e9
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/hash.c
@@ -0,0 +1,520 @@
+/**
+ * \file hash.c
+ * Generic hash table.
+ *
+ * Used for display lists, texture objects, vertex/fragment programs,
+ * buffer objects, etc. The hash functions are thread-safe.
+ *
+ * \note key=0 is illegal.
+ *
+ * \author Brian Paul
+ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "hash.h"
+#include "hash_table.h"
+
+/**
+ * Magic GLuint object name that gets stored outside of the struct hash_table.
+ *
+ * The hash table needs a particular pointer to be the marker for a key that
+ * was deleted from the table, along with NULL for the "never allocated in the
+ * table" marker. Legacy GL allows any GLuint to be used as a GL object name,
+ * and we use a 1:1 mapping from GLuints to key pointers, so we need to be
+ * able to track a GLuint that happens to match the deleted key outside of
+ * struct hash_table. We tell the hash table to use "1" as the deleted key
+ * value, so that we test the deleted-key-in-the-table path as best we can.
+ */
+#define DELETED_KEY_VALUE 1
+
+/**
+ * The hash table data structure.
+ */
+struct _mesa_HashTable {
+ struct hash_table *ht;
+ GLuint MaxKey; /**< highest key inserted so far */
+ mtx_t Mutex; /**< mutual exclusion lock */
+ mtx_t WalkMutex; /**< for _mesa_HashWalk() */
+ GLboolean InDeleteAll; /**< Debug check */
+ /** Value that would be in the table for DELETED_KEY_VALUE. */
+ void *deleted_key_data;
+};
+
+/** @{
+ * Mapping from our use of GLuint as both the key and the hash value to the
+ * hash_table.h API
+ *
+ * There exist many integer hash functions, designed to avoid collisions when
+ * the integers are spread across key space with some patterns. In GL, the
+ * pattern (in the case of glGen*()ed object IDs) is that the keys are unique
+ * contiguous integers starting from 1. Because of that, we just use the key
+ * as the hash value, to minimize the cost of the hash function. If objects
+ * are never deleted, we will never see a collision in the table, because the
+ * table resizes itself when it approaches full, and thus key % table_size ==
+ * key.
+ *
+ * The case where we could have collisions for genned objects would be
+ * something like: glGenBuffers(&a, 100); glDeleteBuffers(&a + 50, 50);
+ * glGenBuffers(&b, 100), because objects 1-50 and 101-200 are allocated at
+ * the end of that sequence, instead of 1-150. So far it doesn't appear to be
+ * a problem.
+ */
+static bool
+uint_key_compare(const void *a, const void *b)
+{
+ return a == b;
+}
+
+static uint32_t
+uint_hash(GLuint id)
+{
+ return id;
+}
+
+static void *
+uint_key(GLuint id)
+{
+ return (void *)(uintptr_t) id;
+}
+/** @} */
+
+/**
+ * Create a new hash table.
+ *
+ * \return pointer to a new, empty hash table.
+ */
+struct _mesa_HashTable *
+_mesa_NewHashTable(void)
+{
+ struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable);
+
+ if (table) {
+ table->ht = _mesa_hash_table_create(NULL, uint_key_compare);
+ _mesa_hash_table_set_deleted_key(table->ht, uint_key(DELETED_KEY_VALUE));
+ mtx_init(&table->Mutex, mtx_plain);
+ mtx_init(&table->WalkMutex, mtx_plain);
+ }
+ return table;
+}
+
+
+
+/**
+ * Delete a hash table.
+ * Frees each entry on the hash table and then the hash table structure itself.
+ * Note that the caller should have already traversed the table and deleted
+ * the objects in the table (i.e. We don't free the entries' data pointer).
+ *
+ * \param table the hash table to delete.
+ */
+void
+_mesa_DeleteHashTable(struct _mesa_HashTable *table)
+{
+ assert(table);
+
+ if (_mesa_hash_table_next_entry(table->ht, NULL) != NULL) {
+ _mesa_problem(NULL, "In _mesa_DeleteHashTable, found non-freed data");
+ }
+
+ _mesa_hash_table_destroy(table->ht, NULL);
+
+ mtx_destroy(&table->Mutex);
+ mtx_destroy(&table->WalkMutex);
+ free(table);
+}
+
+
+
+/**
+ * Lookup an entry in the hash table, without locking.
+ * \sa _mesa_HashLookup
+ */
+static inline void *
+_mesa_HashLookup_unlocked(struct _mesa_HashTable *table, GLuint key)
+{
+ const struct hash_entry *entry;
+
+ assert(table);
+ assert(key);
+
+ if (key == DELETED_KEY_VALUE)
+ return table->deleted_key_data;
+
+ entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key));
+ if (!entry)
+ return NULL;
+
+ return entry->data;
+}
+
+
+/**
+ * Lookup an entry in the hash table.
+ *
+ * \param table the hash table.
+ * \param key the key.
+ *
+ * \return pointer to user's data or NULL if key not in table
+ */
+void *
+_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key)
+{
+ void *res;
+ assert(table);
+ mtx_lock(&table->Mutex);
+ res = _mesa_HashLookup_unlocked(table, key);
+ mtx_unlock(&table->Mutex);
+ return res;
+}
+
+
+/**
+ * Lookup an entry in the hash table without locking the mutex.
+ *
+ * The hash table mutex must be locked manually by calling
+ * _mesa_HashLockMutex() before calling this function.
+ *
+ * \param table the hash table.
+ * \param key the key.
+ *
+ * \return pointer to user's data or NULL if key not in table
+ */
+void *
+_mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key)
+{
+ return _mesa_HashLookup_unlocked(table, key);
+}
+
+
+/**
+ * Lock the hash table mutex.
+ *
+ * This function should be used when multiple objects need
+ * to be looked up in the hash table, to avoid having to lock
+ * and unlock the mutex each time.
+ *
+ * \param table the hash table.
+ */
+void
+_mesa_HashLockMutex(struct _mesa_HashTable *table)
+{
+ assert(table);
+ mtx_lock(&table->Mutex);
+}
+
+
+/**
+ * Unlock the hash table mutex.
+ *
+ * \param table the hash table.
+ */
+void
+_mesa_HashUnlockMutex(struct _mesa_HashTable *table)
+{
+ assert(table);
+ mtx_unlock(&table->Mutex);
+}
+
+
+static inline void
+_mesa_HashInsert_unlocked(struct _mesa_HashTable *table, GLuint key, void *data)
+{
+ uint32_t hash = uint_hash(key);
+ struct hash_entry *entry;
+
+ assert(table);
+ assert(key);
+
+ if (key > table->MaxKey)
+ table->MaxKey = key;
+
+ if (key == DELETED_KEY_VALUE) {
+ table->deleted_key_data = data;
+ } else {
+ entry = _mesa_hash_table_search(table->ht, hash, uint_key(key));
+ if (entry) {
+ entry->data = data;
+ } else {
+ _mesa_hash_table_insert(table->ht, hash, uint_key(key), data);
+ }
+ }
+}
+
+
+/**
+ * Insert a key/pointer pair into the hash table without locking the mutex.
+ * If an entry with this key already exists we'll replace the existing entry.
+ *
+ * The hash table mutex must be locked manually by calling
+ * _mesa_HashLockMutex() before calling this function.
+ *
+ * \param table the hash table.
+ * \param key the key (not zero).
+ * \param data pointer to user data.
+ */
+void
+_mesa_HashInsertLocked(struct _mesa_HashTable *table, GLuint key, void *data)
+{
+ _mesa_HashInsert_unlocked(table, key, data);
+}
+
+
+/**
+ * Insert a key/pointer pair into the hash table.
+ * If an entry with this key already exists we'll replace the existing entry.
+ *
+ * \param table the hash table.
+ * \param key the key (not zero).
+ * \param data pointer to user data.
+ */
+void
+_mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
+{
+ assert(table);
+ mtx_lock(&table->Mutex);
+ _mesa_HashInsert_unlocked(table, key, data);
+ mtx_unlock(&table->Mutex);
+}
+
+
+/**
+ * Remove an entry from the hash table.
+ *
+ * \param table the hash table.
+ * \param key key of entry to remove.
+ *
+ * While holding the hash table's lock, searches the entry with the matching
+ * key and unlinks it.
+ */
+void
+_mesa_HashRemove(struct _mesa_HashTable *table, GLuint key)
+{
+ struct hash_entry *entry;
+
+ assert(table);
+ assert(key);
+
+ /* have to check this outside of mutex lock */
+ if (table->InDeleteAll) {
+ _mesa_problem(NULL, "_mesa_HashRemove illegally called from "
+ "_mesa_HashDeleteAll callback function");
+ return;
+ }
+
+ mtx_lock(&table->Mutex);
+ if (key == DELETED_KEY_VALUE) {
+ table->deleted_key_data = NULL;
+ } else {
+ entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key));
+ _mesa_hash_table_remove(table->ht, entry);
+ }
+ mtx_unlock(&table->Mutex);
+}
+
+
+
+/**
+ * Delete all entries in a hash table, but don't delete the table itself.
+ * Invoke the given callback function for each table entry.
+ *
+ * \param table the hash table to delete
+ * \param callback the callback function
+ * \param userData arbitrary pointer to pass along to the callback
+ * (this is typically a struct gl_context pointer)
+ */
+void
+_mesa_HashDeleteAll(struct _mesa_HashTable *table,
+ void (*callback)(GLuint key, void *data, void *userData),
+ void *userData)
+{
+ struct hash_entry *entry;
+
+ ASSERT(table);
+ ASSERT(callback);
+ mtx_lock(&table->Mutex);
+ table->InDeleteAll = GL_TRUE;
+ hash_table_foreach(table->ht, entry) {
+ callback((uintptr_t)entry->key, entry->data, userData);
+ _mesa_hash_table_remove(table->ht, entry);
+ }
+ if (table->deleted_key_data) {
+ callback(DELETED_KEY_VALUE, table->deleted_key_data, userData);
+ table->deleted_key_data = NULL;
+ }
+ table->InDeleteAll = GL_FALSE;
+ mtx_unlock(&table->Mutex);
+}
+
+
+/**
+ * Clone all entries in a hash table, into a new table.
+ *
+ * \param table the hash table to clone
+ */
+struct _mesa_HashTable *
+_mesa_HashClone(const struct _mesa_HashTable *table)
+{
+ /* cast-away const */
+ struct _mesa_HashTable *table2 = (struct _mesa_HashTable *) table;
+ struct hash_entry *entry;
+ struct _mesa_HashTable *clonetable;
+
+ ASSERT(table);
+ mtx_lock(&table2->Mutex);
+
+ clonetable = _mesa_NewHashTable();
+ assert(clonetable);
+ hash_table_foreach(table->ht, entry) {
+ _mesa_HashInsert(clonetable, (GLint)(uintptr_t)entry->key, entry->data);
+ }
+
+ mtx_unlock(&table2->Mutex);
+
+ return clonetable;
+}
+
+
+/**
+ * Walk over all entries in a hash table, calling callback function for each.
+ * Note: we use a separate mutex in this function to avoid a recursive
+ * locking deadlock (in case the callback calls _mesa_HashRemove()) and to
+ * prevent multiple threads/contexts from getting tangled up.
+ * A lock-less version of this function could be used when the table will
+ * not be modified.
+ * \param table the hash table to walk
+ * \param callback the callback function
+ * \param userData arbitrary pointer to pass along to the callback
+ * (this is typically a struct gl_context pointer)
+ */
+void
+_mesa_HashWalk(const struct _mesa_HashTable *table,
+ void (*callback)(GLuint key, void *data, void *userData),
+ void *userData)
+{
+ /* cast-away const */
+ struct _mesa_HashTable *table2 = (struct _mesa_HashTable *) table;
+ struct hash_entry *entry;
+
+ ASSERT(table);
+ ASSERT(callback);
+ mtx_lock(&table2->WalkMutex);
+ hash_table_foreach(table->ht, entry) {
+ callback((uintptr_t)entry->key, entry->data, userData);
+ }
+ if (table->deleted_key_data)
+ callback(DELETED_KEY_VALUE, table->deleted_key_data, userData);
+ mtx_unlock(&table2->WalkMutex);
+}
+
+static void
+debug_print_entry(GLuint key, void *data, void *userData)
+{
+ _mesa_debug(NULL, "%u %p\n", key, data);
+}
+
+/**
+ * Dump contents of hash table for debugging.
+ *
+ * \param table the hash table.
+ */
+void
+_mesa_HashPrint(const struct _mesa_HashTable *table)
+{
+ if (table->deleted_key_data)
+ debug_print_entry(DELETED_KEY_VALUE, table->deleted_key_data, NULL);
+ _mesa_HashWalk(table, debug_print_entry, NULL);
+}
+
+
+/**
+ * Find a block of adjacent unused hash keys.
+ *
+ * \param table the hash table.
+ * \param numKeys number of keys needed.
+ *
+ * \return Starting key of free block or 0 if failure.
+ *
+ * If there are enough free keys between the maximum key existing in the table
+ * (_mesa_HashTable::MaxKey) and the maximum key possible, then simply return
+ * the adjacent key. Otherwise do a full search for a free key block in the
+ * allowable key range.
+ */
+GLuint
+_mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys)
+{
+ const GLuint maxKey = ~((GLuint) 0) - 1;
+ mtx_lock(&table->Mutex);
+ if (maxKey - numKeys > table->MaxKey) {
+ /* the quick solution */
+ mtx_unlock(&table->Mutex);
+ return table->MaxKey + 1;
+ }
+ else {
+ /* the slow solution */
+ GLuint freeCount = 0;
+ GLuint freeStart = 1;
+ GLuint key;
+ for (key = 1; key != maxKey; key++) {
+ if (_mesa_HashLookup_unlocked(table, key)) {
+ /* darn, this key is already in use */
+ freeCount = 0;
+ freeStart = key+1;
+ }
+ else {
+ /* this key not in use, check if we've found enough */
+ freeCount++;
+ if (freeCount == numKeys) {
+ mtx_unlock(&table->Mutex);
+ return freeStart;
+ }
+ }
+ }
+ /* cannot allocate a block of numKeys consecutive keys */
+ mtx_unlock(&table->Mutex);
+ return 0;
+ }
+}
+
+
+/**
+ * Return the number of entries in the hash table.
+ */
+GLuint
+_mesa_HashNumEntries(const struct _mesa_HashTable *table)
+{
+ struct hash_entry *entry;
+ GLuint count = 0;
+
+ if (table->deleted_key_data)
+ count++;
+
+ hash_table_foreach(table->ht, entry)
+ count++;
+
+ return count;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/hash.h b/icd/intel/compiler/mesa-utils/src/mesa/main/hash.h
new file mode 100644
index 0000000..e3e8f49
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/hash.h
@@ -0,0 +1,80 @@
+/**
+ * \file hash.h
+ * Generic hash table.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef HASH_H
+#define HASH_H
+
+
+#include "glheader.h"
+
+
+extern struct _mesa_HashTable *_mesa_NewHashTable(void);
+
+extern void _mesa_DeleteHashTable(struct _mesa_HashTable *table);
+
+extern void *_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key);
+
+extern void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data);
+
+extern void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key);
+
+extern void _mesa_HashLockMutex(struct _mesa_HashTable *table);
+
+extern void _mesa_HashUnlockMutex(struct _mesa_HashTable *table);
+
+extern void *_mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key);
+
+extern void _mesa_HashInsertLocked(struct _mesa_HashTable *table,
+ GLuint key, void *data);
+
+extern void
+_mesa_HashDeleteAll(struct _mesa_HashTable *table,
+ void (*callback)(GLuint key, void *data, void *userData),
+ void *userData);
+
+extern struct _mesa_HashTable *
+_mesa_HashClone(const struct _mesa_HashTable *table);
+
+extern void
+_mesa_HashWalk(const struct _mesa_HashTable *table,
+ void (*callback)(GLuint key, void *data, void *userData),
+ void *userData);
+
+extern void _mesa_HashPrint(const struct _mesa_HashTable *table);
+
+extern GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys);
+
+extern GLuint
+_mesa_HashNumEntries(const struct _mesa_HashTable *table);
+
+extern void _mesa_test_hash_functions(void);
+
+
+#endif
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/imports.c b/icd/intel/compiler/mesa-utils/src/mesa/main/imports.c
new file mode 100644
index 0000000..a82272a
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/imports.c
@@ -0,0 +1,622 @@
+/**
+ * \file imports.c
+ * Standard C library function wrappers.
+ *
+ * Imports are services which the device driver or window system or
+ * operating system provides to the core renderer. The core renderer (Mesa)
+ * will call these functions in order to do memory allocation, simple I/O,
+ * etc.
+ *
+ * Some drivers will want to override/replace this file with something
+ * specialized, but that'll be rare.
+ *
+ * Eventually, I want to move roll the glheader.h file into this.
+ *
+ * \todo Functions still needed:
+ * - scanf
+ * - qsort
+ * - rand and RAND_MAX
+ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include "imports.h"
+#include "mtypes.h"
+#include "version.h"
+
+#ifdef _GNU_SOURCE
+#include <locale.h>
+#ifdef __APPLE__
+#include <xlocale.h>
+#endif
+#endif
+
+
+#ifdef _WIN32
+#define vsnprintf _vsnprintf
+#elif defined(__IBMC__) || defined(__IBMCPP__)
+extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
+#endif
+
+/**********************************************************************/
+/** \name Memory */
+/*@{*/
+
+/**
+ * Allocate aligned memory.
+ *
+ * \param bytes number of bytes to allocate.
+ * \param alignment alignment (must be greater than zero).
+ *
+ * Allocates extra memory to accommodate rounding up the address for
+ * alignment and to record the real malloc address.
+ *
+ * \sa _mesa_align_free().
+ */
+void *
+_mesa_align_malloc(size_t bytes, unsigned long alignment)
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+ void *mem;
+ int err = posix_memalign(& mem, alignment, bytes);
+ if (err)
+ return NULL;
+ return mem;
+#elif defined(_WIN32) && defined(_MSC_VER)
+ return _aligned_malloc(bytes, alignment);
+#else
+ uintptr_t ptr, buf;
+
+ ASSERT( alignment > 0 );
+
+ ptr = (uintptr_t)malloc(bytes + alignment + sizeof(void *));
+ if (!ptr)
+ return NULL;
+
+ buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
+ *(uintptr_t *)(buf - sizeof(void *)) = ptr;
+
+#ifdef DEBUG
+ /* mark the non-aligned area */
+ while ( ptr < buf - sizeof(void *) ) {
+ *(unsigned long *)ptr = 0xcdcdcdcd;
+ ptr += sizeof(unsigned long);
+ }
+#endif
+
+ return (void *) buf;
+#endif /* defined(HAVE_POSIX_MEMALIGN) */
+}
+
+/**
+ * Same as _mesa_align_malloc(), but using calloc(1, ) instead of
+ * malloc()
+ */
+void *
+_mesa_align_calloc(size_t bytes, unsigned long alignment)
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+ void *mem;
+
+ mem = _mesa_align_malloc(bytes, alignment);
+ if (mem != NULL) {
+ (void) memset(mem, 0, bytes);
+ }
+
+ return mem;
+#elif defined(_WIN32) && defined(_MSC_VER)
+ void *mem;
+
+ mem = _aligned_malloc(bytes, alignment);
+ if (mem != NULL) {
+ (void) memset(mem, 0, bytes);
+ }
+
+ return mem;
+#else
+ uintptr_t ptr, buf;
+
+ ASSERT( alignment > 0 );
+
+ ptr = (uintptr_t)calloc(1, bytes + alignment + sizeof(void *));
+ if (!ptr)
+ return NULL;
+
+ buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
+ *(uintptr_t *)(buf - sizeof(void *)) = ptr;
+
+#ifdef DEBUG
+ /* mark the non-aligned area */
+ while ( ptr < buf - sizeof(void *) ) {
+ *(unsigned long *)ptr = 0xcdcdcdcd;
+ ptr += sizeof(unsigned long);
+ }
+#endif
+
+ return (void *)buf;
+#endif /* defined(HAVE_POSIX_MEMALIGN) */
+}
+
+/**
+ * Free memory which was allocated with either _mesa_align_malloc()
+ * or _mesa_align_calloc().
+ * \param ptr pointer to the memory to be freed.
+ * The actual address to free is stored in the word immediately before the
+ * address the client sees.
+ * Note that it is legal to pass NULL pointer to this function and will be
+ * handled accordingly.
+ */
+void
+_mesa_align_free(void *ptr)
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+ free(ptr);
+#elif defined(_WIN32) && defined(_MSC_VER)
+ _aligned_free(ptr);
+#else
+ if (ptr) {
+ void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
+ void *realAddr = *cubbyHole;
+ free(realAddr);
+ }
+#endif /* defined(HAVE_POSIX_MEMALIGN) */
+}
+
+/**
+ * Reallocate memory, with alignment.
+ */
+void *
+_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
+ unsigned long alignment)
+{
+#if defined(_WIN32) && defined(_MSC_VER)
+ (void) oldSize;
+ return _aligned_realloc(oldBuffer, newSize, alignment);
+#else
+ const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
+ void *newBuf = _mesa_align_malloc(newSize, alignment);
+ if (newBuf && oldBuffer && copySize > 0) {
+ memcpy(newBuf, oldBuffer, copySize);
+ }
+
+ _mesa_align_free(oldBuffer);
+ return newBuf;
+#endif
+}
+
+
+
+/** Reallocate memory */
+void *
+_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
+{
+ const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
+ void *newBuffer = malloc(newSize);
+ if (newBuffer && oldBuffer && copySize > 0)
+ memcpy(newBuffer, oldBuffer, copySize);
+ free(oldBuffer);
+ return newBuffer;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Math */
+/*@{*/
+
+
+#ifndef __GNUC__
+/**
+ * Find the first bit set in a word.
+ */
+int
+ffs(int i)
+{
+ register int bit = 0;
+ if (i != 0) {
+ if ((i & 0xffff) == 0) {
+ bit += 16;
+ i >>= 16;
+ }
+ if ((i & 0xff) == 0) {
+ bit += 8;
+ i >>= 8;
+ }
+ if ((i & 0xf) == 0) {
+ bit += 4;
+ i >>= 4;
+ }
+ while ((i & 1) == 0) {
+ bit++;
+ i >>= 1;
+ }
+ bit++;
+ }
+ return bit;
+}
+
+
+/**
+ * Find position of first bit set in given value.
+ * XXX Warning: this function can only be used on 64-bit systems!
+ * \return position of least-significant bit set, starting at 1, return zero
+ * if no bits set.
+ */
+int
+ffsll(long long int val)
+{
+ int bit;
+
+ assert(sizeof(val) == 8);
+
+ bit = ffs((int) val);
+ if (bit != 0)
+ return bit;
+
+ bit = ffs((int) (val >> 32));
+ if (bit != 0)
+ return 32 + bit;
+
+ return 0;
+}
+#endif /* __GNUC__ */
+
+
+#if !defined(__GNUC__) ||\
+ ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
+/**
+ * Return number of bits set in given GLuint.
+ */
+unsigned int
+_mesa_bitcount(unsigned int n)
+{
+ unsigned int bits;
+ for (bits = 0; n > 0; n = n >> 1) {
+ bits += (n & 1);
+ }
+ return bits;
+}
+
+/**
+ * Return number of bits set in given 64-bit uint.
+ */
+unsigned int
+_mesa_bitcount_64(uint64_t n)
+{
+ unsigned int bits;
+ for (bits = 0; n > 0; n = n >> 1) {
+ bits += (n & 1);
+ }
+ return bits;
+}
+#endif
+
+
+/* Using C99 rounding functions for roundToEven() implementation is
+ * difficult, because round(), rint, and nearbyint() are affected by
+ * fesetenv(), which the application may have done for its own
+ * purposes. Mesa's IROUND macro is close to what we want, but it
+ * rounds away from 0 on n + 0.5.
+ */
+int
+_mesa_round_to_even(float val)
+{
+ int rounded = IROUND(val);
+
+ if (val - floor(val) == 0.5) {
+ if (rounded % 2 != 0)
+ rounded += val > 0 ? -1 : 1;
+ }
+
+ return rounded;
+}
+
+
+/**
+ * Convert a 4-byte float to a 2-byte half float.
+ *
+ * Not all float32 values can be represented exactly as a float16 value. We
+ * round such intermediate float32 values to the nearest float16. When the
+ * float32 lies exactly between to float16 values, we round to the one with
+ * an even mantissa.
+ *
+ * This rounding behavior has several benefits:
+ * - It has no sign bias.
+ *
+ * - It reproduces the behavior of real hardware: opcode F32TO16 in Intel's
+ * GPU ISA.
+ *
+ * - By reproducing the behavior of the GPU (at least on Intel hardware),
+ * compile-time evaluation of constant packHalf2x16 GLSL expressions will
+ * result in the same value as if the expression were executed on the GPU.
+ */
+GLhalfARB
+_mesa_float_to_half(float val)
+{
+ const fi_type fi = {val};
+ const int flt_m = fi.i & 0x7fffff;
+ const int flt_e = (fi.i >> 23) & 0xff;
+ const int flt_s = (fi.i >> 31) & 0x1;
+ int s, e, m = 0;
+ GLhalfARB result;
+
+ /* sign bit */
+ s = flt_s;
+
+ /* handle special cases */
+ if ((flt_e == 0) && (flt_m == 0)) {
+ /* zero */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if ((flt_e == 0) && (flt_m != 0)) {
+ /* denorm -- denorm float maps to 0 half */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if ((flt_e == 0xff) && (flt_m == 0)) {
+ /* infinity */
+ /* m = 0; - already set */
+ e = 31;
+ }
+ else if ((flt_e == 0xff) && (flt_m != 0)) {
+ /* NaN */
+ m = 1;
+ e = 31;
+ }
+ else {
+ /* regular number */
+ const int new_exp = flt_e - 127;
+ if (new_exp < -14) {
+ /* The float32 lies in the range (0.0, min_normal16) and is rounded
+ * to a nearby float16 value. The result will be either zero, subnormal,
+ * or normal.
+ */
+ e = 0;
+ m = _mesa_round_to_even((1 << 24) * fabsf(fi.f));
+ }
+ else if (new_exp > 15) {
+ /* map this value to infinity */
+ /* m = 0; - already set */
+ e = 31;
+ }
+ else {
+ /* The float32 lies in the range
+ * [min_normal16, max_normal16 + max_step16)
+ * and is rounded to a nearby float16 value. The result will be
+ * either normal or infinite.
+ */
+ e = new_exp + 15;
+ m = _mesa_round_to_even(flt_m / (float) (1 << 13));
+ }
+ }
+
+ assert(0 <= m && m <= 1024);
+ if (m == 1024) {
+ /* The float32 was rounded upwards into the range of the next exponent,
+ * so bump the exponent. This correctly handles the case where f32
+ * should be rounded up to float16 infinity.
+ */
+ ++e;
+ m = 0;
+ }
+
+ result = (s << 15) | (e << 10) | m;
+ return result;
+}
+
+
+/**
+ * Convert a 2-byte half float to a 4-byte float.
+ * Based on code from:
+ * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
+ */
+float
+_mesa_half_to_float(GLhalfARB val)
+{
+ /* XXX could also use a 64K-entry lookup table */
+ const int m = val & 0x3ff;
+ const int e = (val >> 10) & 0x1f;
+ const int s = (val >> 15) & 0x1;
+ int flt_m, flt_e, flt_s;
+ fi_type fi;
+ float result;
+
+ /* sign bit */
+ flt_s = s;
+
+ /* handle special cases */
+ if ((e == 0) && (m == 0)) {
+ /* zero */
+ flt_m = 0;
+ flt_e = 0;
+ }
+ else if ((e == 0) && (m != 0)) {
+ /* denorm -- denorm half will fit in non-denorm single */
+ const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
+ float mantissa = ((float) (m)) / 1024.0f;
+ float sign = s ? -1.0f : 1.0f;
+ return sign * mantissa * half_denorm;
+ }
+ else if ((e == 31) && (m == 0)) {
+ /* infinity */
+ flt_e = 0xff;
+ flt_m = 0;
+ }
+ else if ((e == 31) && (m != 0)) {
+ /* NaN */
+ flt_e = 0xff;
+ flt_m = 1;
+ }
+ else {
+ /* regular */
+ flt_e = e + 112;
+ flt_m = m << 13;
+ }
+
+ fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
+ result = fi.f;
+ return result;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Sort & Search */
+/*@{*/
+
+/**
+ * Wrapper for bsearch().
+ */
+void *
+_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *) )
+{
+#if defined(_WIN32_WCE)
+ void *mid;
+ int cmp;
+ while (nmemb) {
+ nmemb >>= 1;
+ mid = (char *)base + nmemb * size;
+ cmp = (*compar)(key, mid);
+ if (cmp == 0)
+ return mid;
+ if (cmp > 0) {
+ base = (char *)mid + size;
+ --nmemb;
+ }
+ }
+ return NULL;
+#else
+ return bsearch(key, base, nmemb, size, compar);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Environment vars */
+/*@{*/
+
+/**
+ * Wrapper for getenv().
+ */
+char *
+_mesa_getenv( const char *var )
+{
+#if defined(_XBOX) || defined(_WIN32_WCE)
+ return NULL;
+#else
+ return getenv(var);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name String */
+/*@{*/
+
+/**
+ * Implemented using malloc() and strcpy.
+ * Note that NULL is handled accordingly.
+ */
+char *
+_mesa_strdup( const char *s )
+{
+ if (s) {
+ size_t l = strlen(s);
+ char *s2 = malloc(l + 1);
+ if (s2)
+ strcpy(s2, s);
+ return s2;
+ }
+ else {
+ return NULL;
+ }
+}
+
+/** Wrapper around strtof() */
+float
+_mesa_strtof( const char *s, char **end )
+{
+#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
+ !defined(ANDROID) && !defined(__HAIKU__) && !defined(__UCLIBC__) && \
+ !defined(__NetBSD__)
+ static locale_t loc = NULL;
+ if (!loc) {
+ loc = newlocale(LC_CTYPE_MASK, "C", NULL);
+ }
+ return strtof_l(s, end, loc);
+#elif defined(_ISOC99_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
+ return strtof(s, end);
+#else
+ return (float)strtod(s, end);
+#endif
+}
+
+/** Compute simple checksum/hash for a string */
+unsigned int
+_mesa_str_checksum(const char *str)
+{
+ /* This could probably be much better */
+ unsigned int sum, i;
+ const char *c;
+ sum = i = 1;
+ for (c = str; *c; c++, i++)
+ sum += *c * (i % 100);
+ return sum + i;
+}
+
+
+/*@}*/
+
+
+/** Needed due to #ifdef's, above. */
+int
+_mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list args)
+{
+ return vsnprintf( str, size, fmt, args);
+}
+
+/** Wrapper around vsnprintf() */
+int
+_mesa_snprintf( char *str, size_t size, const char *fmt, ... )
+{
+ int r;
+ va_list args;
+ va_start( args, fmt );
+ r = vsnprintf( str, size, fmt, args );
+ va_end( args );
+ return r;
+}
+
+
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/imports.h b/icd/intel/compiler/mesa-utils/src/mesa/main/imports.h
new file mode 100644
index 0000000..db588a7
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/imports.h
@@ -0,0 +1,603 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file imports.h
+ * Standard C library function wrappers.
+ *
+ * This file provides wrappers for all the standard C library functions
+ * like malloc(), free(), printf(), getenv(), etc.
+ */
+
+
+#ifndef IMPORTS_H
+#define IMPORTS_H
+
+
+#include "compiler.h"
+#include "glheader.h"
+#include "errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**********************************************************************/
+/** Memory macros */
+/*@{*/
+
+/** Allocate a structure of type \p T */
+#define MALLOC_STRUCT(T) (struct T *) malloc(sizeof(struct T))
+/** Allocate and zero a structure of type \p T */
+#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
+
+/*@}*/
+
+
+/*
+ * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers
+ * as offsets into buffer stores. Since the vertex array pointer and
+ * buffer store pointer are both pointers and we need to add them, we use
+ * this macro.
+ * Both pointers/offsets are expressed in bytes.
+ */
+#define ADD_POINTERS(A, B) ( (GLubyte *) (A) + (uintptr_t) (B) )
+
+
+/**
+ * Sometimes we treat GLfloats as GLints. On x86 systems, moving a float
+ * as a int (thereby using integer registers instead of FP registers) is
+ * a performance win. Typically, this can be done with ordinary casts.
+ * But with gcc's -fstrict-aliasing flag (which defaults to on in gcc 3.0)
+ * these casts generate warnings.
+ * The following union typedef is used to solve that.
+ */
+typedef union { GLfloat f; GLint i; GLuint u; } fi_type;
+
+
+
+/**********************************************************************
+ * Math macros
+ */
+
+#define MAX_GLUSHORT 0xffff
+#define MAX_GLUINT 0xffffffff
+
+/* Degrees to radians conversion: */
+#define DEG2RAD (M_PI/180.0)
+
+
+/**
+ * \name Work-arounds for platforms that lack C99 math functions
+ */
+/*@{*/
+#if (!defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 600)) && !defined(_ISOC99_SOURCE) \
+ && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)) \
+ && (!defined(_MSC_VER) || (_MSC_VER < 1400))
+#define acosf(f) ((float) acos(f))
+#define asinf(f) ((float) asin(f))
+#define atan2f(x,y) ((float) atan2(x,y))
+#define atanf(f) ((float) atan(f))
+#define ceilf(f) ((float) ceil(f))
+#define cosf(f) ((float) cos(f))
+#define coshf(f) ((float) cosh(f))
+#define expf(f) ((float) exp(f))
+#define exp2f(f) ((float) exp2(f))
+#define floorf(f) ((float) floor(f))
+#define logf(f) ((float) log(f))
+
+#ifdef ANDROID
+#define log2f(f) (logf(f) * (float) (1.0 / M_LN2))
+#else
+#define log2f(f) ((float) log2(f))
+#endif
+
+#define powf(x,y) ((float) pow(x,y))
+#define sinf(f) ((float) sin(f))
+#define sinhf(f) ((float) sinh(f))
+#define sqrtf(f) ((float) sqrt(f))
+#define tanf(f) ((float) tan(f))
+#define tanhf(f) ((float) tanh(f))
+#define acoshf(f) ((float) acosh(f))
+#define asinhf(f) ((float) asinh(f))
+#define atanhf(f) ((float) atanh(f))
+#endif
+
+#if defined(_MSC_VER)
+#if _MSC_VER < 1800 /* Not req'd on VS2013 and above */
+static inline float truncf(float x) { return x < 0.0f ? ceilf(x) : floorf(x); }
+static inline float exp2f(float x) { return powf(2.0f, x); }
+static inline float log2f(float x) { return logf(x) * 1.442695041f; }
+static inline float asinhf(float x) { return logf(x + sqrtf(x * x + 1.0f)); }
+static inline float acoshf(float x) { return logf(x + sqrtf(x * x - 1.0f)); }
+static inline float atanhf(float x) { return (logf(1.0f + x) - logf(1.0f - x)) / 2.0f; }
+static inline int isblank(int ch) { return ch == ' ' || ch == '\t'; }
+#define strtoll(p, e, b) _strtoi64(p, e, b)
+#endif /* _MSC_VER < 1800 */
+#define strcasecmp(s1, s2) _stricmp(s1, s2)
+#endif
+/*@}*/
+
+
+/*
+ * signbit() is a macro on Linux. Not available on Windows.
+ */
+#ifndef signbit
+#define signbit(x) ((x) < 0.0f)
+#endif
+
+
+/** single-precision inverse square root */
+static inline float
+INV_SQRTF(float x)
+{
+ /* XXX we could try Quake's fast inverse square root function here */
+ return 1.0F / sqrtf(x);
+}
+
+
+/***
+ *** LOG2: Log base 2 of float
+ ***/
+static inline GLfloat LOG2(GLfloat x)
+{
+#ifdef USE_IEEE
+#if 0
+ /* This is pretty fast, but not accurate enough (only 2 fractional bits).
+ * Based on code from http://www.stereopsis.com/log2.html
+ */
+ const GLfloat y = x * x * x * x;
+ const GLuint ix = *((GLuint *) &y);
+ const GLuint exp = (ix >> 23) & 0xFF;
+ const GLint log2 = ((GLint) exp) - 127;
+ return (GLfloat) log2 * (1.0 / 4.0); /* 4, because of x^4 above */
+#endif
+ /* Pretty fast, and accurate.
+ * Based on code from http://www.flipcode.com/totd/
+ */
+ fi_type num;
+ GLint log_2;
+ num.f = x;
+ log_2 = ((num.i >> 23) & 255) - 128;
+ num.i &= ~(255 << 23);
+ num.i += 127 << 23;
+ num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3;
+ return num.f + log_2;
+#else
+ /*
+ * NOTE: log_base_2(x) = log(x) / log(2)
+ * NOTE: 1.442695 = 1/log(2).
+ */
+ return (GLfloat) (log(x) * 1.442695F);
+#endif
+}
+
+
+
+/***
+ *** IS_INF_OR_NAN: test if float is infinite or NaN
+ ***/
+#ifdef USE_IEEE
+static inline int IS_INF_OR_NAN( float x )
+{
+ fi_type tmp;
+ tmp.f = x;
+ return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31);
+}
+#elif defined(isfinite)
+#define IS_INF_OR_NAN(x) (!isfinite(x))
+#elif defined(finite)
+#define IS_INF_OR_NAN(x) (!finite(x))
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#define IS_INF_OR_NAN(x) (!isfinite(x))
+#else
+#define IS_INF_OR_NAN(x) (!finite(x))
+#endif
+
+
+/***
+ *** CEILF: ceiling of float
+ *** FLOORF: floor of float
+ *** FABSF: absolute value of float
+ *** LOGF: the natural logarithm (base e) of the value
+ *** EXPF: raise e to the value
+ *** LDEXPF: multiply value by an integral power of two
+ *** FREXPF: extract mantissa and exponent from value
+ ***/
+#if defined(__gnu_linux__)
+/* C99 functions */
+#define CEILF(x) ceilf(x)
+#define FLOORF(x) floorf(x)
+#define FABSF(x) fabsf(x)
+#define LOGF(x) logf(x)
+#define EXPF(x) expf(x)
+#define LDEXPF(x,y) ldexpf(x,y)
+#define FREXPF(x,y) frexpf(x,y)
+#else
+#define CEILF(x) ((GLfloat) ceil(x))
+#define FLOORF(x) ((GLfloat) floor(x))
+#define FABSF(x) ((GLfloat) fabs(x))
+#define LOGF(x) ((GLfloat) log(x))
+#define EXPF(x) ((GLfloat) exp(x))
+#define LDEXPF(x,y) ((GLfloat) ldexp(x,y))
+#define FREXPF(x,y) ((GLfloat) frexp(x,y))
+#endif
+
+
+/**
+ * Convert float to int by rounding to nearest integer, away from zero.
+ */
+static inline int IROUND(float f)
+{
+ return (int) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F));
+}
+
+
+/**
+ * Convert float to int64 by rounding to nearest integer.
+ */
+static inline GLint64 IROUND64(float f)
+{
+ return (GLint64) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F));
+}
+
+
+/**
+ * Convert positive float to int by rounding to nearest integer.
+ */
+static inline int IROUND_POS(float f)
+{
+ assert(f >= 0.0F);
+ return (int) (f + 0.5F);
+}
+
+
+/**
+ * Convert float to int using a fast method. The rounding mode may vary.
+ * XXX We could use an x86-64/SSE2 version here.
+ */
+static inline int F_TO_I(float f)
+{
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+ int r;
+ __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
+ return r;
+#elif defined(USE_X86_ASM) && defined(_MSC_VER)
+ int r;
+ _asm {
+ fld f
+ fistp r
+ }
+ return r;
+#else
+ return IROUND(f);
+#endif
+}
+
+
+/** Return (as an integer) floor of float */
+static inline int IFLOOR(float f)
+{
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+ /*
+ * IEEE floor for computers that round to nearest or even.
+ * 'f' must be between -4194304 and 4194303.
+ * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
+ * but uses some IEEE specific tricks for better speed.
+ * Contributed by Josh Vanderhoof
+ */
+ int ai, bi;
+ double af, bf;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ /* GCC generates an extra fstp/fld without this. */
+ __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+ return (ai - bi) >> 1;
+#elif defined(USE_IEEE)
+ int ai, bi;
+ double af, bf;
+ fi_type u;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ u.f = (float) af; ai = u.i;
+ u.f = (float) bf; bi = u.i;
+ return (ai - bi) >> 1;
+#else
+ int i = IROUND(f);
+ return (i > f) ? i - 1 : i;
+#endif
+}
+
+
+/** Return (as an integer) ceiling of float */
+static inline int ICEIL(float f)
+{
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+ /*
+ * IEEE ceil for computers that round to nearest or even.
+ * 'f' must be between -4194304 and 4194303.
+ * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
+ * but uses some IEEE specific tricks for better speed.
+ * Contributed by Josh Vanderhoof
+ */
+ int ai, bi;
+ double af, bf;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ /* GCC generates an extra fstp/fld without this. */
+ __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+ return (ai - bi + 1) >> 1;
+#elif defined(USE_IEEE)
+ int ai, bi;
+ double af, bf;
+ fi_type u;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ u.f = (float) af; ai = u.i;
+ u.f = (float) bf; bi = u.i;
+ return (ai - bi + 1) >> 1;
+#else
+ int i = IROUND(f);
+ return (i < f) ? i + 1 : i;
+#endif
+}
+
+
+/**
+ * Is x a power of two?
+ */
+static inline int
+_mesa_is_pow_two(int x)
+{
+ return !(x & (x - 1));
+}
+
+/**
+ * Round given integer to next higer power of two
+ * If X is zero result is undefined.
+ *
+ * Source for the fallback implementation is
+ * Sean Eron Anderson's webpage "Bit Twiddling Hacks"
+ * http://graphics.stanford.edu/~seander/bithacks.html
+ *
+ * When using builtin function have to do some work
+ * for case when passed values 1 to prevent hiting
+ * undefined result from __builtin_clz. Undefined
+ * results would be different depending on optimization
+ * level used for build.
+ */
+static inline int32_t
+_mesa_next_pow_two_32(uint32_t x)
+{
+#if defined(__GNUC__) && \
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+ uint32_t y = (x != 1);
+ return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
+#else
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x++;
+ return x;
+#endif
+}
+
+static inline int64_t
+_mesa_next_pow_two_64(uint64_t x)
+{
+#if defined(__GNUC__) && \
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+ uint64_t y = (x != 1);
+ if (sizeof(x) == sizeof(long))
+ return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
+ else
+ return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
+#else
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x |= x >> 32;
+ x++;
+ return x;
+#endif
+}
+
+
+/*
+ * Returns the floor form of binary logarithm for a 32-bit integer.
+ */
+static inline GLuint
+_mesa_logbase2(GLuint n)
+{
+#if defined(__GNUC__) && \
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+ return (31 - __builtin_clz(n | 1));
+#else
+ GLuint pos = 0;
+ if (n >= 1<<16) { n >>= 16; pos += 16; }
+ if (n >= 1<< 8) { n >>= 8; pos += 8; }
+ if (n >= 1<< 4) { n >>= 4; pos += 4; }
+ if (n >= 1<< 2) { n >>= 2; pos += 2; }
+ if (n >= 1<< 1) { pos += 1; }
+ return pos;
+#endif
+}
+
+
+/**
+ * Return 1 if this is a little endian machine, 0 if big endian.
+ */
+static inline GLboolean
+_mesa_little_endian(void)
+{
+ const GLuint ui = 1; /* intentionally not static */
+ return *((const GLubyte *) &ui);
+}
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+
+static inline int
+_mesa_mkdir(const char *path)
+{
+#ifdef _WIN32
+ if (_mkdir(path) != 0)
+ return errno;
+ return 0;
+#else
+ if (mkdir(path, 0775) != 0)
+ return errno;
+ return 0;
+#endif
+}
+
+
+
+/**********************************************************************
+ * Functions
+ */
+
+extern void *
+_mesa_align_malloc( size_t bytes, unsigned long alignment );
+
+extern void *
+_mesa_align_calloc( size_t bytes, unsigned long alignment );
+
+extern void
+_mesa_align_free( void *ptr );
+
+extern void *
+_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
+ unsigned long alignment);
+
+extern void *
+_mesa_exec_malloc( GLuint size );
+
+extern void
+_mesa_exec_free( void *addr );
+
+extern void *
+_mesa_realloc( void *oldBuffer, size_t oldSize, size_t newSize );
+
+
+#ifndef FFS_DEFINED
+#define FFS_DEFINED 1
+#ifdef __GNUC__
+#define ffs __builtin_ffs
+#define ffsll __builtin_ffsll
+#else
+extern int ffs(int i);
+extern int ffsll(long long int i);
+#endif /*__ GNUC__ */
+#endif /* FFS_DEFINED */
+
+
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#define _mesa_bitcount(i) __builtin_popcount(i)
+#define _mesa_bitcount_64(i) __builtin_popcountll(i)
+#else
+extern unsigned int
+_mesa_bitcount(unsigned int n);
+extern unsigned int
+_mesa_bitcount_64(uint64_t n);
+#endif
+
+/**
+ * Find the last (most significant) bit set in a word.
+ *
+ * Essentially ffs() in the reverse direction.
+ */
+static inline unsigned int
+_mesa_fls(unsigned int n)
+{
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304)
+ return n == 0 ? 0 : 32 - __builtin_clz(n);
+#else
+ unsigned int v = 1;
+
+ if (n == 0)
+ return 0;
+
+ while (n >>= 1)
+ v++;
+
+ return v;
+#endif
+}
+
+extern int
+_mesa_round_to_even(float val);
+
+extern GLhalfARB
+_mesa_float_to_half(float f);
+
+extern float
+_mesa_half_to_float(GLhalfARB h);
+
+
+extern void *
+_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *) );
+
+extern char *
+_mesa_getenv( const char *var );
+
+extern char *
+_mesa_strdup( const char *s );
+
+extern float
+_mesa_strtof( const char *s, char **end );
+
+extern unsigned int
+_mesa_str_checksum(const char *str);
+
+extern int
+_mesa_snprintf( char *str, size_t size, const char *fmt, ... ) PRINTFLIKE(3, 4);
+
+extern int
+_mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list arg);
+
+
+#if defined(_MSC_VER) && !defined(snprintf)
+#define snprintf _snprintf
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* IMPORTS_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/macros.h b/icd/intel/compiler/mesa-utils/src/mesa/main/macros.h
new file mode 100644
index 0000000..5228c3a
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/macros.h
@@ -0,0 +1,826 @@
+/**
+ * \file macros.h
+ * A collection of useful macros.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef MACROS_H
+#define MACROS_H
+
+#include "imports.h"
+
+
+/**
+ * \name Integer / float conversion for colors, normals, etc.
+ */
+/*@{*/
+
+/** Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */
+extern GLfloat _mesa_ubyte_to_float_color_tab[256];
+#define UBYTE_TO_FLOAT(u) _mesa_ubyte_to_float_color_tab[(unsigned int)(u)]
+
+/** Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */
+#define FLOAT_TO_UBYTE(X) ((GLubyte) (GLint) ((X) * 255.0F))
+
+
+/** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */
+#define BYTE_TO_FLOAT(B) ((2.0F * (B) + 1.0F) * (1.0F/255.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */
+#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 )
+
+
+/** Convert GLbyte to GLfloat while preserving zero */
+#define BYTE_TO_FLOATZ(B) ((B) == 0 ? 0.0F : BYTE_TO_FLOAT(B))
+
+
+/** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0], texture/fb data */
+#define BYTE_TO_FLOAT_TEX(B) ((B) == -128 ? -1.0F : (B) * (1.0F/127.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127], texture/fb data */
+#define FLOAT_TO_BYTE_TEX(X) CLAMP( (GLint) (127.0F * (X)), -128, 127 )
+
+/** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */
+#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F))
+
+/** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */
+#define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.0F))
+
+
+/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
+#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767] */
+#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 )
+
+/** Convert GLshort to GLfloat while preserving zero */
+#define SHORT_TO_FLOATZ(S) ((S) == 0 ? 0.0F : SHORT_TO_FLOAT(S))
+
+
+/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0], texture/fb data */
+#define SHORT_TO_FLOAT_TEX(S) ((S) == -32768 ? -1.0F : (S) * (1.0F/32767.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767], texture/fb data */
+#define FLOAT_TO_SHORT_TEX(X) ( (GLint) (32767.0F * (X)) )
+
+
+/** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
+#define UINT_TO_FLOAT(U) ((GLfloat) ((U) * (1.0F / 4294967295.0)))
+
+/** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */
+#define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0))
+
+
+/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
+#define INT_TO_FLOAT(I) ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0)))
+
+/** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */
+/* causes overflow:
+#define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0 * (X))) - 1) / 2 )
+*/
+/* a close approximation: */
+#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) )
+
+/** Convert GLfloat in [-1.0,1.0] to GLint64 in [-(1<<63),(1 << 63) -1] */
+#define FLOAT_TO_INT64(X) ( (GLint64) (9223372036854775807.0 * (double)(X)) )
+
+
+/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */
+#define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0F : (I) * (1.0F/2147483647.0))
+
+/** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647], texture/fb data */
+#define FLOAT_TO_INT_TEX(X) ( (GLint) (2147483647.0 * (X)) )
+
+
+#define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
+#define SHORT_TO_UBYTE(s) ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
+#define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
+#define INT_TO_UBYTE(i) ((GLubyte) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23)))
+#define UINT_TO_UBYTE(i) ((GLubyte) ((i) >> 24))
+
+
+#define BYTE_TO_USHORT(b) ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255)))
+#define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b))
+#define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767))))
+#define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15)))
+#define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16)))
+#define UNCLAMPED_FLOAT_TO_USHORT(us, f) \
+ us = ( (GLushort) F_TO_I( CLAMP((f), 0.0F, 1.0F) * 65535.0F) )
+#define CLAMPED_FLOAT_TO_USHORT(us, f) \
+ us = ( (GLushort) F_TO_I( (f) * 65535.0F) )
+
+#define UNCLAMPED_FLOAT_TO_SHORT(s, f) \
+ s = ( (GLshort) F_TO_I( CLAMP((f), -1.0F, 1.0F) * 32767.0F) )
+
+/***
+ *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255]
+ *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255]
+ ***/
+#if defined(USE_IEEE) && !defined(DEBUG)
+/* This function/macro is sensitive to precision. Test very carefully
+ * if you change it!
+ */
+#define UNCLAMPED_FLOAT_TO_UBYTE(UB, F) \
+ do { \
+ fi_type __tmp; \
+ __tmp.f = (F); \
+ if (__tmp.i < 0) \
+ UB = (GLubyte) 0; \
+ else if (__tmp.i >= IEEE_ONE) \
+ UB = (GLubyte) 255; \
+ else { \
+ __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F; \
+ UB = (GLubyte) __tmp.i; \
+ } \
+ } while (0)
+#define CLAMPED_FLOAT_TO_UBYTE(UB, F) \
+ do { \
+ fi_type __tmp; \
+ __tmp.f = (F) * (255.0F/256.0F) + 32768.0F; \
+ UB = (GLubyte) __tmp.i; \
+ } while (0)
+#else
+#define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
+ ub = ((GLubyte) F_TO_I(CLAMP((f), 0.0F, 1.0F) * 255.0F))
+#define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
+ ub = ((GLubyte) F_TO_I((f) * 255.0F))
+#endif
+
+static inline GLfloat INT_AS_FLT(GLint i)
+{
+ fi_type tmp;
+ tmp.i = i;
+ return tmp.f;
+}
+
+static inline GLfloat UINT_AS_FLT(GLuint u)
+{
+ fi_type tmp;
+ tmp.u = u;
+ return tmp.f;
+}
+
+/**
+ * Convert a floating point value to an unsigned fixed point value.
+ *
+ * \param frac_bits The number of bits used to store the fractional part.
+ */
+static INLINE uint32_t
+U_FIXED(float value, uint32_t frac_bits)
+{
+ value *= (1 << frac_bits);
+ return value < 0.0f ? 0 : (uint32_t) value;
+}
+
+/**
+ * Convert a floating point value to an signed fixed point value.
+ *
+ * \param frac_bits The number of bits used to store the fractional part.
+ */
+static INLINE int32_t
+S_FIXED(float value, uint32_t frac_bits)
+{
+ return (int32_t) (value * (1 << frac_bits));
+}
+/*@}*/
+
+
+/** Stepping a GLfloat pointer by a byte stride */
+#define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i))
+/** Stepping a GLuint pointer by a byte stride */
+#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i))
+/** Stepping a GLubyte[4] pointer by a byte stride */
+#define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i))
+/** Stepping a GLfloat[4] pointer by a byte stride */
+#define STRIDE_4F(p, i) (p = (GLfloat (*)[4])((GLubyte *)p + i))
+/** Stepping a \p t pointer by a byte stride */
+#define STRIDE_T(p, t, i) (p = (t)((GLubyte *)p + i))
+
+
+/**********************************************************************/
+/** \name 4-element vector operations */
+/*@{*/
+
+/** Zero */
+#define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0
+
+/** Test for equality */
+#define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \
+ (a)[1] == (b)[1] && \
+ (a)[2] == (b)[2] && \
+ (a)[3] == (b)[3])
+
+/** Test for equality (unsigned bytes) */
+static inline GLboolean
+TEST_EQ_4UBV(const GLubyte a[4], const GLubyte b[4])
+{
+#if defined(__i386__)
+ return *((const GLuint *) a) == *((const GLuint *) b);
+#else
+ return TEST_EQ_4V(a, b);
+#endif
+}
+
+
+/** Copy a 4-element vector */
+#define COPY_4V( DST, SRC ) \
+do { \
+ (DST)[0] = (SRC)[0]; \
+ (DST)[1] = (SRC)[1]; \
+ (DST)[2] = (SRC)[2]; \
+ (DST)[3] = (SRC)[3]; \
+} while (0)
+
+/** Copy a 4-element unsigned byte vector */
+static inline void
+COPY_4UBV(GLubyte dst[4], const GLubyte src[4])
+{
+#if defined(__i386__)
+ *((GLuint *) dst) = *((GLuint *) src);
+#else
+ /* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */
+ COPY_4V(dst, src);
+#endif
+}
+
+/** Copy a 4-element float vector */
+static inline void
+COPY_4FV(GLfloat dst[4], const GLfloat src[4])
+{
+ /* memcpy seems to be most efficient */
+ memcpy(dst, src, sizeof(GLfloat) * 4);
+}
+
+/** Copy \p SZ elements into a 4-element vector */
+#define COPY_SZ_4V(DST, SZ, SRC) \
+do { \
+ switch (SZ) { \
+ case 4: (DST)[3] = (SRC)[3]; \
+ case 3: (DST)[2] = (SRC)[2]; \
+ case 2: (DST)[1] = (SRC)[1]; \
+ case 1: (DST)[0] = (SRC)[0]; \
+ } \
+} while(0)
+
+/** Copy \p SZ elements into a homegeneous (4-element) vector, giving
+ * default values to the remaining */
+#define COPY_CLEAN_4V(DST, SZ, SRC) \
+do { \
+ ASSIGN_4V( DST, 0, 0, 0, 1 ); \
+ COPY_SZ_4V( DST, SZ, SRC ); \
+} while (0)
+
+/** Subtraction */
+#define SUB_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] - (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] - (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] - (SRCB)[2]; \
+ (DST)[3] = (SRCA)[3] - (SRCB)[3]; \
+} while (0)
+
+/** Addition */
+#define ADD_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] + (SRCB)[2]; \
+ (DST)[3] = (SRCA)[3] + (SRCB)[3]; \
+} while (0)
+
+/** Element-wise multiplication */
+#define SCALE_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] * (SRCB)[2]; \
+ (DST)[3] = (SRCA)[3] * (SRCB)[3]; \
+} while (0)
+
+/** In-place addition */
+#define ACC_4V( DST, SRC ) \
+do { \
+ (DST)[0] += (SRC)[0]; \
+ (DST)[1] += (SRC)[1]; \
+ (DST)[2] += (SRC)[2]; \
+ (DST)[3] += (SRC)[3]; \
+} while (0)
+
+/** Element-wise multiplication and addition */
+#define ACC_SCALE_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] += (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] += (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] += (SRCA)[2] * (SRCB)[2]; \
+ (DST)[3] += (SRCA)[3] * (SRCB)[3]; \
+} while (0)
+
+/** In-place scalar multiplication and addition */
+#define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \
+do { \
+ (DST)[0] += S * (SRCB)[0]; \
+ (DST)[1] += S * (SRCB)[1]; \
+ (DST)[2] += S * (SRCB)[2]; \
+ (DST)[3] += S * (SRCB)[3]; \
+} while (0)
+
+/** Scalar multiplication */
+#define SCALE_SCALAR_4V( DST, S, SRCB ) \
+do { \
+ (DST)[0] = S * (SRCB)[0]; \
+ (DST)[1] = S * (SRCB)[1]; \
+ (DST)[2] = S * (SRCB)[2]; \
+ (DST)[3] = S * (SRCB)[3]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SELF_SCALE_SCALAR_4V( DST, S ) \
+do { \
+ (DST)[0] *= S; \
+ (DST)[1] *= S; \
+ (DST)[2] *= S; \
+ (DST)[3] *= S; \
+} while (0)
+
+/** Assignment */
+#define ASSIGN_4V( V, V0, V1, V2, V3 ) \
+do { \
+ V[0] = V0; \
+ V[1] = V1; \
+ V[2] = V2; \
+ V[3] = V3; \
+} while(0)
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name 3-element vector operations*/
+/*@{*/
+
+/** Zero */
+#define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0
+
+/** Test for equality */
+#define TEST_EQ_3V(a,b) \
+ ((a)[0] == (b)[0] && \
+ (a)[1] == (b)[1] && \
+ (a)[2] == (b)[2])
+
+/** Copy a 3-element vector */
+#define COPY_3V( DST, SRC ) \
+do { \
+ (DST)[0] = (SRC)[0]; \
+ (DST)[1] = (SRC)[1]; \
+ (DST)[2] = (SRC)[2]; \
+} while (0)
+
+/** Copy a 3-element vector with cast */
+#define COPY_3V_CAST( DST, SRC, CAST ) \
+do { \
+ (DST)[0] = (CAST)(SRC)[0]; \
+ (DST)[1] = (CAST)(SRC)[1]; \
+ (DST)[2] = (CAST)(SRC)[2]; \
+} while (0)
+
+/** Copy a 3-element float vector */
+#define COPY_3FV( DST, SRC ) \
+do { \
+ const GLfloat *_tmp = (SRC); \
+ (DST)[0] = _tmp[0]; \
+ (DST)[1] = _tmp[1]; \
+ (DST)[2] = _tmp[2]; \
+} while (0)
+
+/** Subtraction */
+#define SUB_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] - (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] - (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] - (SRCB)[2]; \
+} while (0)
+
+/** Addition */
+#define ADD_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] + (SRCB)[2]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SCALE_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] * (SRCB)[2]; \
+} while (0)
+
+/** In-place element-wise multiplication */
+#define SELF_SCALE_3V( DST, SRC ) \
+do { \
+ (DST)[0] *= (SRC)[0]; \
+ (DST)[1] *= (SRC)[1]; \
+ (DST)[2] *= (SRC)[2]; \
+} while (0)
+
+/** In-place addition */
+#define ACC_3V( DST, SRC ) \
+do { \
+ (DST)[0] += (SRC)[0]; \
+ (DST)[1] += (SRC)[1]; \
+ (DST)[2] += (SRC)[2]; \
+} while (0)
+
+/** Element-wise multiplication and addition */
+#define ACC_SCALE_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] += (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] += (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] += (SRCA)[2] * (SRCB)[2]; \
+} while (0)
+
+/** Scalar multiplication */
+#define SCALE_SCALAR_3V( DST, S, SRCB ) \
+do { \
+ (DST)[0] = S * (SRCB)[0]; \
+ (DST)[1] = S * (SRCB)[1]; \
+ (DST)[2] = S * (SRCB)[2]; \
+} while (0)
+
+/** In-place scalar multiplication and addition */
+#define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \
+do { \
+ (DST)[0] += S * (SRCB)[0]; \
+ (DST)[1] += S * (SRCB)[1]; \
+ (DST)[2] += S * (SRCB)[2]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SELF_SCALE_SCALAR_3V( DST, S ) \
+do { \
+ (DST)[0] *= S; \
+ (DST)[1] *= S; \
+ (DST)[2] *= S; \
+} while (0)
+
+/** In-place scalar addition */
+#define ACC_SCALAR_3V( DST, S ) \
+do { \
+ (DST)[0] += S; \
+ (DST)[1] += S; \
+ (DST)[2] += S; \
+} while (0)
+
+/** Assignment */
+#define ASSIGN_3V( V, V0, V1, V2 ) \
+do { \
+ V[0] = V0; \
+ V[1] = V1; \
+ V[2] = V2; \
+} while(0)
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name 2-element vector operations*/
+/*@{*/
+
+/** Zero */
+#define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0
+
+/** Copy a 2-element vector */
+#define COPY_2V( DST, SRC ) \
+do { \
+ (DST)[0] = (SRC)[0]; \
+ (DST)[1] = (SRC)[1]; \
+} while (0)
+
+/** Copy a 2-element vector with cast */
+#define COPY_2V_CAST( DST, SRC, CAST ) \
+do { \
+ (DST)[0] = (CAST)(SRC)[0]; \
+ (DST)[1] = (CAST)(SRC)[1]; \
+} while (0)
+
+/** Copy a 2-element float vector */
+#define COPY_2FV( DST, SRC ) \
+do { \
+ const GLfloat *_tmp = (SRC); \
+ (DST)[0] = _tmp[0]; \
+ (DST)[1] = _tmp[1]; \
+} while (0)
+
+/** Subtraction */
+#define SUB_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] - (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] - (SRCB)[1]; \
+} while (0)
+
+/** Addition */
+#define ADD_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SCALE_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
+} while (0)
+
+/** In-place addition */
+#define ACC_2V( DST, SRC ) \
+do { \
+ (DST)[0] += (SRC)[0]; \
+ (DST)[1] += (SRC)[1]; \
+} while (0)
+
+/** Element-wise multiplication and addition */
+#define ACC_SCALE_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] += (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] += (SRCA)[1] * (SRCB)[1]; \
+} while (0)
+
+/** Scalar multiplication */
+#define SCALE_SCALAR_2V( DST, S, SRCB ) \
+do { \
+ (DST)[0] = S * (SRCB)[0]; \
+ (DST)[1] = S * (SRCB)[1]; \
+} while (0)
+
+/** In-place scalar multiplication and addition */
+#define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \
+do { \
+ (DST)[0] += S * (SRCB)[0]; \
+ (DST)[1] += S * (SRCB)[1]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SELF_SCALE_SCALAR_2V( DST, S ) \
+do { \
+ (DST)[0] *= S; \
+ (DST)[1] *= S; \
+} while (0)
+
+/** In-place scalar addition */
+#define ACC_SCALAR_2V( DST, S ) \
+do { \
+ (DST)[0] += S; \
+ (DST)[1] += S; \
+} while (0)
+
+/** Assign scalers to short vectors */
+#define ASSIGN_2V( V, V0, V1 ) \
+do { \
+ V[0] = V0; \
+ V[1] = V1; \
+} while(0)
+
+/*@}*/
+
+/** Copy \p sz elements into a homegeneous (4-element) vector, giving
+ * default values to the remaining components.
+ * The default values are chosen based on \p type.
+ */
+static inline void
+COPY_CLEAN_4V_TYPE_AS_FLOAT(GLfloat dst[4], int sz, const GLfloat src[4],
+ GLenum type)
+{
+ switch (type) {
+ case GL_FLOAT:
+ ASSIGN_4V(dst, 0, 0, 0, 1);
+ break;
+ case GL_INT:
+ ASSIGN_4V(dst, INT_AS_FLT(0), INT_AS_FLT(0),
+ INT_AS_FLT(0), INT_AS_FLT(1));
+ break;
+ case GL_UNSIGNED_INT:
+ ASSIGN_4V(dst, UINT_AS_FLT(0), UINT_AS_FLT(0),
+ UINT_AS_FLT(0), UINT_AS_FLT(1));
+ break;
+ default:
+ ASSIGN_4V(dst, 0.0f, 0.0f, 0.0f, 1.0f); /* silence warnings */
+ ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_FLOAT macro");
+ }
+ COPY_SZ_4V(dst, sz, src);
+}
+
+/** \name Linear interpolation functions */
+/*@{*/
+
+static inline GLfloat
+LINTERP(GLfloat t, GLfloat out, GLfloat in)
+{
+ return out + t * (in - out);
+}
+
+static inline void
+INTERP_3F(GLfloat t, GLfloat dst[3], const GLfloat out[3], const GLfloat in[3])
+{
+ dst[0] = LINTERP( t, out[0], in[0] );
+ dst[1] = LINTERP( t, out[1], in[1] );
+ dst[2] = LINTERP( t, out[2], in[2] );
+}
+
+static inline void
+INTERP_4F(GLfloat t, GLfloat dst[4], const GLfloat out[4], const GLfloat in[4])
+{
+ dst[0] = LINTERP( t, out[0], in[0] );
+ dst[1] = LINTERP( t, out[1], in[1] );
+ dst[2] = LINTERP( t, out[2], in[2] );
+ dst[3] = LINTERP( t, out[3], in[3] );
+}
+
+/*@}*/
+
+
+
+/** Clamp X to [MIN,MAX] */
+#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
+
+/** Minimum of two values: */
+#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
+
+/** Maximum of two values: */
+#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
+
+/** Minimum and maximum of three values: */
+#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C))
+#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
+
+static inline unsigned
+minify(unsigned value, unsigned levels)
+{
+ return MAX2(1, value >> levels);
+}
+
+/**
+ * Return true if the given value is a power of two.
+ *
+ * Note that this considers 0 a power of two.
+ */
+static inline bool
+is_power_of_two(unsigned value)
+{
+ return (value & (value - 1)) == 0;
+}
+
+/**
+ * Align a value up to an alignment value
+ *
+ * If \c value is not already aligned to the requested alignment value, it
+ * will be rounded up.
+ *
+ * \param value Value to be rounded
+ * \param alignment Alignment value to be used. This must be a power of two.
+ *
+ * \sa ROUND_DOWN_TO()
+ */
+#define ALIGN(value, alignment) (((value) + (alignment) - 1) & ~((alignment) - 1))
+
+/**
+ * Align a value down to an alignment value
+ *
+ * If \c value is not already aligned to the requested alignment value, it
+ * will be rounded down.
+ *
+ * \param value Value to be rounded
+ * \param alignment Alignment value to be used. This must be a power of two.
+ *
+ * \sa ALIGN()
+ */
+#define ROUND_DOWN_TO(value, alignment) ((value) & ~(alignment - 1))
+
+
+/** Cross product of two 3-element vectors */
+static inline void
+CROSS3(GLfloat n[3], const GLfloat u[3], const GLfloat v[3])
+{
+ n[0] = u[1] * v[2] - u[2] * v[1];
+ n[1] = u[2] * v[0] - u[0] * v[2];
+ n[2] = u[0] * v[1] - u[1] * v[0];
+}
+
+
+/** Dot product of two 2-element vectors */
+static inline GLfloat
+DOT2(const GLfloat a[2], const GLfloat b[2])
+{
+ return a[0] * b[0] + a[1] * b[1];
+}
+
+static inline GLfloat
+DOT3(const GLfloat a[3], const GLfloat b[3])
+{
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+static inline GLfloat
+DOT4(const GLfloat a[4], const GLfloat b[4])
+{
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
+}
+
+
+static inline GLfloat
+LEN_SQUARED_3FV(const GLfloat v[3])
+{
+ return DOT3(v, v);
+}
+
+static inline GLfloat
+LEN_SQUARED_2FV(const GLfloat v[2])
+{
+ return DOT2(v, v);
+}
+
+
+static inline GLfloat
+LEN_3FV(const GLfloat v[3])
+{
+ return sqrtf(LEN_SQUARED_3FV(v));
+}
+
+static inline GLfloat
+LEN_2FV(const GLfloat v[2])
+{
+ return sqrtf(LEN_SQUARED_2FV(v));
+}
+
+
+/* Normalize a 3-element vector to unit length. */
+static inline void
+NORMALIZE_3FV(GLfloat v[3])
+{
+ GLfloat len = (GLfloat) LEN_SQUARED_3FV(v);
+ if (len) {
+ len = INV_SQRTF(len);
+ v[0] *= len;
+ v[1] *= len;
+ v[2] *= len;
+ }
+}
+
+
+/** Is float value negative? */
+static inline GLboolean
+IS_NEGATIVE(float x)
+{
+ return signbit(x) != 0;
+}
+
+/** Test two floats have opposite signs */
+static inline GLboolean
+DIFFERENT_SIGNS(GLfloat x, GLfloat y)
+{
+ return signbit(x) != signbit(y);
+}
+
+
+/** Compute ceiling of integer quotient of A divided by B. */
+#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
+
+
+/** casts to silence warnings with some compilers */
+#define ENUM_TO_INT(E) ((GLint)(E))
+#define ENUM_TO_FLOAT(E) ((GLfloat)(GLint)(E))
+#define ENUM_TO_DOUBLE(E) ((GLdouble)(GLint)(E))
+#define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE)
+
+/* Compute the size of an array */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+/* Stringify */
+#define STRINGIFY(x) #x
+
+#endif
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/mtypes.h b/icd/intel/compiler/mesa-utils/src/mesa/main/mtypes.h
index cc03c53..ddd3f1a 100644
--- a/icd/intel/compiler/mesa-utils/src/mesa/main/mtypes.h
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/mtypes.h
@@ -415,70 +415,6 @@
#define MESA_SHADER_STAGES (MESA_SHADER_COMPUTE + 1)
-/**
- * Framebuffer configuration (aka visual / pixelformat)
- * Note: some of these fields should be boolean, but it appears that
- * code in drivers/dri/common/util.c requires int-sized fields.
- */
-struct gl_config
-{
- GLboolean rgbMode;
- GLboolean floatMode;
- GLboolean colorIndexMode; /* XXX is this used anywhere? */
- GLuint doubleBufferMode;
- GLuint stereoMode;
-
- GLboolean haveAccumBuffer;
- GLboolean haveDepthBuffer;
- GLboolean haveStencilBuffer;
-
- GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
- GLuint redMask, greenMask, blueMask, alphaMask;
- GLint rgbBits; /* total bits for rgb */
- GLint indexBits; /* total bits for colorindex */
-
- GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
- GLint depthBits;
- GLint stencilBits;
-
- GLint numAuxBuffers;
-
- GLint level;
-
- /* EXT_visual_rating / GLX 1.2 */
- GLint visualRating;
-
- /* EXT_visual_info / GLX 1.2 */
- GLint transparentPixel;
- /* colors are floats scaled to ints */
- GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
- GLint transparentIndex;
-
- /* ARB_multisample / SGIS_multisample */
- GLint sampleBuffers;
- GLint samples;
-
- /* SGIX_pbuffer / GLX 1.3 */
- GLint maxPbufferWidth;
- GLint maxPbufferHeight;
- GLint maxPbufferPixels;
- GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
- GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
-
- /* OML_swap_method */
- GLint swapMethod;
-
- /* EXT_texture_from_pixmap */
- GLint bindToTextureRgb;
- GLint bindToTextureRgba;
- GLint bindToMipmapTexture;
- GLint bindToTextureTargets;
- GLint yInverted;
-
- /* EXT_framebuffer_sRGB */
- GLint sRGBCapable;
-};
-
/**
* \name Bit flags used for updating material values.
@@ -542,15 +478,6 @@
/**
- * Material state.
- */
-struct gl_material
-{
- GLfloat Attrib[MAT_ATTRIB_MAX][4];
-};
-
-
-/**
* Light state flags.
*/
/*@{*/
@@ -561,334 +488,7 @@
/*@}*/
-/**
- * Light source state.
- */
-struct gl_light
-{
- struct gl_light *next; /**< double linked list with sentinel */
- struct gl_light *prev;
- GLfloat Ambient[4]; /**< ambient color */
- GLfloat Diffuse[4]; /**< diffuse color */
- GLfloat Specular[4]; /**< specular color */
- GLfloat EyePosition[4]; /**< position in eye coordinates */
- GLfloat SpotDirection[4]; /**< spotlight direction in eye coordinates */
- GLfloat SpotExponent;
- GLfloat SpotCutoff; /**< in degrees */
- GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
- GLfloat ConstantAttenuation;
- GLfloat LinearAttenuation;
- GLfloat QuadraticAttenuation;
- GLboolean Enabled; /**< On/off flag */
-
- /**
- * \name Derived fields
- */
- /*@{*/
- GLbitfield _Flags; /**< Mask of LIGHT_x bits defined above */
-
- GLfloat _Position[4]; /**< position in eye/obj coordinates */
- GLfloat _VP_inf_norm[3]; /**< Norm direction to infinite light */
- GLfloat _h_inf_norm[3]; /**< Norm( _VP_inf_norm + <0,0,1> ) */
- GLfloat _NormSpotDirection[4]; /**< normalized spotlight direction */
- GLfloat _VP_inf_spot_attenuation;
-
- GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */
- GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */
- GLfloat _MatSpecular[2][3]; /**< material spec * light specular */
- /*@}*/
-};
-
-
-/**
- * Light model state.
- */
-struct gl_lightmodel
-{
- GLfloat Ambient[4]; /**< ambient color */
- GLboolean LocalViewer; /**< Local (or infinite) view point? */
- GLboolean TwoSide; /**< Two (or one) sided lighting? */
- GLenum ColorControl; /**< either GL_SINGLE_COLOR
- * or GL_SEPARATE_SPECULAR_COLOR */
-};
-
-
-/**
- * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT)
- */
-struct gl_accum_attrib
-{
- GLfloat ClearColor[4]; /**< Accumulation buffer clear color */
-};
-
-
-/**
- * Used for storing clear color, texture border color, etc.
- * The float values are typically unclamped.
- */
-union gl_color_union
-{
- GLfloat f[4];
- GLint i[4];
- GLuint ui[4];
-};
-
-
-/**
- * Color buffer attribute group (GL_COLOR_BUFFER_BIT).
- */
-struct gl_colorbuffer_attrib
-{
- GLuint ClearIndex; /**< Index for glClear */
- union gl_color_union ClearColor; /**< Color for glClear, unclamped */
- GLuint IndexMask; /**< Color index write mask */
- GLubyte ColorMask[MAX_DRAW_BUFFERS][4]; /**< Each flag is 0xff or 0x0 */
-
- GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */
-
- /**
- * \name alpha testing
- */
- /*@{*/
- GLboolean AlphaEnabled; /**< Alpha test enabled flag */
- GLenum AlphaFunc; /**< Alpha test function */
- GLfloat AlphaRefUnclamped;
- GLclampf AlphaRef; /**< Alpha reference value */
- /*@}*/
-
- /**
- * \name Blending
- */
- /*@{*/
- GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */
-
- /* NOTE: this does _not_ depend on fragment clamping or any other clamping
- * control, only on the fixed-pointness of the render target.
- * The query does however depend on fragment color clamping.
- */
- GLfloat BlendColorUnclamped[4]; /**< Blending color */
- GLfloat BlendColor[4]; /**< Blending color */
-
- struct
- {
- GLenum SrcRGB; /**< RGB blend source term */
- GLenum DstRGB; /**< RGB blend dest term */
- GLenum SrcA; /**< Alpha blend source term */
- GLenum DstA; /**< Alpha blend dest term */
- GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
- GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
- /**
- * Set if any blend factor uses SRC1. Computed at the time blend factors
- * get set.
- */
- GLboolean _UsesDualSrc;
- } Blend[MAX_DRAW_BUFFERS];
- /** Are the blend func terms currently different for each buffer/target? */
- GLboolean _BlendFuncPerBuffer;
- /** Are the blend equations currently different for each buffer/target? */
- GLboolean _BlendEquationPerBuffer;
- /*@}*/
-
- /**
- * \name Logic op
- */
- /*@{*/
- GLenum LogicOp; /**< Logic operator */
- GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */
- GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */
- /*@}*/
-
- GLboolean DitherFlag; /**< Dither enable flag */
-
- GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
- GLboolean _ClampFragmentColor; /** < with GL_FIXED_ONLY_ARB resolved */
- GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
-
- GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */
-};
-
-
-/**
- * Current attribute group (GL_CURRENT_BIT).
- */
-struct gl_current_attrib
-{
- /**
- * \name Current vertex attributes.
- * \note Values are valid only after FLUSH_VERTICES has been called.
- * \note Index and Edgeflag current values are stored as floats in the
- * SIX and SEVEN attribute slots.
- */
- GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */
-
- /**
- * \name Current raster position attributes (always valid).
- * \note This set of attributes is very similar to the SWvertex struct.
- */
- /*@{*/
- GLfloat RasterPos[4];
- GLfloat RasterDistance;
- GLfloat RasterColor[4];
- GLfloat RasterSecondaryColor[4];
- GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4];
- GLboolean RasterPosValid;
- /*@}*/
-};
-
-
-/**
- * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT).
- */
-struct gl_depthbuffer_attrib
-{
- GLenum Func; /**< Function for depth buffer compare */
- GLclampd Clear; /**< Value to clear depth buffer to */
- GLboolean Test; /**< Depth buffering enabled flag */
- GLboolean Mask; /**< Depth buffer writable? */
- GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */
- GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */
-};
-
-
-/**
- * Evaluator attribute group (GL_EVAL_BIT).
- */
-struct gl_eval_attrib
-{
- /**
- * \name Enable bits
- */
- /*@{*/
- GLboolean Map1Color4;
- GLboolean Map1Index;
- GLboolean Map1Normal;
- GLboolean Map1TextureCoord1;
- GLboolean Map1TextureCoord2;
- GLboolean Map1TextureCoord3;
- GLboolean Map1TextureCoord4;
- GLboolean Map1Vertex3;
- GLboolean Map1Vertex4;
- GLboolean Map2Color4;
- GLboolean Map2Index;
- GLboolean Map2Normal;
- GLboolean Map2TextureCoord1;
- GLboolean Map2TextureCoord2;
- GLboolean Map2TextureCoord3;
- GLboolean Map2TextureCoord4;
- GLboolean Map2Vertex3;
- GLboolean Map2Vertex4;
- GLboolean AutoNormal;
- /*@}*/
-
- /**
- * \name Map Grid endpoints and divisions and calculated du values
- */
- /*@{*/
- GLint MapGrid1un;
- GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du;
- GLint MapGrid2un, MapGrid2vn;
- GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du;
- GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv;
- /*@}*/
-};
-
-
-/**
- * Fog attribute group (GL_FOG_BIT).
- */
-struct gl_fog_attrib
-{
- GLboolean Enabled; /**< Fog enabled flag */
- GLfloat ColorUnclamped[4]; /**< Fog color */
- GLfloat Color[4]; /**< Fog color */
- GLfloat Density; /**< Density >= 0.0 */
- GLfloat Start; /**< Start distance in eye coords */
- GLfloat End; /**< End distance in eye coords */
- GLfloat Index; /**< Fog index */
- GLenum Mode; /**< Fog mode */
- GLboolean ColorSumEnabled;
- GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */
- GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */
- GLenum FogDistanceMode; /**< GL_NV_fog_distance */
-};
-
-
-/**
- * Hint attribute group (GL_HINT_BIT).
- *
- * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE.
- */
-struct gl_hint_attrib
-{
- GLenum PerspectiveCorrection;
- GLenum PointSmooth;
- GLenum LineSmooth;
- GLenum PolygonSmooth;
- GLenum Fog;
- GLenum TextureCompression; /**< GL_ARB_texture_compression */
- GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */
-};
-
-
-/**
- * Lighting attribute group (GL_LIGHT_BIT).
- */
-struct gl_light_attrib
-{
- struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */
- struct gl_lightmodel Model; /**< Lighting model */
-
- /**
- * Front and back material values.
- * Note: must call FLUSH_VERTICES() before using.
- */
- struct gl_material Material;
-
- GLboolean Enabled; /**< Lighting enabled flag */
- GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */
- GLenum ProvokingVertex; /**< GL_EXT_provoking_vertex */
- GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */
- GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */
- GLbitfield _ColorMaterialBitmask; /**< bitmask formed from Face and Mode */
- GLboolean ColorMaterialEnabled;
- GLenum ClampVertexColor; /**< GL_TRUE, GL_FALSE, GL_FIXED_ONLY */
- GLboolean _ClampVertexColor;
-
- struct gl_light EnabledList; /**< List sentinel */
-
- /**
- * Derived state for optimizations:
- */
- /*@{*/
- GLboolean _NeedEyeCoords;
- GLboolean _NeedVertices; /**< Use fast shader? */
- GLfloat _BaseColor[2][3];
- /*@}*/
-};
-
-
-/**
- * Line attribute group (GL_LINE_BIT).
- */
-struct gl_line_attrib
-{
- GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */
- GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */
- GLushort StipplePattern; /**< Stipple pattern */
- GLint StippleFactor; /**< Stipple repeat factor */
- GLfloat Width; /**< Line width */
-};
-
-
-/**
- * Display list attribute group (GL_LIST_BIT).
- */
-struct gl_list_attrib
-{
- GLuint ListBase;
-};
/**
@@ -914,156 +514,6 @@
/**
- * A pixelmap (see glPixelMap)
- */
-struct gl_pixelmap
-{
- GLint Size;
- GLfloat Map[MAX_PIXEL_MAP_TABLE];
-};
-
-
-/**
- * Collection of all pixelmaps
- */
-struct gl_pixelmaps
-{
- struct gl_pixelmap RtoR; /**< i.e. GL_PIXEL_MAP_R_TO_R */
- struct gl_pixelmap GtoG;
- struct gl_pixelmap BtoB;
- struct gl_pixelmap AtoA;
- struct gl_pixelmap ItoR;
- struct gl_pixelmap ItoG;
- struct gl_pixelmap ItoB;
- struct gl_pixelmap ItoA;
- struct gl_pixelmap ItoI;
- struct gl_pixelmap StoS;
-};
-
-
-/**
- * Pixel attribute group (GL_PIXEL_MODE_BIT).
- */
-struct gl_pixel_attrib
-{
- GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */
-
- /*--- Begin Pixel Transfer State ---*/
- /* Fields are in the order in which they're applied... */
-
- /** Scale & Bias (index shift, offset) */
- /*@{*/
- GLfloat RedBias, RedScale;
- GLfloat GreenBias, GreenScale;
- GLfloat BlueBias, BlueScale;
- GLfloat AlphaBias, AlphaScale;
- GLfloat DepthBias, DepthScale;
- GLint IndexShift, IndexOffset;
- /*@}*/
-
- /* Pixel Maps */
- /* Note: actual pixel maps are not part of this attrib group */
- GLboolean MapColorFlag;
- GLboolean MapStencilFlag;
-
- /*--- End Pixel Transfer State ---*/
-
- /** glPixelZoom */
- GLfloat ZoomX, ZoomY;
-};
-
-
-/**
- * Point attribute group (GL_POINT_BIT).
- */
-struct gl_point_attrib
-{
- GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */
- GLfloat Size; /**< User-specified point size */
- GLfloat Params[3]; /**< GL_EXT_point_parameters */
- GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */
- GLfloat Threshold; /**< GL_EXT_point_parameters */
- GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */
- GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */
- GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/
- GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */
- GLenum SpriteOrigin; /**< GL_ARB_point_sprite */
-};
-
-
-/**
- * Polygon attribute group (GL_POLYGON_BIT).
- */
-struct gl_polygon_attrib
-{
- GLenum FrontFace; /**< Either GL_CW or GL_CCW */
- GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
- GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
- GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */
- GLboolean CullFlag; /**< Culling on/off flag */
- GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */
- GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */
- GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */
- GLfloat OffsetFactor; /**< Polygon offset factor, from user */
- GLfloat OffsetUnits; /**< Polygon offset units, from user */
- GLboolean OffsetPoint; /**< Offset in GL_POINT mode */
- GLboolean OffsetLine; /**< Offset in GL_LINE mode */
- GLboolean OffsetFill; /**< Offset in GL_FILL mode */
-};
-
-
-/**
- * Scissor attributes (GL_SCISSOR_BIT).
- */
-struct gl_scissor_rect
-{
- GLint X, Y; /**< Lower left corner of box */
- GLsizei Width, Height; /**< Size of box */
-};
-struct gl_scissor_attrib
-{
- GLbitfield EnableFlags; /**< Scissor test enabled? */
- struct gl_scissor_rect ScissorArray[MAX_VIEWPORTS];
-};
-
-
-/**
- * Stencil attribute group (GL_STENCIL_BUFFER_BIT).
- *
- * Three sets of stencil data are tracked so that OpenGL 2.0,
- * GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported
- * simultaneously. In each of the stencil state arrays, element 0 corresponds
- * to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 /
- * GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the
- * GL_EXT_stencil_two_side GL_BACK state.
- *
- * The derived value \c _BackFace is either 1 or 2 depending on whether or
- * not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled.
- *
- * The derived value \c _TestTwoSide is set when the front-face and back-face
- * stencil state are different.
- */
-struct gl_stencil_attrib
-{
- GLboolean Enabled; /**< Enabled flag */
- GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
- GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */
- GLboolean _Enabled; /**< Enabled and stencil buffer present */
- GLboolean _WriteEnabled; /**< _Enabled and non-zero writemasks */
- GLboolean _TestTwoSide;
- GLubyte _BackFace; /**< Current back stencil state (1 or 2) */
- GLenum Function[3]; /**< Stencil function */
- GLenum FailFunc[3]; /**< Fail function */
- GLenum ZPassFunc[3]; /**< Depth buffer pass function */
- GLenum ZFailFunc[3]; /**< Depth buffer fail function */
- GLint Ref[3]; /**< Reference value */
- GLuint ValueMask[3]; /**< Value mask */
- GLuint WriteMask[3]; /**< Write mask */
- GLuint Clear; /**< Clear value */
-};
-
-
-/**
* An index for each type of texture object. These correspond to the GL
* texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc.
* Note: the order is from highest priority to lowest priority.
@@ -1106,45 +556,6 @@
/**
- * Texture image state. Drivers will typically create a subclass of this
- * with extra fields for memory buffers, etc.
- */
-struct gl_texture_image
-{
- GLint InternalFormat; /**< Internal format as given by the user */
- GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA,
- * GL_LUMINANCE, GL_LUMINANCE_ALPHA,
- * GL_INTENSITY, GL_DEPTH_COMPONENT or
- * GL_DEPTH_STENCIL_EXT only. Used for
- * choosing TexEnv arithmetic.
- */
- mesa_format TexFormat; /**< The actual texture memory format */
-
- GLuint Border; /**< 0 or 1 */
- GLuint Width; /**< = 2^WidthLog2 + 2*Border */
- GLuint Height; /**< = 2^HeightLog2 + 2*Border */
- GLuint Depth; /**< = 2^DepthLog2 + 2*Border */
- GLuint Width2; /**< = Width - 2*Border */
- GLuint Height2; /**< = Height - 2*Border */
- GLuint Depth2; /**< = Depth - 2*Border */
- GLuint WidthLog2; /**< = log2(Width2) */
- GLuint HeightLog2; /**< = log2(Height2) */
- GLuint DepthLog2; /**< = log2(Depth2) */
- GLuint MaxNumLevels; /**< = maximum possible number of mipmap
- levels, computed from the dimensions */
-
- struct gl_texture_object *TexObject; /**< Pointer back to parent object */
- GLuint Level; /**< Which mipmap level am I? */
- /** Cube map face: index into gl_texture_object::Image[] array */
- GLuint Face;
-
- /** GL_ARB_texture_multisample */
- GLuint NumSamples; /**< Sample count, or 0 for non-multisample */
- GLboolean FixedSampleLocations; /**< Same sample locations for all pixels? */
-};
-
-
-/**
* Indexes for cube map faces.
*/
typedef enum
@@ -1159,94 +570,6 @@
} gl_face_index;
-/**
- * Sampler object state. These objects are new with GL_ARB_sampler_objects
- * and OpenGL 3.3. Legacy texture objects also contain a sampler object.
- */
-struct gl_sampler_object
-{
- GLuint Name;
- GLint RefCount;
- GLchar *Label; /**< GL_KHR_debug */
-
- GLenum WrapS; /**< S-axis texture image wrap mode */
- GLenum WrapT; /**< T-axis texture image wrap mode */
- GLenum WrapR; /**< R-axis texture image wrap mode */
- GLenum MinFilter; /**< minification filter */
- GLenum MagFilter; /**< magnification filter */
- union gl_color_union BorderColor; /**< Interpreted according to texture format */
- GLfloat MinLod; /**< min lambda, OpenGL 1.2 */
- GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */
- GLfloat LodBias; /**< OpenGL 1.4 */
- GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
- GLenum CompareMode; /**< GL_ARB_shadow */
- GLenum CompareFunc; /**< GL_ARB_shadow */
- GLenum sRGBDecode; /**< GL_DECODE_EXT or GL_SKIP_DECODE_EXT */
- GLboolean CubeMapSeamless; /**< GL_AMD_seamless_cubemap_per_texture */
-};
-
-
-/**
- * Texture object state. Contains the array of mipmap images, border color,
- * wrap modes, filter modes, and shadow/texcompare state.
- */
-struct gl_texture_object
-{
- mtx_t Mutex; /**< for thread safety */
- GLint RefCount; /**< reference count */
- GLuint Name; /**< the user-visible texture object ID */
- GLchar *Label; /**< GL_KHR_debug */
- GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
- gl_texture_index TargetIndex; /**< The gl_texture_unit::CurrentTex index.
- Only valid when Target is valid. */
-
- struct gl_sampler_object Sampler;
-
- GLenum DepthMode; /**< GL_ARB_depth_texture */
- bool StencilSampling; /**< Should we sample stencil instead of depth? */
-
- GLfloat Priority; /**< in [0,1] */
- GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
- GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
- GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */
- GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
- GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - p in spec) */
- GLint CropRect[4]; /**< GL_OES_draw_texture */
- GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */
- GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */
- GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLboolean _BaseComplete; /**< Is the base texture level valid? */
- GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */
- GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */
- GLboolean _RenderToTexture; /**< Any rendering to this texture? */
- GLboolean Purgeable; /**< Is the buffer purgeable under memory
- pressure? */
- GLboolean Immutable; /**< GL_ARB_texture_storage */
-
- GLuint MinLevel; /**< GL_ARB_texture_view */
- GLuint MinLayer; /**< GL_ARB_texture_view */
- GLuint NumLevels; /**< GL_ARB_texture_view */
- GLuint NumLayers; /**< GL_ARB_texture_view */
-
- /** Actual texture images, indexed by [cube face] and [mipmap level] */
- struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
-
- /** GL_ARB_texture_buffer_object */
- struct gl_buffer_object *BufferObject;
- GLenum BufferObjectFormat;
- /** Equivalent Mesa format for BufferObjectFormat. */
- mesa_format _BufferObjectFormat;
- /** GL_ARB_texture_buffer_range */
- GLintptr BufferOffset;
- GLsizeiptr BufferSize; /**< if this is -1, use BufferObject->Size instead */
-
- /** GL_OES_EGL_image_external */
- GLint RequiredTextureImageUnits;
-
- /** GL_ARB_shader_image_load_store */
- GLenum ImageFormatCompatibilityType;
-};
-
/** Up to four combiner sources are possible with GL_NV_texture_env_combine4 */
#define MAX_COMBINER_TERMS 4
@@ -1311,144 +634,6 @@
/** Non-identity texture matrix for texture unit? */
#define ENABLE_TEXMAT(unit) (1 << (unit))
-
-/**
- * Texture coord generation state.
- */
-struct gl_texgen
-{
- GLenum Mode; /**< GL_EYE_LINEAR, GL_SPHERE_MAP, etc */
- GLbitfield _ModeBit; /**< TEXGEN_x bit corresponding to Mode */
- GLfloat ObjectPlane[4];
- GLfloat EyePlane[4];
-};
-
-
-/**
- * Texture unit state. Contains enable flags, texture environment/function/
- * combiners, texgen state, and pointers to current texture objects.
- */
-struct gl_texture_unit
-{
- GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */
-
- GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */
- GLclampf EnvColor[4];
- GLfloat EnvColorUnclamped[4];
-
- struct gl_texgen GenS;
- struct gl_texgen GenT;
- struct gl_texgen GenR;
- struct gl_texgen GenQ;
- GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */
- GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */
-
- GLfloat LodBias; /**< for biasing mipmap levels */
- GLenum BumpTarget;
- GLfloat RotMatrix[4]; /* 2x2 matrix */
-
- /** Current sampler object (GL_ARB_sampler_objects) */
- struct gl_sampler_object *Sampler;
-
- /**
- * \name GL_EXT_texture_env_combine
- */
- struct gl_tex_env_combine_state Combine;
-
- /**
- * Derived state based on \c EnvMode and the \c BaseFormat of the
- * currently enabled texture.
- */
- struct gl_tex_env_combine_state _EnvMode;
-
- /**
- * Currently enabled combiner state. This will point to either
- * \c Combine or \c _EnvMode.
- */
- struct gl_tex_env_combine_state *_CurrentCombine;
-
- /** Current texture object pointers */
- struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS];
-
- /** Points to highest priority, complete and enabled texture object */
- struct gl_texture_object *_Current;
-
- /** Texture targets that have a non-default texture bound */
- GLbitfield _BoundTextures;
-};
-
-
-/**
- * Texture attribute group (GL_TEXTURE_BIT).
- */
-struct gl_texture_attrib
-{
- GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */
- struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
- struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS];
-
- /** GL_ARB_texture_buffer_object */
- struct gl_buffer_object *BufferObject;
-
- /** GL_ARB_seamless_cubemap */
- GLboolean CubeMapSeamless;
-
- /** Texture coord units/sets used for fragment texturing */
- GLbitfield _EnabledCoordUnits;
-
- /** Texture coord units that have texgen enabled */
- GLbitfield _TexGenEnabled;
-
- /** Texture coord units that have non-identity matrices */
- GLbitfield _TexMatEnabled;
-
- /** Bitwise-OR of all Texture.Unit[i]._GenFlags */
- GLbitfield _GenFlags;
-
- /** Largest index of a texture unit with _Current != NULL. */
- GLint _MaxEnabledTexImageUnit;
-
- /** Largest index + 1 of texture units that have had any CurrentTex set. */
- GLint NumCurrentTexUsed;
-};
-
-
-/**
- * Data structure representing a single clip plane (e.g. one of the elements
- * of the ctx->Transform.EyeUserPlane or ctx->Transform._ClipUserPlane array).
- */
-typedef GLfloat gl_clip_plane[4];
-
-
-/**
- * Transformation attribute group (GL_TRANSFORM_BIT).
- */
-struct gl_transform_attrib
-{
- GLenum MatrixMode; /**< Matrix mode */
- gl_clip_plane EyeUserPlane[MAX_CLIP_PLANES]; /**< User clip planes */
- gl_clip_plane _ClipUserPlane[MAX_CLIP_PLANES]; /**< derived */
- GLbitfield ClipPlanesEnabled; /**< on/off bitmask */
- GLboolean Normalize; /**< Normalize all normals? */
- GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */
- GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */
- GLboolean DepthClamp; /**< GL_ARB_depth_clamp */
-};
-
-
-/**
- * Viewport attribute group (GL_VIEWPORT_BIT).
- */
-struct gl_viewport_attrib
-{
- GLfloat X, Y; /**< position */
- GLfloat Width, Height; /**< size */
- GLdouble Near, Far; /**< Depth buffer range */
- GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */
-};
-
-
typedef enum {
MAP_USER,
MAP_INTERNAL,
@@ -1460,318 +645,6 @@
/**
* Fields describing a mapped buffer range.
*/
-struct gl_buffer_mapping {
- GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */
- GLvoid *Pointer; /**< User-space address of mapping */
- GLintptr Offset; /**< Mapped offset */
- GLsizeiptr Length; /**< Mapped length */
-};
-
-
-/**
- * GL_ARB_vertex/pixel_buffer_object buffer object
- */
-struct gl_buffer_object
-{
- mtx_t Mutex;
- GLint RefCount;
- GLuint Name;
- GLchar *Label; /**< GL_KHR_debug */
- GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */
- GLbitfield StorageFlags; /**< GL_MAP_PERSISTENT_BIT, etc. */
- GLsizeiptrARB Size; /**< Size of buffer storage in bytes */
- GLubyte *Data; /**< Location of storage either in RAM or VRAM. */
- GLboolean DeletePending; /**< true if buffer object is removed from the hash */
- GLboolean Written; /**< Ever written to? (for debugging) */
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
- GLboolean Immutable; /**< GL_ARB_buffer_storage */
-
- struct gl_buffer_mapping Mappings[MAP_COUNT];
-};
-
-
-/**
- * Client pixel packing/unpacking attributes
- */
-struct gl_pixelstore_attrib
-{
- GLint Alignment;
- GLint RowLength;
- GLint SkipPixels;
- GLint SkipRows;
- GLint ImageHeight;
- GLint SkipImages;
- GLboolean SwapBytes;
- GLboolean LsbFirst;
- GLboolean Invert; /**< GL_MESA_pack_invert */
- struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */
-};
-
-
-/**
- * Client vertex array attributes
- */
-struct gl_client_array
-{
- GLint Size; /**< components per element (1,2,3,4) */
- GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */
- GLenum Format; /**< default: GL_RGBA, but may be GL_BGRA */
- GLsizei Stride; /**< user-specified stride */
- GLsizei StrideB; /**< actual stride in bytes */
- const GLubyte *Ptr; /**< Points to array data */
- GLboolean Enabled; /**< Enabled flag is a boolean */
- GLboolean Normalized; /**< GL_ARB_vertex_program */
- GLboolean Integer; /**< Integer-valued? */
- GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
- GLuint _ElementSize; /**< size of each element in bytes */
-
- struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */
- GLuint _MaxElement; /**< max element index into array buffer + 1 */
-};
-
-
-/**
- * Vertex attribute array as seen by the client.
- *
- * Contains the size, type, format and normalization flag,
- * along with the index of a vertex buffer binding point.
- *
- * Note that the Stride field corresponds to VERTEX_ATTRIB_ARRAY_STRIDE
- * and is only present for backwards compatibility reasons.
- * Rendering always uses VERTEX_BINDING_STRIDE.
- * The gl*Pointer() functions will set VERTEX_ATTRIB_ARRAY_STRIDE
- * and VERTEX_BINDING_STRIDE to the same value, while
- * glBindVertexBuffer() will only set VERTEX_BINDING_STRIDE.
- */
-struct gl_vertex_attrib_array
-{
- GLint Size; /**< Components per element (1,2,3,4) */
- GLenum Type; /**< Datatype: GL_FLOAT, GL_INT, etc */
- GLenum Format; /**< Default: GL_RGBA, but may be GL_BGRA */
- GLsizei Stride; /**< Stride as specified with gl*Pointer() */
- const GLubyte *Ptr; /**< Points to client array data. Not used when a VBO is bound */
- GLintptr RelativeOffset; /**< Offset of the first element relative to the binding offset */
- GLboolean Enabled; /**< Whether the array is enabled */
- GLboolean Normalized; /**< Fixed-point values are normalized when converted to floats */
- GLboolean Integer; /**< Fixed-point values are not converted to floats */
- GLuint _ElementSize; /**< Size of each element in bytes */
- GLuint VertexBinding; /**< Vertex buffer binding */
-};
-
-
-/**
- * This describes the buffer object used for a vertex array (or
- * multiple vertex arrays). If BufferObj points to the default/null
- * buffer object, then the vertex array lives in user memory and not a VBO.
- */
-struct gl_vertex_buffer_binding
-{
- GLintptr Offset; /**< User-specified offset */
- GLsizei Stride; /**< User-specified stride */
- GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
- struct gl_buffer_object *BufferObj; /**< GL_ARB_vertex_buffer_object */
- GLbitfield64 _BoundArrays; /**< Arrays bound to this binding point */
-};
-
-
-/**
- * A representation of "Vertex Array Objects" (VAOs) from OpenGL 3.1+,
- * GL_ARB_vertex_array_object, or the original GL_APPLE_vertex_array_object
- * extension.
- */
-struct gl_vertex_array_object
-{
- /** Name of the VAO as received from glGenVertexArray. */
- GLuint Name;
- GLchar *Label; /**< GL_KHR_debug */
-
- GLint RefCount;
- mtx_t Mutex;
-
- /**
- * Does the VAO use ARB semantics or Apple semantics?
- *
- * There are several ways in which ARB_vertex_array_object and
- * APPLE_vertex_array_object VAOs have differing semantics. At the very
- * least,
- *
- * - ARB VAOs require that all array data be sourced from vertex buffer
- * objects, but Apple VAOs do not.
- *
- * - ARB VAOs require that names come from GenVertexArrays.
- *
- * This flag notes which behavior governs this VAO.
- */
- GLboolean ARBsemantics;
-
- /**
- * Has this array object been bound?
- */
- GLboolean EverBound;
-
- /**
- * Derived vertex attribute arrays
- *
- * This is a legacy data structure created from gl_vertex_attrib_array and
- * gl_vertex_buffer_binding, for compatibility with existing driver code.
- */
- struct gl_client_array _VertexAttrib[VERT_ATTRIB_MAX];
-
- /** Vertex attribute arrays */
- struct gl_vertex_attrib_array VertexAttrib[VERT_ATTRIB_MAX];
-
- /** Vertex buffer bindings */
- struct gl_vertex_buffer_binding VertexBinding[VERT_ATTRIB_MAX];
-
- /** Mask of VERT_BIT_* values indicating which arrays are enabled */
- GLbitfield64 _Enabled;
-
- /** Mask of VERT_BIT_* values indicating changed/dirty arrays */
- GLbitfield64 NewArrays;
-
- /**
- * Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs
- * we can determine the max legal (in bounds) glDrawElements array index.
- */
- GLuint _MaxElement;
-
- /** The index buffer (also known as the element array buffer in OpenGL). */
- struct gl_buffer_object *IndexBufferObj;
-};
-
-
-/**
- * Vertex array state
- */
-struct gl_array_attrib
-{
- /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */
- struct gl_vertex_array_object *VAO;
-
- /** The default vertex array object */
- struct gl_vertex_array_object *DefaultVAO;
-
- /** Array objects (GL_ARB/APPLE_vertex_array_object) */
- struct _mesa_HashTable *Objects;
-
- GLint ActiveTexture; /**< Client Active Texture */
- GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */
- GLuint LockCount; /**< GL_EXT_compiled_vertex_array */
-
- /**
- * \name Primitive restart controls
- *
- * Primitive restart is enabled if either \c PrimitiveRestart or
- * \c PrimitiveRestartFixedIndex is set.
- */
- /*@{*/
- GLboolean PrimitiveRestart;
- GLboolean PrimitiveRestartFixedIndex;
- GLboolean _PrimitiveRestart;
- GLuint RestartIndex;
- /*@}*/
-
- /* GL_ARB_vertex_buffer_object */
- struct gl_buffer_object *ArrayBufferObj;
-
- /**
- * Vertex arrays as consumed by a driver.
- * The array pointer is set up only by the VBO module.
- */
- const struct gl_client_array **_DrawArrays; /**< 0..VERT_ATTRIB_MAX-1 */
-};
-
-
-/**
- * Feedback buffer state
- */
-struct gl_feedback
-{
- GLenum Type;
- GLbitfield _Mask; /**< FB_* bits */
- GLfloat *Buffer;
- GLuint BufferSize;
- GLuint Count;
-};
-
-
-/**
- * Selection buffer state
- */
-struct gl_selection
-{
- GLuint *Buffer; /**< selection buffer */
- GLuint BufferSize; /**< size of the selection buffer */
- GLuint BufferCount; /**< number of values in the selection buffer */
- GLuint Hits; /**< number of records in the selection buffer */
- GLuint NameStackDepth; /**< name stack depth */
- GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */
- GLboolean HitFlag; /**< hit flag */
- GLfloat HitMinZ; /**< minimum hit depth */
- GLfloat HitMaxZ; /**< maximum hit depth */
-};
-
-
-/**
- * 1-D Evaluator control points
- */
-struct gl_1d_map
-{
- GLuint Order; /**< Number of control points */
- GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */
- GLfloat *Points; /**< Points to contiguous control points */
-};
-
-
-/**
- * 2-D Evaluator control points
- */
-struct gl_2d_map
-{
- GLuint Uorder; /**< Number of control points in U dimension */
- GLuint Vorder; /**< Number of control points in V dimension */
- GLfloat u1, u2, du;
- GLfloat v1, v2, dv;
- GLfloat *Points; /**< Points to contiguous control points */
-};
-
-
-/**
- * All evaluator control point state
- */
-struct gl_evaluators
-{
- /**
- * \name 1-D maps
- */
- /*@{*/
- struct gl_1d_map Map1Vertex3;
- struct gl_1d_map Map1Vertex4;
- struct gl_1d_map Map1Index;
- struct gl_1d_map Map1Color4;
- struct gl_1d_map Map1Normal;
- struct gl_1d_map Map1Texture1;
- struct gl_1d_map Map1Texture2;
- struct gl_1d_map Map1Texture3;
- struct gl_1d_map Map1Texture4;
- /*@}*/
-
- /**
- * \name 2-D maps
- */
- /*@{*/
- struct gl_2d_map Map2Vertex3;
- struct gl_2d_map Map2Vertex4;
- struct gl_2d_map Map2Index;
- struct gl_2d_map Map2Color4;
- struct gl_2d_map Map2Normal;
- struct gl_2d_map Map2Texture1;
- struct gl_2d_map Map2Texture2;
- struct gl_2d_map Map2Texture3;
- struct gl_2d_map Map2Texture4;
- /*@}*/
-};
-
struct gl_transform_feedback_varying_info
{
@@ -1831,175 +704,6 @@
/**
- * Transform feedback object state
- */
-struct gl_transform_feedback_object
-{
- GLuint Name; /**< AKA the object ID */
- GLchar *Label; /**< GL_KHR_debug */
- GLint RefCount;
- GLboolean Active; /**< Is transform feedback enabled? */
- GLboolean Paused; /**< Is transform feedback paused? */
- GLboolean EndedAnytime; /**< Has EndTransformFeedback been called
- at least once? */
- GLboolean EverBound; /**< Has this object been bound? */
-
- /**
- * The shader program active when BeginTransformFeedback() was called.
- * When active and unpaused, this equals ctx->Shader.CurrentProgram[stage],
- * where stage is the pipeline stage that is the source of data for
- * transform feedback.
- */
- struct gl_shader_program *shader_program;
-
- /**
- * GLES: if Active is true, remaining number of primitives which can be
- * rendered without overflow. This is necessary to track because GLES
- * requires us to generate INVALID_OPERATION if a call to glDrawArrays or
- * glDrawArraysInstanced would overflow transform feedback buffers.
- * Undefined if Active is false.
- *
- * Not tracked for desktop GL since it's unnecessary.
- */
- unsigned GlesRemainingPrims;
-
- /** The feedback buffers */
- GLuint BufferNames[MAX_FEEDBACK_BUFFERS];
- struct gl_buffer_object *Buffers[MAX_FEEDBACK_BUFFERS];
-
- /** Start of feedback data in dest buffer */
- GLintptr Offset[MAX_FEEDBACK_BUFFERS];
-
- /**
- * Max data to put into dest buffer (in bytes). Computed based on
- * RequestedSize and the actual size of the buffer.
- */
- GLsizeiptr Size[MAX_FEEDBACK_BUFFERS];
-
- /**
- * Size that was specified when the buffer was bound. If the buffer was
- * bound with glBindBufferBase() or glBindBufferOffsetEXT(), this value is
- * zero.
- */
- GLsizeiptr RequestedSize[MAX_FEEDBACK_BUFFERS];
-};
-
-
-/**
- * Context state for transform feedback.
- */
-struct gl_transform_feedback_state
-{
- GLenum Mode; /**< GL_POINTS, GL_LINES or GL_TRIANGLES */
-
- /** The general binding point (GL_TRANSFORM_FEEDBACK_BUFFER) */
- struct gl_buffer_object *CurrentBuffer;
-
- /** The table of all transform feedback objects */
- struct _mesa_HashTable *Objects;
-
- /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */
- struct gl_transform_feedback_object *CurrentObject;
-
- /** The default xform-fb object (Name==0) */
- struct gl_transform_feedback_object *DefaultObject;
-};
-
-
-/**
- * A "performance monitor" as described in AMD_performance_monitor.
- */
-struct gl_perf_monitor_object
-{
- GLuint Name;
-
- /** True if the monitor is currently active (Begin called but not End). */
- GLboolean Active;
-
- /**
- * True if the monitor has ended.
- *
- * This is distinct from !Active because it may never have began.
- */
- GLboolean Ended;
-
- /**
- * A list of groups with currently active counters.
- *
- * ActiveGroups[g] == n if there are n counters active from group 'g'.
- */
- unsigned *ActiveGroups;
-
- /**
- * An array of bitsets, subscripted by group ID, then indexed by counter ID.
- *
- * Checking whether counter 'c' in group 'g' is active can be done via:
- *
- * BITSET_TEST(ActiveCounters[g], c)
- */
- GLuint **ActiveCounters;
-};
-
-
-union gl_perf_monitor_counter_value
-{
- float f;
- uint64_t u64;
- uint32_t u32;
-};
-
-
-struct gl_perf_monitor_counter
-{
- /** Human readable name for the counter. */
- const char *Name;
-
- /**
- * Data type of the counter. Valid values are FLOAT, UNSIGNED_INT,
- * UNSIGNED_INT64_AMD, and PERCENTAGE_AMD.
- */
- GLenum Type;
-
- /** Minimum counter value. */
- union gl_perf_monitor_counter_value Minimum;
-
- /** Maximum counter value. */
- union gl_perf_monitor_counter_value Maximum;
-};
-
-
-struct gl_perf_monitor_group
-{
- /** Human readable name for the group. */
- const char *Name;
-
- /**
- * Maximum number of counters in this group which can be active at the
- * same time.
- */
- GLuint MaxActiveCounters;
-
- /** Array of counters within this group. */
- const struct gl_perf_monitor_counter *Counters;
- GLuint NumCounters;
-};
-
-
-/**
- * Context state for AMD_performance_monitor.
- */
-struct gl_perf_monitor_state
-{
- /** Array of performance monitor groups (indexed by group ID) */
- const struct gl_perf_monitor_group *Groups;
- GLuint NumGroups;
-
- /** The table of all performance monitors. */
- struct _mesa_HashTable *Monitors;
-};
-
-
-/**
* Names of the various vertex/fragment program register files, etc.
*
* NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
@@ -2805,59 +1509,6 @@
#define GLSL_USE_GLASS 0x400 /**< Use LunarGlass optimizer */
/**
- * Context state for GLSL vertex/fragment shaders.
- * Extended to support pipeline object
- */
-struct gl_pipeline_object
-{
- /** Name of the pipeline object as received from glGenProgramPipelines.
- * It would be 0 for shaders without separate shader objects.
- */
- GLuint Name;
-
- GLint RefCount;
-
- mtx_t Mutex;
-
- /**
- * Programs used for rendering
- *
- * There is a separate program set for each shader stage.
- */
- struct gl_shader_program *CurrentProgram[MESA_SHADER_STAGES];
-
- struct gl_shader_program *_CurrentFragmentProgram;
-
- /**
- * Program used by glUniform calls.
- *
- * Explicitly set by \c glUseProgram and \c glActiveProgramEXT.
- */
- struct gl_shader_program *ActiveProgram;
-
- GLboolean EverBound; /**< Has the pipeline object been created */
-
- GLboolean Validated; /**< Pipeline Validation status */
-
- GLchar *InfoLog;
-};
-
-/**
- * Context state for GLSL pipeline shaders.
- */
-struct gl_pipeline_shader_state
-{
- /** Currently bound pipeline object. See _mesa_BindProgramPipeline() */
- struct gl_pipeline_object *Current;
-
- /* Default Object to ensure that _Shader is never NULL */
- struct gl_pipeline_object *Default;
-
- /** Pipeline objects */
- struct _mesa_HashTable *Objects;
-};
-
-/**
* Compiler options for a single GLSL shaders type
*/
struct gl_shader_compiler_options
@@ -2897,61 +1548,6 @@
struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */
};
-
-/**
- * Occlusion/timer query object.
- */
-struct gl_query_object
-{
- GLenum Target; /**< The query target, when active */
- GLuint Id; /**< hash table ID/name */
- GLchar *Label; /**< GL_KHR_debug */
- GLuint64EXT Result; /**< the counter */
- GLboolean Active; /**< inside Begin/EndQuery */
- GLboolean Ready; /**< result is ready? */
- GLboolean EverBound;/**< has query object ever been bound */
-};
-
-
-/**
- * Context state for query objects.
- */
-struct gl_query_state
-{
- struct _mesa_HashTable *QueryObjects;
- struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */
- struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */
-
- /** GL_NV_conditional_render */
- struct gl_query_object *CondRenderQuery;
-
- /** GL_EXT_transform_feedback */
- struct gl_query_object *PrimitivesGenerated;
- struct gl_query_object *PrimitivesWritten;
-
- /** GL_ARB_timer_query */
- struct gl_query_object *TimeElapsed;
-
- GLenum CondRenderMode;
-};
-
-
-/** Sync object state */
-struct gl_sync_object
-{
- GLenum Type; /**< GL_SYNC_FENCE */
- GLuint Name; /**< Fence name */
- GLchar *Label; /**< GL_KHR_debug */
- GLint RefCount; /**< Reference count */
- GLboolean DeletePending; /**< Object was deleted while there were still
- * live references (e.g., sync not yet finished)
- */
- GLenum SyncCondition;
- GLbitfield Flags; /**< Flags passed to glFenceSync */
- GLuint StatusFlag:1; /**< Has the sync object been signaled? */
-};
-
-
/**
* State which can be shared by multiple contexts:
*/
@@ -2959,28 +1555,6 @@
{
mtx_t Mutex; /**< for thread safety */
GLint RefCount; /**< Reference count */
- struct _mesa_HashTable *DisplayList; /**< Display lists hash table */
- struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */
-
- /** Default texture objects (shared by all texture units) */
- struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
-
- /** Fallback texture used when a bound texture is incomplete */
- struct gl_texture_object *FallbackTex[NUM_TEXTURE_TARGETS];
-
- /**
- * \name Thread safety and statechange notification for texture
- * objects.
- *
- * \todo Improve the granularity of locking.
- */
- /*@{*/
- mtx_t TexMutex; /**< texobj thread safety */
- GLuint TextureStateStamp; /**< state notification for shared tex */
- /*@}*/
-
- /** Default buffer object for vertex arrays that aren't in VBOs */
- struct gl_buffer_object *NullBufferObj;
/**
* \name Vertex/geometry/fragment programs
@@ -2996,21 +1570,9 @@
struct _mesa_HashTable *ATIShaders;
struct ati_fragment_shader *DefaultFragmentShader;
- struct _mesa_HashTable *BufferObjects;
-
/** Table of both gl_shader and gl_shader_program objects */
struct _mesa_HashTable *ShaderObjects;
- /* GL_EXT_framebuffer_object */
- struct _mesa_HashTable *RenderBuffers;
- struct _mesa_HashTable *FrameBuffers;
-
- /* GL_ARB_sync */
- struct set *SyncObjects;
-
- /** GL_ARB_sampler_objects */
- struct _mesa_HashTable *SamplerObjects;
-
/**
* Some context in this share group was affected by a GPU reset
*
@@ -3026,164 +1588,6 @@
/**
- * Renderbuffers represent drawing surfaces such as color, depth and/or
- * stencil. A framebuffer object has a set of renderbuffers.
- * Drivers will typically derive subclasses of this type.
- */
-struct gl_renderbuffer
-{
- mtx_t Mutex; /**< for thread safety */
- GLuint ClassID; /**< Useful for drivers */
- GLuint Name;
- GLchar *Label; /**< GL_KHR_debug */
- GLint RefCount;
- GLuint Width, Height;
- GLuint Depth;
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
- GLboolean AttachedAnytime; /**< TRUE if it was attached to a framebuffer */
- /**
- * True for renderbuffers that wrap textures, giving the driver a chance to
- * flush render caches through the FinishRenderTexture hook.
- *
- * Drivers may also set this on renderbuffers other than those generated by
- * glFramebufferTexture(), though it means FinishRenderTexture() would be
- * called without a rb->TexImage.
- */
- GLboolean NeedsFinishRenderTexture;
- GLubyte NumSamples;
- GLenum InternalFormat; /**< The user-specified format */
- GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
- GL_STENCIL_INDEX. */
- mesa_format Format; /**< The actual renderbuffer memory format */
- /**
- * Pointer to the texture image if this renderbuffer wraps a texture,
- * otherwise NULL.
- *
- * Note that the reference on the gl_texture_object containing this
- * TexImage is held by the gl_renderbuffer_attachment.
- */
- struct gl_texture_image *TexImage;
-
- /** Delete this renderbuffer */
- void (*Delete)(struct gl_context *ctx, struct gl_renderbuffer *rb);
-
- /** Allocate new storage for this renderbuffer */
- GLboolean (*AllocStorage)(struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLenum internalFormat,
- GLuint width, GLuint height);
-};
-
-
-/**
- * A renderbuffer attachment points to either a texture object (and specifies
- * a mipmap level, cube face or 3D texture slice) or points to a renderbuffer.
- */
-struct gl_renderbuffer_attachment
-{
- GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */
- GLboolean Complete;
-
- /**
- * If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the
- * application supplied renderbuffer object.
- */
- struct gl_renderbuffer *Renderbuffer;
-
- /**
- * If \c Type is \c GL_TEXTURE, this stores a pointer to the application
- * supplied texture object.
- */
- struct gl_texture_object *Texture;
- GLuint TextureLevel; /**< Attached mipmap level. */
- GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */
- GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D
- * and 2D array textures */
- GLboolean Layered;
-};
-
-
-/**
- * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc).
- * In C++ terms, think of this as a base class from which device drivers
- * will make derived classes.
- */
-struct gl_framebuffer
-{
- mtx_t Mutex; /**< for thread safety */
- /**
- * If zero, this is a window system framebuffer. If non-zero, this
- * is a FBO framebuffer; note that for some devices (i.e. those with
- * a natural pixel coordinate system for FBOs that differs from the
- * OpenGL/Mesa coordinate system), this means that the viewport,
- * polygon face orientation, and polygon stipple will have to be inverted.
- */
- GLuint Name;
- GLchar *Label; /**< GL_KHR_debug */
-
- GLint RefCount;
- GLboolean DeletePending;
-
- /**
- * The framebuffer's visual. Immutable if this is a window system buffer.
- * Computed from attachments if user-made FBO.
- */
- struct gl_config Visual;
-
- GLuint Width, Height; /**< size of frame buffer in pixels */
-
- /** \name Drawing bounds (Intersection of buffer size and scissor box) */
- /*@{*/
- GLint _Xmin, _Xmax; /**< inclusive */
- GLint _Ymin, _Ymax; /**< exclusive */
- /*@}*/
-
- /** \name Derived Z buffer stuff */
- /*@{*/
- GLuint _DepthMax; /**< Max depth buffer value */
- GLfloat _DepthMaxF; /**< Float max depth buffer value */
- GLfloat _MRD; /**< minimum resolvable difference in Z values */
- /*@}*/
-
- /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
- GLenum _Status;
-
- /** Integer color values */
- GLboolean _IntegerColor;
-
- /* ARB_color_buffer_float */
- GLboolean _AllColorBuffersFixedPoint; /* no integer, no float */
- GLboolean _HasSNormOrFloatColorBuffer;
-
- /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */
- struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT];
-
- /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER
- * attribute group and GL_PIXEL attribute group, respectively.
- */
- GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS];
- GLenum ColorReadBuffer;
-
- /** Computed from ColorDraw/ReadBuffer above */
- GLuint _NumColorDrawBuffers;
- GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */
- GLint _ColorReadBufferIndex; /* -1 = None */
- struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
- struct gl_renderbuffer *_ColorReadBuffer;
-
- /**
- * The maximum number of layers in the framebuffer, or 0 if the framebuffer
- * is not layered. For cube maps and cube map arrays, each cube face
- * counts as a layer.
- */
- GLuint MaxNumLayers;
-
- /** Delete this framebuffer */
- void (*Delete)(struct gl_framebuffer *fb);
-};
-
-
-/**
* Precision info for shader datatypes. See glGetShaderPrecisionFormat().
*/
struct gl_precision
@@ -3792,53 +2196,6 @@
*/
#define DLIST_DANGLING_REFS 0x1
-
-/** Opaque declaration of display list payload data type */
-union gl_dlist_node;
-
-
-/**
- * Provide a location where information about a display list can be
- * collected. Could be extended with driverPrivate structures,
- * etc. in the future.
- */
-struct gl_display_list
-{
- GLuint Name;
- GLchar *Label; /**< GL_KHR_debug */
- GLbitfield Flags; /**< DLIST_x flags */
- /** The dlist commands are in a linked list of nodes */
- union gl_dlist_node *Head;
-};
-
-
-/**
- * State used during display list compilation and execution.
- */
-struct gl_dlist_state
-{
- GLuint CallDepth; /**< Current recursion calling depth */
-
- struct gl_display_list *CurrentList; /**< List currently being compiled */
- union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */
- GLuint CurrentPos; /**< Index into current block of nodes */
-
- GLvertexformat ListVtxfmt;
-
- GLubyte ActiveAttribSize[VERT_ATTRIB_MAX];
- GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4];
-
- GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX];
- GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4];
-
- struct {
- /* State known to have been set by the currently-compiling display
- * list. Used to eliminate some redundant state changes.
- */
- GLenum ShadeModel;
- } Current;
-};
-
/** @{
*
* These are a mapping of the GL_ARB_debug_output/GL_KHR_debug enums
@@ -3893,121 +2250,6 @@
API_OPENGL_LAST = API_OPENGL_CORE
} gl_api;
-/**
- * Driver-specific state flags.
- *
- * These are or'd with gl_context::NewDriverState to notify a driver about
- * a state change. The driver sets the flags at context creation and
- * the meaning of the bits set is opaque to core Mesa.
- */
-struct gl_driver_flags
-{
- /** gl_context::Array::_DrawArrays (vertex array state) */
- GLbitfield NewArray;
-
- /** gl_context::TransformFeedback::CurrentObject */
- GLbitfield NewTransformFeedback;
-
- /** gl_context::TransformFeedback::CurrentObject::shader_program */
- GLbitfield NewTransformFeedbackProg;
-
- /** gl_context::RasterDiscard */
- GLbitfield NewRasterizerDiscard;
-
- /**
- * gl_context::UniformBufferBindings
- * gl_shader_program::UniformBlocks
- */
- GLbitfield NewUniformBuffer;
-
- /**
- * gl_context::AtomicBufferBindings
- */
- GLbitfield NewAtomicBuffer;
-
- /**
- * gl_context::ImageUnits
- */
- GLbitfield NewImageUnits;
-};
-
-struct gl_uniform_buffer_binding
-{
- struct gl_buffer_object *BufferObject;
- /** Start of uniform block data in the buffer */
- GLintptr Offset;
- /** Size of data allowed to be referenced from the buffer (in bytes) */
- GLsizeiptr Size;
- /**
- * glBindBufferBase() indicates that the Size should be ignored and only
- * limited by the current size of the BufferObject.
- */
- GLboolean AutomaticSize;
-};
-
-/**
- * ARB_shader_image_load_store image unit.
- */
-struct gl_image_unit
-{
- /**
- * Texture object bound to this unit.
- */
- struct gl_texture_object *TexObj;
-
- /**
- * Level of the texture object bound to this unit.
- */
- GLuint Level;
-
- /**
- * \c GL_TRUE if the whole level is bound as an array of layers, \c
- * GL_FALSE if only some specific layer of the texture is bound.
- * \sa Layer
- */
- GLboolean Layered;
-
- /**
- * Layer of the texture object bound to this unit, or zero if the
- * whole level is bound.
- */
- GLuint Layer;
-
- /**
- * Access allowed to this texture image. Either \c GL_READ_ONLY,
- * \c GL_WRITE_ONLY or \c GL_READ_WRITE.
- */
- GLenum Access;
-
- /**
- * GL internal format that determines the interpretation of the
- * image memory when shader image operations are performed through
- * this unit.
- */
- GLenum Format;
-
- /**
- * Mesa format corresponding to \c Format.
- */
- mesa_format _ActualFormat;
-
- /**
- * GL_TRUE if the state of this image unit is valid and access from
- * the shader is allowed. Otherwise loads from this unit should
- * return zero and stores should have no effect.
- */
- GLboolean _Valid;
-};
-
-/**
- * Binding point for an atomic counter buffer object.
- */
-struct gl_atomic_buffer_binding
-{
- struct gl_buffer_object *BufferObject;
- GLintptr Offset;
- GLsizeiptr Size;
-};
/**
* Mesa rendering context.
@@ -4020,67 +2262,20 @@
struct gl_context
{
/** State possibly shared with other contexts in the address space */
- struct gl_shared_state *Shared;
+ struct gl_shared_state *Shared;
/** \name API function pointer tables */
/*@{*/
- gl_api API;
- /**
- * The current dispatch table for non-displaylist-saving execution, either
- * BeginEnd or OutsideBeginEnd
- */
- struct _glapi_table *Exec;
- /**
- * The normal dispatch table for non-displaylist-saving, non-begin/end
- */
- struct _glapi_table *OutsideBeginEnd;
- /** The dispatch table used between glNewList() and glEndList() */
- struct _glapi_table *Save;
- /**
- * The dispatch table used between glBegin() and glEnd() (outside of a
- * display list). Only valid functions between those two are set, which is
- * mostly just the set in a GLvertexformat struct.
- */
- struct _glapi_table *BeginEnd;
- /**
- * Tracks the current dispatch table out of the 3 above, so that it can be
- * re-set on glXMakeCurrent().
- */
- struct _glapi_table *CurrentDispatch;
- /*@}*/
-
- struct gl_config Visual;
- struct gl_framebuffer *DrawBuffer; /**< buffer for writing */
- struct gl_framebuffer *ReadBuffer; /**< buffer for reading */
- struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */
- struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */
+ gl_api API;
/**
* Device driver function pointer table
*/
- struct dd_function_table Driver;
+ struct dd_function_table Driver; // LunarG: MARKED_FOR_DEATH
/** Core/Driver constants */
struct gl_constants Const;
- /** \name The various 4x4 matrix stacks */
- /*@{*/
- struct gl_matrix_stack ModelviewMatrixStack;
- struct gl_matrix_stack ProjectionMatrixStack;
- struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS];
- struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
- struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
- /*@}*/
-
- /** Combined modelview and projection matrix */
- GLmatrix _ModelProjectMatrix;
-
- /** \name Display lists */
- struct gl_dlist_state ListState;
-
- GLboolean ExecuteFlag; /**< Execute GL commands? */
- GLboolean CompileFlag; /**< Compile GL commands into display list? */
-
/** Extension information */
struct gl_extensions Extensions;
@@ -4088,61 +2283,7 @@
GLuint Version;
char *VersionString;
- /** \name State attribute stack (for glPush/PopAttrib) */
- /*@{*/
- GLuint AttribStackDepth;
- struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH];
- /*@}*/
-
- /** \name Renderer attribute groups
- *
- * We define a struct for each attribute group to make pushing and popping
- * attributes easy. Also it's a good organization.
- */
- /*@{*/
- struct gl_accum_attrib Accum; /**< Accum buffer attributes */
- struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */
- struct gl_current_attrib Current; /**< Current attributes */
- struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */
- struct gl_eval_attrib Eval; /**< Eval attributes */
- struct gl_fog_attrib Fog; /**< Fog attributes */
- struct gl_hint_attrib Hint; /**< Hint attributes */
- struct gl_light_attrib Light; /**< Light attributes */
- struct gl_line_attrib Line; /**< Line attributes */
- struct gl_list_attrib List; /**< List attributes */
struct gl_multisample_attrib Multisample;
- struct gl_pixel_attrib Pixel; /**< Pixel attributes */
- struct gl_point_attrib Point; /**< Point attributes */
- struct gl_polygon_attrib Polygon; /**< Polygon attributes */
- GLuint PolygonStipple[32]; /**< Polygon stipple */
- struct gl_scissor_attrib Scissor; /**< Scissor attributes */
- struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */
- struct gl_texture_attrib Texture; /**< Texture attributes */
- struct gl_transform_attrib Transform; /**< Transformation attributes */
- struct gl_viewport_attrib ViewportArray[MAX_VIEWPORTS]; /**< Viewport attributes */
- /*@}*/
-
- /** \name Client attribute stack */
- /*@{*/
- GLuint ClientAttribStackDepth;
- struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH];
- /*@}*/
-
- /** \name Client attribute groups */
- /*@{*/
- struct gl_array_attrib Array; /**< Vertex arrays */
- struct gl_pixelstore_attrib Pack; /**< Pixel packing */
- struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */
- struct gl_pixelstore_attrib DefaultPacking; /**< Default params */
- /*@}*/
-
- /** \name Other assorted state (not pushed/popped on attribute stack) */
- /*@{*/
- struct gl_pixelmaps PixelMaps;
-
- struct gl_evaluators EvalMap; /**< All evaluators */
- struct gl_feedback Feedback; /**< Feedback */
- struct gl_selection Select; /**< Selection */
struct gl_program_state Program; /**< general program state */
struct gl_vertex_program_state VertexProgram;
@@ -4150,80 +2291,8 @@
struct gl_geometry_program_state GeometryProgram;
struct gl_ati_fragment_shader_state ATIFragmentShader;
- struct gl_pipeline_shader_state Pipeline; /**< GLSL pipeline shader object state */
- struct gl_pipeline_object Shader; /**< GLSL shader object state */
-
- /**
- * Current active shader pipeline state
- *
- * Almost all internal users want ::_Shader instead of ::Shader. The
- * exceptions are bits of legacy GLSL API that do not know about separate
- * shader objects.
- *
- * If a program is active via \c glUseProgram, this will point to
- * \c ::Shader.
- *
- * If a program pipeline is active via \c glBindProgramPipeline, this will
- * point to \c ::Pipeline.Current.
- *
- * If neither a program nor a program pipeline is active, this will point to
- * \c ::Pipeline.Default. This ensures that \c ::_Shader will never be
- * \c NULL.
- */
- struct gl_pipeline_object *_Shader;
-
struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_STAGES];
- struct gl_query_state Query; /**< occlusion, timer queries */
-
- struct gl_transform_feedback_state TransformFeedback;
-
- struct gl_perf_monitor_state PerfMonitor;
-
- struct gl_buffer_object *DrawIndirectBuffer; /** < GL_ARB_draw_indirect */
-
- struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */
- struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
-
- /**
- * Current GL_ARB_uniform_buffer_object binding referenced by
- * GL_UNIFORM_BUFFER target for glBufferData, glMapBuffer, etc.
- */
- struct gl_buffer_object *UniformBuffer;
-
- /**
- * Array of uniform buffers for GL_ARB_uniform_buffer_object and GL 3.1.
- * This is set up using glBindBufferRange() or glBindBufferBase(). They are
- * associated with uniform blocks by glUniformBlockBinding()'s state in the
- * shader program.
- */
- struct gl_uniform_buffer_binding
- UniformBufferBindings[MAX_COMBINED_UNIFORM_BUFFERS];
-
- /**
- * Object currently associated with the GL_ATOMIC_COUNTER_BUFFER
- * target.
- */
- struct gl_buffer_object *AtomicBuffer;
-
- /**
- * Array of atomic counter buffer binding points.
- */
- struct gl_atomic_buffer_binding
- AtomicBufferBindings[MAX_COMBINED_ATOMIC_BUFFERS];
-
- /**
- * Array of image units for ARB_shader_image_load_store.
- */
- struct gl_image_unit ImageUnits[MAX_IMAGE_UNITS];
-
- /*@}*/
-
- struct gl_meta_state *Meta; /**< for "meta" operations */
-
- /* GL_EXT_framebuffer_object */
- struct gl_renderbuffer *CurrentRenderbuffer;
-
GLenum ErrorValue; /**< Last error code */
/**
@@ -4233,92 +2302,17 @@
GLuint ErrorDebugCount;
/* GL_ARB_debug_output/GL_KHR_debug */
+ // LunarG: MARKED_FOR_DEATH
mtx_t DebugMutex;
struct gl_debug_state *Debug;
- GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
- GLbitfield NewState; /**< bitwise-or of _NEW_* flags */
- GLbitfield NewDriverState;/**< bitwise-or of flags from DriverFlags */
-
- struct gl_driver_flags DriverFlags;
-
- GLboolean ViewportInitialized; /**< has viewport size been initialized? */
-
- GLbitfield64 varying_vp_inputs; /**< mask of VERT_BIT_* flags */
-
- /** \name Derived state */
- GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */
- GLfloat _EyeZDir[3];
- GLfloat _ModelViewInvScale;
- GLboolean _NeedEyeCoords;
- GLboolean _ForceEyeCoords;
-
- GLuint TextureStateTimestamp; /**< detect changes to shared state */
struct gl_list_extensions *ListExt; /**< driver dlist extensions */
- /** \name For debugging/development only */
- /*@{*/
- GLboolean FirstTimeCurrent;
- /*@}*/
-
- /**
- * False if this context was created without a config. This is needed
- * because the initial state of glDrawBuffers depends on this
- */
- GLboolean HasConfig;
-
- /** software compression/decompression supported or not */
- GLboolean Mesa_DXTn;
-
- GLboolean TextureFormatSupported[MESA_FORMAT_COUNT];
-
- GLboolean RasterDiscard; /**< GL_RASTERIZER_DISCARD */
-
- /**
- * \name Hooks for module contexts.
- *
- * These will eventually live in the driver or elsewhere.
- */
- /*@{*/
- void *swrast_context;
- void *swsetup_context;
- void *swtnl_context;
- struct vbo_context *vbo_context;
- struct st_context *st;
- void *aelt_context;
- /*@}*/
-
- /**
- * \name NV_vdpau_interop
- */
- /*@{*/
- const void *vdpDevice;
- const void *vdpGetProcAddress;
- struct set *vdpSurfaces;
- /*@}*/
-
- /**
- * Has this context observed a GPU reset in any context in the share group?
- *
- * Once this field becomes true, it is never reset to false.
- */
- GLboolean ShareGroupReset;
-
GLbitfield GlslFlags; /**< Mask of GLSL_x flags */
/* A thread pool for threaded shader compilation */
struct _mesa_threadpool *ThreadPool;
-
- /**
- * Binary shader cache disk location, activity, and maximum size.
- */
- char *BinaryShaderCachePath;
- char *BinaryProgramCachePath;
- GLboolean BinaryShaderCacheActive;
- GLboolean BinaryProgramCacheActive;
-
-
};
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/shaderobj.h b/icd/intel/compiler/mesa-utils/src/mesa/main/shaderobj.h
new file mode 100644
index 0000000..c2f8a0d
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/shaderobj.h
@@ -0,0 +1,174 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef SHADEROBJ_H
+#define SHADEROBJ_H
+
+
+#include "main/compiler.h"
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "program/ir_to_mesa.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Internal functions
+ */
+
+extern void
+_mesa_init_shader_state(struct gl_context * ctx);
+
+extern void
+_mesa_free_shader_state(struct gl_context *ctx);
+
+
+extern void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh);
+
+extern void
+_mesa_wait_shaders(struct gl_context *ctx,
+ struct gl_shader **shaders,
+ int num_shaders);
+
+extern struct gl_shader *
+_mesa_lookup_shader_no_wait(struct gl_context *ctx, GLuint name);
+
+extern struct gl_shader *
+_mesa_lookup_shader_err_no_wait(struct gl_context *ctx, GLuint name,
+ const char *caller);
+
+static inline struct gl_shader *
+_mesa_lookup_shader(struct gl_context *ctx, GLuint name)
+{
+ struct gl_shader *sh = _mesa_lookup_shader_no_wait(ctx, name);
+ if (sh)
+ _mesa_wait_shaders(ctx, &sh, 1);
+ return sh;
+}
+
+static inline struct gl_shader *
+_mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller)
+{
+ struct gl_shader *sh = _mesa_lookup_shader_err_no_wait(ctx, name, caller);
+ if (sh)
+ _mesa_wait_shaders(ctx, &sh, 1);
+ return sh;
+}
+
+extern void
+_mesa_reference_shader_program(struct gl_context *ctx,
+ struct gl_shader_program **ptr,
+ struct gl_shader_program *shProg);
+extern void
+_mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader);
+
+extern struct gl_shader *
+_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type);
+
+extern void
+_mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog);
+
+extern void
+_mesa_wait_shader_program(struct gl_context *ctx,
+ struct gl_shader_program *shProg);
+
+extern struct gl_shader_program *
+_mesa_lookup_shader_program_no_wait(struct gl_context *ctx, GLuint name);
+
+extern struct gl_shader_program *
+_mesa_lookup_shader_program_err_no_wait(struct gl_context *ctx, GLuint name,
+ const char *caller);
+
+static inline struct gl_shader_program *
+_mesa_lookup_shader_program(struct gl_context *ctx, GLuint name)
+{
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_no_wait(ctx, name);
+ if (shProg)
+ _mesa_wait_shader_program(ctx, shProg);
+ return shProg;
+}
+
+static inline struct gl_shader_program *
+_mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name,
+ const char *caller)
+{
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err_no_wait(ctx, name, caller);
+ if (shProg)
+ _mesa_wait_shader_program(ctx, shProg);
+ return shProg;
+}
+
+extern void
+_mesa_clear_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg);
+
+extern void
+_mesa_free_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg);
+
+
+
+extern void
+_mesa_init_shader_object_functions(struct dd_function_table *driver);
+
+extern void
+_mesa_init_shader_state(struct gl_context *ctx);
+
+extern void
+_mesa_free_shader_state(struct gl_context *ctx);
+
+
+static inline gl_shader_stage
+_mesa_shader_enum_to_shader_stage(GLenum v)
+{
+ switch (v) {
+ case GL_VERTEX_SHADER:
+ return MESA_SHADER_VERTEX;
+ case GL_FRAGMENT_SHADER:
+ return MESA_SHADER_FRAGMENT;
+ case GL_GEOMETRY_SHADER:
+ return MESA_SHADER_GEOMETRY;
+ case GL_COMPUTE_SHADER:
+ return MESA_SHADER_COMPUTE;
+ default:
+ ASSERT(0 && "bad value in _mesa_shader_enum_to_shader_stage()");
+ return MESA_SHADER_VERTEX;
+ }
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SHADEROBJ_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/uniforms.h b/icd/intel/compiler/mesa-utils/src/mesa/main/uniforms.h
new file mode 100644
index 0000000..10518dc
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/uniforms.h
@@ -0,0 +1,394 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2010 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef UNIFORMS_H
+#define UNIFORMS_H
+
+#include "glheader.h"
+#include "program/prog_parameter.h"
+#include "../glsl/glsl_types.h"
+#include "../glsl/ir_uniform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct gl_program;
+struct _glapi_table;
+
+void GLAPIENTRY
+_mesa_Uniform1f(GLint, GLfloat);
+void GLAPIENTRY
+_mesa_Uniform2f(GLint, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_Uniform3f(GLint, GLfloat, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_Uniform4f(GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_Uniform1i(GLint, GLint);
+void GLAPIENTRY
+_mesa_Uniform2i(GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_Uniform3i(GLint, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_Uniform4i(GLint, GLint, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_Uniform1fv(GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_Uniform2fv(GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_Uniform3fv(GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_Uniform4fv(GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_Uniform1iv(GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_Uniform2iv(GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_Uniform3iv(GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_Uniform4iv(GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_Uniform1ui(GLint location, GLuint v0);
+void GLAPIENTRY
+_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1);
+void GLAPIENTRY
+_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+void GLAPIENTRY
+_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+void GLAPIENTRY
+_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+void GLAPIENTRY
+_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+void GLAPIENTRY
+_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+void GLAPIENTRY
+_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+void GLAPIENTRY
+_mesa_UniformMatrix2fv(GLint, GLsizei, GLboolean, const GLfloat *);
+void GLAPIENTRY
+_mesa_UniformMatrix3fv(GLint, GLsizei, GLboolean, const GLfloat *);
+void GLAPIENTRY
+_mesa_UniformMatrix4fv(GLint, GLsizei, GLboolean, const GLfloat *);
+void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+void GLAPIENTRY
+_mesa_ProgramUniform1f(GLuint program, GLint, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform2f(GLuint program, GLint, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform3f(GLuint program, GLint, GLfloat, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform4f(GLuint program, GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform1i(GLuint program, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform2i(GLuint program, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform3i(GLuint program, GLint, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform4i(GLuint program, GLint, GLint, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform1fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform2fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform3fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform4fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform1iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform2iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform3iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform4iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform1ui(GLuint program, GLint location, GLuint v0);
+void GLAPIENTRY
+_mesa_ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1);
+void GLAPIENTRY
+_mesa_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1,
+ GLuint v2);
+void GLAPIENTRY
+_mesa_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1,
+ GLuint v2, GLuint v3);
+void GLAPIENTRY
+_mesa_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2fv(GLuint program, GLint, GLsizei, GLboolean,
+ const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3fv(GLuint program, GLint, GLsizei, GLboolean,
+ const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4fv(GLuint program, GLint, GLsizei, GLboolean,
+ const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+
+void GLAPIENTRY
+_mesa_GetnUniformfvARB(GLuint, GLint, GLsizei, GLfloat *);
+void GLAPIENTRY
+_mesa_GetUniformfv(GLuint, GLint, GLfloat *);
+void GLAPIENTRY
+_mesa_GetnUniformivARB(GLuint, GLint, GLsizei, GLint *);
+void GLAPIENTRY
+_mesa_GetUniformuiv(GLuint, GLint, GLuint *);
+void GLAPIENTRY
+_mesa_GetnUniformuivARB(GLuint, GLint, GLsizei, GLuint *);
+void GLAPIENTRY
+_mesa_GetUniformuiv(GLuint program, GLint location, GLuint *params);
+void GLAPIENTRY
+_mesa_GetnUniformdvARB(GLuint, GLint, GLsizei, GLdouble *);
+void GLAPIENTRY
+_mesa_GetUniformdv(GLuint, GLint, GLdouble *);
+GLint GLAPIENTRY
+_mesa_GetUniformLocation(GLuint, const GLcharARB *);
+GLuint GLAPIENTRY
+_mesa_GetUniformBlockIndex(GLuint program,
+ const GLchar *uniformBlockName);
+void GLAPIENTRY
+_mesa_GetUniformIndices(GLuint program,
+ GLsizei uniformCount,
+ const GLchar * const *uniformNames,
+ GLuint *uniformIndices);
+void GLAPIENTRY
+_mesa_UniformBlockBinding(GLuint program,
+ GLuint uniformBlockIndex,
+ GLuint uniformBlockBinding);
+void GLAPIENTRY
+_mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
+ GLenum pname, GLint *params);
+void GLAPIENTRY
+_mesa_GetActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params);
+void GLAPIENTRY
+_mesa_GetActiveUniformBlockName(GLuint program,
+ GLuint uniformBlockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName);
+void GLAPIENTRY
+_mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex,
+ GLsizei bufSize, GLsizei *length,
+ GLchar *uniformName);
+void GLAPIENTRY
+_mesa_GetActiveUniform(GLuint, GLuint, GLsizei, GLsizei *,
+ GLint *, GLenum *, GLcharARB *);
+void GLAPIENTRY
+_mesa_GetActiveUniformsiv(GLuint program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params);
+void GLAPIENTRY
+_mesa_GetUniformiv(GLuint, GLint, GLint *);
+
+long
+_mesa_parse_program_resource_name(const GLchar *name,
+ const GLchar **out_base_name_end);
+
+unsigned
+_mesa_get_uniform_location(struct gl_context *ctx, struct gl_shader_program *shProg,
+ const GLchar *name, unsigned *offset);
+
+void
+_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shader_program,
+ GLint location, GLsizei count,
+ const GLvoid *values, GLenum type);
+
+void
+_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
+ GLuint cols, GLuint rows,
+ GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *values);
+
+void
+_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
+ GLsizei bufSize, enum glsl_base_type returnType,
+ GLvoid *paramsOut);
+
+extern void
+_mesa_uniform_attach_driver_storage(struct gl_uniform_storage *,
+ unsigned element_stride,
+ unsigned vector_stride,
+ enum gl_uniform_driver_format format,
+ void *data);
+
+extern void
+_mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage *uni);
+
+extern void
+_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
+ unsigned array_index,
+ unsigned count);
+
+extern void
+_mesa_update_shader_textures_used(struct gl_shader_program *shProg,
+ struct gl_program *prog);
+
+extern bool
+_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
+ char *errMsg, size_t errMsgLength);
+extern bool
+_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *);
+
+extern const struct gl_program_parameter *
+get_uniform_parameter(struct gl_shader_program *shProg, GLint index);
+
+extern void
+_mesa_get_uniform_name(const struct gl_uniform_storage *uni,
+ GLsizei maxLength, GLsizei *length,
+ GLchar *nameOut);
+
+struct gl_builtin_uniform_element {
+ const char *field;
+ int tokens[STATE_LENGTH];
+ int swizzle;
+};
+
+struct gl_builtin_uniform_desc {
+ const char *name;
+ const struct gl_builtin_uniform_element *elements;
+ unsigned int num_elements;
+};
+
+/**
+ * \name GLSL uniform arrays and structs require special handling.
+ *
+ * The GL_ARB_shader_objects spec says that if you use
+ * glGetUniformLocation to get the location of an array, you CANNOT
+ * access other elements of the array by adding an offset to the
+ * returned location. For example, you must call
+ * glGetUniformLocation("foo[16]") if you want to set the 16th element
+ * of the array with glUniform().
+ *
+ * HOWEVER, some other OpenGL drivers allow accessing array elements
+ * by adding an offset to the returned array location. And some apps
+ * seem to depend on that behaviour.
+ *
+ * Mesa's gl_uniform_list doesn't directly support this since each
+ * entry in the list describes one uniform variable, not one uniform
+ * element. We could insert dummy entries in the list for each array
+ * element after [0] but that causes complications elsewhere.
+ *
+ * We solve this problem by creating multiple entries for uniform arrays
+ * in the UniformRemapTable so that their elements get sequential locations.
+ *
+ * Utility functions below offer functionality to split UniformRemapTable
+ * location in to location of the uniform in UniformStorage + offset to the
+ * array element (0 if not an array) and also merge it back again as the
+ * UniformRemapTable location.
+ *
+ */
+/*@{*/
+/**
+ * Combine the uniform's storage index and the array index
+ */
+static inline GLint
+_mesa_uniform_merge_location_offset(const struct gl_shader_program *prog,
+ unsigned storage_index,
+ unsigned uniform_array_index)
+{
+ /* location in remap table + array element offset */
+ return prog->UniformStorage[storage_index].remap_location +
+ uniform_array_index;
+}
+
+/**
+ * Separate the uniform storage index and array index
+ */
+static inline void
+_mesa_uniform_split_location_offset(const struct gl_shader_program *prog,
+ GLint location, unsigned *storage_index,
+ unsigned *uniform_array_index)
+{
+ *storage_index = prog->UniformRemapTable[location] - prog->UniformStorage;
+ *uniform_array_index = location -
+ prog->UniformRemapTable[location]->remap_location;
+
+ /*gl_uniform_storage in UniformStorage with the calculated base_location
+ * must match with the entry in remap table
+ */
+ assert(&prog->UniformStorage[*storage_index] ==
+ prog->UniformRemapTable[location]);
+}
+/*@}*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* UNIFORMS_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/version.c b/icd/intel/compiler/mesa-utils/src/mesa/main/version.c
new file mode 100644
index 0000000..68db57a
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/version.c
@@ -0,0 +1,413 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2010 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "imports.h"
+#include "mtypes.h"
+#include "version.h"
+// #include "git_sha1.h" // LunarG DEL:
+
+/**
+ * Scans 'string' to see if it ends with 'ending'.
+ */
+static GLboolean
+check_for_ending(const char *string, const char *ending)
+{
+ int len1, len2;
+
+ len1 = strlen(string);
+ len2 = strlen(ending);
+
+ if (len2 > len1) {
+ return GL_FALSE;
+ }
+
+ if (strcmp(string + (len1 - len2), ending) == 0) {
+ return GL_TRUE;
+ } else {
+ return GL_FALSE;
+ }
+}
+
+/**
+ * Returns the gl override data
+ *
+ * version > 0 indicates there is an override requested
+ * fwd_context is only valid if version > 0
+ */
+static void
+get_gl_override(int *version, GLboolean *fwd_context)
+{
+ const char *env_var = "MESA_GL_VERSION_OVERRIDE";
+ const char *version_str;
+ int major, minor, n;
+ static int override_version = -1;
+ static GLboolean fc_suffix = GL_FALSE;
+
+ if (override_version < 0) {
+ override_version = 0;
+
+ version_str = getenv(env_var);
+ if (version_str) {
+ fc_suffix = check_for_ending(version_str, "FC");
+
+ n = sscanf(version_str, "%u.%u", &major, &minor);
+ if (n != 2) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version_str);
+ override_version = 0;
+ } else {
+ override_version = major * 10 + minor;
+ if (override_version < 30 && fc_suffix) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version_str);
+ }
+ }
+ }
+ }
+
+ *version = override_version;
+ *fwd_context = fc_suffix;
+}
+
+/**
+ * Builds the MESA version string.
+ */
+static void
+create_version_string(struct gl_context *ctx, const char *prefix)
+{
+ static const int max = 100;
+
+ ctx->VersionString = malloc(max);
+ if (ctx->VersionString) {
+ ctx->VersionString[0] = '\0';
+ }
+}
+
+/**
+ * Override the context's version and/or API type if the
+ * environment variable MESA_GL_VERSION_OVERRIDE is set.
+ *
+ * Example uses of MESA_GL_VERSION_OVERRIDE:
+ *
+ * 2.1: select a compatibility (non-Core) profile with GL version 2.1
+ * 3.0: select a compatibility (non-Core) profile with GL version 3.0
+ * 3.0FC: select a Core+Forward Compatible profile with GL version 3.0
+ * 3.1: select a Core profile with GL version 3.1
+ * 3.1FC: select a Core+Forward Compatible profile with GL version 3.1
+ */
+void
+_mesa_override_gl_version(struct gl_context *ctx)
+{
+ int version;
+ GLboolean fwd_context;
+
+ get_gl_override(&version, &fwd_context);
+
+ if (version > 0) {
+ ctx->Version = version;
+ if (version >= 30 && fwd_context) {
+ ctx->API = API_OPENGL_CORE;
+ ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
+ } else if (version >= 31) {
+ ctx->API = API_OPENGL_CORE;
+ } else {
+ ctx->API = API_OPENGL_COMPAT;
+ }
+ create_version_string(ctx, "");
+ }
+}
+
+/**
+ * Returns the gl override value
+ *
+ * version > 0 indicates there is an override requested
+ */
+int
+_mesa_get_gl_version_override(void)
+{
+ int version;
+ GLboolean fwd_context;
+
+ get_gl_override(&version, &fwd_context);
+
+ return version;
+}
+
+/**
+ * Override the context's GLSL version if the environment variable
+ * MESA_GLSL_VERSION_OVERRIDE is set. Valid values for
+ * MESA_GLSL_VERSION_OVERRIDE are integers, such as "130".
+ */
+void
+_mesa_override_glsl_version(struct gl_context *ctx)
+{
+ const char *env_var = "MESA_GLSL_VERSION_OVERRIDE";
+ const char *version;
+ int n;
+
+ version = getenv(env_var);
+ if (!version) {
+ return;
+ }
+
+ n = sscanf(version, "%u", &ctx->Const.GLSLVersion);
+ if (n != 1) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
+ return;
+ }
+}
+
+/**
+ * Examine enabled GL extensions to determine GL version.
+ */
+static void
+compute_version(struct gl_context *ctx)
+{
+ GLuint major, minor;
+
+ const GLboolean ver_1_3 = (ctx->Extensions.ARB_texture_border_clamp &&
+ ctx->Extensions.ARB_texture_cube_map &&
+ ctx->Extensions.ARB_texture_env_combine &&
+ ctx->Extensions.ARB_texture_env_dot3);
+ const GLboolean ver_1_4 = (ver_1_3 &&
+ ctx->Extensions.ARB_depth_texture &&
+ ctx->Extensions.ARB_shadow &&
+ ctx->Extensions.ARB_texture_env_crossbar &&
+ ctx->Extensions.EXT_blend_color &&
+ ctx->Extensions.EXT_blend_func_separate &&
+ ctx->Extensions.EXT_blend_minmax &&
+ ctx->Extensions.EXT_point_parameters);
+ const GLboolean ver_1_5 = (ver_1_4 &&
+ ctx->Extensions.ARB_occlusion_query);
+ const GLboolean ver_2_0 = (ver_1_5 &&
+ ctx->Extensions.ARB_point_sprite &&
+ ctx->Extensions.ARB_vertex_shader &&
+ ctx->Extensions.ARB_fragment_shader &&
+ ctx->Extensions.ARB_texture_non_power_of_two &&
+ ctx->Extensions.EXT_blend_equation_separate &&
+
+ /* Technically, 2.0 requires the functionality
+ * of the EXT version. Enable 2.0 if either
+ * extension is available, and assume that a
+ * driver that only exposes the ATI extension
+ * will fallback to software when necessary.
+ */
+ (ctx->Extensions.EXT_stencil_two_side
+ || ctx->Extensions.ATI_separate_stencil));
+ const GLboolean ver_2_1 = (ver_2_0 &&
+ ctx->Extensions.EXT_pixel_buffer_object &&
+ ctx->Extensions.EXT_texture_sRGB);
+ const GLboolean ver_3_0 = (ver_2_1 &&
+ ctx->Const.GLSLVersion >= 130 &&
+ (ctx->Const.MaxSamples >= 4 || ctx->Const.FakeSWMSAA) &&
+ (ctx->API == API_OPENGL_CORE ||
+ ctx->Extensions.ARB_color_buffer_float) &&
+ ctx->Extensions.ARB_depth_buffer_float &&
+ ctx->Extensions.ARB_half_float_vertex &&
+ ctx->Extensions.ARB_map_buffer_range &&
+ ctx->Extensions.ARB_shader_texture_lod &&
+ ctx->Extensions.ARB_texture_float &&
+ ctx->Extensions.ARB_texture_rg &&
+ ctx->Extensions.ARB_texture_compression_rgtc &&
+ ctx->Extensions.EXT_draw_buffers2 &&
+ ctx->Extensions.ARB_framebuffer_object &&
+ ctx->Extensions.EXT_framebuffer_sRGB &&
+ ctx->Extensions.EXT_packed_float &&
+ ctx->Extensions.EXT_texture_array &&
+ ctx->Extensions.EXT_texture_shared_exponent &&
+ ctx->Extensions.EXT_transform_feedback &&
+ ctx->Extensions.NV_conditional_render);
+ const GLboolean ver_3_1 = (ver_3_0 &&
+ ctx->Const.GLSLVersion >= 140 &&
+ ctx->Extensions.ARB_draw_instanced &&
+ ctx->Extensions.ARB_texture_buffer_object &&
+ ctx->Extensions.ARB_uniform_buffer_object &&
+ ctx->Extensions.EXT_texture_snorm &&
+ ctx->Extensions.NV_primitive_restart &&
+ ctx->Extensions.NV_texture_rectangle &&
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits >= 16);
+ const GLboolean ver_3_2 = (ver_3_1 &&
+ ctx->Const.GLSLVersion >= 150 &&
+ ctx->Extensions.ARB_depth_clamp &&
+ ctx->Extensions.ARB_draw_elements_base_vertex &&
+ ctx->Extensions.ARB_fragment_coord_conventions &&
+ ctx->Extensions.EXT_provoking_vertex &&
+ ctx->Extensions.ARB_seamless_cube_map &&
+ ctx->Extensions.ARB_sync &&
+ ctx->Extensions.ARB_texture_multisample &&
+ ctx->Extensions.EXT_vertex_array_bgra);
+ const GLboolean ver_3_3 = (ver_3_2 &&
+ ctx->Const.GLSLVersion >= 330 &&
+ ctx->Extensions.ARB_blend_func_extended &&
+ ctx->Extensions.ARB_explicit_attrib_location &&
+ ctx->Extensions.ARB_instanced_arrays &&
+ ctx->Extensions.ARB_occlusion_query2 &&
+ ctx->Extensions.ARB_shader_bit_encoding &&
+ ctx->Extensions.ARB_texture_rgb10_a2ui &&
+ ctx->Extensions.ARB_timer_query &&
+ ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
+ ctx->Extensions.EXT_texture_swizzle);
+ /* ARB_sampler_objects is always enabled in mesa */
+
+ if (ver_3_3) {
+ major = 3;
+ minor = 3;
+ }
+ else if (ver_3_2) {
+ major = 3;
+ minor = 2;
+ }
+ else if (ver_3_1) {
+ major = 3;
+ minor = 1;
+ }
+ else if (ver_3_0) {
+ major = 3;
+ minor = 0;
+ }
+ else if (ver_2_1) {
+ major = 2;
+ minor = 1;
+ }
+ else if (ver_2_0) {
+ major = 2;
+ minor = 0;
+ }
+ else if (ver_1_5) {
+ major = 1;
+ minor = 5;
+ }
+ else if (ver_1_4) {
+ major = 1;
+ minor = 4;
+ }
+ else if (ver_1_3) {
+ major = 1;
+ minor = 3;
+ }
+ else {
+ major = 1;
+ minor = 2;
+ }
+
+ ctx->Version = major * 10 + minor;
+
+ create_version_string(ctx, "");
+}
+
+static void
+compute_version_es1(struct gl_context *ctx)
+{
+ /* OpenGL ES 1.0 is derived from OpenGL 1.3 */
+ const GLboolean ver_1_0 = (ctx->Extensions.ARB_texture_env_combine &&
+ ctx->Extensions.ARB_texture_env_dot3);
+ /* OpenGL ES 1.1 is derived from OpenGL 1.5 */
+ const GLboolean ver_1_1 = (ver_1_0 &&
+ ctx->Extensions.EXT_point_parameters);
+
+ if (ver_1_1) {
+ ctx->Version = 11;
+ } else if (ver_1_0) {
+ ctx->Version = 10;
+ } else {
+ _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support.");
+ }
+
+ create_version_string(ctx, "OpenGL ES-CM ");
+}
+
+static void
+compute_version_es2(struct gl_context *ctx)
+{
+ /* OpenGL ES 2.0 is derived from OpenGL 2.0 */
+ const GLboolean ver_2_0 = (ctx->Extensions.ARB_texture_cube_map &&
+ ctx->Extensions.EXT_blend_color &&
+ ctx->Extensions.EXT_blend_func_separate &&
+ ctx->Extensions.EXT_blend_minmax &&
+ ctx->Extensions.ARB_vertex_shader &&
+ ctx->Extensions.ARB_fragment_shader &&
+ ctx->Extensions.ARB_texture_non_power_of_two &&
+ ctx->Extensions.EXT_blend_equation_separate);
+ /* FINISHME: This list isn't quite right. */
+ const GLboolean ver_3_0 = (ctx->Extensions.ARB_half_float_vertex &&
+ ctx->Extensions.ARB_internalformat_query &&
+ ctx->Extensions.ARB_map_buffer_range &&
+ ctx->Extensions.ARB_shader_texture_lod &&
+ ctx->Extensions.ARB_texture_float &&
+ ctx->Extensions.ARB_texture_rg &&
+ ctx->Extensions.ARB_texture_compression_rgtc &&
+ ctx->Extensions.EXT_draw_buffers2 &&
+ /* ctx->Extensions.ARB_framebuffer_object && */
+ ctx->Extensions.EXT_framebuffer_sRGB &&
+ ctx->Extensions.EXT_packed_float &&
+ ctx->Extensions.EXT_texture_array &&
+ ctx->Extensions.EXT_texture_shared_exponent &&
+ ctx->Extensions.EXT_transform_feedback &&
+ ctx->Extensions.NV_conditional_render &&
+ ctx->Extensions.ARB_draw_instanced &&
+ ctx->Extensions.ARB_uniform_buffer_object &&
+ ctx->Extensions.EXT_texture_snorm &&
+ ctx->Extensions.NV_primitive_restart &&
+ ctx->Extensions.OES_depth_texture_cube_map);
+ if (ver_3_0) {
+ ctx->Version = 30;
+ } else if (ver_2_0) {
+ ctx->Version = 20;
+ } else {
+ _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support.");
+ }
+
+ create_version_string(ctx, "OpenGL ES ");
+}
+
+/**
+ * Set the context's Version and VersionString fields.
+ * This should only be called once as part of context initialization
+ * or to perform version check for GLX_ARB_create_context_profile.
+ */
+void
+_mesa_compute_version(struct gl_context *ctx)
+{
+ if (ctx->Version)
+ return;
+
+ switch (ctx->API) {
+ case API_OPENGL_COMPAT:
+ /* Disable GLSL 1.40 and later for legacy contexts.
+ * This disallows creation of the GL 3.1 compatibility context. */
+ if (ctx->Const.GLSLVersion > 130) {
+ ctx->Const.GLSLVersion = 130;
+ }
+ /* fall through */
+ case API_OPENGL_CORE:
+ compute_version(ctx);
+ break;
+ case API_OPENGLES:
+ compute_version_es1(ctx);
+ break;
+ case API_OPENGLES2:
+ compute_version_es2(ctx);
+ break;
+ }
+
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/main/version.h b/icd/intel/compiler/mesa-utils/src/mesa/main/version.h
new file mode 100644
index 0000000..c78f87a
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/main/version.h
@@ -0,0 +1,46 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef VERSION_H
+#define VERSION_H
+
+
+struct gl_context;
+
+
+extern void
+_mesa_compute_version(struct gl_context *ctx);
+
+extern void
+_mesa_override_gl_version(struct gl_context *ctx);
+
+extern void
+_mesa_override_glsl_version(struct gl_context *ctx);
+
+extern int
+_mesa_get_gl_version_override(void);
+
+#endif /* VERSION_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/Android.mk b/icd/intel/compiler/mesa-utils/src/mesa/program/Android.mk
new file mode 100644
index 0000000..e85afe6
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/Android.mk
@@ -0,0 +1,79 @@
+# Copyright 2012 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+define local-l-to-c
+ @mkdir -p $(dir $@)
+ @echo "Mesa Lex: $(PRIVATE_MODULE) <= $<"
+ $(hide) $(LEX) -o$@ $<
+endef
+
+define mesa_local-y-to-c-and-h
+ @mkdir -p $(dir $@)
+ @echo "Mesa Yacc: $(PRIVATE_MODULE) <= $<"
+ $(hide) $(YACC) -o $@ -p "_mesa_program_" $<
+endef
+
+# ----------------------------------------------------------------------
+# libmesa_program.a
+# ----------------------------------------------------------------------
+
+# Import the following variables:
+# PROGRAM_FILES
+include $(MESA_TOP)/src/mesa/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libmesa_program
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+
+intermediates := $(call local-intermediates-dir)
+
+# TODO(chadv): In Makefile.sources, move these vars to a different list so we can
+# remove this kludge.
+generated_sources_basenames := \
+ lex.yy.c \
+ program_parse.tab.c \
+ program_parse.tab.h
+
+LOCAL_SRC_FILES := \
+ $(filter-out $(generated_sources_basenames),$(subst program/,,$(PROGRAM_FILES)))
+
+LOCAL_GENERATED_SOURCES := \
+ $(addprefix $(intermediates)/program/,$(generated_sources_basenames))
+
+$(intermediates)/program/program_parse.tab.c: $(LOCAL_PATH)/program_parse.y
+ $(mesa_local-y-to-c-and-h)
+
+$(intermediates)/program/program_parse.tab.h: $(intermediates)/program/program_parse.tab.c
+ @
+
+$(intermediates)/program/lex.yy.c: $(LOCAL_PATH)/program_lexer.l
+ $(local-l-to-c)
+
+LOCAL_C_INCLUDES := \
+ $(intermediates) \
+ $(MESA_TOP)/src/mapi \
+ $(MESA_TOP)/src/mesa \
+ $(MESA_TOP)/src/glsl
+
+include $(MESA_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/arbprogparse.c b/icd/intel/compiler/mesa-utils/src/mesa/program/arbprogparse.c
new file mode 100644
index 0000000..5b96650
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/arbprogparse.c
@@ -0,0 +1,213 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define DEBUG_PARSING 0
+
+/**
+ * \file arbprogparse.c
+ * ARB_*_program parser core
+ * \author Karl Rasche
+ */
+
+/**
+Notes on program parameters, etc.
+
+The instructions we emit will use six kinds of source registers:
+
+ PROGRAM_INPUT - input registers
+ PROGRAM_TEMPORARY - temp registers
+ PROGRAM_ADDRESS - address/indirect register
+ PROGRAM_SAMPLER - texture sampler
+ PROGRAM_CONSTANT - indexes into program->Parameters, a known constant/literal
+ PROGRAM_STATE_VAR - indexes into program->Parameters, and may actually be:
+ + a state variable, like "state.fog.color", or
+ + a pointer to a "program.local[k]" parameter, or
+ + a pointer to a "program.env[k]" parameter
+
+Basically, all the program.local[] and program.env[] values will get mapped
+into the unified gl_program->Parameters array. This solves the problem of
+having three separate program parameter arrays.
+*/
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/mtypes.h"
+#include "arbprogparse.h"
+#include "programopt.h"
+#include "prog_parameter.h"
+#include "prog_statevars.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+
+void
+_mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
+ const GLvoid *str, GLsizei len,
+ struct gl_fragment_program *program)
+{
+ struct gl_program prog;
+ struct asm_parser_state state;
+ GLuint i;
+
+ ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
+
+ memset(&prog, 0, sizeof(prog));
+ memset(&state, 0, sizeof(state));
+ state.prog = &prog;
+
+ if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
+ &state)) {
+ /* Error in the program. Just return. */
+ return;
+ }
+
+ free(program->Base.String);
+
+ /* Copy the relevant contents of the arb_program struct into the
+ * fragment_program struct.
+ */
+ program->Base.String = prog.String;
+ program->Base.NumInstructions = prog.NumInstructions;
+ program->Base.NumTemporaries = prog.NumTemporaries;
+ program->Base.NumParameters = prog.NumParameters;
+ program->Base.NumAttributes = prog.NumAttributes;
+ program->Base.NumAddressRegs = prog.NumAddressRegs;
+ program->Base.NumNativeInstructions = prog.NumNativeInstructions;
+ program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
+ program->Base.NumNativeParameters = prog.NumNativeParameters;
+ program->Base.NumNativeAttributes = prog.NumNativeAttributes;
+ program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
+ program->Base.NumAluInstructions = prog.NumAluInstructions;
+ program->Base.NumTexInstructions = prog.NumTexInstructions;
+ program->Base.NumTexIndirections = prog.NumTexIndirections;
+ program->Base.NumNativeAluInstructions = prog.NumAluInstructions;
+ program->Base.NumNativeTexInstructions = prog.NumTexInstructions;
+ program->Base.NumNativeTexIndirections = prog.NumTexIndirections;
+ program->Base.InputsRead = prog.InputsRead;
+ program->Base.OutputsWritten = prog.OutputsWritten;
+ program->Base.IndirectRegisterFiles = prog.IndirectRegisterFiles;
+ for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
+ program->Base.TexturesUsed[i] = prog.TexturesUsed[i];
+ if (prog.TexturesUsed[i])
+ program->Base.SamplersUsed |= (1 << i);
+ }
+ program->Base.ShadowSamplers = prog.ShadowSamplers;
+ program->OriginUpperLeft = state.option.OriginUpperLeft;
+ program->PixelCenterInteger = state.option.PixelCenterInteger;
+
+ program->UsesKill = state.fragment.UsesKill;
+ program->UsesDFdy = state.fragment.UsesDFdy;
+
+ free(program->Base.Instructions);
+ program->Base.Instructions = prog.Instructions;
+
+ if (program->Base.Parameters)
+ _mesa_free_parameter_list(program->Base.Parameters);
+ program->Base.Parameters = prog.Parameters;
+
+ /* Append fog instructions now if the program has "OPTION ARB_fog_exp"
+ * or similar. We used to leave this up to drivers, but it appears
+ * there's no hardware that wants to do fog in a discrete stage separate
+ * from the fragment shader.
+ */
+ if (state.option.Fog != OPTION_NONE) {
+ static const GLenum fog_modes[4] = {
+ GL_NONE, GL_EXP, GL_EXP2, GL_LINEAR
+ };
+
+ /* XXX: we should somehow recompile this to remove clamping if disabled
+ * On the ATI driver, this is unclampled if fragment clamping is disabled
+ */
+ _mesa_append_fog_code(ctx, program, fog_modes[state.option.Fog], GL_TRUE);
+ }
+
+#if DEBUG_FP
+ printf("____________Fragment program %u ________\n", program->Base.Id);
+ _mesa_print_program(&program->Base);
+#endif
+}
+
+
+
+/**
+ * Parse the vertex program string. If success, update the given
+ * vertex_program object with the new program. Else, leave the vertex_program
+ * object unchanged.
+ */
+void
+_mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
+ const GLvoid *str, GLsizei len,
+ struct gl_vertex_program *program)
+{
+ struct gl_program prog;
+ struct asm_parser_state state;
+
+ ASSERT(target == GL_VERTEX_PROGRAM_ARB);
+
+ memset(&prog, 0, sizeof(prog));
+ memset(&state, 0, sizeof(state));
+ state.prog = &prog;
+
+ if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
+ &state)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)");
+ return;
+ }
+
+ free(program->Base.String);
+
+ /* Copy the relevant contents of the arb_program struct into the
+ * vertex_program struct.
+ */
+ program->Base.String = prog.String;
+ program->Base.NumInstructions = prog.NumInstructions;
+ program->Base.NumTemporaries = prog.NumTemporaries;
+ program->Base.NumParameters = prog.NumParameters;
+ program->Base.NumAttributes = prog.NumAttributes;
+ program->Base.NumAddressRegs = prog.NumAddressRegs;
+ program->Base.NumNativeInstructions = prog.NumNativeInstructions;
+ program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
+ program->Base.NumNativeParameters = prog.NumNativeParameters;
+ program->Base.NumNativeAttributes = prog.NumNativeAttributes;
+ program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
+ program->Base.InputsRead = prog.InputsRead;
+ program->Base.OutputsWritten = prog.OutputsWritten;
+ program->Base.IndirectRegisterFiles = prog.IndirectRegisterFiles;
+ program->IsPositionInvariant = (state.option.PositionInvariant)
+ ? GL_TRUE : GL_FALSE;
+
+ free(program->Base.Instructions);
+ program->Base.Instructions = prog.Instructions;
+
+ if (program->Base.Parameters)
+ _mesa_free_parameter_list(program->Base.Parameters);
+ program->Base.Parameters = prog.Parameters;
+
+#if DEBUG_VP
+ printf("____________Vertex program %u __________\n", program->Base.Id);
+ _mesa_print_program(&program->Base);
+#endif
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/arbprogparse.h b/icd/intel/compiler/mesa-utils/src/mesa/program/arbprogparse.h
new file mode 100644
index 0000000..39d2116
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/arbprogparse.h
@@ -0,0 +1,45 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef ARBPROGPARSE_H
+#define ARBPROGPARSE_H
+
+#include "main/glheader.h"
+
+struct gl_context;
+struct gl_fragment_program;
+struct gl_vertex_program;
+
+extern void
+_mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
+ const GLvoid *str, GLsizei len,
+ struct gl_vertex_program *program);
+
+extern void
+_mesa_parse_arb_fragment_program(struct gl_context *ctx, GLenum target,
+ const GLvoid *str, GLsizei len,
+ struct gl_fragment_program *program);
+
+#endif
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/hash_table.h b/icd/intel/compiler/mesa-utils/src/mesa/program/hash_table.h
new file mode 100644
index 0000000..ece43a1
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/hash_table.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file hash_table.h
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#ifndef HASH_TABLE_H
+#define HASH_TABLE_H
+
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <assert.h>
+
+struct string_to_uint_map;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hash_table;
+
+typedef unsigned (*hash_func_t)(const void *key);
+typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
+
+/**
+ * Hash table constructor
+ *
+ * Creates a hash table with the specified number of buckets. The supplied
+ * \c hash and \c compare routines are used when adding elements to the table
+ * and when searching for elements in the table.
+ *
+ * \param num_buckets Number of buckets (bins) in the hash table.
+ * \param hash Function used to compute hash value of input keys.
+ * \param compare Function used to compare keys.
+ */
+extern struct hash_table *hash_table_ctor(unsigned num_buckets,
+ hash_func_t hash, hash_compare_func_t compare);
+
+
+/**
+ * Release all memory associated with a hash table
+ *
+ * \warning
+ * This function cannot release memory occupied either by keys or data.
+ */
+extern void hash_table_dtor(struct hash_table *ht);
+
+
+/**
+ * Flush all entries from a hash table
+ *
+ * \param ht Table to be cleared of its entries.
+ */
+extern void hash_table_clear(struct hash_table *ht);
+
+
+/**
+ * Search a hash table for a specific element
+ *
+ * \param ht Table to be searched
+ * \param key Key of the desired element
+ *
+ * \return
+ * The \c data value supplied to \c hash_table_insert when the element with
+ * the matching key was added. If no matching key exists in the table,
+ * \c NULL is returned.
+ */
+extern void *hash_table_find(struct hash_table *ht, const void *key);
+
+
+/**
+ * Add an element to a hash table
+ *
+ * \warning
+ * If \c key is already in the hash table, it will be added again. Future
+ * calls to \c hash_table_find and \c hash_table_remove will return or remove,
+ * repsectively, the most recently added instance of \c key.
+ *
+ * \warning
+ * The value passed by \c key is kept in the hash table and is used by later
+ * calls to \c hash_table_find.
+ *
+ * \sa hash_table_replace
+ */
+extern void hash_table_insert(struct hash_table *ht, void *data,
+ const void *key);
+
+/**
+ * Add an element to a hash table with replacement
+ *
+ * \return
+ * 1 if it did replace the the value (in which case the old key is kept), 0 if
+ * it did not replace the value (in which case the new key is kept).
+ *
+ * \warning
+ * If \c key is already in the hash table, \c data will \b replace the most
+ * recently inserted \c data (see the warning in \c hash_table_insert) for
+ * that key.
+ *
+ * \sa hash_table_insert
+ */
+extern bool hash_table_replace(struct hash_table *ht, void *data,
+ const void *key);
+
+/**
+ * Remove a specific element from a hash table.
+ */
+extern void hash_table_remove(struct hash_table *ht, const void *key);
+
+/**
+ * Compute hash value of a string
+ *
+ * Computes the hash value of a string using the DJB2 algorithm developed by
+ * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
+ * a time. I was unable to find the original posting in the archives.
+ *
+ * \param key Pointer to a NUL terminated string to be hashed.
+ *
+ * \sa hash_table_string_compare
+ */
+extern unsigned hash_table_string_hash(const void *key);
+
+
+/**
+ * Compare two strings used as keys
+ *
+ * This is just a macro wrapper around \c strcmp.
+ *
+ * \sa hash_table_string_hash
+ */
+#define hash_table_string_compare ((hash_compare_func_t) strcmp)
+
+
+/**
+ * Compute hash value of a pointer
+ *
+ * \param key Pointer to be used as a hash key
+ *
+ * \note
+ * The memory pointed to by \c key is \b never accessed. The value of \c key
+ * itself is used as the hash key
+ *
+ * \sa hash_table_pointer_compare
+ */
+unsigned
+hash_table_pointer_hash(const void *key);
+
+
+/**
+ * Compare two pointers used as keys
+ *
+ * \sa hash_table_pointer_hash
+ */
+int
+hash_table_pointer_compare(const void *key1, const void *key2);
+
+void
+hash_table_call_foreach(struct hash_table *ht,
+ void (*callback)(const void *key,
+ void *data,
+ void *closure),
+ void *closure);
+
+struct string_to_uint_map *
+string_to_uint_map_ctor();
+
+void
+string_to_uint_map_dtor(struct string_to_uint_map *);
+
+
+#ifdef __cplusplus
+}
+
+/**
+ * Map from a string (name) to an unsigned integer value
+ *
+ * \note
+ * Because of the way this class interacts with the \c hash_table
+ * implementation, values of \c UINT_MAX cannot be stored in the map.
+ */
+struct string_to_uint_map {
+public:
+ string_to_uint_map()
+ {
+ this->ht = hash_table_ctor(0, hash_table_string_hash,
+ hash_table_string_compare);
+ }
+
+ ~string_to_uint_map()
+ {
+ hash_table_call_foreach(this->ht, delete_key, NULL);
+ hash_table_dtor(this->ht);
+ }
+
+ /**
+ * Remove all mappings from this map.
+ */
+ void clear()
+ {
+ hash_table_call_foreach(this->ht, delete_key, NULL);
+ hash_table_clear(this->ht);
+ }
+
+ /**
+ * Runs a passed callback for the hash
+ */
+ void iterate(void (*func)(const void *, void *, void *), void *closure)
+ {
+ hash_table_call_foreach(this->ht, func, closure);
+ }
+
+ /**
+ * Get the value associated with a particular key
+ *
+ * \return
+ * If \c key is found in the map, \c true is returned. Otherwise \c false
+ * is returned.
+ *
+ * \note
+ * If \c key is not found in the table, \c value is not modified.
+ */
+ bool get(unsigned &value, const char *key)
+ {
+ const intptr_t v =
+ (intptr_t) hash_table_find(this->ht, (const void *) key);
+
+ if (v == 0)
+ return false;
+
+ value = (unsigned)(v - 1);
+ return true;
+ }
+
+ void put(unsigned value, const char *key)
+ {
+ /* The low-level hash table structure returns NULL if key is not in the
+ * hash table. However, users of this map might want to store zero as a
+ * valid value in the table. Bias the value by +1 so that a
+ * user-specified zero is stored as 1. This enables ::get to tell the
+ * difference between a user-specified zero (returned as 1 by
+ * hash_table_find) and the key not in the table (returned as 0 by
+ * hash_table_find).
+ *
+ * The net effect is that we can't store UINT_MAX in the table. This is
+ * because UINT_MAX+1 = 0.
+ */
+ assert(value != UINT_MAX);
+ char *dup_key = strdup(key);
+ bool result = hash_table_replace(this->ht,
+ (void *) (intptr_t) (value + 1),
+ dup_key);
+ if (result)
+ free(dup_key);
+ }
+
+private:
+ static void delete_key(const void *key, void *data, void *closure)
+ {
+ (void) data;
+ (void) closure;
+
+ free((char *)key);
+ }
+
+ struct hash_table *ht;
+};
+
+#endif /* __cplusplus */
+#endif /* HASH_TABLE_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/ir_to_mesa.cpp b/icd/intel/compiler/mesa-utils/src/mesa/program/ir_to_mesa.cpp
new file mode 100644
index 0000000..e7e734b
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/ir_to_mesa.cpp
@@ -0,0 +1,3119 @@
+/*
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file ir_to_mesa.cpp
+ *
+ * Translate GLSL IR to Mesa's gl_program representation.
+ */
+
+#include <stdio.h>
+#include "main/compiler.h"
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_expression_flattening.h"
+#include "ir_uniform.h"
+#include "glsl_types.h"
+#include "glsl_parser_extras.h"
+#include "../glsl/program.h"
+#include "ir_optimization.h"
+#include "ast.h"
+#include "linker.h"
+
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
+#include "main/uniforms.h"
+#include "program/hash_table.h"
+
+extern "C" {
+#include "main/shaderapi.h"
+#include "program/prog_instruction.h"
+#include "program/prog_optimize.h"
+#include "program/prog_print.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/sampler.h"
+#include "program/prog_diskcache.h"
+}
+
+static int swizzle_for_size(int size);
+
+namespace {
+
+class src_reg;
+class dst_reg;
+
+/**
+ * This struct is a corresponding struct to Mesa prog_src_register, with
+ * wider fields.
+ */
+class src_reg {
+public:
+ src_reg(gl_register_file file, int index, const glsl_type *type)
+ {
+ this->file = file;
+ this->index = index;
+ if (type && (type->is_scalar() || type->is_vector() || type->is_matrix()))
+ this->swizzle = swizzle_for_size(type->vector_elements);
+ else
+ this->swizzle = SWIZZLE_XYZW;
+ this->negate = 0;
+ this->reladdr = NULL;
+ }
+
+ src_reg()
+ {
+ this->file = PROGRAM_UNDEFINED;
+ this->index = 0;
+ this->swizzle = 0;
+ this->negate = 0;
+ this->reladdr = NULL;
+ }
+
+ explicit src_reg(dst_reg reg);
+
+ gl_register_file file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
+ GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
+ int negate; /**< NEGATE_XYZW mask from mesa */
+ /** Register index should be offset by the integer in this reg. */
+ src_reg *reladdr;
+};
+
+class dst_reg {
+public:
+ dst_reg(gl_register_file file, int writemask)
+ {
+ this->file = file;
+ this->index = 0;
+ this->writemask = writemask;
+ this->cond_mask = COND_TR;
+ this->reladdr = NULL;
+ }
+
+ dst_reg()
+ {
+ this->file = PROGRAM_UNDEFINED;
+ this->index = 0;
+ this->writemask = 0;
+ this->cond_mask = COND_TR;
+ this->reladdr = NULL;
+ }
+
+ explicit dst_reg(src_reg reg);
+
+ gl_register_file file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
+ int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
+ GLuint cond_mask:4;
+ /** Register index should be offset by the integer in this reg. */
+ src_reg *reladdr;
+};
+
+} /* anonymous namespace */
+
+src_reg::src_reg(dst_reg reg)
+{
+ this->file = reg.file;
+ this->index = reg.index;
+ this->swizzle = SWIZZLE_XYZW;
+ this->negate = 0;
+ this->reladdr = reg.reladdr;
+}
+
+dst_reg::dst_reg(src_reg reg)
+{
+ this->file = reg.file;
+ this->index = reg.index;
+ this->writemask = WRITEMASK_XYZW;
+ this->cond_mask = COND_TR;
+ this->reladdr = reg.reladdr;
+}
+
+namespace {
+
+class ir_to_mesa_instruction : public exec_node {
+public:
+ DECLARE_RALLOC_CXX_OPERATORS(ir_to_mesa_instruction)
+
+ enum prog_opcode op;
+ dst_reg dst;
+ src_reg src[3];
+ /** Pointer to the ir source this tree came from for debugging */
+ ir_instruction *ir;
+ GLboolean cond_update;
+ bool saturate;
+ int sampler; /**< sampler index */
+ int tex_target; /**< One of TEXTURE_*_INDEX */
+ GLboolean tex_shadow;
+};
+
+class variable_storage : public exec_node {
+public:
+ variable_storage(ir_variable *var, gl_register_file file, int index)
+ : file(file), index(index), var(var)
+ {
+ /* empty */
+ }
+
+ gl_register_file file;
+ int index;
+ ir_variable *var; /* variable that maps to this, if any */
+};
+
+class function_entry : public exec_node {
+public:
+ ir_function_signature *sig;
+
+ /**
+ * identifier of this function signature used by the program.
+ *
+ * At the point that Mesa instructions for function calls are
+ * generated, we don't know the address of the first instruction of
+ * the function body. So we make the BranchTarget that is called a
+ * small integer and rewrite them during set_branchtargets().
+ */
+ int sig_id;
+
+ /**
+ * Pointer to first instruction of the function body.
+ *
+ * Set during function body emits after main() is processed.
+ */
+ ir_to_mesa_instruction *bgn_inst;
+
+ /**
+ * Index of the first instruction of the function body in actual
+ * Mesa IR.
+ *
+ * Set after convertion from ir_to_mesa_instruction to prog_instruction.
+ */
+ int inst;
+
+ /** Storage for the return value. */
+ src_reg return_reg;
+};
+
+class ir_to_mesa_visitor : public ir_visitor {
+public:
+ ir_to_mesa_visitor();
+ ~ir_to_mesa_visitor();
+
+ function_entry *current_function;
+
+ struct gl_context *ctx;
+ struct gl_program *prog;
+ struct gl_shader_program *shader_program;
+ struct gl_shader_compiler_options *options;
+
+ int next_temp;
+
+ variable_storage *find_variable_storage(const ir_variable *var);
+
+ src_reg get_temp(const glsl_type *type);
+ void reladdr_to_temp(ir_instruction *ir, src_reg *reg, int *num_reladdr);
+
+ src_reg src_reg_for_float(float val);
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(ir_variable *);
+ virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
+ virtual void visit(ir_function_signature *);
+ virtual void visit(ir_function *);
+ virtual void visit(ir_expression *);
+ virtual void visit(ir_swizzle *);
+ virtual void visit(ir_dereference_variable *);
+ virtual void visit(ir_dereference_array *);
+ virtual void visit(ir_dereference_record *);
+ virtual void visit(ir_assignment *);
+ virtual void visit(ir_constant *);
+ virtual void visit(ir_call *);
+ virtual void visit(ir_return *);
+ virtual void visit(ir_discard *);
+ virtual void visit(ir_texture *);
+ virtual void visit(ir_if *);
+ virtual void visit(ir_emit_vertex *);
+ virtual void visit(ir_end_primitive *);
+ /*@}*/
+
+ src_reg result;
+
+ /** List of variable_storage */
+ exec_list variables;
+
+ /** List of function_entry */
+ exec_list function_signatures;
+ int next_signature_id;
+
+ /** List of ir_to_mesa_instruction */
+ exec_list instructions;
+
+ ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op);
+
+ ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, src_reg src0);
+
+ ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, src_reg src0, src_reg src1);
+
+ ir_to_mesa_instruction *emit(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst,
+ src_reg src0, src_reg src1, src_reg src2);
+
+ /**
+ * Emit the correct dot-product instruction for the type of arguments
+ */
+ ir_to_mesa_instruction * emit_dp(ir_instruction *ir,
+ dst_reg dst,
+ src_reg src0,
+ src_reg src1,
+ unsigned elements);
+
+ void emit_scalar(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, src_reg src0);
+
+ void emit_scalar(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, src_reg src0, src_reg src1);
+
+ void emit_scs(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, const src_reg &src);
+
+ bool try_emit_mad(ir_expression *ir,
+ int mul_operand);
+ bool try_emit_mad_for_and_not(ir_expression *ir,
+ int mul_operand);
+ bool try_emit_sat(ir_expression *ir);
+
+ void emit_swz(ir_expression *ir);
+
+ bool process_move_condition(ir_rvalue *ir);
+
+ void copy_propagate(void);
+
+ void *mem_ctx;
+};
+
+} /* anonymous namespace */
+
+static src_reg undef_src = src_reg(PROGRAM_UNDEFINED, 0, NULL);
+
+static dst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP);
+
+static dst_reg address_reg = dst_reg(PROGRAM_ADDRESS, WRITEMASK_X);
+
+static int
+swizzle_for_size(int size)
+{
+ static const int size_swizzles[4] = {
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
+ };
+
+ assert((size >= 1) && (size <= 4));
+ return size_swizzles[size - 1];
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst,
+ src_reg src0, src_reg src1, src_reg src2)
+{
+ ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
+ int num_reladdr = 0;
+
+ /* If we have to do relative addressing, we want to load the ARL
+ * reg directly for one of the regs, and preload the other reladdr
+ * sources into temps.
+ */
+ num_reladdr += dst.reladdr != NULL;
+ num_reladdr += src0.reladdr != NULL;
+ num_reladdr += src1.reladdr != NULL;
+ num_reladdr += src2.reladdr != NULL;
+
+ reladdr_to_temp(ir, &src2, &num_reladdr);
+ reladdr_to_temp(ir, &src1, &num_reladdr);
+ reladdr_to_temp(ir, &src0, &num_reladdr);
+
+ if (dst.reladdr) {
+ emit(ir, OPCODE_ARL, address_reg, *dst.reladdr);
+ num_reladdr--;
+ }
+ assert(num_reladdr == 0);
+
+ inst->op = op;
+ inst->dst = dst;
+ inst->src[0] = src0;
+ inst->src[1] = src1;
+ inst->src[2] = src2;
+ inst->ir = ir;
+
+ this->instructions.push_tail(inst);
+
+ return inst;
+}
+
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, src_reg src0, src_reg src1)
+{
+ return emit(ir, op, dst, src0, src1, undef_src);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, src_reg src0)
+{
+ assert(dst.writemask != 0);
+ return emit(ir, op, dst, src0, undef_src, undef_src);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::emit(ir_instruction *ir, enum prog_opcode op)
+{
+ return emit(ir, op, undef_dst, undef_src, undef_src, undef_src);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::emit_dp(ir_instruction *ir,
+ dst_reg dst, src_reg src0, src_reg src1,
+ unsigned elements)
+{
+ static const gl_inst_opcode dot_opcodes[] = {
+ OPCODE_DP2, OPCODE_DP3, OPCODE_DP4
+ };
+
+ return emit(ir, dot_opcodes[elements - 2], dst, src0, src1);
+}
+
+/**
+ * Emits Mesa scalar opcodes to produce unique answers across channels.
+ *
+ * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X
+ * channel determines the result across all channels. So to do a vec4
+ * of this operation, we want to emit a scalar per source channel used
+ * to produce dest channels.
+ */
+void
+ir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst,
+ src_reg orig_src0, src_reg orig_src1)
+{
+ int i, j;
+ int done_mask = ~dst.writemask;
+
+ /* Mesa RCP is a scalar operation splatting results to all channels,
+ * like ARB_fp/vp. So emit as many RCPs as necessary to cover our
+ * dst channels.
+ */
+ for (i = 0; i < 4; i++) {
+ GLuint this_mask = (1 << i);
+ ir_to_mesa_instruction *inst;
+ src_reg src0 = orig_src0;
+ src_reg src1 = orig_src1;
+
+ if (done_mask & this_mask)
+ continue;
+
+ GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
+ GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
+ for (j = i + 1; j < 4; j++) {
+ /* If there is another enabled component in the destination that is
+ * derived from the same inputs, generate its value on this pass as
+ * well.
+ */
+ if (!(done_mask & (1 << j)) &&
+ GET_SWZ(src0.swizzle, j) == src0_swiz &&
+ GET_SWZ(src1.swizzle, j) == src1_swiz) {
+ this_mask |= (1 << j);
+ }
+ }
+ src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
+ src0_swiz, src0_swiz);
+ src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
+ src1_swiz, src1_swiz);
+
+ inst = emit(ir, op, dst, src0, src1);
+ inst->dst.writemask = this_mask;
+ done_mask |= this_mask;
+ }
+}
+
+void
+ir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst, src_reg src0)
+{
+ src_reg undef = undef_src;
+
+ undef.swizzle = SWIZZLE_XXXX;
+
+ emit_scalar(ir, op, dst, src0, undef);
+}
+
+/**
+ * Emit an OPCODE_SCS instruction
+ *
+ * The \c SCS opcode functions a bit differently than the other Mesa (or
+ * ARB_fragment_program) opcodes. Instead of splatting its result across all
+ * four components of the destination, it writes one value to the \c x
+ * component and another value to the \c y component.
+ *
+ * \param ir IR instruction being processed
+ * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which
+ * value is desired.
+ * \param dst Destination register
+ * \param src Source register
+ */
+void
+ir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op,
+ dst_reg dst,
+ const src_reg &src)
+{
+ /* Vertex programs cannot use the SCS opcode.
+ */
+ if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) {
+ emit_scalar(ir, op, dst, src);
+ return;
+ }
+
+ const unsigned component = (op == OPCODE_SIN) ? 0 : 1;
+ const unsigned scs_mask = (1U << component);
+ int done_mask = ~dst.writemask;
+ src_reg tmp;
+
+ assert(op == OPCODE_SIN || op == OPCODE_COS);
+
+ /* If there are compnents in the destination that differ from the component
+ * that will be written by the SCS instrution, we'll need a temporary.
+ */
+ if (scs_mask != unsigned(dst.writemask)) {
+ tmp = get_temp(glsl_type::vec4_type);
+ }
+
+ for (unsigned i = 0; i < 4; i++) {
+ unsigned this_mask = (1U << i);
+ src_reg src0 = src;
+
+ if ((done_mask & this_mask) != 0)
+ continue;
+
+ /* The source swizzle specified which component of the source generates
+ * sine / cosine for the current component in the destination. The SCS
+ * instruction requires that this value be swizzle to the X component.
+ * Replace the current swizzle with a swizzle that puts the source in
+ * the X component.
+ */
+ unsigned src0_swiz = GET_SWZ(src.swizzle, i);
+
+ src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
+ src0_swiz, src0_swiz);
+ for (unsigned j = i + 1; j < 4; j++) {
+ /* If there is another enabled component in the destination that is
+ * derived from the same inputs, generate its value on this pass as
+ * well.
+ */
+ if (!(done_mask & (1 << j)) &&
+ GET_SWZ(src0.swizzle, j) == src0_swiz) {
+ this_mask |= (1 << j);
+ }
+ }
+
+ if (this_mask != scs_mask) {
+ ir_to_mesa_instruction *inst;
+ dst_reg tmp_dst = dst_reg(tmp);
+
+ /* Emit the SCS instruction.
+ */
+ inst = emit(ir, OPCODE_SCS, tmp_dst, src0);
+ inst->dst.writemask = scs_mask;
+
+ /* Move the result of the SCS instruction to the desired location in
+ * the destination.
+ */
+ tmp.swizzle = MAKE_SWIZZLE4(component, component,
+ component, component);
+ inst = emit(ir, OPCODE_SCS, dst, tmp);
+ inst->dst.writemask = this_mask;
+ } else {
+ /* Emit the SCS instruction to write directly to the destination.
+ */
+ ir_to_mesa_instruction *inst = emit(ir, OPCODE_SCS, dst, src0);
+ inst->dst.writemask = scs_mask;
+ }
+
+ done_mask |= this_mask;
+ }
+}
+
+src_reg
+ir_to_mesa_visitor::src_reg_for_float(float val)
+{
+ src_reg src(PROGRAM_CONSTANT, -1, NULL);
+
+ src.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+ (const gl_constant_value *)&val, 1, &src.swizzle);
+
+ return src;
+}
+
+static int
+type_size(const struct glsl_type *type)
+{
+ unsigned int i;
+ int size;
+
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ if (type->is_matrix()) {
+ return type->matrix_columns;
+ } else {
+ /* Regardless of size of vector, it gets a vec4. This is bad
+ * packing for things like floats, but otherwise arrays become a
+ * mess. Hopefully a later pass over the code can pack scalars
+ * down if appropriate.
+ */
+ return 1;
+ }
+ case GLSL_TYPE_ARRAY:
+ assert(type->length > 0);
+ return type_size(type->fields.array) * type->length;
+ case GLSL_TYPE_STRUCT:
+ size = 0;
+ for (i = 0; i < type->length; i++) {
+ size += type_size(type->fields.structure[i].type);
+ }
+ return size;
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
+ /* Samplers take up one slot in UNIFORMS[], but they're baked in
+ * at link time.
+ */
+ return 1;
+ case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_ERROR:
+ case GLSL_TYPE_INTERFACE:
+ assert(!"Invalid type in type_size");
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results. (not SSA -- variable assignments will reuse
+ * storage). Actual register allocation for the Mesa VM occurs in a
+ * pass over the Mesa IR later.
+ */
+src_reg
+ir_to_mesa_visitor::get_temp(const glsl_type *type)
+{
+ src_reg src;
+
+ src.file = PROGRAM_TEMPORARY;
+ src.index = next_temp;
+ src.reladdr = NULL;
+ next_temp += type_size(type);
+
+ if (type->is_array() || type->is_record()) {
+ src.swizzle = SWIZZLE_NOOP;
+ } else {
+ src.swizzle = swizzle_for_size(type->vector_elements);
+ }
+ src.negate = 0;
+
+ return src;
+}
+
+variable_storage *
+ir_to_mesa_visitor::find_variable_storage(const ir_variable *var)
+{
+ variable_storage *entry;
+
+ foreach_list(node, &this->variables) {
+ entry = (variable_storage *) node;
+
+ if (entry->var == var)
+ return entry;
+ }
+
+ return NULL;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_variable *ir)
+{
+ if (strcmp(ir->name, "gl_FragCoord") == 0) {
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
+
+ fp->OriginUpperLeft = ir->data.origin_upper_left;
+ fp->PixelCenterInteger = ir->data.pixel_center_integer;
+ }
+
+ if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
+ unsigned int i;
+ const ir_state_slot *const slots = ir->state_slots;
+ assert(ir->state_slots != NULL);
+
+ /* Check if this statevar's setup in the STATE file exactly
+ * matches how we'll want to reference it as a
+ * struct/array/whatever. If not, then we need to move it into
+ * temporary storage and hope that it'll get copy-propagated
+ * out.
+ */
+ for (i = 0; i < ir->num_state_slots; i++) {
+ if (slots[i].swizzle != SWIZZLE_XYZW) {
+ break;
+ }
+ }
+
+ variable_storage *storage;
+ dst_reg dst;
+ if (i == ir->num_state_slots) {
+ /* We'll set the index later. */
+ storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1);
+ this->variables.push_tail(storage);
+
+ dst = undef_dst;
+ } else {
+ /* The variable_storage constructor allocates slots based on the size
+ * of the type. However, this had better match the number of state
+ * elements that we're going to copy into the new temporary.
+ */
+ assert((int) ir->num_state_slots == type_size(ir->type));
+
+ storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY,
+ this->next_temp);
+ this->variables.push_tail(storage);
+ this->next_temp += type_size(ir->type);
+
+ dst = dst_reg(src_reg(PROGRAM_TEMPORARY, storage->index, NULL));
+ }
+
+
+ for (unsigned int i = 0; i < ir->num_state_slots; i++) {
+ int index = _mesa_add_state_reference(this->prog->Parameters,
+ (gl_state_index *)slots[i].tokens);
+
+ if (storage->file == PROGRAM_STATE_VAR) {
+ if (storage->index == -1) {
+ storage->index = index;
+ } else {
+ assert(index == storage->index + (int)i);
+ }
+ } else {
+ src_reg src(PROGRAM_STATE_VAR, index, NULL);
+ src.swizzle = slots[i].swizzle;
+ emit(ir, OPCODE_MOV, dst, src);
+ /* even a float takes up a whole vec4 reg in a struct/array. */
+ dst.index++;
+ }
+ }
+
+ if (storage->file == PROGRAM_TEMPORARY &&
+ dst.index != storage->index + (int) ir->num_state_slots) {
+ linker_error(this->shader_program,
+ "failed to load builtin uniform `%s' "
+ "(%d/%d regs loaded)\n",
+ ir->name, dst.index - storage->index,
+ type_size(ir->type));
+ }
+ }
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop *ir)
+{
+ emit(NULL, OPCODE_BGNLOOP);
+
+ visit_exec_list(&ir->body_instructions, this);
+
+ emit(NULL, OPCODE_ENDLOOP);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop_jump *ir)
+{
+ switch (ir->mode) {
+ case ir_loop_jump::jump_break:
+ emit(NULL, OPCODE_BRK);
+ break;
+ case ir_loop_jump::jump_continue:
+ emit(NULL, OPCODE_CONT);
+ break;
+ }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_function_signature *ir)
+{
+ assert(0);
+ (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_function *ir)
+{
+ /* Ignore function bodies other than main() -- we shouldn't see calls to
+ * them since they should all be inlined before we get to ir_to_mesa.
+ */
+ if (strcmp(ir->name, "main") == 0) {
+ const ir_function_signature *sig;
+ exec_list empty;
+
+ sig = ir->matching_signature(NULL, &empty);
+
+ assert(sig);
+
+ foreach_list(node, &sig->body) {
+ ir_instruction *ir = (ir_instruction *) node;
+
+ ir->accept(this);
+ }
+ }
+}
+
+bool
+ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
+{
+ int nonmul_operand = 1 - mul_operand;
+ src_reg a, b, c;
+
+ ir_expression *expr = ir->operands[mul_operand]->as_expression();
+ if (!expr || expr->operation != ir_binop_mul)
+ return false;
+
+ expr->operands[0]->accept(this);
+ a = this->result;
+ expr->operands[1]->accept(this);
+ b = this->result;
+ ir->operands[nonmul_operand]->accept(this);
+ c = this->result;
+
+ this->result = get_temp(ir->type);
+ emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, c);
+
+ return true;
+}
+
+/**
+ * Emit OPCODE_MAD(a, -b, a) instead of AND(a, NOT(b))
+ *
+ * The logic values are 1.0 for true and 0.0 for false. Logical-and is
+ * implemented using multiplication, and logical-or is implemented using
+ * addition. Logical-not can be implemented as (true - x), or (1.0 - x).
+ * As result, the logical expression (a & !b) can be rewritten as:
+ *
+ * - a * !b
+ * - a * (1 - b)
+ * - (a * 1) - (a * b)
+ * - a + -(a * b)
+ * - a + (a * -b)
+ *
+ * This final expression can be implemented as a single MAD(a, -b, a)
+ * instruction.
+ */
+bool
+ir_to_mesa_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand)
+{
+ const int other_operand = 1 - try_operand;
+ src_reg a, b;
+
+ ir_expression *expr = ir->operands[try_operand]->as_expression();
+ if (!expr || expr->operation != ir_unop_logic_not)
+ return false;
+
+ ir->operands[other_operand]->accept(this);
+ a = this->result;
+ expr->operands[0]->accept(this);
+ b = this->result;
+
+ b.negate = ~b.negate;
+
+ this->result = get_temp(ir->type);
+ emit(ir, OPCODE_MAD, dst_reg(this->result), a, b, a);
+
+ return true;
+}
+
+bool
+ir_to_mesa_visitor::try_emit_sat(ir_expression *ir)
+{
+ /* Saturates were only introduced to vertex programs in
+ * NV_vertex_program3, so don't give them to drivers in the VP.
+ */
+ if (this->prog->Target == GL_VERTEX_PROGRAM_ARB)
+ return false;
+
+ ir_rvalue *sat_src = ir->as_rvalue_to_saturate();
+ if (!sat_src)
+ return false;
+
+ sat_src->accept(this);
+ src_reg src = this->result;
+
+ /* If we generated an expression instruction into a temporary in
+ * processing the saturate's operand, apply the saturate to that
+ * instruction. Otherwise, generate a MOV to do the saturate.
+ *
+ * Note that we have to be careful to only do this optimization if
+ * the instruction in question was what generated src->result. For
+ * example, ir_dereference_array might generate a MUL instruction
+ * to create the reladdr, and return us a src reg using that
+ * reladdr. That MUL result is not the value we're trying to
+ * saturate.
+ */
+ ir_expression *sat_src_expr = sat_src->as_expression();
+ ir_to_mesa_instruction *new_inst;
+ new_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
+ if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul ||
+ sat_src_expr->operation == ir_binop_add ||
+ sat_src_expr->operation == ir_binop_dot)) {
+ new_inst->saturate = true;
+ } else {
+ this->result = get_temp(ir->type);
+ ir_to_mesa_instruction *inst;
+ inst = emit(ir, OPCODE_MOV, dst_reg(this->result), src);
+ inst->saturate = true;
+ }
+
+ return true;
+}
+
+void
+ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
+ src_reg *reg, int *num_reladdr)
+{
+ if (!reg->reladdr)
+ return;
+
+ emit(ir, OPCODE_ARL, address_reg, *reg->reladdr);
+
+ if (*num_reladdr != 1) {
+ src_reg temp = get_temp(glsl_type::vec4_type);
+
+ emit(ir, OPCODE_MOV, dst_reg(temp), *reg);
+ *reg = temp;
+ }
+
+ (*num_reladdr)--;
+}
+
+void
+ir_to_mesa_visitor::emit_swz(ir_expression *ir)
+{
+ /* Assume that the vector operator is in a form compatible with OPCODE_SWZ.
+ * This means that each of the operands is either an immediate value of -1,
+ * 0, or 1, or is a component from one source register (possibly with
+ * negation).
+ */
+ uint8_t components[4] = { 0 };
+ bool negate[4] = { false };
+ ir_variable *var = NULL;
+
+ for (unsigned i = 0; i < ir->type->vector_elements; i++) {
+ ir_rvalue *op = ir->operands[i];
+
+ assert(op->type->is_scalar());
+
+ while (op != NULL) {
+ switch (op->ir_type) {
+ case ir_type_constant: {
+
+ assert(op->type->is_scalar());
+
+ const ir_constant *const c = op->as_constant();
+ if (c->is_one()) {
+ components[i] = SWIZZLE_ONE;
+ } else if (c->is_zero()) {
+ components[i] = SWIZZLE_ZERO;
+ } else if (c->is_negative_one()) {
+ components[i] = SWIZZLE_ONE;
+ negate[i] = true;
+ } else {
+ assert(!"SWZ constant must be 0.0 or 1.0.");
+ }
+
+ op = NULL;
+ break;
+ }
+
+ case ir_type_dereference_variable: {
+ ir_dereference_variable *const deref =
+ (ir_dereference_variable *) op;
+
+ assert((var == NULL) || (deref->var == var));
+ components[i] = SWIZZLE_X;
+ var = deref->var;
+ op = NULL;
+ break;
+ }
+
+ case ir_type_expression: {
+ ir_expression *const expr = (ir_expression *) op;
+
+ assert(expr->operation == ir_unop_neg);
+ negate[i] = true;
+
+ op = expr->operands[0];
+ break;
+ }
+
+ case ir_type_swizzle: {
+ ir_swizzle *const swiz = (ir_swizzle *) op;
+
+ components[i] = swiz->mask.x;
+ op = swiz->val;
+ break;
+ }
+
+ default:
+ assert(!"Should not get here.");
+ return;
+ }
+ }
+ }
+
+ assert(var != NULL);
+
+ ir_dereference_variable *const deref =
+ new(mem_ctx) ir_dereference_variable(var);
+
+ this->result.file = PROGRAM_UNDEFINED;
+ deref->accept(this);
+ if (this->result.file == PROGRAM_UNDEFINED) {
+ printf("Failed to get tree for expression operand:\n");
+ deref->print();
+ printf("\n");
+ exit(1);
+ }
+
+ src_reg src;
+
+ src = this->result;
+ src.swizzle = MAKE_SWIZZLE4(components[0],
+ components[1],
+ components[2],
+ components[3]);
+ src.negate = ((unsigned(negate[0]) << 0)
+ | (unsigned(negate[1]) << 1)
+ | (unsigned(negate[2]) << 2)
+ | (unsigned(negate[3]) << 3));
+
+ /* Storage for our result. Ideally for an assignment we'd be using the
+ * actual storage for the result here, instead.
+ */
+ const src_reg result_src = get_temp(ir->type);
+ dst_reg result_dst = dst_reg(result_src);
+
+ /* Limit writes to the channels that will be used by result_src later.
+ * This does limit this temp's use as a temporary for multi-instruction
+ * sequences.
+ */
+ result_dst.writemask = (1 << ir->type->vector_elements) - 1;
+
+ emit(ir, OPCODE_SWZ, result_dst, src);
+ this->result = result_src;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_expression *ir)
+{
+ unsigned int operand;
+ src_reg op[Elements(ir->operands)];
+ src_reg result_src;
+ dst_reg result_dst;
+
+ /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
+ */
+ if (ir->operation == ir_binop_add) {
+ if (try_emit_mad(ir, 1))
+ return;
+ if (try_emit_mad(ir, 0))
+ return;
+ }
+
+ /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b))
+ */
+ if (ir->operation == ir_binop_logic_and) {
+ if (try_emit_mad_for_and_not(ir, 1))
+ return;
+ if (try_emit_mad_for_and_not(ir, 0))
+ return;
+ }
+
+ if (try_emit_sat(ir))
+ return;
+
+ if (ir->operation == ir_quadop_vector) {
+ this->emit_swz(ir);
+ return;
+ }
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ this->result.file = PROGRAM_UNDEFINED;
+ ir->operands[operand]->accept(this);
+ if (this->result.file == PROGRAM_UNDEFINED) {
+ printf("Failed to get tree for expression operand:\n");
+ ir->operands[operand]->print();
+ printf("\n");
+ exit(1);
+ }
+ op[operand] = this->result;
+
+ /* Matrix expression operands should have been broken down to vector
+ * operations already.
+ */
+ assert(!ir->operands[operand]->type->is_matrix());
+ }
+
+ int vector_elements = ir->operands[0]->type->vector_elements;
+ if (ir->operands[1]) {
+ vector_elements = MAX2(vector_elements,
+ ir->operands[1]->type->vector_elements);
+ }
+
+ this->result.file = PROGRAM_UNDEFINED;
+
+ /* Storage for our result. Ideally for an assignment we'd be using
+ * the actual storage for the result here, instead.
+ */
+ result_src = get_temp(ir->type);
+ /* convenience for the emit functions below. */
+ result_dst = dst_reg(result_src);
+ /* Limit writes to the channels that will be used by result_src later.
+ * This does limit this temp's use as a temporary for multi-instruction
+ * sequences.
+ */
+ result_dst.writemask = (1 << ir->type->vector_elements) - 1;
+
+ switch (ir->operation) {
+ case ir_unop_logic_not:
+ /* Previously 'SEQ dst, src, 0.0' was used for this. However, many
+ * older GPUs implement SEQ using multiple instructions (i915 uses two
+ * SGE instructions and a MUL instruction). Since our logic values are
+ * 0.0 and 1.0, 1-x also implements !x.
+ */
+ op[0].negate = ~op[0].negate;
+ emit(ir, OPCODE_ADD, result_dst, op[0], src_reg_for_float(1.0));
+ break;
+ case ir_unop_neg:
+ op[0].negate = ~op[0].negate;
+ result_src = op[0];
+ break;
+ case ir_unop_abs:
+ emit(ir, OPCODE_ABS, result_dst, op[0]);
+ break;
+ case ir_unop_sign:
+ emit(ir, OPCODE_SSG, result_dst, op[0]);
+ break;
+ case ir_unop_rcp:
+ emit_scalar(ir, OPCODE_RCP, result_dst, op[0]);
+ break;
+
+ case ir_unop_exp2:
+ emit_scalar(ir, OPCODE_EX2, result_dst, op[0]);
+ break;
+ case ir_unop_exp:
+ case ir_unop_log:
+ assert(!"not reached: should be handled by ir_explog_to_explog2");
+ break;
+ case ir_unop_log2:
+ emit_scalar(ir, OPCODE_LG2, result_dst, op[0]);
+ break;
+ case ir_unop_sin:
+ emit_scalar(ir, OPCODE_SIN, result_dst, op[0]);
+ break;
+ case ir_unop_cos:
+ emit_scalar(ir, OPCODE_COS, result_dst, op[0]);
+ break;
+ case ir_unop_sin_reduced:
+ emit_scs(ir, OPCODE_SIN, result_dst, op[0]);
+ break;
+ case ir_unop_cos_reduced:
+ emit_scs(ir, OPCODE_COS, result_dst, op[0]);
+ break;
+
+ case ir_unop_dFdx:
+ emit(ir, OPCODE_DDX, result_dst, op[0]);
+ break;
+ case ir_unop_dFdy:
+ emit(ir, OPCODE_DDY, result_dst, op[0]);
+ break;
+
+ case ir_unop_noise: {
+ const enum prog_opcode opcode =
+ prog_opcode(OPCODE_NOISE1
+ + (ir->operands[0]->type->vector_elements) - 1);
+ assert((opcode >= OPCODE_NOISE1) && (opcode <= OPCODE_NOISE4));
+
+ emit(ir, opcode, result_dst, op[0]);
+ break;
+ }
+
+ case ir_binop_add:
+ emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_sub:
+ emit(ir, OPCODE_SUB, result_dst, op[0], op[1]);
+ break;
+
+ case ir_binop_mul:
+ emit(ir, OPCODE_MUL, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_div:
+ assert(!"not reached: should be handled by ir_div_to_mul_rcp");
+ break;
+ case ir_binop_mod:
+ /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */
+ assert(ir->type->is_integer());
+ emit(ir, OPCODE_MUL, result_dst, op[0], op[1]);
+ break;
+
+ case ir_binop_less:
+ emit(ir, OPCODE_SLT, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_greater:
+ emit(ir, OPCODE_SGT, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_lequal:
+ emit(ir, OPCODE_SLE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_gequal:
+ emit(ir, OPCODE_SGE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_equal:
+ emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_nequal:
+ emit(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_all_equal:
+ /* "==" operator producing a scalar boolean. */
+ if (ir->operands[0]->type->is_vector() ||
+ ir->operands[1]->type->is_vector()) {
+ src_reg temp = get_temp(glsl_type::vec4_type);
+ emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]);
+
+ /* After the dot-product, the value will be an integer on the
+ * range [0,4]. Zero becomes 1.0, and positive values become zero.
+ */
+ emit_dp(ir, result_dst, temp, temp, vector_elements);
+
+ /* Negating the result of the dot-product gives values on the range
+ * [-4, 0]. Zero becomes 1.0, and negative values become zero. This
+ * achieved using SGE.
+ */
+ src_reg sge_src = result_src;
+ sge_src.negate = ~sge_src.negate;
+ emit(ir, OPCODE_SGE, result_dst, sge_src, src_reg_for_float(0.0));
+ } else {
+ emit(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+ }
+ break;
+ case ir_binop_any_nequal:
+ /* "!=" operator producing a scalar boolean. */
+ if (ir->operands[0]->type->is_vector() ||
+ ir->operands[1]->type->is_vector()) {
+ src_reg temp = get_temp(glsl_type::vec4_type);
+ emit(ir, OPCODE_SNE, dst_reg(temp), op[0], op[1]);
+
+ /* After the dot-product, the value will be an integer on the
+ * range [0,4]. Zero stays zero, and positive values become 1.0.
+ */
+ ir_to_mesa_instruction *const dp =
+ emit_dp(ir, result_dst, temp, temp, vector_elements);
+ if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
+ /* The clamping to [0,1] can be done for free in the fragment
+ * shader with a saturate.
+ */
+ dp->saturate = true;
+ } else {
+ /* Negating the result of the dot-product gives values on the range
+ * [-4, 0]. Zero stays zero, and negative values become 1.0. This
+ * achieved using SLT.
+ */
+ src_reg slt_src = result_src;
+ slt_src.negate = ~slt_src.negate;
+ emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0));
+ }
+ } else {
+ emit(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+ }
+ break;
+
+ case ir_unop_any: {
+ assert(ir->operands[0]->type->is_vector());
+
+ /* After the dot-product, the value will be an integer on the
+ * range [0,4]. Zero stays zero, and positive values become 1.0.
+ */
+ ir_to_mesa_instruction *const dp =
+ emit_dp(ir, result_dst, op[0], op[0],
+ ir->operands[0]->type->vector_elements);
+ if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
+ /* The clamping to [0,1] can be done for free in the fragment
+ * shader with a saturate.
+ */
+ dp->saturate = true;
+ } else {
+ /* Negating the result of the dot-product gives values on the range
+ * [-4, 0]. Zero stays zero, and negative values become 1.0. This
+ * is achieved using SLT.
+ */
+ src_reg slt_src = result_src;
+ slt_src.negate = ~slt_src.negate;
+ emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0));
+ }
+ break;
+ }
+
+ case ir_binop_logic_xor:
+ emit(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+ break;
+
+ case ir_binop_logic_or: {
+ /* After the addition, the value will be an integer on the
+ * range [0,2]. Zero stays zero, and positive values become 1.0.
+ */
+ ir_to_mesa_instruction *add =
+ emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
+ if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
+ /* The clamping to [0,1] can be done for free in the fragment
+ * shader with a saturate.
+ */
+ add->saturate = true;
+ } else {
+ /* Negating the result of the addition gives values on the range
+ * [-2, 0]. Zero stays zero, and negative values become 1.0. This
+ * is achieved using SLT.
+ */
+ src_reg slt_src = result_src;
+ slt_src.negate = ~slt_src.negate;
+ emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0));
+ }
+ break;
+ }
+
+ case ir_binop_logic_and:
+ /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
+ emit(ir, OPCODE_MUL, result_dst, op[0], op[1]);
+ break;
+
+ case ir_binop_dot:
+ assert(ir->operands[0]->type->is_vector());
+ assert(ir->operands[0]->type == ir->operands[1]->type);
+ emit_dp(ir, result_dst, op[0], op[1],
+ ir->operands[0]->type->vector_elements);
+ break;
+
+ case ir_unop_sqrt:
+ /* sqrt(x) = x * rsq(x). */
+ emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]);
+ emit(ir, OPCODE_MUL, result_dst, result_src, op[0]);
+ /* For incoming channels <= 0, set the result to 0. */
+ op[0].negate = ~op[0].negate;
+ emit(ir, OPCODE_CMP, result_dst,
+ op[0], result_src, src_reg_for_float(0.0));
+ break;
+ case ir_unop_rsq:
+ emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]);
+ break;
+ case ir_unop_i2f:
+ case ir_unop_u2f:
+ case ir_unop_b2f:
+ case ir_unop_b2i:
+ case ir_unop_i2u:
+ case ir_unop_u2i:
+ /* Mesa IR lacks types, ints are stored as truncated floats. */
+ result_src = op[0];
+ break;
+ case ir_unop_f2i:
+ case ir_unop_f2u:
+ emit(ir, OPCODE_TRUNC, result_dst, op[0]);
+ break;
+ case ir_unop_f2b:
+ case ir_unop_i2b:
+ emit(ir, OPCODE_SNE, result_dst,
+ op[0], src_reg_for_float(0.0));
+ break;
+ case ir_unop_bitcast_f2i: // Ignore these 4, they can't happen here anyway
+ case ir_unop_bitcast_f2u:
+ case ir_unop_bitcast_i2f:
+ case ir_unop_bitcast_u2f:
+ break;
+ case ir_unop_trunc:
+ emit(ir, OPCODE_TRUNC, result_dst, op[0]);
+ break;
+ case ir_unop_ceil:
+ op[0].negate = ~op[0].negate;
+ emit(ir, OPCODE_FLR, result_dst, op[0]);
+ result_src.negate = ~result_src.negate;
+ break;
+ case ir_unop_floor:
+ emit(ir, OPCODE_FLR, result_dst, op[0]);
+ break;
+ case ir_unop_fract:
+ emit(ir, OPCODE_FRC, result_dst, op[0]);
+ break;
+ case ir_unop_pack_snorm_2x16:
+ case ir_unop_pack_snorm_4x8:
+ case ir_unop_pack_unorm_2x16:
+ case ir_unop_pack_unorm_4x8:
+ case ir_unop_pack_half_2x16:
+ case ir_unop_unpack_snorm_2x16:
+ case ir_unop_unpack_snorm_4x8:
+ case ir_unop_unpack_unorm_2x16:
+ case ir_unop_unpack_unorm_4x8:
+ case ir_unop_unpack_half_2x16:
+ case ir_unop_unpack_half_2x16_split_x:
+ case ir_unop_unpack_half_2x16_split_y:
+ case ir_binop_pack_half_2x16_split:
+ case ir_unop_bitfield_reverse:
+ case ir_unop_bit_count:
+ case ir_unop_find_msb:
+ case ir_unop_find_lsb:
+ assert(!"not supported");
+ break;
+ case ir_binop_min:
+ emit(ir, OPCODE_MIN, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_max:
+ emit(ir, OPCODE_MAX, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_pow:
+ emit_scalar(ir, OPCODE_POW, result_dst, op[0], op[1]);
+ break;
+
+ /* GLSL 1.30 integer ops are unsupported in Mesa IR, but since
+ * hardware backends have no way to avoid Mesa IR generation
+ * even if they don't use it, we need to emit "something" and
+ * continue.
+ */
+ case ir_binop_lshift:
+ case ir_binop_rshift:
+ case ir_binop_bit_and:
+ case ir_binop_bit_xor:
+ case ir_binop_bit_or:
+ emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
+ break;
+
+ case ir_unop_bit_not:
+ case ir_unop_round_even:
+ emit(ir, OPCODE_MOV, result_dst, op[0]);
+ break;
+
+ case ir_binop_ubo_load:
+ assert(!"not supported");
+ break;
+
+ case ir_triop_lrp:
+ /* ir_triop_lrp operands are (x, y, a) while
+ * OPCODE_LRP operands are (a, y, x) to match ARB_fragment_program.
+ */
+ emit(ir, OPCODE_LRP, result_dst, op[2], op[1], op[0]);
+ break;
+
+ case ir_binop_vector_extract:
+ case ir_binop_bfm:
+ case ir_triop_fma:
+ case ir_triop_bfi:
+ case ir_triop_bitfield_extract:
+ case ir_triop_vector_insert:
+ case ir_quadop_bitfield_insert:
+ case ir_binop_ldexp:
+ case ir_triop_csel:
+ case ir_binop_carry:
+ case ir_binop_borrow:
+ case ir_binop_imul_high:
+ assert(!"not supported");
+ break;
+
+ case ir_quadop_vector:
+ /* This operation should have already been handled.
+ */
+ assert(!"Should not get here.");
+ break;
+ }
+
+ this->result = result_src;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_swizzle *ir)
+{
+ src_reg src;
+ int i;
+ int swizzle[4];
+
+ /* Note that this is only swizzles in expressions, not those on the left
+ * hand side of an assignment, which do write masking. See ir_assignment
+ * for that.
+ */
+
+ ir->val->accept(this);
+ src = this->result;
+ assert(src.file != PROGRAM_UNDEFINED);
+
+ for (i = 0; i < 4; i++) {
+ if (i < ir->type->vector_elements) {
+ switch (i) {
+ case 0:
+ swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x);
+ break;
+ case 1:
+ swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y);
+ break;
+ case 2:
+ swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z);
+ break;
+ case 3:
+ swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w);
+ break;
+ }
+ } else {
+ /* If the type is smaller than a vec4, replicate the last
+ * channel out.
+ */
+ swizzle[i] = swizzle[ir->type->vector_elements - 1];
+ }
+ }
+
+ src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
+
+ this->result = src;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
+{
+ variable_storage *entry = find_variable_storage(ir->var);
+ ir_variable *var = ir->var;
+
+ if (!entry) {
+ switch (var->data.mode) {
+ case ir_var_uniform:
+ entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM,
+ var->data.location);
+ this->variables.push_tail(entry);
+ break;
+ case ir_var_shader_in:
+ /* The linker assigns locations for varyings and attributes,
+ * including deprecated builtins (like gl_Color),
+ * user-assigned generic attributes (glBindVertexLocation),
+ * and user-defined varyings.
+ */
+ assert(var->data.location != -1);
+ entry = new(mem_ctx) variable_storage(var,
+ PROGRAM_INPUT,
+ var->data.location);
+ break;
+ case ir_var_shader_out:
+ assert(var->data.location != -1);
+ entry = new(mem_ctx) variable_storage(var,
+ PROGRAM_OUTPUT,
+ var->data.location);
+ break;
+ case ir_var_system_value:
+ entry = new(mem_ctx) variable_storage(var,
+ PROGRAM_SYSTEM_VALUE,
+ var->data.location);
+ break;
+ case ir_var_auto:
+ case ir_var_temporary:
+ entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY,
+ this->next_temp);
+ this->variables.push_tail(entry);
+
+ next_temp += type_size(var->type);
+ break;
+ }
+
+ if (!entry) {
+ printf("Failed to make storage for %s\n", var->name);
+ exit(1);
+ }
+ }
+
+ this->result = src_reg(entry->file, entry->index, var->type);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_array *ir)
+{
+ ir_constant *index;
+ src_reg src;
+ int element_size = type_size(ir->type);
+
+ index = ir->array_index->constant_expression_value();
+
+ ir->array->accept(this);
+ src = this->result;
+
+ if (index) {
+ src.index += index->value.i[0] * element_size;
+ } else {
+ /* Variable index array dereference. It eats the "vec4" of the
+ * base of the array and an index that offsets the Mesa register
+ * index.
+ */
+ ir->array_index->accept(this);
+
+ src_reg index_reg;
+
+ if (element_size == 1) {
+ index_reg = this->result;
+ } else {
+ index_reg = get_temp(glsl_type::float_type);
+
+ emit(ir, OPCODE_MUL, dst_reg(index_reg),
+ this->result, src_reg_for_float(element_size));
+ }
+
+ /* If there was already a relative address register involved, add the
+ * new and the old together to get the new offset.
+ */
+ if (src.reladdr != NULL) {
+ src_reg accum_reg = get_temp(glsl_type::float_type);
+
+ emit(ir, OPCODE_ADD, dst_reg(accum_reg),
+ index_reg, *src.reladdr);
+
+ index_reg = accum_reg;
+ }
+
+ src.reladdr = ralloc(mem_ctx, src_reg);
+ memcpy(src.reladdr, &index_reg, sizeof(index_reg));
+ }
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ if (ir->type->is_scalar() || ir->type->is_vector())
+ src.swizzle = swizzle_for_size(ir->type->vector_elements);
+ else
+ src.swizzle = SWIZZLE_NOOP;
+
+ this->result = src;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_record *ir)
+{
+ unsigned int i;
+ const glsl_type *struct_type = ir->record->type;
+ int offset = 0;
+
+ ir->record->accept(this);
+
+ for (i = 0; i < struct_type->length; i++) {
+ if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
+ break;
+ offset += type_size(struct_type->fields.structure[i].type);
+ }
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ if (ir->type->is_scalar() || ir->type->is_vector())
+ this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
+ else
+ this->result.swizzle = SWIZZLE_NOOP;
+
+ this->result.index += offset;
+}
+
+/**
+ * We want to be careful in assignment setup to hit the actual storage
+ * instead of potentially using a temporary like we might with the
+ * ir_dereference handler.
+ */
+static dst_reg
+get_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v)
+{
+ /* The LHS must be a dereference. If the LHS is a variable indexed array
+ * access of a vector, it must be separated into a series conditional moves
+ * before reaching this point (see ir_vec_index_to_cond_assign).
+ */
+ assert(ir->as_dereference());
+ ir_dereference_array *deref_array = ir->as_dereference_array();
+ if (deref_array) {
+ assert(!deref_array->array->type->is_vector());
+ }
+
+ /* Use the rvalue deref handler for the most part. We'll ignore
+ * swizzles in it and write swizzles using writemask, though.
+ */
+ ir->accept(v);
+ return dst_reg(v->result);
+}
+
+/**
+ * Process the condition of a conditional assignment
+ *
+ * Examines the condition of a conditional assignment to generate the optimal
+ * first operand of a \c CMP instruction. If the condition is a relational
+ * operator with 0 (e.g., \c ir_binop_less), the value being compared will be
+ * used as the source for the \c CMP instruction. Otherwise the comparison
+ * is processed to a boolean result, and the boolean result is used as the
+ * operand to the CMP instruction.
+ */
+bool
+ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir)
+{
+ ir_rvalue *src_ir = ir;
+ bool negate = true;
+ bool switch_order = false;
+
+ ir_expression *const expr = ir->as_expression();
+ if ((expr != NULL) && (expr->get_num_operands() == 2)) {
+ bool zero_on_left = false;
+
+ if (expr->operands[0]->is_zero()) {
+ src_ir = expr->operands[1];
+ zero_on_left = true;
+ } else if (expr->operands[1]->is_zero()) {
+ src_ir = expr->operands[0];
+ zero_on_left = false;
+ }
+
+ /* a is - 0 + - 0 +
+ * (a < 0) T F F ( a < 0) T F F
+ * (0 < a) F F T (-a < 0) F F T
+ * (a <= 0) T T F (-a < 0) F F T (swap order of other operands)
+ * (0 <= a) F T T ( a < 0) T F F (swap order of other operands)
+ * (a > 0) F F T (-a < 0) F F T
+ * (0 > a) T F F ( a < 0) T F F
+ * (a >= 0) F T T ( a < 0) T F F (swap order of other operands)
+ * (0 >= a) T T F (-a < 0) F F T (swap order of other operands)
+ *
+ * Note that exchanging the order of 0 and 'a' in the comparison simply
+ * means that the value of 'a' should be negated.
+ */
+ if (src_ir != ir) {
+ switch (expr->operation) {
+ case ir_binop_less:
+ switch_order = false;
+ negate = zero_on_left;
+ break;
+
+ case ir_binop_greater:
+ switch_order = false;
+ negate = !zero_on_left;
+ break;
+
+ case ir_binop_lequal:
+ switch_order = true;
+ negate = !zero_on_left;
+ break;
+
+ case ir_binop_gequal:
+ switch_order = true;
+ negate = zero_on_left;
+ break;
+
+ default:
+ /* This isn't the right kind of comparison afterall, so make sure
+ * the whole condition is visited.
+ */
+ src_ir = ir;
+ break;
+ }
+ }
+ }
+
+ src_ir->accept(this);
+
+ /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the
+ * condition we produced is 0.0 or 1.0. By flipping the sign, we can
+ * choose which value OPCODE_CMP produces without an extra instruction
+ * computing the condition.
+ */
+ if (negate)
+ this->result.negate = ~this->result.negate;
+
+ return switch_order;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_assignment *ir)
+{
+ dst_reg l;
+ src_reg r;
+ int i;
+
+ ir->rhs->accept(this);
+ r = this->result;
+
+ l = get_assignment_lhs(ir->lhs, this);
+
+ /* FINISHME: This should really set to the correct maximal writemask for each
+ * FINISHME: component written (in the loops below). This case can only
+ * FINISHME: occur for matrices, arrays, and structures.
+ */
+ if (ir->write_mask == 0) {
+ assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
+ l.writemask = WRITEMASK_XYZW;
+ } else if (ir->lhs->type->is_scalar()) {
+ /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the
+ * FINISHME: W component of fragment shader output zero, work correctly.
+ */
+ l.writemask = WRITEMASK_XYZW;
+ } else {
+ int swizzles[4];
+ int first_enabled_chan = 0;
+ int rhs_chan = 0;
+
+ assert(ir->lhs->type->is_vector());
+ l.writemask = ir->write_mask;
+
+ for (int i = 0; i < 4; i++) {
+ if (l.writemask & (1 << i)) {
+ first_enabled_chan = GET_SWZ(r.swizzle, i);
+ break;
+ }
+ }
+
+ /* Swizzle a small RHS vector into the channels being written.
+ *
+ * glsl ir treats write_mask as dictating how many channels are
+ * present on the RHS while Mesa IR treats write_mask as just
+ * showing which channels of the vec4 RHS get written.
+ */
+ for (int i = 0; i < 4; i++) {
+ if (l.writemask & (1 << i))
+ swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++);
+ else
+ swizzles[i] = first_enabled_chan;
+ }
+ r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1],
+ swizzles[2], swizzles[3]);
+ }
+
+ assert(l.file != PROGRAM_UNDEFINED);
+ assert(r.file != PROGRAM_UNDEFINED);
+
+ if (ir->condition) {
+ const bool switch_order = this->process_move_condition(ir->condition);
+ src_reg condition = this->result;
+
+ for (i = 0; i < type_size(ir->lhs->type); i++) {
+ if (switch_order) {
+ emit(ir, OPCODE_CMP, l, condition, src_reg(l), r);
+ } else {
+ emit(ir, OPCODE_CMP, l, condition, r, src_reg(l));
+ }
+
+ l.index++;
+ r.index++;
+ }
+ } else {
+ for (i = 0; i < type_size(ir->lhs->type); i++) {
+ emit(ir, OPCODE_MOV, l, r);
+ l.index++;
+ r.index++;
+ }
+ }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_constant *ir)
+{
+ src_reg src;
+ GLfloat stack_vals[4] = { 0 };
+ GLfloat *values = stack_vals;
+ unsigned int i;
+
+ /* Unfortunately, 4 floats is all we can get into
+ * _mesa_add_unnamed_constant. So, make a temp to store an
+ * aggregate constant and move each constant value into it. If we
+ * get lucky, copy propagation will eliminate the extra moves.
+ */
+
+ if (ir->type->base_type == GLSL_TYPE_STRUCT) {
+ src_reg temp_base = get_temp(ir->type);
+ dst_reg temp = dst_reg(temp_base);
+
+ foreach_list(node, &ir->components) {
+ ir_constant *field_value = (ir_constant *) node;
+ int size = type_size(field_value->type);
+
+ assert(size > 0);
+
+ field_value->accept(this);
+ src = this->result;
+
+ for (i = 0; i < (unsigned int)size; i++) {
+ emit(ir, OPCODE_MOV, temp, src);
+
+ src.index++;
+ temp.index++;
+ }
+ }
+ this->result = temp_base;
+ return;
+ }
+
+ if (ir->type->is_array()) {
+ src_reg temp_base = get_temp(ir->type);
+ dst_reg temp = dst_reg(temp_base);
+ int size = type_size(ir->type->fields.array);
+
+ assert(size > 0);
+
+ for (i = 0; i < ir->type->length; i++) {
+ ir->array_elements[i]->accept(this);
+ src = this->result;
+ for (int j = 0; j < size; j++) {
+ emit(ir, OPCODE_MOV, temp, src);
+
+ src.index++;
+ temp.index++;
+ }
+ }
+ this->result = temp_base;
+ return;
+ }
+
+ if (ir->type->is_matrix()) {
+ src_reg mat = get_temp(ir->type);
+ dst_reg mat_column = dst_reg(mat);
+
+ for (i = 0; i < ir->type->matrix_columns; i++) {
+ assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+ values = &ir->value.f[i * ir->type->vector_elements];
+
+ src = src_reg(PROGRAM_CONSTANT, -1, NULL);
+ src.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+ (gl_constant_value *) values,
+ ir->type->vector_elements,
+ &src.swizzle);
+ emit(ir, OPCODE_MOV, mat_column, src);
+
+ mat_column.index++;
+ }
+
+ this->result = mat;
+ return;
+ }
+
+ src.file = PROGRAM_CONSTANT;
+ switch (ir->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ values = &ir->value.f[0];
+ break;
+ case GLSL_TYPE_UINT:
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ values[i] = ir->value.u[i];
+ }
+ break;
+ case GLSL_TYPE_INT:
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ values[i] = ir->value.i[i];
+ }
+ break;
+ case GLSL_TYPE_BOOL:
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ values[i] = ir->value.b[i];
+ }
+ break;
+ default:
+ assert(!"Non-float/uint/int/bool constant");
+ }
+
+ this->result = src_reg(PROGRAM_CONSTANT, -1, ir->type);
+ this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+ (gl_constant_value *) values,
+ ir->type->vector_elements,
+ &this->result.swizzle);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_call *)
+{
+ assert(!"ir_to_mesa: All function calls should have been inlined by now.");
+}
+
+void
+ir_to_mesa_visitor::visit(ir_texture *ir)
+{
+ src_reg result_src, coord, lod_info, projector, dx, dy;
+ dst_reg result_dst, coord_dst;
+ ir_to_mesa_instruction *inst = NULL;
+ prog_opcode opcode = OPCODE_NOP;
+
+ /* Neither opcode uses coordinate */
+ if (ir->op == ir_txs || ir->op == ir_query_levels)
+ this->result = src_reg_for_float(0.0);
+ else
+ ir->coordinate->accept(this);
+
+ /* Put our coords in a temp. We'll need to modify them for shadow,
+ * projection, or LOD, so the only case we'd use it as is is if
+ * we're doing plain old texturing. Mesa IR optimization should
+ * handle cleaning up our mess in that case.
+ */
+ coord = get_temp(glsl_type::vec4_type);
+ coord_dst = dst_reg(coord);
+ emit(ir, OPCODE_MOV, coord_dst, this->result);
+
+ if (ir->projector) {
+ ir->projector->accept(this);
+ projector = this->result;
+ }
+
+ /* Storage for our result. Ideally for an assignment we'd be using
+ * the actual storage for the result here, instead.
+ */
+ result_src = get_temp(glsl_type::vec4_type);
+ result_dst = dst_reg(result_src);
+
+ switch (ir->op) {
+ case ir_tex:
+ case ir_txs:
+ opcode = OPCODE_TEX;
+ break;
+ case ir_txb:
+ opcode = OPCODE_TXB;
+ ir->lod_info.bias->accept(this);
+ lod_info = this->result;
+ break;
+ case ir_txf:
+ /* Pretend to be TXL so the sampler, coordinate, lod are available */
+ case ir_txl:
+ opcode = OPCODE_TXL;
+ ir->lod_info.lod->accept(this);
+ lod_info = this->result;
+ break;
+ case ir_txd:
+ opcode = OPCODE_TXD;
+ ir->lod_info.grad.dPdx->accept(this);
+ dx = this->result;
+ ir->lod_info.grad.dPdy->accept(this);
+ dy = this->result;
+ break;
+ case ir_txf_ms:
+ assert(!"Unexpected ir_txf_ms opcode");
+ break;
+ case ir_lod:
+ assert(!"Unexpected ir_lod opcode");
+ break;
+ case ir_tg4:
+ assert(!"Unexpected ir_tg4 opcode");
+ break;
+ case ir_query_levels:
+ assert(!"Unexpected ir_query_levels opcode");
+ break;
+ }
+
+ const glsl_type *sampler_type = ir->sampler->type;
+
+ if (ir->projector) {
+ if (opcode == OPCODE_TEX) {
+ /* Slot the projector in as the last component of the coord. */
+ coord_dst.writemask = WRITEMASK_W;
+ emit(ir, OPCODE_MOV, coord_dst, projector);
+ coord_dst.writemask = WRITEMASK_XYZW;
+ opcode = OPCODE_TXP;
+ } else {
+ src_reg coord_w = coord;
+ coord_w.swizzle = SWIZZLE_WWWW;
+
+ /* For the other TEX opcodes there's no projective version
+ * since the last slot is taken up by lod info. Do the
+ * projective divide now.
+ */
+ coord_dst.writemask = WRITEMASK_W;
+ emit(ir, OPCODE_RCP, coord_dst, projector);
+
+ /* In the case where we have to project the coordinates "by hand,"
+ * the shadow comparitor value must also be projected.
+ */
+ src_reg tmp_src = coord;
+ if (ir->shadow_comparitor) {
+ /* Slot the shadow value in as the second to last component of the
+ * coord.
+ */
+ ir->shadow_comparitor->accept(this);
+
+ tmp_src = get_temp(glsl_type::vec4_type);
+ dst_reg tmp_dst = dst_reg(tmp_src);
+
+ /* Projective division not allowed for array samplers. */
+ assert(!sampler_type->sampler_array);
+
+ tmp_dst.writemask = WRITEMASK_Z;
+ emit(ir, OPCODE_MOV, tmp_dst, this->result);
+
+ tmp_dst.writemask = WRITEMASK_XY;
+ emit(ir, OPCODE_MOV, tmp_dst, coord);
+ }
+
+ coord_dst.writemask = WRITEMASK_XYZ;
+ emit(ir, OPCODE_MUL, coord_dst, tmp_src, coord_w);
+
+ coord_dst.writemask = WRITEMASK_XYZW;
+ coord.swizzle = SWIZZLE_XYZW;
+ }
+ }
+
+ /* If projection is done and the opcode is not OPCODE_TXP, then the shadow
+ * comparitor was put in the correct place (and projected) by the code,
+ * above, that handles by-hand projection.
+ */
+ if (ir->shadow_comparitor && (!ir->projector || opcode == OPCODE_TXP)) {
+ /* Slot the shadow value in as the second to last component of the
+ * coord.
+ */
+ ir->shadow_comparitor->accept(this);
+
+ /* XXX This will need to be updated for cubemap array samplers. */
+ if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
+ sampler_type->sampler_array) {
+ coord_dst.writemask = WRITEMASK_W;
+ } else {
+ coord_dst.writemask = WRITEMASK_Z;
+ }
+
+ emit(ir, OPCODE_MOV, coord_dst, this->result);
+ coord_dst.writemask = WRITEMASK_XYZW;
+ }
+
+ if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
+ /* Mesa IR stores lod or lod bias in the last channel of the coords. */
+ coord_dst.writemask = WRITEMASK_W;
+ emit(ir, OPCODE_MOV, coord_dst, lod_info);
+ coord_dst.writemask = WRITEMASK_XYZW;
+ }
+
+ if (opcode == OPCODE_TXD)
+ inst = emit(ir, opcode, result_dst, coord, dx, dy);
+ else
+ inst = emit(ir, opcode, result_dst, coord);
+
+ if (ir->shadow_comparitor)
+ inst->tex_shadow = GL_TRUE;
+
+ inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler,
+ this->shader_program,
+ this->prog);
+
+ switch (sampler_type->sampler_dimensionality) {
+ case GLSL_SAMPLER_DIM_1D:
+ inst->tex_target = (sampler_type->sampler_array)
+ ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_2D:
+ inst->tex_target = (sampler_type->sampler_array)
+ ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_3D:
+ inst->tex_target = TEXTURE_3D_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_CUBE:
+ inst->tex_target = TEXTURE_CUBE_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_RECT:
+ inst->tex_target = TEXTURE_RECT_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_BUF:
+ assert(!"FINISHME: Implement ARB_texture_buffer_object");
+ break;
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ inst->tex_target = TEXTURE_EXTERNAL_INDEX;
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+
+ this->result = result_src;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_return *ir)
+{
+ /* Non-void functions should have been inlined. We may still emit RETs
+ * from main() unless the EmitNoMainReturn option is set.
+ */
+ assert(!ir->get_value());
+ emit(ir, OPCODE_RET);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_discard *ir)
+{
+ if (ir->condition) {
+ ir->condition->accept(this);
+ this->result.negate = ~this->result.negate;
+ emit(ir, OPCODE_KIL, undef_dst, this->result);
+ } else {
+ emit(ir, OPCODE_KIL_NV);
+ }
+}
+
+void
+ir_to_mesa_visitor::visit(ir_if *ir)
+{
+ ir_to_mesa_instruction *cond_inst, *if_inst;
+ ir_to_mesa_instruction *prev_inst;
+
+ prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
+
+ ir->condition->accept(this);
+ assert(this->result.file != PROGRAM_UNDEFINED);
+
+ if (this->options->EmitCondCodes) {
+ cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
+
+ /* See if we actually generated any instruction for generating
+ * the condition. If not, then cook up a move to a temp so we
+ * have something to set cond_update on.
+ */
+ if (cond_inst == prev_inst) {
+ src_reg temp = get_temp(glsl_type::bool_type);
+ cond_inst = emit(ir->condition, OPCODE_MOV, dst_reg(temp), result);
+ }
+ cond_inst->cond_update = GL_TRUE;
+
+ if_inst = emit(ir->condition, OPCODE_IF);
+ if_inst->dst.cond_mask = COND_NE;
+ } else {
+ if_inst = emit(ir->condition, OPCODE_IF, undef_dst, this->result);
+ }
+
+ this->instructions.push_tail(if_inst);
+
+ visit_exec_list(&ir->then_instructions, this);
+
+ if (!ir->else_instructions.is_empty()) {
+ emit(ir->condition, OPCODE_ELSE);
+ visit_exec_list(&ir->else_instructions, this);
+ }
+
+ emit(ir->condition, OPCODE_ENDIF);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_emit_vertex *)
+{
+ assert(!"Geometry shaders not supported.");
+}
+
+void
+ir_to_mesa_visitor::visit(ir_end_primitive *)
+{
+ assert(!"Geometry shaders not supported.");
+}
+
+ir_to_mesa_visitor::ir_to_mesa_visitor()
+{
+ result.file = PROGRAM_UNDEFINED;
+ next_temp = 1;
+ next_signature_id = 1;
+ current_function = NULL;
+ mem_ctx = ralloc_context(NULL);
+}
+
+ir_to_mesa_visitor::~ir_to_mesa_visitor()
+{
+ ralloc_free(mem_ctx);
+}
+
+static struct prog_src_register
+mesa_src_reg_from_ir_src_reg(src_reg reg)
+{
+ struct prog_src_register mesa_reg;
+
+ mesa_reg.File = reg.file;
+ assert(reg.index < (1 << INST_INDEX_BITS));
+ mesa_reg.Index = reg.index;
+ mesa_reg.Swizzle = reg.swizzle;
+ mesa_reg.RelAddr = reg.reladdr != NULL;
+ mesa_reg.Negate = reg.negate;
+ mesa_reg.Abs = 0;
+ mesa_reg.HasIndex2 = GL_FALSE;
+ mesa_reg.RelAddr2 = 0;
+ mesa_reg.Index2 = 0;
+
+ return mesa_reg;
+}
+
+static void
+set_branchtargets(ir_to_mesa_visitor *v,
+ struct prog_instruction *mesa_instructions,
+ int num_instructions)
+{
+ int if_count = 0, loop_count = 0;
+ int *if_stack, *loop_stack;
+ int if_stack_pos = 0, loop_stack_pos = 0;
+ int i, j;
+
+ for (i = 0; i < num_instructions; i++) {
+ switch (mesa_instructions[i].Opcode) {
+ case OPCODE_IF:
+ if_count++;
+ break;
+ case OPCODE_BGNLOOP:
+ loop_count++;
+ break;
+ case OPCODE_BRK:
+ case OPCODE_CONT:
+ mesa_instructions[i].BranchTarget = -1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if_stack = rzalloc_array(v->mem_ctx, int, if_count);
+ loop_stack = rzalloc_array(v->mem_ctx, int, loop_count);
+
+ for (i = 0; i < num_instructions; i++) {
+ switch (mesa_instructions[i].Opcode) {
+ case OPCODE_IF:
+ if_stack[if_stack_pos] = i;
+ if_stack_pos++;
+ break;
+ case OPCODE_ELSE:
+ mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+ if_stack[if_stack_pos - 1] = i;
+ break;
+ case OPCODE_ENDIF:
+ mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+ if_stack_pos--;
+ break;
+ case OPCODE_BGNLOOP:
+ loop_stack[loop_stack_pos] = i;
+ loop_stack_pos++;
+ break;
+ case OPCODE_ENDLOOP:
+ loop_stack_pos--;
+ /* Rewrite any breaks/conts at this nesting level (haven't
+ * already had a BranchTarget assigned) to point to the end
+ * of the loop.
+ */
+ for (j = loop_stack[loop_stack_pos]; j < i; j++) {
+ if (mesa_instructions[j].Opcode == OPCODE_BRK ||
+ mesa_instructions[j].Opcode == OPCODE_CONT) {
+ if (mesa_instructions[j].BranchTarget == -1) {
+ mesa_instructions[j].BranchTarget = i;
+ }
+ }
+ }
+ /* The loop ends point at each other. */
+ mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
+ mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
+ break;
+ case OPCODE_CAL:
+ foreach_list(n, &v->function_signatures) {
+ function_entry *entry = (function_entry *) n;
+
+ if (entry->sig_id == mesa_instructions[i].BranchTarget) {
+ mesa_instructions[i].BranchTarget = entry->inst;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void
+print_program(struct prog_instruction *mesa_instructions,
+ ir_instruction **mesa_instruction_annotation,
+ int num_instructions)
+{
+ ir_instruction *last_ir = NULL;
+ int i;
+ int indent = 0;
+
+ for (i = 0; i < num_instructions; i++) {
+ struct prog_instruction *mesa_inst = mesa_instructions + i;
+ ir_instruction *ir = mesa_instruction_annotation[i];
+
+ fprintf(stdout, "%3d: ", i);
+
+ if (last_ir != ir && ir) {
+ int j;
+
+ for (j = 0; j < indent; j++) {
+ fprintf(stdout, " ");
+ }
+ ir->print();
+ printf("\n");
+ last_ir = ir;
+
+ fprintf(stdout, " "); /* line number spacing. */
+ }
+
+ indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
+ PROG_PRINT_DEBUG, NULL);
+ }
+}
+
+namespace {
+
+class add_uniform_to_shader : public program_resource_visitor {
+public:
+ add_uniform_to_shader(struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params,
+ gl_shader_stage shader_type)
+ : shader_program(shader_program), params(params), idx(-1),
+ shader_type(shader_type)
+ {
+ /* empty */
+ }
+
+ void process(ir_variable *var)
+ {
+ this->idx = -1;
+ this->program_resource_visitor::process(var);
+
+ var->data.location = this->idx;
+ }
+
+private:
+ virtual void visit_field(const glsl_type *type, const char *name,
+ bool row_major);
+
+ struct gl_shader_program *shader_program;
+ struct gl_program_parameter_list *params;
+ int idx;
+ gl_shader_stage shader_type;
+};
+
+} /* anonymous namespace */
+
+void
+add_uniform_to_shader::visit_field(const glsl_type *type, const char *name,
+ bool row_major)
+{
+ unsigned int size;
+
+ (void) row_major;
+
+ if (type->is_vector() || type->is_scalar()) {
+ size = type->vector_elements;
+ } else {
+ size = type_size(type) * 4;
+ }
+
+ gl_register_file file;
+ if (type->is_sampler() ||
+ (type->is_array() && type->fields.array->is_sampler())) {
+ file = PROGRAM_SAMPLER;
+ } else {
+ file = PROGRAM_UNIFORM;
+ }
+
+ int index = _mesa_lookup_parameter_index(params, -1, name);
+ if (index < 0) {
+ index = _mesa_add_parameter(params, file, name, size, type->gl_type,
+ NULL, NULL);
+
+ /* Sampler uniform values are stored in prog->SamplerUnits,
+ * and the entry in that array is selected by this index we
+ * store in ParameterValues[].
+ */
+ if (file == PROGRAM_SAMPLER) {
+ unsigned location;
+ const bool found =
+ this->shader_program->UniformHash->get(location,
+ params->Parameters[index].Name);
+ assert(found);
+
+ if (!found)
+ return;
+
+ struct gl_uniform_storage *storage =
+ &this->shader_program->UniformStorage[location];
+
+ assert(storage->sampler[shader_type].active);
+
+ for (unsigned int j = 0; j < size / 4; j++)
+ params->ParameterValues[index + j][0].f =
+ storage->sampler[shader_type].index + j;
+ }
+ }
+
+ /* The first part of the uniform that's processed determines the base
+ * location of the whole uniform (for structures).
+ */
+ if (this->idx < 0)
+ this->idx = index;
+}
+
+/**
+ * Generate the program parameters list for the user uniforms in a shader
+ *
+ * \param shader_program Linked shader program. This is only used to
+ * emit possible link errors to the info log.
+ * \param sh Shader whose uniforms are to be processed.
+ * \param params Parameter list to be filled in.
+ */
+void
+_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
+ *shader_program,
+ struct gl_shader *sh,
+ struct gl_program_parameter_list
+ *params)
+{
+ add_uniform_to_shader add(shader_program, params, sh->Stage);
+
+ foreach_list(node, sh->ir) {
+ ir_variable *var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->data.mode != ir_var_uniform)
+ || var->is_in_uniform_block() || (strncmp(var->name, "gl_", 3) == 0))
+ continue;
+
+ add.process(var);
+ }
+}
+
+void
+_mesa_associate_uniform_storage(struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params)
+{
+ /* After adding each uniform to the parameter list, connect the storage for
+ * the parameter with the tracking structure used by the API for the
+ * uniform.
+ */
+ unsigned last_location = unsigned(~0);
+ for (unsigned i = 0; i < params->NumParameters; i++) {
+ if (params->Parameters[i].Type != PROGRAM_UNIFORM)
+ continue;
+
+ unsigned location;
+ const bool found =
+ shader_program->UniformHash->get(location, params->Parameters[i].Name);
+ assert(found);
+
+ if (!found)
+ continue;
+
+ if (location != last_location) {
+ struct gl_uniform_storage *storage =
+ &shader_program->UniformStorage[location];
+ enum gl_uniform_driver_format format = uniform_native;
+
+ unsigned columns = 0;
+ switch (storage->type->base_type) {
+ case GLSL_TYPE_UINT:
+ assert(ctx->Const.NativeIntegers);
+ format = uniform_native;
+ columns = 1;
+ break;
+ case GLSL_TYPE_INT:
+ format =
+ (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float;
+ columns = 1;
+ break;
+ case GLSL_TYPE_FLOAT:
+ format = uniform_native;
+ columns = storage->type->matrix_columns;
+ break;
+ case GLSL_TYPE_BOOL:
+ if (ctx->Const.NativeIntegers) {
+ format = (ctx->Const.UniformBooleanTrue == 1)
+ ? uniform_bool_int_0_1 : uniform_bool_int_0_not0;
+ } else {
+ format = uniform_bool_float;
+ }
+ columns = 1;
+ break;
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
+ format = uniform_native;
+ columns = 1;
+ break;
+ case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_ARRAY:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_STRUCT:
+ case GLSL_TYPE_ERROR:
+ case GLSL_TYPE_INTERFACE:
+ assert(!"Should not get here.");
+ break;
+ }
+
+ _mesa_uniform_attach_driver_storage(storage,
+ 4 * sizeof(float) * columns,
+ 4 * sizeof(float),
+ format,
+ ¶ms->ParameterValues[i]);
+
+ /* After attaching the driver's storage to the uniform, propagate any
+ * data from the linker's backing store. This will cause values from
+ * initializers in the source code to be copied over.
+ */
+ _mesa_propagate_uniforms_to_driver_storage(storage,
+ 0,
+ MAX2(1, storage->array_elements));
+
+ last_location = location;
+ }
+ }
+}
+
+/*
+ * On a basic block basis, tracks available PROGRAM_TEMPORARY register
+ * channels for copy propagation and updates following instructions to
+ * use the original versions.
+ *
+ * The ir_to_mesa_visitor lazily produces code assuming that this pass
+ * will occur. As an example, a TXP production before this pass:
+ *
+ * 0: MOV TEMP[1], INPUT[4].xyyy;
+ * 1: MOV TEMP[1].w, INPUT[4].wwww;
+ * 2: TXP TEMP[2], TEMP[1], texture[0], 2D;
+ *
+ * and after:
+ *
+ * 0: MOV TEMP[1], INPUT[4].xyyy;
+ * 1: MOV TEMP[1].w, INPUT[4].wwww;
+ * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
+ *
+ * which allows for dead code elimination on TEMP[1]'s writes.
+ */
+void
+ir_to_mesa_visitor::copy_propagate(void)
+{
+ ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx,
+ ir_to_mesa_instruction *,
+ this->next_temp * 4);
+ int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
+ int level = 0;
+
+ foreach_list(node, &this->instructions) {
+ ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node;
+
+ assert(inst->dst.file != PROGRAM_TEMPORARY
+ || inst->dst.index < this->next_temp);
+
+ /* First, do any copy propagation possible into the src regs. */
+ for (int r = 0; r < 3; r++) {
+ ir_to_mesa_instruction *first = NULL;
+ bool good = true;
+ int acp_base = inst->src[r].index * 4;
+
+ if (inst->src[r].file != PROGRAM_TEMPORARY ||
+ inst->src[r].reladdr)
+ continue;
+
+ /* See if we can find entries in the ACP consisting of MOVs
+ * from the same src register for all the swizzled channels
+ * of this src register reference.
+ */
+ for (int i = 0; i < 4; i++) {
+ int src_chan = GET_SWZ(inst->src[r].swizzle, i);
+ ir_to_mesa_instruction *copy_chan = acp[acp_base + src_chan];
+
+ if (!copy_chan) {
+ good = false;
+ break;
+ }
+
+ assert(acp_level[acp_base + src_chan] <= level);
+
+ if (!first) {
+ first = copy_chan;
+ } else {
+ if (first->src[0].file != copy_chan->src[0].file ||
+ first->src[0].index != copy_chan->src[0].index) {
+ good = false;
+ break;
+ }
+ }
+ }
+
+ if (good) {
+ /* We've now validated that we can copy-propagate to
+ * replace this src register reference. Do it.
+ */
+ inst->src[r].file = first->src[0].file;
+ inst->src[r].index = first->src[0].index;
+
+ int swizzle = 0;
+ for (int i = 0; i < 4; i++) {
+ int src_chan = GET_SWZ(inst->src[r].swizzle, i);
+ ir_to_mesa_instruction *copy_inst = acp[acp_base + src_chan];
+ swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) <<
+ (3 * i));
+ }
+ inst->src[r].swizzle = swizzle;
+ }
+ }
+
+ switch (inst->op) {
+ case OPCODE_BGNLOOP:
+ case OPCODE_ENDLOOP:
+ /* End of a basic block, clear the ACP entirely. */
+ memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
+ break;
+
+ case OPCODE_IF:
+ ++level;
+ break;
+
+ case OPCODE_ENDIF:
+ case OPCODE_ELSE:
+ /* Clear all channels written inside the block from the ACP, but
+ * leaving those that were not touched.
+ */
+ for (int r = 0; r < this->next_temp; r++) {
+ for (int c = 0; c < 4; c++) {
+ if (!acp[4 * r + c])
+ continue;
+
+ if (acp_level[4 * r + c] >= level)
+ acp[4 * r + c] = NULL;
+ }
+ }
+ if (inst->op == OPCODE_ENDIF)
+ --level;
+ break;
+
+ default:
+ /* Continuing the block, clear any written channels from
+ * the ACP.
+ */
+ if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) {
+ /* Any temporary might be written, so no copy propagation
+ * across this instruction.
+ */
+ memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
+ } else if (inst->dst.file == PROGRAM_OUTPUT &&
+ inst->dst.reladdr) {
+ /* Any output might be written, so no copy propagation
+ * from outputs across this instruction.
+ */
+ for (int r = 0; r < this->next_temp; r++) {
+ for (int c = 0; c < 4; c++) {
+ if (!acp[4 * r + c])
+ continue;
+
+ if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT)
+ acp[4 * r + c] = NULL;
+ }
+ }
+ } else if (inst->dst.file == PROGRAM_TEMPORARY ||
+ inst->dst.file == PROGRAM_OUTPUT) {
+ /* Clear where it's used as dst. */
+ if (inst->dst.file == PROGRAM_TEMPORARY) {
+ for (int c = 0; c < 4; c++) {
+ if (inst->dst.writemask & (1 << c)) {
+ acp[4 * inst->dst.index + c] = NULL;
+ }
+ }
+ }
+
+ /* Clear where it's used as src. */
+ for (int r = 0; r < this->next_temp; r++) {
+ for (int c = 0; c < 4; c++) {
+ if (!acp[4 * r + c])
+ continue;
+
+ int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c);
+
+ if (acp[4 * r + c]->src[0].file == inst->dst.file &&
+ acp[4 * r + c]->src[0].index == inst->dst.index &&
+ inst->dst.writemask & (1 << src_chan))
+ {
+ acp[4 * r + c] = NULL;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ /* If this is a copy, add it to the ACP. */
+ if (inst->op == OPCODE_MOV &&
+ inst->dst.file == PROGRAM_TEMPORARY &&
+ !(inst->dst.file == inst->src[0].file &&
+ inst->dst.index == inst->src[0].index) &&
+ !inst->dst.reladdr &&
+ !inst->saturate &&
+ !inst->src[0].reladdr &&
+ !inst->src[0].negate) {
+ for (int i = 0; i < 4; i++) {
+ if (inst->dst.writemask & (1 << i)) {
+ acp[4 * inst->dst.index + i] = inst;
+ acp_level[4 * inst->dst.index + i] = level;
+ }
+ }
+ }
+ }
+
+ ralloc_free(acp_level);
+ ralloc_free(acp);
+}
+
+
+/**
+ * Convert a shader's GLSL IR into a Mesa gl_program.
+ */
+struct gl_program *
+_mesa_ir_get_program(struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_shader *shader)
+{
+ ir_to_mesa_visitor v;
+ struct prog_instruction *mesa_instructions, *mesa_inst;
+ ir_instruction **mesa_instruction_annotation;
+ int i;
+ struct gl_program *prog;
+ GLenum target = _mesa_shader_stage_to_program(shader->Stage);
+ const char *target_string = _mesa_shader_stage_to_string(shader->Stage);
+ struct gl_shader_compiler_options *options =
+ &ctx->ShaderCompilerOptions[shader->Stage];
+
+ validate_ir_tree(shader->ir);
+
+ prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name);
+ if (!prog)
+ return NULL;
+ prog->Parameters = _mesa_new_parameter_list();
+ v.ctx = ctx;
+ v.prog = prog;
+ v.shader_program = shader_program;
+ v.options = options;
+
+ _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
+ prog->Parameters);
+
+ /* Emit Mesa IR for main(). */
+ visit_exec_list(shader->ir, &v);
+ v.emit(NULL, OPCODE_END);
+
+ prog->NumTemporaries = v.next_temp;
+
+ int num_instructions = 0;
+ foreach_list(node, &v.instructions) {
+ num_instructions++;
+ }
+
+ mesa_instructions =
+ (struct prog_instruction *)calloc(num_instructions,
+ sizeof(*mesa_instructions));
+ mesa_instruction_annotation = ralloc_array(v.mem_ctx, ir_instruction *,
+ num_instructions);
+
+ v.copy_propagate();
+
+ /* Convert ir_mesa_instructions into prog_instructions.
+ */
+ mesa_inst = mesa_instructions;
+ i = 0;
+ foreach_list(node, &v.instructions) {
+ const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node;
+
+ mesa_inst->Opcode = inst->op;
+ mesa_inst->CondUpdate = inst->cond_update;
+ if (inst->saturate)
+ mesa_inst->SaturateMode = SATURATE_ZERO_ONE;
+ mesa_inst->DstReg.File = inst->dst.file;
+ mesa_inst->DstReg.Index = inst->dst.index;
+ mesa_inst->DstReg.CondMask = inst->dst.cond_mask;
+ mesa_inst->DstReg.WriteMask = inst->dst.writemask;
+ mesa_inst->DstReg.RelAddr = inst->dst.reladdr != NULL;
+ mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src[0]);
+ mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src[1]);
+ mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src[2]);
+ mesa_inst->TexSrcUnit = inst->sampler;
+ mesa_inst->TexSrcTarget = inst->tex_target;
+ mesa_inst->TexShadow = inst->tex_shadow;
+ mesa_instruction_annotation[i] = inst->ir;
+
+ /* Set IndirectRegisterFiles. */
+ if (mesa_inst->DstReg.RelAddr)
+ prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File;
+
+ /* Update program's bitmask of indirectly accessed register files */
+ for (unsigned src = 0; src < 3; src++)
+ if (mesa_inst->SrcReg[src].RelAddr)
+ prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File;
+
+ switch (mesa_inst->Opcode) {
+ case OPCODE_IF:
+ if (options->MaxIfDepth == 0) {
+ linker_warning(shader_program,
+ "Couldn't flatten if-statement. "
+ "This will likely result in software "
+ "rasterization.\n");
+ }
+ break;
+ case OPCODE_BGNLOOP:
+ if (options->EmitNoLoops) {
+ linker_warning(shader_program,
+ "Couldn't unroll loop. "
+ "This will likely result in software "
+ "rasterization.\n");
+ }
+ break;
+ case OPCODE_CONT:
+ if (options->EmitNoCont) {
+ linker_warning(shader_program,
+ "Couldn't lower continue-statement. "
+ "This will likely result in software "
+ "rasterization.\n");
+ }
+ break;
+ case OPCODE_ARL:
+ prog->NumAddressRegs = 1;
+ break;
+ default:
+ break;
+ }
+
+ mesa_inst++;
+ i++;
+
+ if (!shader_program->LinkStatus)
+ break;
+ }
+
+ if (!shader_program->LinkStatus) {
+ goto fail_exit;
+ }
+
+ set_branchtargets(&v, mesa_instructions, num_instructions);
+
+ if (ctx->GlslFlags & GLSL_DUMP) {
+ fprintf(stderr, "\n");
+ fprintf(stderr, "GLSL IR for linked %s program %d:\n", target_string,
+ shader_program->Name);
+ _mesa_print_ir(stderr, shader->ir, NULL);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Mesa IR for linked %s program %d:\n", target_string,
+ shader_program->Name);
+ print_program(mesa_instructions, mesa_instruction_annotation,
+ num_instructions);
+ fflush(stderr);
+ }
+
+ prog->Instructions = mesa_instructions;
+ prog->NumInstructions = num_instructions;
+
+ /* Setting this to NULL prevents a possible double free in the fail_exit
+ * path (far below).
+ */
+ mesa_instructions = NULL;
+
+ do_set_program_inouts(shader->ir, prog, shader->Stage);
+
+ prog->SamplersUsed = shader->active_samplers;
+ prog->ShadowSamplers = shader->shadow_samplers;
+ _mesa_update_shader_textures_used(shader_program, prog);
+
+ /* Set the gl_FragDepth layout. */
+ if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)prog;
+ fp->FragDepthLayout = shader_program->FragDepthLayout;
+ }
+
+ _mesa_reference_program(ctx, &shader->Program, prog);
+
+ if ((ctx->GlslFlags & GLSL_NO_OPT) == 0) {
+ _mesa_optimize_program(ctx, prog);
+ }
+
+ /* This has to be done last. Any operation that can cause
+ * prog->ParameterValues to get reallocated (e.g., anything that adds a
+ * program constant) has to happen before creating this linkage.
+ */
+ _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters);
+ if (!shader_program->LinkStatus) {
+ goto fail_exit;
+ }
+
+ return prog;
+
+fail_exit:
+ free(mesa_instructions);
+ _mesa_reference_program(ctx, &shader->Program, NULL);
+ return NULL;
+}
+
+extern "C" {
+
+/**
+ * Link a shader.
+ * Called via ctx->Driver.LinkShader()
+ * This actually involves converting GLSL IR into Mesa gl_programs with
+ * code lowering and other optimizations.
+ */
+GLboolean
+_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+ assert(prog->LinkStatus);
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ bool progress;
+ exec_list *ir = prog->_LinkedShaders[i]->ir;
+ const struct gl_shader_compiler_options *options =
+ &ctx->ShaderCompilerOptions[prog->_LinkedShaders[i]->Stage];
+
+ do {
+ progress = false;
+
+ /* Lowering */
+ do_mat_op_to_vec(ir);
+ lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2
+ | LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP
+ | ((options->EmitNoPow) ? POW_TO_EXP2 : 0)));
+
+ progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
+
+ progress = do_common_optimization(ir, true, true,
+ options, ctx->Const.NativeIntegers)
+ || progress;
+
+ progress = lower_quadop_vector(ir, true) || progress;
+
+ if (options->MaxIfDepth == 0)
+ progress = lower_discard(ir) || progress;
+
+ progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress;
+
+ if (options->EmitNoNoise)
+ progress = lower_noise(ir) || progress;
+
+ /* If there are forms of indirect addressing that the driver
+ * cannot handle, perform the lowering pass.
+ */
+ if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput
+ || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform)
+ progress =
+ lower_variable_index_to_cond_assign(ir,
+ options->EmitNoIndirectInput,
+ options->EmitNoIndirectOutput,
+ options->EmitNoIndirectTemp,
+ options->EmitNoIndirectUniform)
+ || progress;
+
+ progress = do_vec_index_to_cond_assign(ir) || progress;
+ progress = lower_vector_insert(ir, true) || progress;
+ } while (progress);
+
+ validate_ir_tree(ir);
+ }
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ struct gl_program *linked_prog;
+
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ linked_prog = _mesa_ir_get_program(ctx, prog, prog->_LinkedShaders[i]);
+
+ if (linked_prog) {
+ _mesa_copy_linked_program_data((gl_shader_stage) i, prog, linked_prog);
+
+ _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
+ linked_prog);
+ if (!ctx->Driver.ProgramStringNotify(ctx,
+ _mesa_shader_stage_to_program(i),
+ linked_prog)) {
+ return GL_FALSE;
+ }
+ }
+
+ _mesa_reference_program(ctx, &linked_prog, NULL);
+ }
+
+ return prog->LinkStatus;
+}
+
+/**
+ * Link a GLSL shader program. Called via glLinkProgram().
+ */
+void
+_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+ unsigned int i;
+
+ _mesa_clear_shader_program_data(ctx, prog);
+
+ prog->LinkStatus = GL_TRUE;
+
+ for (i = 0; i < prog->NumShaders; i++) {
+ if (!prog->Shaders[i]->CompileStatus) {
+ linker_error(prog, "linking with uncompiled shader");
+ }
+ }
+
+ /* Search program disk cache if active. */
+ if (ctx->BinaryProgramCacheActive && mesa_program_diskcache_find(ctx, prog) == 0)
+ return;
+
+ if (prog->LinkStatus) {
+ link_shaders(ctx, prog);
+ }
+
+ if (prog->LinkStatus) {
+ if (!ctx->Driver.LinkShader(ctx, prog)) {
+ prog->LinkStatus = GL_FALSE;
+ } else {
+ if (ctx->BinaryProgramCacheActive)
+ mesa_program_diskcache_cache(ctx, prog);
+ prog->_Linked = GL_TRUE;
+ }
+ }
+
+ if (ctx->GlslFlags & GLSL_DUMP) {
+ if (!prog->LinkStatus) {
+ fprintf(stderr, "GLSL shader program %d failed to link\n", prog->Name);
+ }
+
+ if (prog->InfoLog && prog->InfoLog[0] != 0) {
+ fprintf(stderr, "GLSL shader program %d info log:\n", prog->Name);
+ fprintf(stderr, "%s\n", prog->InfoLog);
+ }
+ }
+}
+
+} /* extern "C" */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/ir_to_mesa.h b/icd/intel/compiler/mesa-utils/src/mesa/program/ir_to_mesa.h
new file mode 100644
index 0000000..f450555
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/ir_to_mesa.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "main/glheader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct gl_context;
+struct gl_shader;
+struct gl_shader_program;
+
+void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
+GLboolean _mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader);
+GLboolean _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
+struct gl_program *
+_mesa_ir_get_program(struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_shader *shader);
+
+void
+_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
+ *shader_program,
+ struct gl_shader *sh,
+ struct gl_program_parameter_list
+ *params);
+void
+_mesa_associate_uniform_storage(struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/lex.yy.c b/icd/intel/compiler/mesa-utils/src/mesa/program/lex.yy.c
new file mode 100644
index 0000000..7b058d3
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/lex.yy.c
@@ -0,0 +1,3682 @@
+#line 2 "program/lex.yy.c"
+
+#line 4 "program/lex.yy.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE _mesa_program_lexer_restart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via _mesa_program_lexer_restart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void _mesa_program_lexer_restart (FILE *input_file ,yyscan_t yyscanner );
+void _mesa_program_lexer__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE _mesa_program_lexer__create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void _mesa_program_lexer__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void _mesa_program_lexer__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void _mesa_program_lexer_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void _mesa_program_lexer_pop_buffer_state (yyscan_t yyscanner );
+
+static void _mesa_program_lexer_ensure_buffer_stack (yyscan_t yyscanner );
+static void _mesa_program_lexer__load_buffer_state (yyscan_t yyscanner );
+static void _mesa_program_lexer__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER _mesa_program_lexer__flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE _mesa_program_lexer__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE _mesa_program_lexer__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE _mesa_program_lexer__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *_mesa_program_lexer_alloc (yy_size_t ,yyscan_t yyscanner );
+void *_mesa_program_lexer_realloc (void *,yy_size_t ,yyscan_t yyscanner );
+void _mesa_program_lexer_free (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer _mesa_program_lexer__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ _mesa_program_lexer_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ _mesa_program_lexer__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ _mesa_program_lexer_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ _mesa_program_lexer__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define _mesa_program_lexer_wrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 170
+#define YY_END_OF_BUFFER 171
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[850] =
+ { 0,
+ 0, 0, 171, 169, 167, 166, 169, 169, 139, 165,
+ 141, 141, 141, 141, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 167, 0, 0, 168, 139,
+ 0, 140, 142, 162, 162, 0, 0, 0, 0, 162,
+ 0, 0, 0, 0, 0, 0, 0, 119, 163, 120,
+ 121, 153, 153, 153, 153, 0, 141, 0, 127, 128,
+ 129, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 161, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 160, 160, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 159, 159, 159, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 150, 150, 150, 151, 151, 152, 143,
+ 142, 143, 0, 144, 11, 12, 139, 13, 139, 139,
+ 14, 15, 139, 16, 17, 18, 19, 20, 21, 6,
+
+ 22, 23, 24, 25, 26, 28, 27, 29, 30, 31,
+ 32, 33, 34, 35, 139, 139, 139, 139, 139, 40,
+ 41, 139, 42, 43, 44, 45, 46, 47, 48, 139,
+ 49, 50, 51, 52, 53, 54, 55, 139, 56, 57,
+ 58, 59, 139, 139, 64, 65, 139, 139, 139, 139,
+ 139, 139, 0, 0, 0, 0, 142, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 80, 81, 83,
+ 0, 158, 0, 0, 0, 0, 0, 0, 97, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 157,
+ 156, 156, 109, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 147, 147, 148, 149, 0, 145, 11,
+ 11, 139, 12, 12, 12, 139, 139, 139, 139, 139,
+ 15, 15, 139, 130, 16, 16, 139, 17, 17, 139,
+ 18, 18, 139, 19, 19, 139, 20, 20, 139, 21,
+ 21, 139, 22, 22, 139, 24, 24, 139, 25, 25,
+ 139, 28, 28, 139, 27, 27, 139, 30, 30, 139,
+ 31, 31, 139, 32, 32, 139, 33, 33, 139, 34,
+ 34, 139, 35, 35, 139, 139, 139, 139, 36, 139,
+ 38, 139, 40, 40, 139, 41, 41, 139, 131, 42,
+ 42, 139, 43, 43, 139, 139, 45, 45, 139, 46,
+
+ 46, 139, 47, 47, 139, 48, 48, 139, 139, 49,
+ 49, 139, 50, 50, 139, 51, 51, 139, 52, 52,
+ 139, 53, 53, 139, 54, 54, 139, 139, 10, 56,
+ 139, 57, 139, 58, 139, 59, 139, 60, 139, 62,
+ 139, 64, 64, 139, 139, 139, 139, 139, 139, 139,
+ 139, 0, 164, 0, 0, 0, 73, 74, 0, 0,
+ 0, 0, 0, 0, 0, 85, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 155, 0, 0, 0, 113, 0,
+ 115, 0, 0, 0, 0, 0, 0, 154, 146, 139,
+
+ 139, 139, 4, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 9, 37, 39, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 60, 139, 61, 62, 139, 63, 139, 139, 139, 139,
+ 139, 69, 139, 139, 0, 0, 0, 0, 0, 75,
+ 76, 0, 0, 0, 0, 84, 0, 0, 88, 91,
+ 0, 0, 0, 0, 0, 0, 0, 102, 103, 0,
+ 0, 0, 0, 108, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 139, 139, 139, 139, 139, 139,
+ 5, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 7, 8, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 61, 139, 139, 63, 139, 139,
+ 139, 139, 139, 70, 139, 66, 0, 0, 0, 0,
+ 124, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 94, 0, 98, 99, 0, 101, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 117, 118, 0, 0,
+
+ 125, 11, 3, 12, 135, 136, 139, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 24, 25, 28, 27,
+ 30, 31, 32, 33, 34, 35, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 139, 139, 139, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 139,
+ 139, 139, 139, 64, 65, 139, 68, 126, 0, 0,
+ 71, 0, 77, 0, 0, 0, 86, 0, 0, 0,
+ 0, 0, 0, 100, 0, 0, 106, 93, 0, 0,
+ 0, 0, 0, 0, 122, 0, 139, 132, 133, 139,
+ 60, 139, 62, 139, 67, 0, 0, 0, 0, 79,
+
+ 82, 87, 0, 0, 92, 0, 0, 0, 105, 0,
+ 0, 0, 0, 114, 116, 0, 139, 139, 61, 63,
+ 2, 1, 0, 78, 0, 90, 0, 96, 104, 0,
+ 0, 111, 112, 123, 139, 134, 0, 89, 0, 107,
+ 110, 139, 72, 95, 139, 139, 137, 138, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 1, 6, 7, 1, 1, 1, 1,
+ 1, 1, 8, 1, 8, 9, 1, 10, 11, 12,
+ 13, 14, 15, 15, 15, 15, 15, 1, 1, 1,
+ 1, 1, 1, 1, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 7, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 1, 1, 1, 1, 41, 1, 42, 43, 44, 45,
+
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[68] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 2, 1, 3, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2
+ } ;
+
+static yyconst flex_int16_t yy_base[853] =
+ { 0,
+ 0, 0, 1299, 1300, 66, 1300, 1293, 1294, 0, 69,
+ 85, 128, 140, 152, 151, 58, 56, 63, 76, 1272,
+ 158, 160, 39, 163, 173, 189, 52, 1265, 76, 1235,
+ 1234, 1246, 1230, 1244, 1243, 105, 1272, 1284, 1300, 0,
+ 225, 1300, 218, 160, 157, 20, 123, 66, 119, 192,
+ 1244, 1230, 54, 162, 1228, 1240, 194, 1300, 200, 195,
+ 98, 227, 196, 231, 235, 293, 305, 316, 1300, 1300,
+ 1300, 1249, 1262, 1256, 223, 1245, 1248, 1244, 1259, 107,
+ 298, 1241, 1255, 246, 1241, 1254, 1245, 1258, 1235, 1246,
+ 1237, 182, 1238, 1229, 1238, 1229, 1228, 1229, 144, 1223,
+
+ 1229, 1240, 1231, 1225, 1222, 1223, 1227, 289, 1236, 1223,
+ 302, 1230, 1217, 1231, 1207, 65, 315, 276, 1227, 1226,
+ 1202, 1187, 1182, 1199, 1175, 1180, 1206, 279, 1195, 293,
+ 1190, 342, 299, 1192, 1173, 317, 1183, 1179, 1174, 207,
+ 1180, 1166, 1182, 1179, 1170, 320, 324, 1172, 1161, 1175,
+ 1178, 1160, 1175, 1162, 1159, 1166, 284, 1174, 227, 288,
+ 327, 342, 345, 1151, 1168, 1169, 1162, 1144, 318, 1145,
+ 1167, 1158, 330, 341, 345, 349, 353, 357, 361, 1300,
+ 419, 430, 436, 442, 440, 441, 1191, 0, 1190, 1173,
+ 1163, 443, 1183, 444, 451, 468, 470, 472, 471, 0,
+
+ 496, 0, 497, 498, 0, 499, 500, 0, 524, 525,
+ 526, 536, 537, 553, 1178, 1171, 1184, 354, 356, 561,
+ 563, 1165, 564, 565, 1157, 580, 590, 591, 592, 1178,
+ 593, 617, 618, 619, 629, 630, 1155, 1165, 330, 362,
+ 419, 483, 445, 364, 646, 1153, 1145, 1144, 1129, 1129,
+ 1128, 1127, 1170, 1142, 1130, 662, 669, 643, 1134, 487,
+ 1131, 1125, 1125, 1119, 1132, 1132, 1117, 1300, 1300, 1132,
+ 1120, 646, 1127, 135, 1124, 1130, 561, 1125, 1300, 1116,
+ 1123, 1122, 1125, 1111, 1110, 1114, 1109, 448, 1114, 650,
+ 653, 665, 1300, 1106, 1104, 1104, 1112, 1113, 1095, 670,
+
+ 1100, 1106, 486, 579, 655, 661, 668, 726, 732, 1112,
+ 682, 1119, 1110, 688, 730, 1117, 1116, 1109, 1123, 1113,
+ 1104, 712, 1111, 0, 1102, 731, 1109, 1100, 733, 1107,
+ 1098, 734, 1105, 1096, 736, 1103, 1094, 737, 1101, 1092,
+ 738, 1099, 1090, 739, 1097, 1088, 740, 1095, 1086, 741,
+ 1093, 1084, 742, 1091, 1082, 743, 1089, 1080, 744, 1087,
+ 1078, 745, 1085, 1076, 746, 1083, 1074, 747, 1081, 1072,
+ 748, 1079, 1070, 749, 1077, 1080, 1073, 1080, 0, 1073,
+ 0, 1088, 1063, 750, 1070, 1061, 751, 1068, 0, 1059,
+ 752, 1066, 1057, 755, 1064, 1063, 1054, 758, 1061, 1052,
+
+ 776, 1059, 1050, 777, 1057, 1048, 779, 1055, 1058, 1045,
+ 780, 1052, 1043, 782, 1050, 1041, 783, 1048, 1039, 784,
+ 1046, 1037, 785, 1044, 1035, 786, 1042, 1041, 0, 1032,
+ 1039, 1030, 1037, 1028, 1035, 1026, 1033, 787, 1032, 788,
+ 1047, 1022, 789, 1029, 1028, 1006, 1000, 1005, 1011, 994,
+ 1009, 424, 1300, 1008, 998, 1002, 1300, 1300, 992, 1001,
+ 987, 1004, 987, 990, 984, 1300, 985, 984, 981, 988,
+ 981, 989, 985, 995, 992, 974, 980, 987, 971, 970,
+ 988, 970, 982, 981, 1300, 980, 970, 974, 1300, 961,
+ 1300, 966, 966, 974, 957, 958, 968, 1300, 1300, 1000,
+
+ 982, 998, 0, 798, 996, 996, 995, 994, 993, 992,
+ 991, 990, 989, 988, 987, 986, 985, 984, 983, 982,
+ 981, 980, 979, 978, 965, 958, 0, 0, 0, 975,
+ 974, 973, 972, 971, 970, 969, 968, 967, 945, 965,
+ 964, 963, 962, 961, 960, 959, 958, 957, 956, 955,
+ 929, 936, 793, 927, 934, 794, 950, 949, 918, 921,
+ 901, 0, 902, 895, 902, 901, 902, 894, 912, 1300,
+ 1300, 894, 892, 902, 895, 1300, 890, 907, 516, 1300,
+ 898, 882, 883, 892, 883, 882, 882, 1300, 881, 890,
+ 880, 896, 893, 1300, 892, 890, 879, 880, 876, 868,
+
+ 875, 870, 871, 866, 892, 892, 890, 904, 903, 898,
+ 0, 886, 885, 884, 883, 882, 881, 880, 879, 878,
+ 877, 876, 875, 874, 873, 872, 871, 870, 869, 868,
+ 0, 0, 867, 866, 865, 864, 863, 862, 861, 860,
+ 859, 804, 858, 857, 856, 855, 854, 853, 852, 851,
+ 850, 849, 848, 865, 839, 846, 862, 836, 843, 841,
+ 840, 818, 818, 0, 825, 0, 859, 858, 807, 825,
+ 1300, 820, 815, 808, 804, 816, 806, 804, 800, 816,
+ 807, 806, 1300, 1300, 809, 1300, 804, 797, 786, 797,
+ 789, 793, 806, 801, 804, 786, 1300, 1300, 798, 787,
+
+ 1300, 0, 0, 0, 0, 0, 826, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 814, 813, 802, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 785,
+ 798, 779, 792, 0, 0, 656, 0, 0, 706, 702,
+ 1300, 649, 1300, 648, 648, 654, 1300, 637, 645, 610,
+ 612, 608, 608, 1300, 572, 583, 1300, 1300, 577, 573,
+ 560, 557, 542, 555, 1300, 539, 573, 0, 0, 572,
+ 0, 555, 0, 546, 0, 562, 551, 495, 479, 1300,
+
+ 1300, 1300, 481, 481, 1300, 480, 443, 31, 1300, 141,
+ 166, 171, 186, 1300, 1300, 211, 236, 276, 0, 0,
+ 1300, 1300, 290, 1300, 325, 1300, 346, 1300, 1300, 343,
+ 341, 1300, 1300, 1300, 365, 0, 380, 1300, 371, 1300,
+ 1300, 486, 1300, 1300, 451, 458, 0, 0, 1300, 836,
+ 503, 839
+ } ;
+
+static yyconst flex_int16_t yy_def[853] =
+ { 0,
+ 849, 1, 849, 849, 849, 849, 849, 850, 851, 849,
+ 849, 849, 849, 849, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 849, 849, 850, 849, 851,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 852, 849, 849, 849, 849,
+ 849, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 851,
+
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+
+ 849, 849, 849, 849, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+
+ 849, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 851, 851, 851, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 851, 851, 851, 851,
+ 851, 851, 851, 851, 851, 849, 849, 849, 849, 849,
+
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 851, 851, 851, 851,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 851, 851, 849, 849, 849, 849,
+ 849, 851, 849, 849, 851, 851, 851, 851, 0, 849,
+ 849, 849
+ } ;
+
+static yyconst flex_int16_t yy_nxt[1368] =
+ { 0,
+ 4, 5, 6, 5, 7, 8, 9, 4, 10, 11,
+ 12, 13, 14, 11, 11, 15, 9, 16, 17, 18,
+ 19, 9, 9, 9, 20, 21, 22, 9, 23, 24,
+ 9, 25, 26, 27, 28, 9, 9, 29, 9, 9,
+ 9, 9, 9, 9, 9, 9, 30, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 31, 9, 32, 33,
+ 34, 9, 35, 9, 9, 9, 9, 36, 96, 36,
+ 41, 116, 137, 97, 80, 138, 829, 42, 43, 43,
+ 43, 43, 43, 43, 77, 81, 78, 119, 82, 117,
+ 83, 238, 79, 66, 67, 67, 67, 67, 67, 67,
+
+ 84, 85, 239, 150, 68, 120, 36, 86, 36, 151,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 141,
+ 142, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 68, 143, 62, 63, 64, 65, 66, 67, 67, 67,
+ 67, 67, 67, 170, 194, 195, 69, 68, 66, 67,
+ 67, 67, 67, 67, 67, 218, 171, 219, 70, 68,
+ 66, 67, 67, 67, 67, 67, 67, 72, 139, 73,
+ 71, 68, 140, 68, 144, 92, 74, 145, 98, 88,
+ 467, 89, 75, 93, 76, 68, 90, 99, 94, 91,
+ 101, 100, 102, 103, 95, 468, 830, 68, 136, 133,
+
+ 210, 133, 133, 152, 133, 104, 105, 133, 106, 107,
+ 108, 109, 110, 134, 111, 133, 112, 153, 133, 211,
+ 135, 831, 113, 114, 154, 115, 41, 43, 43, 43,
+ 43, 43, 43, 146, 147, 157, 832, 132, 165, 133,
+ 166, 161, 162, 167, 168, 833, 158, 163, 188, 159,
+ 133, 169, 160, 265, 189, 164, 834, 201, 133, 174,
+ 173, 175, 176, 132, 835, 266, 128, 129, 46, 47,
+ 48, 49, 172, 51, 52, 202, 285, 53, 54, 55,
+ 56, 57, 58, 130, 60, 61, 286, 243, 131, 244,
+ 173, 173, 173, 173, 177, 173, 173, 178, 179, 173,
+
+ 173, 173, 181, 181, 181, 181, 181, 181, 228, 836,
+ 196, 197, 182, 66, 67, 67, 67, 67, 67, 67,
+ 198, 232, 229, 183, 68, 184, 184, 184, 184, 184,
+ 184, 240, 134, 241, 255, 233, 282, 287, 182, 135,
+ 258, 258, 283, 288, 242, 837, 258, 430, 164, 256,
+ 68, 257, 257, 257, 257, 257, 257, 258, 258, 258,
+ 261, 258, 258, 298, 258, 272, 258, 258, 258, 258,
+ 431, 258, 381, 299, 258, 258, 379, 838, 258, 432,
+ 440, 289, 258, 290, 258, 258, 291, 292, 380, 258,
+ 382, 839, 258, 303, 303, 303, 303, 840, 441, 841,
+
+ 258, 842, 433, 258, 303, 303, 303, 303, 304, 303,
+ 303, 305, 306, 303, 303, 303, 303, 303, 303, 303,
+ 307, 303, 303, 303, 303, 303, 303, 303, 43, 43,
+ 43, 43, 43, 43, 843, 844, 434, 308, 132, 309,
+ 309, 309, 309, 309, 309, 184, 184, 184, 184, 184,
+ 184, 184, 184, 184, 184, 184, 184, 310, 313, 435,
+ 321, 325, 311, 314, 132, 322, 326, 438, 328, 847,
+ 565, 311, 315, 329, 322, 326, 848, 311, 314, 439,
+ 312, 316, 329, 323, 327, 331, 566, 334, 340, 337,
+ 332, 330, 335, 341, 338, 482, 845, 846, 483, 332,
+
+ 436, 335, 341, 338, 40, 332, 828, 335, 333, 338,
+ 336, 342, 339, 343, 346, 349, 352, 355, 344, 347,
+ 350, 353, 356, 437, 827, 826, 825, 344, 347, 350,
+ 353, 356, 455, 824, 347, 350, 345, 348, 351, 354,
+ 357, 358, 361, 364, 823, 456, 359, 362, 365, 498,
+ 498, 498, 498, 367, 370, 359, 362, 365, 368, 371,
+ 822, 359, 362, 365, 360, 363, 366, 368, 371, 678,
+ 373, 821, 679, 368, 371, 374, 369, 372, 383, 820,
+ 386, 390, 393, 384, 374, 387, 391, 394, 819, 818,
+ 374, 817, 384, 375, 387, 391, 394, 397, 816, 815,
+
+ 814, 385, 398, 388, 392, 395, 471, 400, 403, 406,
+ 410, 398, 401, 404, 407, 411, 813, 398, 812, 472,
+ 399, 401, 404, 407, 411, 811, 810, 401, 404, 407,
+ 402, 405, 408, 412, 413, 416, 419, 809, 808, 414,
+ 417, 420, 498, 498, 498, 498, 422, 425, 414, 417,
+ 420, 423, 426, 807, 414, 417, 420, 415, 418, 421,
+ 423, 426, 806, 442, 805, 804, 423, 426, 443, 424,
+ 427, 257, 257, 257, 257, 257, 257, 443, 257, 257,
+ 257, 257, 257, 257, 453, 453, 444, 453, 453, 803,
+ 453, 453, 453, 453, 453, 453, 802, 453, 801, 310,
+
+ 453, 453, 800, 799, 453, 313, 485, 453, 453, 798,
+ 797, 453, 453, 492, 796, 493, 795, 494, 499, 498,
+ 498, 498, 312, 453, 498, 498, 498, 498, 316, 321,
+ 495, 498, 498, 498, 498, 309, 309, 309, 309, 309,
+ 309, 309, 309, 309, 309, 309, 309, 313, 325, 501,
+ 328, 331, 323, 334, 337, 340, 343, 346, 349, 352,
+ 355, 358, 361, 364, 367, 370, 373, 383, 386, 390,
+ 316, 327, 393, 330, 333, 397, 336, 339, 342, 345,
+ 348, 351, 354, 357, 360, 363, 366, 369, 372, 375,
+ 385, 388, 392, 400, 403, 395, 406, 410, 399, 413,
+
+ 416, 419, 422, 425, 551, 554, 442, 794, 608, 609,
+ 655, 658, 793, 792, 736, 737, 402, 405, 791, 408,
+ 412, 790, 415, 418, 421, 424, 427, 552, 555, 444,
+ 610, 789, 788, 656, 659, 738, 38, 38, 38, 180,
+ 180, 787, 786, 785, 784, 783, 782, 781, 780, 779,
+ 778, 777, 776, 775, 774, 773, 772, 771, 770, 769,
+ 768, 767, 766, 765, 764, 763, 762, 761, 760, 759,
+ 758, 757, 756, 755, 754, 753, 659, 752, 751, 656,
+ 750, 749, 748, 747, 746, 745, 744, 743, 742, 741,
+ 740, 739, 735, 734, 733, 732, 731, 730, 729, 728,
+
+ 727, 726, 725, 724, 723, 722, 721, 720, 719, 718,
+ 717, 716, 715, 714, 713, 712, 711, 710, 709, 708,
+ 707, 706, 705, 704, 703, 702, 701, 700, 699, 698,
+ 697, 696, 695, 694, 693, 692, 691, 690, 689, 688,
+ 687, 686, 685, 684, 683, 682, 681, 680, 677, 676,
+ 675, 674, 673, 672, 671, 670, 669, 668, 667, 666,
+ 665, 664, 663, 662, 661, 660, 657, 555, 654, 552,
+ 653, 652, 651, 650, 649, 648, 647, 646, 645, 644,
+ 643, 642, 641, 640, 639, 638, 637, 636, 635, 634,
+ 633, 632, 631, 630, 629, 628, 627, 626, 625, 624,
+
+ 623, 622, 621, 620, 619, 618, 617, 616, 615, 614,
+ 613, 612, 611, 607, 606, 605, 604, 603, 602, 601,
+ 600, 599, 598, 597, 596, 595, 594, 593, 592, 591,
+ 590, 589, 588, 587, 586, 585, 584, 583, 582, 581,
+ 580, 579, 578, 577, 576, 575, 574, 573, 572, 571,
+ 570, 569, 568, 567, 564, 563, 562, 561, 560, 559,
+ 558, 557, 444, 556, 553, 550, 437, 549, 435, 548,
+ 433, 547, 431, 546, 545, 427, 544, 424, 543, 421,
+ 542, 418, 541, 415, 540, 412, 539, 538, 408, 537,
+ 405, 536, 402, 535, 399, 534, 533, 395, 532, 392,
+
+ 531, 388, 530, 385, 529, 528, 527, 526, 525, 524,
+ 375, 523, 372, 522, 369, 521, 366, 520, 363, 519,
+ 360, 518, 357, 517, 354, 516, 351, 515, 348, 514,
+ 345, 513, 342, 512, 339, 511, 336, 510, 333, 509,
+ 330, 508, 327, 507, 323, 506, 505, 504, 503, 502,
+ 316, 500, 312, 497, 496, 491, 490, 489, 488, 487,
+ 486, 484, 481, 480, 479, 478, 477, 476, 475, 474,
+ 473, 470, 469, 466, 465, 464, 463, 462, 461, 460,
+ 459, 458, 457, 454, 289, 261, 452, 451, 450, 449,
+ 448, 447, 446, 445, 429, 428, 409, 396, 389, 378,
+
+ 377, 376, 324, 320, 319, 318, 317, 302, 301, 300,
+ 297, 296, 295, 294, 293, 284, 281, 280, 279, 278,
+ 277, 276, 275, 274, 273, 271, 270, 269, 268, 267,
+ 264, 263, 262, 260, 259, 172, 254, 253, 252, 251,
+ 250, 249, 248, 247, 246, 245, 237, 236, 235, 234,
+ 231, 230, 227, 226, 225, 224, 223, 222, 221, 220,
+ 217, 216, 215, 214, 213, 212, 209, 208, 207, 206,
+ 205, 204, 203, 200, 199, 193, 192, 191, 190, 187,
+ 186, 185, 156, 155, 149, 148, 39, 127, 126, 125,
+ 124, 123, 122, 121, 118, 87, 39, 37, 849, 3,
+
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849
+ } ;
+
+static yyconst flex_int16_t yy_chk[1368] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 5, 23, 5,
+ 10, 27, 46, 23, 17, 46, 808, 10, 10, 10,
+ 10, 10, 10, 10, 16, 17, 16, 29, 17, 27,
+ 18, 116, 16, 11, 11, 11, 11, 11, 11, 11,
+
+ 18, 19, 116, 53, 11, 29, 36, 19, 36, 53,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 48,
+ 48, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 48, 10, 10, 10, 10, 12, 12, 12, 12,
+ 12, 12, 12, 61, 80, 80, 12, 12, 13, 13,
+ 13, 13, 13, 13, 13, 99, 61, 99, 13, 13,
+ 14, 14, 14, 14, 14, 14, 14, 15, 47, 15,
+ 14, 14, 47, 12, 49, 22, 15, 49, 24, 21,
+ 274, 21, 15, 22, 15, 13, 21, 24, 22, 21,
+ 25, 24, 25, 25, 22, 274, 810, 14, 45, 45,
+
+ 92, 44, 44, 54, 45, 25, 26, 44, 26, 26,
+ 26, 26, 26, 44, 26, 45, 26, 54, 44, 92,
+ 44, 811, 26, 26, 54, 26, 41, 43, 43, 43,
+ 43, 43, 43, 50, 50, 57, 812, 43, 60, 50,
+ 60, 59, 59, 60, 60, 813, 57, 59, 75, 57,
+ 50, 60, 57, 140, 75, 59, 816, 84, 59, 63,
+ 63, 63, 63, 43, 817, 140, 41, 41, 41, 41,
+ 41, 41, 62, 41, 41, 84, 159, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 159, 118, 41, 118,
+ 62, 62, 62, 62, 64, 64, 64, 64, 65, 65,
+
+ 65, 65, 66, 66, 66, 66, 66, 66, 108, 818,
+ 81, 81, 66, 67, 67, 67, 67, 67, 67, 67,
+ 81, 111, 108, 68, 67, 68, 68, 68, 68, 68,
+ 68, 117, 128, 117, 130, 111, 157, 160, 66, 128,
+ 133, 133, 157, 160, 117, 823, 133, 239, 130, 132,
+ 67, 132, 132, 132, 132, 132, 132, 133, 136, 136,
+ 136, 146, 146, 169, 136, 147, 147, 146, 161, 161,
+ 239, 147, 219, 169, 161, 136, 218, 825, 146, 240,
+ 244, 161, 147, 162, 162, 161, 163, 163, 218, 162,
+ 219, 827, 163, 173, 173, 173, 173, 830, 244, 831,
+
+ 162, 835, 240, 163, 174, 174, 174, 174, 175, 175,
+ 175, 175, 176, 176, 176, 176, 177, 177, 177, 177,
+ 178, 178, 178, 178, 179, 179, 179, 179, 181, 181,
+ 181, 181, 181, 181, 837, 839, 241, 182, 181, 182,
+ 182, 182, 182, 182, 182, 183, 183, 183, 183, 183,
+ 183, 184, 184, 184, 184, 184, 184, 185, 186, 241,
+ 192, 194, 185, 186, 181, 192, 194, 243, 195, 845,
+ 452, 185, 186, 195, 192, 194, 846, 185, 186, 243,
+ 185, 186, 195, 192, 194, 196, 452, 197, 199, 198,
+ 196, 195, 197, 199, 198, 288, 842, 842, 288, 196,
+
+ 242, 197, 199, 198, 851, 196, 807, 197, 196, 198,
+ 197, 199, 198, 201, 203, 204, 206, 207, 201, 203,
+ 204, 206, 207, 242, 806, 804, 803, 201, 203, 204,
+ 206, 207, 260, 799, 203, 204, 201, 203, 204, 206,
+ 207, 209, 210, 211, 798, 260, 209, 210, 211, 303,
+ 303, 303, 303, 212, 213, 209, 210, 211, 212, 213,
+ 797, 209, 210, 211, 209, 210, 211, 212, 213, 579,
+ 214, 796, 579, 212, 213, 214, 212, 213, 220, 794,
+ 221, 223, 224, 220, 214, 221, 223, 224, 792, 790,
+ 214, 787, 220, 214, 221, 223, 224, 226, 786, 784,
+
+ 783, 220, 226, 221, 223, 224, 277, 227, 228, 229,
+ 231, 226, 227, 228, 229, 231, 782, 226, 781, 277,
+ 226, 227, 228, 229, 231, 780, 779, 227, 228, 229,
+ 227, 228, 229, 231, 232, 233, 234, 776, 775, 232,
+ 233, 234, 304, 304, 304, 304, 235, 236, 232, 233,
+ 234, 235, 236, 773, 232, 233, 234, 232, 233, 234,
+ 235, 236, 772, 245, 771, 770, 235, 236, 245, 235,
+ 236, 256, 256, 256, 256, 256, 256, 245, 257, 257,
+ 257, 257, 257, 257, 258, 258, 245, 272, 272, 769,
+ 258, 290, 290, 272, 291, 291, 768, 290, 766, 311,
+
+ 291, 258, 765, 764, 272, 314, 292, 292, 290, 762,
+ 760, 291, 292, 300, 759, 300, 756, 300, 305, 305,
+ 305, 305, 311, 292, 306, 306, 306, 306, 314, 322,
+ 300, 307, 307, 307, 307, 308, 308, 308, 308, 308,
+ 308, 309, 309, 309, 309, 309, 309, 315, 326, 315,
+ 329, 332, 322, 335, 338, 341, 344, 347, 350, 353,
+ 356, 359, 362, 365, 368, 371, 374, 384, 387, 391,
+ 315, 326, 394, 329, 332, 398, 335, 338, 341, 344,
+ 347, 350, 353, 356, 359, 362, 365, 368, 371, 374,
+ 384, 387, 391, 401, 404, 394, 407, 411, 398, 414,
+
+ 417, 420, 423, 426, 438, 440, 443, 753, 504, 504,
+ 553, 556, 752, 751, 642, 642, 401, 404, 750, 407,
+ 411, 738, 414, 417, 420, 423, 426, 438, 440, 443,
+ 504, 737, 736, 553, 556, 642, 850, 850, 850, 852,
+ 852, 707, 700, 699, 696, 695, 694, 693, 692, 691,
+ 690, 689, 688, 687, 685, 682, 681, 680, 679, 678,
+ 677, 676, 675, 674, 673, 672, 670, 669, 668, 667,
+ 665, 663, 662, 661, 660, 659, 658, 657, 656, 655,
+ 654, 653, 652, 651, 650, 649, 648, 647, 646, 645,
+ 644, 643, 641, 640, 639, 638, 637, 636, 635, 634,
+
+ 633, 630, 629, 628, 627, 626, 625, 624, 623, 622,
+ 621, 620, 619, 618, 617, 616, 615, 614, 613, 612,
+ 610, 609, 608, 607, 606, 605, 604, 603, 602, 601,
+ 600, 599, 598, 597, 596, 595, 593, 592, 591, 590,
+ 589, 587, 586, 585, 584, 583, 582, 581, 578, 577,
+ 575, 574, 573, 572, 569, 568, 567, 566, 565, 564,
+ 563, 561, 560, 559, 558, 557, 555, 554, 552, 551,
+ 550, 549, 548, 547, 546, 545, 544, 543, 542, 541,
+ 540, 539, 538, 537, 536, 535, 534, 533, 532, 531,
+ 530, 526, 525, 524, 523, 522, 521, 520, 519, 518,
+
+ 517, 516, 515, 514, 513, 512, 511, 510, 509, 508,
+ 507, 506, 505, 502, 501, 500, 497, 496, 495, 494,
+ 493, 492, 490, 488, 487, 486, 484, 483, 482, 481,
+ 480, 479, 478, 477, 476, 475, 474, 473, 472, 471,
+ 470, 469, 468, 467, 465, 464, 463, 462, 461, 460,
+ 459, 456, 455, 454, 451, 450, 449, 448, 447, 446,
+ 445, 444, 442, 441, 439, 437, 436, 435, 434, 433,
+ 432, 431, 430, 428, 427, 425, 424, 422, 421, 419,
+ 418, 416, 415, 413, 412, 410, 409, 408, 406, 405,
+ 403, 402, 400, 399, 397, 396, 395, 393, 392, 390,
+
+ 388, 386, 385, 383, 382, 380, 378, 377, 376, 375,
+ 373, 372, 370, 369, 367, 366, 364, 363, 361, 360,
+ 358, 357, 355, 354, 352, 351, 349, 348, 346, 345,
+ 343, 342, 340, 339, 337, 336, 334, 333, 331, 330,
+ 328, 327, 325, 323, 321, 320, 319, 318, 317, 316,
+ 313, 312, 310, 302, 301, 299, 298, 297, 296, 295,
+ 294, 289, 287, 286, 285, 284, 283, 282, 281, 280,
+ 278, 276, 275, 273, 271, 270, 267, 266, 265, 264,
+ 263, 262, 261, 259, 255, 254, 253, 252, 251, 250,
+ 249, 248, 247, 246, 238, 237, 230, 225, 222, 217,
+
+ 216, 215, 193, 191, 190, 189, 187, 172, 171, 170,
+ 168, 167, 166, 165, 164, 158, 156, 155, 154, 153,
+ 152, 151, 150, 149, 148, 145, 144, 143, 142, 141,
+ 139, 138, 137, 135, 134, 131, 129, 127, 126, 125,
+ 124, 123, 122, 121, 120, 119, 115, 114, 113, 112,
+ 110, 109, 107, 106, 105, 104, 103, 102, 101, 100,
+ 98, 97, 96, 95, 94, 93, 91, 90, 89, 88,
+ 87, 86, 85, 83, 82, 79, 78, 77, 76, 74,
+ 73, 72, 56, 55, 52, 51, 38, 37, 35, 34,
+ 33, 32, 31, 30, 28, 20, 8, 7, 3, 849,
+
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "program/program_lexer.l"
+#line 2 "program/program_lexer.l"
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "program/prog_instruction.h"
+#include "program/prog_statevars.h"
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+#include "program/program_parse.tab.h"
+
+#define require_ARB_vp (yyextra->mode == ARB_vertex)
+#define require_ARB_fp (yyextra->mode == ARB_fragment)
+#define require_NV_fp (yyextra->option.NV_fragment)
+#define require_shadow (yyextra->option.Shadow)
+#define require_rect (yyextra->option.TexRect)
+#define require_texarray (yyextra->option.TexArray)
+
+#ifndef HAVE_UNISTD_H
+#define YY_NO_UNISTD_H
+#endif
+
+#define return_token_or_IDENTIFIER(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ return handle_ident(yyextra, yytext, yylval); \
+ } \
+ } while (0)
+
+#define return_token_or_DOT(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ yyless(1); \
+ return DOT; \
+ } \
+ } while (0)
+
+
+#define return_opcode(condition, token, opcode, len) \
+ do { \
+ if (condition && \
+ _mesa_parse_instruction_suffix(yyextra, \
+ yytext + len, \
+ & yylval->temp_inst)) { \
+ yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
+ return token; \
+ } else { \
+ return handle_ident(yyextra, yytext, yylval); \
+ } \
+ } while (0)
+
+#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
+ SWIZZLE_NIL, SWIZZLE_NIL)
+
+static unsigned
+mask_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return WRITEMASK_X;
+ case 'y':
+ case 'g':
+ return WRITEMASK_Y;
+ case 'z':
+ case 'b':
+ return WRITEMASK_Z;
+ case 'w':
+ case 'a':
+ return WRITEMASK_W;
+ }
+
+ return 0;
+}
+
+static unsigned
+swiz_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return SWIZZLE_X;
+ case 'y':
+ case 'g':
+ return SWIZZLE_Y;
+ case 'z':
+ case 'b':
+ return SWIZZLE_Z;
+ case 'w':
+ case 'a':
+ return SWIZZLE_W;
+ }
+
+ return 0;
+}
+
+static int
+handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
+{
+ lval->string = strdup(text);
+
+ return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
+ ? IDENTIFIER : USED_IDENTIFIER;
+}
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->first_column = yylloc->last_column; \
+ yylloc->last_column += yyleng; \
+ if ((yylloc->first_line == 1) \
+ && (yylloc->first_column == 1)) { \
+ yylloc->position = 1; \
+ } else { \
+ yylloc->position += yylloc->last_column - yylloc->first_column; \
+ } \
+ } while(0);
+
+#define YY_NO_INPUT
+
+/* Yes, this is intentionally doing nothing. We have this line of code
+here only to avoid the compiler complaining about an unput function
+that is defined, but never called. */
+#define YY_USER_INIT while (0) { unput(0); }
+
+#define YY_EXTRA_TYPE struct asm_parser_state *
+
+/* Flex defines a couple of functions with no declarations nor the
+static keyword. Declare them here to avoid a compiler warning. */
+int _mesa_program_lexer_get_column (yyscan_t yyscanner);
+void _mesa_program_lexer_set_column (int column_no , yyscan_t yyscanner);
+
+#line 1178 "program/lex.yy.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ YYSTYPE * yylval_r;
+
+ YYLTYPE * yylloc_r;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+ /* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+ # define yylval yyg->yylval_r
+
+ # define yylloc yyg->yylloc_r
+
+int _mesa_program_lexer_lex_init (yyscan_t* scanner);
+
+int _mesa_program_lexer_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int _mesa_program_lexer_lex_destroy (yyscan_t yyscanner );
+
+int _mesa_program_lexer_get_debug (yyscan_t yyscanner );
+
+void _mesa_program_lexer_set_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE _mesa_program_lexer_get_extra (yyscan_t yyscanner );
+
+void _mesa_program_lexer_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *_mesa_program_lexer_get_in (yyscan_t yyscanner );
+
+void _mesa_program_lexer_set_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *_mesa_program_lexer_get_out (yyscan_t yyscanner );
+
+void _mesa_program_lexer_set_out (FILE * out_str ,yyscan_t yyscanner );
+
+int _mesa_program_lexer_get_leng (yyscan_t yyscanner );
+
+char *_mesa_program_lexer_get_text (yyscan_t yyscanner );
+
+int _mesa_program_lexer_get_lineno (yyscan_t yyscanner );
+
+void _mesa_program_lexer_set_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * _mesa_program_lexer_get_lval (yyscan_t yyscanner );
+
+void _mesa_program_lexer_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+ YYLTYPE *_mesa_program_lexer_get_lloc (yyscan_t yyscanner );
+
+ void _mesa_program_lexer_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int _mesa_program_lexer_wrap (yyscan_t yyscanner );
+#else
+extern int _mesa_program_lexer_wrap (yyscan_t yyscanner );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int _mesa_program_lexer_lex \
+ (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int _mesa_program_lexer_lex \
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 170 "program/program_lexer.l"
+
+
+#line 1427 "program/lex.yy.c"
+
+ yylval = yylval_param;
+
+ yylloc = yylloc_param;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ _mesa_program_lexer_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ _mesa_program_lexer__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ _mesa_program_lexer__load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 850 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 1300 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 172 "program/program_lexer.l"
+{ return ARBvp_10; }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 173 "program/program_lexer.l"
+{ return ARBfp_10; }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 174 "program/program_lexer.l"
+{
+ yylval->integer = at_address;
+ return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 178 "program/program_lexer.l"
+{ return ALIAS; }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 179 "program/program_lexer.l"
+{ return ATTRIB; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 180 "program/program_lexer.l"
+{ return END; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 181 "program/program_lexer.l"
+{ return OPTION; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 182 "program/program_lexer.l"
+{ return OUTPUT; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 183 "program/program_lexer.l"
+{ return PARAM; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 184 "program/program_lexer.l"
+{ yylval->integer = at_temp; return TEMP; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 186 "program/program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, ABS, 3); }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 187 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, ADD, 3); }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 188 "program/program_lexer.l"
+{ return_opcode(require_ARB_vp, ARL, ARL, 3); }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 190 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 191 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 193 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 194 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 195 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, DP3, 3); }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 196 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, DP4, 3); }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 197 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, DPH, 3); }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 198 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, DST, 3); }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 200 "program/program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, EX2, 3); }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 201 "program/program_lexer.l"
+{ return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 203 "program/program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, FLR, 3); }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 204 "program/program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, FRC, 3); }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 206 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, KIL, KIL, 3); }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 208 "program/program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, LIT, 3); }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 209 "program/program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, LG2, 3); }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 210 "program/program_lexer.l"
+{ return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 211 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 213 "program/program_lexer.l"
+{ return_opcode( 1, TRI_OP, MAD, 3); }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 214 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, MAX, 3); }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 215 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, MIN, 3); }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 216 "program/program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, MOV, 3); }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 217 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, MUL, 3); }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 219 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 220 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 221 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 222 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 223 "program/program_lexer.l"
+{ return_opcode( 1, BINSC_OP, POW, 3); }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 225 "program/program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, RCP, 3); }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 226 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, BIN_OP, RFL, 3); }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 227 "program/program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, RSQ, 3); }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 229 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 230 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, BIN_OP, SEQ, 3); }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 231 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, BIN_OP, SFL, 3); }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 232 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, SGE, 3); }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 233 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 234 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 235 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 236 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, SLT, 3); }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 237 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, BIN_OP, SNE, 3); }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 238 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, BIN_OP, STR, 3); }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 239 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, SUB, 3); }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 240 "program/program_lexer.l"
+{ return_opcode( 1, SWZ, SWZ, 3); }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 242 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 243 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 244 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 245 "program/program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 247 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 248 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 249 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 250 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 252 "program/program_lexer.l"
+{ return_opcode(require_NV_fp, TRI_OP, X2D, 3); }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 253 "program/program_lexer.l"
+{ return_opcode( 1, BIN_OP, XPD, 3); }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 255 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 256 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 257 "program/program_lexer.l"
+{ return PROGRAM; }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 258 "program/program_lexer.l"
+{ return STATE; }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 259 "program/program_lexer.l"
+{ return RESULT; }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 261 "program/program_lexer.l"
+{ return AMBIENT; }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 262 "program/program_lexer.l"
+{ return ATTENUATION; }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 263 "program/program_lexer.l"
+{ return BACK; }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 264 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, CLIP); }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 265 "program/program_lexer.l"
+{ return COLOR; }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 266 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, DEPTH); }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 267 "program/program_lexer.l"
+{ return DIFFUSE; }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 268 "program/program_lexer.l"
+{ return DIRECTION; }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 269 "program/program_lexer.l"
+{ return EMISSION; }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 270 "program/program_lexer.l"
+{ return ENV; }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 271 "program/program_lexer.l"
+{ return EYE; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 272 "program/program_lexer.l"
+{ return FOGCOORD; }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 273 "program/program_lexer.l"
+{ return FOG; }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 274 "program/program_lexer.l"
+{ return FRONT; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 275 "program/program_lexer.l"
+{ return HALF; }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 276 "program/program_lexer.l"
+{ return INVERSE; }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 277 "program/program_lexer.l"
+{ return INVTRANS; }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 278 "program/program_lexer.l"
+{ return LIGHT; }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 279 "program/program_lexer.l"
+{ return LIGHTMODEL; }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 280 "program/program_lexer.l"
+{ return LIGHTPROD; }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 281 "program/program_lexer.l"
+{ return LOCAL; }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 282 "program/program_lexer.l"
+{ return MATERIAL; }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 283 "program/program_lexer.l"
+{ return MAT_PROGRAM; }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 284 "program/program_lexer.l"
+{ return MATRIX; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 285 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 286 "program/program_lexer.l"
+{ return MODELVIEW; }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 287 "program/program_lexer.l"
+{ return MVP; }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 288 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, NORMAL); }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 289 "program/program_lexer.l"
+{ return OBJECT; }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 290 "program/program_lexer.l"
+{ return PALETTE; }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 291 "program/program_lexer.l"
+{ return PARAMS; }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 292 "program/program_lexer.l"
+{ return PLANE; }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 293 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, POINT_TOK); }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 294 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, POINTSIZE); }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 295 "program/program_lexer.l"
+{ return POSITION; }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 296 "program/program_lexer.l"
+{ return PRIMARY; }
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 297 "program/program_lexer.l"
+{ return PROJECTION; }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 298 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, RANGE); }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 299 "program/program_lexer.l"
+{ return ROW; }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 300 "program/program_lexer.l"
+{ return SCENECOLOR; }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 301 "program/program_lexer.l"
+{ return SECONDARY; }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 302 "program/program_lexer.l"
+{ return SHININESS; }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 303 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 304 "program/program_lexer.l"
+{ return SPECULAR; }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 305 "program/program_lexer.l"
+{ return SPOT; }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 306 "program/program_lexer.l"
+{ return TEXCOORD; }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 307 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, TEXENV); }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 308 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN); }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 309 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 310 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 311 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 312 "program/program_lexer.l"
+{ return TEXTURE; }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 313 "program/program_lexer.l"
+{ return TRANSPOSE; }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 314 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 315 "program/program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, WEIGHT); }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 317 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 318 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 319 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 320 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 321 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 322 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 323 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 324 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 325 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 326 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 327 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 328 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 329 "program/program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 331 "program/program_lexer.l"
+{ return handle_ident(yyextra, yytext, yylval); }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 333 "program/program_lexer.l"
+{ return DOT_DOT; }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 335 "program/program_lexer.l"
+{
+ yylval->integer = strtol(yytext, NULL, 10);
+ return INTEGER;
+}
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 339 "program/program_lexer.l"
+{
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 143:
+/* rule 143 can match eol */
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 343 "program/program_lexer.l"
+{
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 347 "program/program_lexer.l"
+{
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 351 "program/program_lexer.l"
+{
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 356 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return MASK4;
+}
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 362 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return MASK3;
+}
+ YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 368 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return MASK3;
+}
+ YY_BREAK
+case 149:
+YY_RULE_SETUP
+#line 373 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return MASK3;
+}
+ YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 379 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+ YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 385 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+ YY_BREAK
+case 152:
+YY_RULE_SETUP
+#line 391 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return MASK2;
+}
+ YY_BREAK
+case 153:
+YY_RULE_SETUP
+#line 397 "program/program_lexer.l"
+{
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return MASK1;
+}
+ YY_BREAK
+case 154:
+YY_RULE_SETUP
+#line 404 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return SWIZZLE;
+}
+ YY_BREAK
+case 155:
+YY_RULE_SETUP
+#line 413 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return_token_or_DOT(require_ARB_fp, MASK4);
+}
+ YY_BREAK
+case 156:
+YY_RULE_SETUP
+#line 419 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+ YY_BREAK
+case 157:
+YY_RULE_SETUP
+#line 425 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+ YY_BREAK
+case 158:
+YY_RULE_SETUP
+#line 430 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+ YY_BREAK
+case 159:
+YY_RULE_SETUP
+#line 436 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+ YY_BREAK
+case 160:
+YY_RULE_SETUP
+#line 442 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+ YY_BREAK
+case 161:
+YY_RULE_SETUP
+#line 448 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+ YY_BREAK
+case 162:
+YY_RULE_SETUP
+#line 454 "program/program_lexer.l"
+{
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return_token_or_DOT(require_ARB_fp, MASK1);
+}
+ YY_BREAK
+case 163:
+YY_RULE_SETUP
+#line 462 "program/program_lexer.l"
+{
+ if (require_ARB_vp) {
+ return TEXGEN_R;
+ } else {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
+ SWIZZLE_X, SWIZZLE_X);
+ yylval->swiz_mask.mask = WRITEMASK_X;
+ return MASK1;
+ }
+}
+ YY_BREAK
+case 164:
+YY_RULE_SETUP
+#line 473 "program/program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return_token_or_DOT(require_ARB_fp, SWIZZLE);
+}
+ YY_BREAK
+case 165:
+YY_RULE_SETUP
+#line 482 "program/program_lexer.l"
+{ return DOT; }
+ YY_BREAK
+case 166:
+/* rule 166 can match eol */
+YY_RULE_SETUP
+#line 484 "program/program_lexer.l"
+{
+ yylloc->first_line++;
+ yylloc->first_column = 1;
+ yylloc->last_line++;
+ yylloc->last_column = 1;
+ yylloc->position++;
+}
+ YY_BREAK
+case 167:
+YY_RULE_SETUP
+#line 491 "program/program_lexer.l"
+/* eat whitespace */ ;
+ YY_BREAK
+case 168:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 492 "program/program_lexer.l"
+/* eat comments */ ;
+ YY_BREAK
+case 169:
+YY_RULE_SETUP
+#line 493 "program/program_lexer.l"
+{ return yytext[0]; }
+ YY_BREAK
+case 170:
+YY_RULE_SETUP
+#line 494 "program/program_lexer.l"
+ECHO;
+ YY_BREAK
+#line 2491 "program/lex.yy.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * _mesa_program_lexer_lex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( _mesa_program_lexer_wrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of _mesa_program_lexer_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ _mesa_program_lexer_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ _mesa_program_lexer_restart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) _mesa_program_lexer_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 850 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 850 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 849);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
+{
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yyg->yy_hold_char;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yyg->yy_n_chars + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ yyg->yytext_ptr = yy_bp;
+ yyg->yy_hold_char = *yy_cp;
+ yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ _mesa_program_lexer_restart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( _mesa_program_lexer_wrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void _mesa_program_lexer_restart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ _mesa_program_lexer_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ _mesa_program_lexer__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ _mesa_program_lexer__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ _mesa_program_lexer__load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void _mesa_program_lexer__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * _mesa_program_lexer_pop_buffer_state();
+ * _mesa_program_lexer_push_buffer_state(new_buffer);
+ */
+ _mesa_program_lexer_ensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ _mesa_program_lexer__load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (_mesa_program_lexer_wrap()) processing, but the only time this flag
+ * is looked at is after _mesa_program_lexer_wrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void _mesa_program_lexer__load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE _mesa_program_lexer__create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) _mesa_program_lexer_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_program_lexer__create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) _mesa_program_lexer_alloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_program_lexer__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ _mesa_program_lexer__init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with _mesa_program_lexer__create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void _mesa_program_lexer__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ _mesa_program_lexer_free((void *) b->yy_ch_buf ,yyscanner );
+
+ _mesa_program_lexer_free((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a _mesa_program_lexer_restart() or at EOF.
+ */
+ static void _mesa_program_lexer__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ _mesa_program_lexer__flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then _mesa_program_lexer__init_buffer was _probably_
+ * called from _mesa_program_lexer_restart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void _mesa_program_lexer__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ _mesa_program_lexer__load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void _mesa_program_lexer_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ _mesa_program_lexer_ensure_buffer_stack(yyscanner);
+
+ /* This block is copied from _mesa_program_lexer__switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from _mesa_program_lexer__switch_to_buffer. */
+ _mesa_program_lexer__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void _mesa_program_lexer_pop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ _mesa_program_lexer__delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ _mesa_program_lexer__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void _mesa_program_lexer_ensure_buffer_stack (yyscan_t yyscanner)
+{
+ int num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_program_lexer_alloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_program_lexer_ensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_program_lexer_realloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_program_lexer_ensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE _mesa_program_lexer__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) _mesa_program_lexer_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_program_lexer__scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ _mesa_program_lexer__switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to _mesa_program_lexer_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * _mesa_program_lexer__scan_bytes() instead.
+ */
+YY_BUFFER_STATE _mesa_program_lexer__scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return _mesa_program_lexer__scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to _mesa_program_lexer_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE _mesa_program_lexer__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) _mesa_program_lexer_alloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_program_lexer__scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = _mesa_program_lexer__scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in _mesa_program_lexer__scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE _mesa_program_lexer_get_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int _mesa_program_lexer_get_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int _mesa_program_lexer_get_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *_mesa_program_lexer_get_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *_mesa_program_lexer_get_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int _mesa_program_lexer_get_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *_mesa_program_lexer_get_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void _mesa_program_lexer_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void _mesa_program_lexer_set_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "_mesa_program_lexer_set_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void _mesa_program_lexer_set_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "_mesa_program_lexer_set_column called with no buffer" , yyscanner);
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see _mesa_program_lexer__switch_to_buffer
+ */
+void _mesa_program_lexer_set_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void _mesa_program_lexer_set_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int _mesa_program_lexer_get_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void _mesa_program_lexer_set_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * _mesa_program_lexer_get_lval (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylval;
+}
+
+void _mesa_program_lexer_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *_mesa_program_lexer_get_lloc (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylloc;
+}
+
+void _mesa_program_lexer_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* _mesa_program_lexer_lex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int _mesa_program_lexer_lex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) _mesa_program_lexer_alloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* _mesa_program_lexer_lex_init_extra has the same functionality as _mesa_program_lexer_lex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to _mesa_program_lexer_alloc in
+ * the yyextra field.
+ */
+
+int _mesa_program_lexer_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ _mesa_program_lexer_set_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) _mesa_program_lexer_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ _mesa_program_lexer_set_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from _mesa_program_lexer_lex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * _mesa_program_lexer_lex_init()
+ */
+ return 0;
+}
+
+/* _mesa_program_lexer_lex_destroy is for both reentrant and non-reentrant scanners. */
+int _mesa_program_lexer_lex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ _mesa_program_lexer__delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ _mesa_program_lexer_pop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ _mesa_program_lexer_free(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ _mesa_program_lexer_free(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * _mesa_program_lexer_lex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ _mesa_program_lexer_free ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *_mesa_program_lexer_alloc (yy_size_t size , yyscan_t yyscanner)
+{
+ return (void *) malloc( size );
+}
+
+void *_mesa_program_lexer_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void _mesa_program_lexer_free (void * ptr , yyscan_t yyscanner)
+{
+ free( (char *) ptr ); /* see _mesa_program_lexer_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 494 "program/program_lexer.l"
+
+
+
+void
+_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
+ const char *string, size_t len)
+{
+ _mesa_program_lexer_lex_init_extra(state,scanner);
+ _mesa_program_lexer__scan_bytes(string,len,*scanner);
+}
+
+void
+_mesa_program_lexer_dtor(void *scanner)
+{
+ _mesa_program_lexer_lex_destroy(scanner);
+}
+
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_cache.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_cache.c
new file mode 100644
index 0000000..07192a9
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_cache.c
@@ -0,0 +1,258 @@
+/**************************************************************************
+ *
+ * Copyright 2003 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "main/shaderobj.h"
+#include "program/prog_cache.h"
+#include "program/program.h"
+
+
+struct cache_item
+{
+ GLuint hash;
+ unsigned keysize;
+ void *key;
+ struct gl_program *program;
+ struct cache_item *next;
+};
+
+struct gl_program_cache
+{
+ struct cache_item **items;
+ struct cache_item *last;
+ GLuint size, n_items;
+};
+
+
+
+/**
+ * Compute hash index from state key.
+ */
+static GLuint
+hash_key(const void *key, GLuint key_size)
+{
+ const GLuint *ikey = (const GLuint *) key;
+ GLuint hash = 0, i;
+
+ assert(key_size >= 4);
+
+ /* Make a slightly better attempt at a hash function:
+ */
+ for (i = 0; i < key_size / sizeof(*ikey); i++)
+ {
+ hash += ikey[i];
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ return hash;
+}
+
+
+/**
+ * Rebuild/expand the hash table to accomodate more entries
+ */
+static void
+rehash(struct gl_program_cache *cache)
+{
+ struct cache_item **items;
+ struct cache_item *c, *next;
+ GLuint size, i;
+
+ cache->last = NULL;
+
+ size = cache->size * 3;
+ items = malloc(size * sizeof(*items));
+ memset(items, 0, size * sizeof(*items));
+
+ for (i = 0; i < cache->size; i++)
+ for (c = cache->items[i]; c; c = next) {
+ next = c->next;
+ c->next = items[c->hash % size];
+ items[c->hash % size] = c;
+ }
+
+ free(cache->items);
+ cache->items = items;
+ cache->size = size;
+}
+
+
+static void
+clear_cache(struct gl_context *ctx, struct gl_program_cache *cache,
+ GLboolean shader)
+{
+ struct cache_item *c, *next;
+ GLuint i;
+
+ cache->last = NULL;
+
+ for (i = 0; i < cache->size; i++) {
+ for (c = cache->items[i]; c; c = next) {
+ next = c->next;
+ free(c->key);
+ if (shader) {
+ _mesa_reference_shader_program(ctx,
+ (struct gl_shader_program **)&c->program,
+ NULL);
+ } else {
+ _mesa_reference_program(ctx, &c->program, NULL);
+ }
+ free(c);
+ }
+ cache->items[i] = NULL;
+ }
+
+
+ cache->n_items = 0;
+}
+
+
+
+struct gl_program_cache *
+_mesa_new_program_cache(void)
+{
+ struct gl_program_cache *cache = CALLOC_STRUCT(gl_program_cache);
+ if (cache) {
+ cache->size = 17;
+ cache->items =
+ calloc(1, cache->size * sizeof(struct cache_item));
+ if (!cache->items) {
+ free(cache);
+ return NULL;
+ }
+ }
+ return cache;
+}
+
+
+void
+_mesa_delete_program_cache(struct gl_context *ctx, struct gl_program_cache *cache)
+{
+ clear_cache(ctx, cache, GL_FALSE);
+ free(cache->items);
+ free(cache);
+}
+
+void
+_mesa_delete_shader_cache(struct gl_context *ctx,
+ struct gl_program_cache *cache)
+{
+ clear_cache(ctx, cache, GL_TRUE);
+ free(cache->items);
+ free(cache);
+}
+
+
+struct gl_program *
+_mesa_search_program_cache(struct gl_program_cache *cache,
+ const void *key, GLuint keysize)
+{
+ if (cache->last &&
+ cache->last->keysize == keysize &&
+ memcmp(cache->last->key, key, keysize) == 0) {
+ return cache->last->program;
+ }
+ else {
+ const GLuint hash = hash_key(key, keysize);
+ struct cache_item *c;
+
+ for (c = cache->items[hash % cache->size]; c; c = c->next) {
+ if (c->hash == hash &&
+ c->keysize == keysize &&
+ memcmp(c->key, key, keysize) == 0) {
+
+ cache->last = c;
+ return c->program;
+ }
+ }
+
+ return NULL;
+ }
+}
+
+
+void
+_mesa_program_cache_insert(struct gl_context *ctx,
+ struct gl_program_cache *cache,
+ const void *key, GLuint keysize,
+ struct gl_program *program)
+{
+ const GLuint hash = hash_key(key, keysize);
+ struct cache_item *c = CALLOC_STRUCT(cache_item);
+
+ c->hash = hash;
+
+ c->key = malloc(keysize);
+ memcpy(c->key, key, keysize);
+ c->keysize = keysize;
+
+ c->program = program; /* no refcount change */
+
+ if (cache->n_items > cache->size * 1.5) {
+ if (cache->size < 1000)
+ rehash(cache);
+ else
+ clear_cache(ctx, cache, GL_FALSE);
+ }
+
+ cache->n_items++;
+ c->next = cache->items[hash % cache->size];
+ cache->items[hash % cache->size] = c;
+}
+
+void
+_mesa_shader_cache_insert(struct gl_context *ctx,
+ struct gl_program_cache *cache,
+ const void *key, GLuint keysize,
+ struct gl_shader_program *program)
+{
+ const GLuint hash = hash_key(key, keysize);
+ struct cache_item *c = CALLOC_STRUCT(cache_item);
+
+ c->hash = hash;
+
+ c->key = malloc(keysize);
+ memcpy(c->key, key, keysize);
+ c->keysize = keysize;
+
+ c->program = (struct gl_program *)program; /* no refcount change */
+
+ if (cache->n_items > cache->size * 1.5) {
+ if (cache->size < 1000)
+ rehash(cache);
+ else
+ clear_cache(ctx, cache, GL_TRUE);
+ }
+
+ cache->n_items++;
+ c->next = cache->items[hash % cache->size];
+ cache->items[hash % cache->size] = c;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_cache.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_cache.h
new file mode 100644
index 0000000..fdd7e26
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_cache.h
@@ -0,0 +1,68 @@
+/**************************************************************************
+ *
+ * Copyright 2003 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef PROG_CACHE_H
+#define PROG_CACHE_H
+
+
+#include "main/glheader.h"
+
+struct gl_context;
+
+/** Opaque type */
+struct gl_program_cache;
+
+
+extern struct gl_program_cache *
+_mesa_new_program_cache(void);
+
+extern void
+_mesa_delete_program_cache(struct gl_context *ctx, struct gl_program_cache *pc);
+
+extern void
+_mesa_delete_shader_cache(struct gl_context *ctx,
+ struct gl_program_cache *cache);
+
+extern struct gl_program *
+_mesa_search_program_cache(struct gl_program_cache *cache,
+ const void *key, GLuint keysize);
+
+extern void
+_mesa_program_cache_insert(struct gl_context *ctx,
+ struct gl_program_cache *cache,
+ const void *key, GLuint keysize,
+ struct gl_program *program);
+
+void
+_mesa_shader_cache_insert(struct gl_context *ctx,
+ struct gl_program_cache *cache,
+ const void *key, GLuint keysize,
+ struct gl_shader_program *program);
+
+
+#endif /* PROG_CACHE_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_diskcache.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_diskcache.c
new file mode 100644
index 0000000..d8873c0
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_diskcache.c
@@ -0,0 +1,672 @@
+/* -*- c -*- */
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <sys/stat.h>
+#include "shader_cache.h"
+#include "prog_diskcache.h"
+
+#ifdef USE_LUNARGLASS
+#include "glsl_parser_extras.h"
+#endif
+
+#ifndef _WIN32
+#include <dirent.h>
+
+struct dir_entry_t
+{
+ char *path;
+ struct stat info;
+};
+
+
+static int
+sort_by_access_time(const void *_a, const void *_b)
+{
+ /* Compare access time of 2 entries */
+ struct dir_entry_t *a = (struct dir_entry_t *) _a;
+ struct dir_entry_t *b = (struct dir_entry_t *) _b;
+
+ if (a->info.st_atime > b->info.st_atime)
+ return 1;
+ return -1;
+}
+
+
+static int
+valid_cache_entry(const struct dirent *entry)
+{
+ /* Only regular files are possible valid cache entries. */
+ if (entry->d_type == DT_REG)
+ return 1;
+ return 0;
+}
+
+
+/**
+ * Cache size management. If cache size exceeds max_cache_size,
+ * entries are sorted by access time and oldest entries deleted
+ * until we fit.
+ */
+static void
+manage_cache_size(const char *path, const unsigned max_cache_size)
+{
+ if (max_cache_size == 0xFFFFFFFF) {
+ /* cache size of -1 means don't limit the size */
+ return;
+ }
+
+ struct dirent **entries;
+ int n = scandir(path, &entries, valid_cache_entry, NULL);
+
+ if (n <= 0)
+ return;
+
+ struct dir_entry_t *cache = NULL;
+ unsigned cache_size = 0;
+ unsigned cache_entries = 0;
+
+ void *mem_ctx = ralloc_context(NULL);
+
+ cache = ralloc_array(mem_ctx, struct dir_entry_t, n);
+
+ /* Construct entries with path and access information + calculate
+ * total size used by entries.
+ */
+ while (n--) {
+ cache[cache_entries].path =
+ ralloc_asprintf(mem_ctx, "%s/%s", path, entries[n]->d_name);
+ stat(cache[cache_entries].path, &cache[cache_entries].info);
+
+ cache_size += cache[cache_entries].info.st_size;
+
+ cache_entries++;
+ free(entries[n]);
+ }
+ free(entries);
+
+ /* No need to manage if we fit the max size. */
+ if (cache_size < max_cache_size)
+ goto free_allocated_memory;
+
+ /* Sort oldest first so we can 'delete until cache size less than max'. */
+ qsort(cache, cache_entries, sizeof(struct dir_entry_t), sort_by_access_time);
+
+ unsigned i = 0;
+ while (cache_size > max_cache_size && i < cache_entries) {
+ unlink(cache[i].path);
+ cache_size -= cache[i].info.st_size;
+ i++;
+ }
+
+free_allocated_memory:
+
+ ralloc_free(mem_ctx);
+}
+#endif
+
+
+static int
+mesa_mkdir_cache(const char *path)
+{
+ char *copy = _mesa_strdup(path);
+ char *dir = strtok(copy, "/");
+ char *current = ralloc_strdup(NULL, "/");
+ int result = 0;
+
+ /* As example loop iterates and calls mkdir for each token
+ * separated by '/' in "/home/yogsothoth/.cache/mesa".
+ */
+ while (dir) {
+ ralloc_strcat(¤t, dir);
+
+ result = _mesa_mkdir(current);
+
+ if (result != 0 && result != EEXIST)
+ return -1;
+
+ ralloc_strcat(¤t, "/");
+ dir = strtok(NULL, "/");
+ }
+
+ ralloc_free(current);
+ free(copy);
+
+ return 0;
+}
+
+
+int
+mesa_program_diskcache_init(struct gl_context *ctx)
+{
+ const char *tmp = "/tmp", *cache_root = NULL;
+ int result = 0;
+
+ if (ctx->Const.MaxShaderCacheSize == 0) {
+ // if 0 (default) then no cache will be active
+ ctx->BinaryProgramCacheActive = false;
+ return -1;
+ }
+
+ cache_root = _mesa_getenv("XDG_CACHE_DIR");
+ if (!cache_root)
+ cache_root = _mesa_getenv("HOME");
+ if (!cache_root)
+ cache_root = tmp;
+
+ asprintf(&ctx->BinaryProgramCachePath, "%s/.cache/mesa/programs", cache_root);
+
+ struct stat stat_info;
+ if (stat(ctx->BinaryProgramCachePath, &stat_info) != 0)
+ result = mesa_mkdir_cache(ctx->BinaryProgramCachePath);
+#ifndef _WIN32
+ else
+ manage_cache_size(ctx->BinaryProgramCachePath, ctx->Const.MaxShaderCacheSize);
+#endif
+
+ if (result == 0)
+ ctx->BinaryProgramCacheActive = true;
+ else
+ ctx->BinaryProgramCacheActive = false;
+
+ return result;
+}
+
+
+static uint32_t
+checksum(const char *src)
+{
+ uint32_t sum = _mesa_str_checksum(src);
+ unsigned i;
+
+ /* Add some sugar on top (borrowed from brw_state_cache). This is meant
+ * to catch cache collisions when there are only small changes in the
+ * source such as mat3 -> mat4 in a type for example.
+ */
+ for (i = 0; i < strlen(src); i++) {
+ sum ^= (uint32_t) src[i];
+ sum = (sum << 5) | (sum >> 27);
+ }
+
+ return sum;
+}
+
+
+/**
+ * Attempt to generate unique key for a gl_shader_program.
+ * TODO - this should be stronger and be based on some of the
+ * gl_shader_program content, not just sources.
+ */
+static char *
+generate_key(struct gl_shader_program *prog)
+{
+ char *key = ralloc_strdup(prog, "");
+ for (unsigned i = 0; i < prog->NumShaders; i++) {
+
+ /* No source, no key. */
+ if (!prog->Shaders[i]->Source)
+ return NULL;
+
+ /* At least some content required. */
+ if (strcmp(prog->Shaders[i]->Source, "") == 0)
+ return NULL;
+
+ uint64_t sum = checksum(prog->Shaders[i]->Source);
+
+ char tmp[32];
+ _mesa_snprintf(tmp, 32, "%lu", sum);
+
+ ralloc_strcat(&key, tmp);
+ }
+
+ /* Key needs to have enough content. */
+ if (strlen(key) < 7) {
+ ralloc_free(key);
+ key = NULL;
+ }
+
+ return key;
+}
+
+
+/**
+ * Cache gl_shader_program to disk
+ */
+int
+mesa_program_diskcache_cache(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+ assert(ctx);
+ int result = -1;
+ struct stat stat_info;
+ char *key;
+
+ key = generate_key(prog);
+
+ if (!key)
+ return -1;
+
+#ifdef USE_LUNARGLASS
+ /* Glassy vs. Opaque compiled shaders */
+ if (_mesa_use_glass(ctx))
+ ralloc_strcat(&key, ".g");
+#endif
+
+ char *shader_path =
+ ralloc_asprintf(NULL, "%s/%s.bin", ctx->BinaryProgramCachePath, key);
+
+ /* Collision, do not attempt to overwrite. */
+ if (stat(shader_path, &stat_info) == 0)
+ goto cache_epilogue;
+
+ size_t size = 0;
+ char *data = mesa_program_serialize(ctx, prog, &size);
+
+ if (!data)
+ goto cache_epilogue;
+
+ FILE *out = fopen(shader_path, "w+");
+
+ if (!out)
+ goto cache_epilogue;
+
+ fwrite(data, size, 1, out);
+ fclose(out);
+ free(data);
+ result = 0;
+
+cache_epilogue:
+ ralloc_free(shader_path);
+ ralloc_free(key);
+ return result;
+}
+
+bool
+supported_by_program_cache(struct gl_shader_program *prog, bool is_write)
+{
+ /* No geometry shader support. */
+ if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY])
+ return false;
+
+ /* No uniform block support. */
+ if (prog->NumUniformBlocks > 0)
+ return false;
+
+ /* No transform feedback support. */
+ if (prog->TransformFeedback.NumVarying > 0)
+ return false;
+
+ /* These more expensive checks should only be run when generating
+ * the cache entry
+ */
+ if (is_write)
+ {
+ /* Uniform structs are not working */
+ if (prog->UniformStorage) {
+ for (unsigned i = 0; i < prog->NumUserUniformStorage; i++) {
+ if (strchr(prog->UniformStorage[i].name, '.')) {
+ /* The uniforms struct fields have already been broken
+ * down into unique variables, we have to inspect their
+ * names and kick back since these aren't working.
+ */
+ return false;
+ }
+ }
+ }
+
+ /* This is nasty! Short term solution for correctness! */
+ for (unsigned i = 0; i < prog->NumShaders; i++) {
+ if (prog->Shaders[i] && prog->Shaders[i]->Source) {
+ /* This opcode is not supported by MesaIR (yet?) */
+ if (strstr(prog->Shaders[i]->Source, "textureQueryLevels"))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Fill gl_shader_program from cache if found
+ */
+int
+mesa_program_diskcache_find(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+ assert(ctx);
+ int result = 0;
+ char *key;
+
+ /* Do not use diskcache when program relinks. Relinking is not
+ * currently supported due to the way how cache key gets generated.
+ * We would need to modify key generation to take account hashtables
+ * and possible other data in gl_shader_program to catch changes in
+ * the data used as input for linker (resulting in a different program
+ * with same sources).
+ */
+ if (prog->_Linked)
+ return -1;
+
+ /* This is heavier than we'd like, but string compares are
+ * insufficient for this caching. It depends on state as well.
+ */
+ if (!supported_by_program_cache(prog, false /* is_write */))
+ return -1;
+
+ key = generate_key(prog);
+
+ if (!key)
+ return -1;
+
+#ifdef USE_LUNARGLASS
+ /* Glassy vs. Opaque compiled shaders */
+ if (_mesa_use_glass(ctx))
+ ralloc_strcat(&key, ".g");
+#endif
+
+
+ char *shader_path =
+ ralloc_asprintf(NULL, "%s/%s.bin", ctx->BinaryProgramCachePath, key);
+
+ result = mesa_program_load(ctx, prog, shader_path);
+
+ // TODO: ensure we did not get a false cache hit by comparing the
+ // incoming strings with what we just deserialized
+
+ ralloc_free(shader_path);
+ ralloc_free(key);
+
+ return result;
+}
+
+
+
+/* The following functions are shader verions of program caching functions
+ * They could be moved to another file, or merged with the program version
+ * since several have line of code in common. This hasn't been done yet to
+ * prevent premature optimization.
+ */
+
+bool
+supported_by_shader_cache(struct gl_shader *shader, bool is_write)
+{
+ /* No geometry shader support. */
+ // how hard to add?
+ if (shader->Stage == MESA_SHADER_GEOMETRY)
+ return false;
+
+ /* No uniform block support. */
+ if (shader->NumUniformBlocks > 0)
+ return false;
+
+ return true;
+}
+
+
+static int
+mesa_mkdir_shader_cache(const char *path)
+{
+ char *copy = _mesa_strdup(path);
+ char *dir = strtok(copy, "/");
+ char *current = ralloc_strdup(NULL, "/");
+ int result = 0;
+
+ /* As example loop iterates and calls mkdir for each token
+ * separated by '/' in "/home/yogsothoth/.cache/mesa".
+ */
+ while (dir) {
+ ralloc_strcat(¤t, dir);
+
+ result = _mesa_mkdir(current);
+
+ if (result != 0 && result != EEXIST)
+ return -1;
+
+ ralloc_strcat(¤t, "/");
+ dir = strtok(NULL, "/");
+ }
+
+ ralloc_free(current);
+ free(copy);
+
+ return 0;
+}
+
+
+
+/* This is based on mesa_program_diskcache_init,
+ * would be good to merge them at some point.
+ */
+
+int
+mesa_shader_diskcache_init(struct gl_context *ctx)
+{
+ const char *tmp = "/tmp", *cache_root = NULL;
+ int result = 0;
+
+ if (ctx->Const.MaxShaderCacheSize == 0) {
+ // if 0 (default) then no cache will be active
+ ctx->BinaryShaderCacheActive = false;
+ return -1;
+ }
+
+ cache_root = _mesa_getenv("XDG_CACHE_DIR");
+ if (!cache_root)
+ cache_root = _mesa_getenv("HOME");
+ if (!cache_root)
+ cache_root = tmp;
+
+ asprintf(&ctx->BinaryShaderCachePath, "%s/.cache/mesa/shaders", cache_root);
+
+ struct stat stat_info;
+ if (stat(ctx->BinaryShaderCachePath, &stat_info) != 0)
+ result = mesa_mkdir_shader_cache(ctx->BinaryShaderCachePath);
+#ifndef _WIN32
+ else
+ manage_cache_size(ctx->BinaryShaderCachePath, ctx->Const.MaxShaderCacheSize);
+#endif
+
+ if (result == 0)
+ ctx->BinaryShaderCacheActive = true;
+ else
+ ctx->BinaryShaderCacheActive = false;
+
+ return result;
+}
+
+
+static uint32_t
+shader_checksum(const char *src)
+{
+ uint32_t sum = _mesa_str_checksum(src);
+ unsigned i;
+
+ /* Add some sugar on top (borrowed from brw_state_cache). This is meant
+ * to catch cache collisions when there are only small changes in the
+ * source such as mat3 -> mat4 in a type for example.
+ */
+ for (i = 0; i < strlen(src); i++) {
+ sum ^= (uint32_t) src[i];
+ sum = (sum << 5) | (sum >> 27);
+ }
+
+ return sum;
+}
+
+
+/* This is based on generate_key(prog), would
+ * be good to merge them at some point.
+ */
+static char *
+generate_shader_key(struct gl_shader *shader)
+{
+ char *key = ralloc_strdup(shader, "");
+
+ /* No source, no key. */
+ if (shader->Source == NULL)
+ return NULL;
+
+ /* At least some content required. */
+ if (strcmp(shader->Source, "") == 0)
+ return NULL;
+
+ uint64_t sum = shader_checksum(shader->Source);
+
+ char tmp[32];
+ _mesa_snprintf(tmp, 32, "%lu", sum);
+
+ ralloc_strcat(&key, tmp);
+
+ /* Key needs to have enough content. */
+ if (strlen(key) < 7) {
+ ralloc_free(key);
+ key = NULL;
+ }
+
+ return key;
+}
+
+/**
+ * Deserialize gl_shader structure
+ */
+struct gl_shader *
+mesa_shader_deserialize(struct gl_context *ctx, struct gl_shader *shader,
+ const char* path)
+{
+ return read_single_shader(ctx, shader, path);
+}
+
+
+int
+mesa_shader_load(struct gl_context *ctx, struct gl_shader *shader,
+ const char *path)
+{
+
+ struct gl_shader *result = mesa_shader_deserialize(ctx, shader, path);
+
+ if (result)
+ return 0;
+ else
+ return MESA_SHADER_DESERIALIZE_READ_ERROR;
+}
+
+/*
+ * This is based on mesa_program_diskcache_cache, would be good to
+ * merge them at some point.
+ */
+int
+mesa_shader_diskcache_cache(struct gl_context *ctx, struct gl_shader *shader)
+{
+ assert(ctx);
+ int result = -1;
+ struct stat stat_info;
+ char *key;
+ size_t size = 0;
+
+ key = generate_shader_key(shader);
+
+ if (!key)
+ return -1;
+
+#ifdef USE_LUNARGLASS
+ /* Glassy vs. Opaque compiled shaders */
+ if (_mesa_use_glass(ctx))
+ ralloc_strcat(&key, ".g");
+#endif
+
+ char *shader_path =
+ ralloc_asprintf(NULL, "%s/%s.bin", ctx->BinaryShaderCachePath, key);
+
+ char *data = NULL;
+ FILE *out = NULL;
+
+ /* Collision, do not attempt to overwrite. */
+ if (stat(shader_path, &stat_info) == 0)
+ goto cache_epilogue;
+
+ data = mesa_shader_serialize(ctx, shader, &size, true /* shader_only */);
+
+ if (!data)
+ goto cache_epilogue;
+
+ out = fopen(shader_path, "w+");
+
+ if (!out)
+ goto cache_epilogue;
+
+ fwrite(data, size, 1, out);
+ fclose(out);
+ free(data);
+ result = 0;
+
+cache_epilogue:
+ ralloc_free(shader_path);
+ ralloc_free(key);
+ return result;
+}
+
+
+
+/* This is based on mesa_program_diskcache_find, would be good to
+ * merge them at some point.
+ */
+int
+mesa_shader_diskcache_find(struct gl_context *ctx, struct gl_shader *shader)
+{
+ int result = 0;
+ char *key;
+
+ /* Don't lookup if already compiled. */
+ if (shader->CompileStatus)
+ return -1;
+
+ /* This is heavier than we'd like, but string compares are
+ * insufficient for this caching. It depends on state as well.
+ */
+ if (!supported_by_shader_cache(shader, false /* is_write */))
+ return -1;
+
+ key = generate_shader_key(shader);
+
+ if (!key)
+ return -1;
+
+#ifdef USE_LUNARGLASS
+ /* Glassy vs. Opaque compiled shaders */
+ if (_mesa_use_glass(ctx))
+ ralloc_strcat(&key, ".g");
+#endif
+
+
+ char *shader_path =
+ ralloc_asprintf(NULL, "%s/%s.bin", ctx->BinaryShaderCachePath, key);
+
+ result = mesa_shader_load(ctx, shader, shader_path);
+
+ // TODO: ensure we did not get a false cache hit by comparing the
+ // incoming string with what we just deserialized
+
+ ralloc_free(shader_path);
+ ralloc_free(key);
+
+ return result;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_diskcache.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_diskcache.h
new file mode 100644
index 0000000..6e3973b
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_diskcache.h
@@ -0,0 +1,57 @@
+/* -*- c -*- */
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+#ifndef PROGRAM_DISKCACHE_H
+#define PROGRAM_DISKCACHE_H
+
+#include "main/mtypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+mesa_program_diskcache_init(struct gl_context *ctx);
+
+int
+mesa_program_diskcache_cache(struct gl_context *ctx, struct gl_shader_program *prog);
+
+int
+mesa_program_diskcache_find(struct gl_context *ctx, struct gl_shader_program *prog);
+
+extern int
+mesa_shader_diskcache_find(struct gl_context *ctx, struct gl_shader *shader);
+
+extern int
+mesa_shader_diskcache_cache(struct gl_context *ctx, struct gl_shader *shader);
+
+int
+mesa_shader_diskcache_init(struct gl_context *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PROGRAM_DISKCACHE_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_execute.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_execute.c
new file mode 100644
index 0000000..115525e
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_execute.c
@@ -0,0 +1,1679 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_execute.c
+ * Software interpreter for vertex/fragment programs.
+ * \author Brian Paul
+ */
+
+/*
+ * NOTE: we do everything in single-precision floating point; we don't
+ * currently observe the single/half/fixed-precision qualifiers.
+ *
+ */
+
+
+#include "main/glheader.h"
+#include "main/colormac.h"
+#include "main/macros.h"
+#include "prog_execute.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "prog_noise.h"
+
+
+/* debug predicate */
+#define DEBUG_PROG 0
+
+
+/**
+ * Set x to positive or negative infinity.
+ */
+#if defined(USE_IEEE) || defined(_WIN32)
+#define SET_POS_INFINITY(x) \
+ do { \
+ fi_type fi; \
+ fi.i = 0x7F800000; \
+ x = fi.f; \
+ } while (0)
+#define SET_NEG_INFINITY(x) \
+ do { \
+ fi_type fi; \
+ fi.i = 0xFF800000; \
+ x = fi.f; \
+ } while (0)
+#else
+#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL
+#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL
+#endif
+
+#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits
+
+
+static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
+
+
+/**
+ * Return a pointer to the 4-element float vector specified by the given
+ * source register.
+ */
+static inline const GLfloat *
+get_src_register_pointer(const struct prog_src_register *source,
+ const struct gl_program_machine *machine)
+{
+ const struct gl_program *prog = machine->CurProgram;
+ GLint reg = source->Index;
+
+ if (source->RelAddr) {
+ /* add address register value to src index/offset */
+ reg += machine->AddressReg[0][0];
+ if (reg < 0) {
+ return ZeroVec;
+ }
+ }
+
+ switch (source->File) {
+ case PROGRAM_TEMPORARY:
+ if (reg >= MAX_PROGRAM_TEMPS)
+ return ZeroVec;
+ return machine->Temporaries[reg];
+
+ case PROGRAM_INPUT:
+ if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
+ if (reg >= VERT_ATTRIB_MAX)
+ return ZeroVec;
+ return machine->VertAttribs[reg];
+ }
+ else {
+ if (reg >= VARYING_SLOT_MAX)
+ return ZeroVec;
+ return machine->Attribs[reg][machine->CurElement];
+ }
+
+ case PROGRAM_OUTPUT:
+ if (reg >= MAX_PROGRAM_OUTPUTS)
+ return ZeroVec;
+ return machine->Outputs[reg];
+
+ case PROGRAM_STATE_VAR:
+ /* Fallthrough */
+ case PROGRAM_CONSTANT:
+ /* Fallthrough */
+ case PROGRAM_UNIFORM:
+ if (reg >= (GLint) prog->Parameters->NumParameters)
+ return ZeroVec;
+ return (GLfloat *) prog->Parameters->ParameterValues[reg];
+
+ case PROGRAM_SYSTEM_VALUE:
+ assert(reg < Elements(machine->SystemValues));
+ return machine->SystemValues[reg];
+
+ default:
+ _mesa_problem(NULL,
+ "Invalid src register file %d in get_src_register_pointer()",
+ source->File);
+ return ZeroVec;
+ }
+}
+
+
+/**
+ * Return a pointer to the 4-element float vector specified by the given
+ * destination register.
+ */
+static inline GLfloat *
+get_dst_register_pointer(const struct prog_dst_register *dest,
+ struct gl_program_machine *machine)
+{
+ static GLfloat dummyReg[4];
+ GLint reg = dest->Index;
+
+ if (dest->RelAddr) {
+ /* add address register value to src index/offset */
+ reg += machine->AddressReg[0][0];
+ if (reg < 0) {
+ return dummyReg;
+ }
+ }
+
+ switch (dest->File) {
+ case PROGRAM_TEMPORARY:
+ if (reg >= MAX_PROGRAM_TEMPS)
+ return dummyReg;
+ return machine->Temporaries[reg];
+
+ case PROGRAM_OUTPUT:
+ if (reg >= MAX_PROGRAM_OUTPUTS)
+ return dummyReg;
+ return machine->Outputs[reg];
+
+ default:
+ _mesa_problem(NULL,
+ "Invalid dest register file %d in get_dst_register_pointer()",
+ dest->File);
+ return dummyReg;
+ }
+}
+
+
+
+/**
+ * Fetch a 4-element float vector from the given source register.
+ * Apply swizzling and negating as needed.
+ */
+static void
+fetch_vector4(const struct prog_src_register *source,
+ const struct gl_program_machine *machine, GLfloat result[4])
+{
+ const GLfloat *src = get_src_register_pointer(source, machine);
+
+ if (source->Swizzle == SWIZZLE_NOOP) {
+ /* no swizzling */
+ COPY_4V(result, src);
+ }
+ else {
+ ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
+ ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
+ ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
+ ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
+ result[0] = src[GET_SWZ(source->Swizzle, 0)];
+ result[1] = src[GET_SWZ(source->Swizzle, 1)];
+ result[2] = src[GET_SWZ(source->Swizzle, 2)];
+ result[3] = src[GET_SWZ(source->Swizzle, 3)];
+ }
+
+ if (source->Abs) {
+ result[0] = FABSF(result[0]);
+ result[1] = FABSF(result[1]);
+ result[2] = FABSF(result[2]);
+ result[3] = FABSF(result[3]);
+ }
+ if (source->Negate) {
+ ASSERT(source->Negate == NEGATE_XYZW);
+ result[0] = -result[0];
+ result[1] = -result[1];
+ result[2] = -result[2];
+ result[3] = -result[3];
+ }
+
+#ifdef NAN_CHECK
+ assert(!IS_INF_OR_NAN(result[0]));
+ assert(!IS_INF_OR_NAN(result[0]));
+ assert(!IS_INF_OR_NAN(result[0]));
+ assert(!IS_INF_OR_NAN(result[0]));
+#endif
+}
+
+
+/**
+ * Fetch the derivative with respect to X or Y for the given register.
+ * XXX this currently only works for fragment program input attribs.
+ */
+static void
+fetch_vector4_deriv(struct gl_context * ctx,
+ const struct prog_src_register *source,
+ const struct gl_program_machine *machine,
+ char xOrY, GLfloat result[4])
+{
+ if (source->File == PROGRAM_INPUT &&
+ source->Index < (GLint) machine->NumDeriv) {
+ const GLint col = machine->CurElement;
+ const GLfloat w = machine->Attribs[VARYING_SLOT_POS][col][3];
+ const GLfloat invQ = 1.0f / w;
+ GLfloat deriv[4];
+
+ if (xOrY == 'X') {
+ deriv[0] = machine->DerivX[source->Index][0] * invQ;
+ deriv[1] = machine->DerivX[source->Index][1] * invQ;
+ deriv[2] = machine->DerivX[source->Index][2] * invQ;
+ deriv[3] = machine->DerivX[source->Index][3] * invQ;
+ }
+ else {
+ deriv[0] = machine->DerivY[source->Index][0] * invQ;
+ deriv[1] = machine->DerivY[source->Index][1] * invQ;
+ deriv[2] = machine->DerivY[source->Index][2] * invQ;
+ deriv[3] = machine->DerivY[source->Index][3] * invQ;
+ }
+
+ result[0] = deriv[GET_SWZ(source->Swizzle, 0)];
+ result[1] = deriv[GET_SWZ(source->Swizzle, 1)];
+ result[2] = deriv[GET_SWZ(source->Swizzle, 2)];
+ result[3] = deriv[GET_SWZ(source->Swizzle, 3)];
+
+ if (source->Abs) {
+ result[0] = FABSF(result[0]);
+ result[1] = FABSF(result[1]);
+ result[2] = FABSF(result[2]);
+ result[3] = FABSF(result[3]);
+ }
+ if (source->Negate) {
+ ASSERT(source->Negate == NEGATE_XYZW);
+ result[0] = -result[0];
+ result[1] = -result[1];
+ result[2] = -result[2];
+ result[3] = -result[3];
+ }
+ }
+ else {
+ ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0);
+ }
+}
+
+
+/**
+ * As above, but only return result[0] element.
+ */
+static void
+fetch_vector1(const struct prog_src_register *source,
+ const struct gl_program_machine *machine, GLfloat result[4])
+{
+ const GLfloat *src = get_src_register_pointer(source, machine);
+
+ result[0] = src[GET_SWZ(source->Swizzle, 0)];
+
+ if (source->Abs) {
+ result[0] = FABSF(result[0]);
+ }
+ if (source->Negate) {
+ result[0] = -result[0];
+ }
+}
+
+
+static GLuint
+fetch_vector1ui(const struct prog_src_register *source,
+ const struct gl_program_machine *machine)
+{
+ const GLuint *src = (GLuint *) get_src_register_pointer(source, machine);
+ return src[GET_SWZ(source->Swizzle, 0)];
+}
+
+
+/**
+ * Fetch texel from texture. Use partial derivatives when possible.
+ */
+static inline void
+fetch_texel(struct gl_context *ctx,
+ const struct gl_program_machine *machine,
+ const struct prog_instruction *inst,
+ const GLfloat texcoord[4], GLfloat lodBias,
+ GLfloat color[4])
+{
+ const GLuint unit = machine->Samplers[inst->TexSrcUnit];
+
+ /* Note: we only have the right derivatives for fragment input attribs.
+ */
+ if (machine->NumDeriv > 0 &&
+ inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index == VARYING_SLOT_TEX0 + inst->TexSrcUnit) {
+ /* simple texture fetch for which we should have derivatives */
+ GLuint attr = inst->SrcReg[0].Index;
+ machine->FetchTexelDeriv(ctx, texcoord,
+ machine->DerivX[attr],
+ machine->DerivY[attr],
+ lodBias, unit, color);
+ }
+ else {
+ machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color);
+ }
+}
+
+
+/**
+ * Test value against zero and return GT, LT, EQ or UN if NaN.
+ */
+static inline GLuint
+generate_cc(float value)
+{
+ if (value != value)
+ return COND_UN; /* NaN */
+ if (value > 0.0F)
+ return COND_GT;
+ if (value < 0.0F)
+ return COND_LT;
+ return COND_EQ;
+}
+
+
+/**
+ * Test if the ccMaskRule is satisfied by the given condition code.
+ * Used to mask destination writes according to the current condition code.
+ */
+static inline GLboolean
+test_cc(GLuint condCode, GLuint ccMaskRule)
+{
+ switch (ccMaskRule) {
+ case COND_EQ: return (condCode == COND_EQ);
+ case COND_NE: return (condCode != COND_EQ);
+ case COND_LT: return (condCode == COND_LT);
+ case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);
+ case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);
+ case COND_GT: return (condCode == COND_GT);
+ case COND_TR: return GL_TRUE;
+ case COND_FL: return GL_FALSE;
+ default: return GL_TRUE;
+ }
+}
+
+
+/**
+ * Evaluate the 4 condition codes against a predicate and return GL_TRUE
+ * or GL_FALSE to indicate result.
+ */
+static inline GLboolean
+eval_condition(const struct gl_program_machine *machine,
+ const struct prog_instruction *inst)
+{
+ const GLuint swizzle = inst->DstReg.CondSwizzle;
+ const GLuint condMask = inst->DstReg.CondMask;
+ if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
+/**
+ * Store 4 floats into a register. Observe the instructions saturate and
+ * set-condition-code flags.
+ */
+static void
+store_vector4(const struct prog_instruction *inst,
+ struct gl_program_machine *machine, const GLfloat value[4])
+{
+ const struct prog_dst_register *dstReg = &(inst->DstReg);
+ const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;
+ GLuint writeMask = dstReg->WriteMask;
+ GLfloat clampedValue[4];
+ GLfloat *dst = get_dst_register_pointer(dstReg, machine);
+
+#if 0
+ if (value[0] > 1.0e10 ||
+ IS_INF_OR_NAN(value[0]) ||
+ IS_INF_OR_NAN(value[1]) ||
+ IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3]))
+ printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]);
+#endif
+
+ if (clamp) {
+ clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F);
+ clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F);
+ clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F);
+ clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F);
+ value = clampedValue;
+ }
+
+ if (dstReg->CondMask != COND_TR) {
+ /* condition codes may turn off some writes */
+ if (writeMask & WRITEMASK_X) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_X;
+ }
+ if (writeMask & WRITEMASK_Y) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_Y;
+ }
+ if (writeMask & WRITEMASK_Z) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_Z;
+ }
+ if (writeMask & WRITEMASK_W) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_W;
+ }
+ }
+
+#ifdef NAN_CHECK
+ assert(!IS_INF_OR_NAN(value[0]));
+ assert(!IS_INF_OR_NAN(value[0]));
+ assert(!IS_INF_OR_NAN(value[0]));
+ assert(!IS_INF_OR_NAN(value[0]));
+#endif
+
+ if (writeMask & WRITEMASK_X)
+ dst[0] = value[0];
+ if (writeMask & WRITEMASK_Y)
+ dst[1] = value[1];
+ if (writeMask & WRITEMASK_Z)
+ dst[2] = value[2];
+ if (writeMask & WRITEMASK_W)
+ dst[3] = value[3];
+
+ if (inst->CondUpdate) {
+ if (writeMask & WRITEMASK_X)
+ machine->CondCodes[0] = generate_cc(value[0]);
+ if (writeMask & WRITEMASK_Y)
+ machine->CondCodes[1] = generate_cc(value[1]);
+ if (writeMask & WRITEMASK_Z)
+ machine->CondCodes[2] = generate_cc(value[2]);
+ if (writeMask & WRITEMASK_W)
+ machine->CondCodes[3] = generate_cc(value[3]);
+#if DEBUG_PROG
+ printf("CondCodes=(%s,%s,%s,%s) for:\n",
+ _mesa_condcode_string(machine->CondCodes[0]),
+ _mesa_condcode_string(machine->CondCodes[1]),
+ _mesa_condcode_string(machine->CondCodes[2]),
+ _mesa_condcode_string(machine->CondCodes[3]));
+#endif
+ }
+}
+
+
+/**
+ * Store 4 uints into a register. Observe the set-condition-code flags.
+ */
+static void
+store_vector4ui(const struct prog_instruction *inst,
+ struct gl_program_machine *machine, const GLuint value[4])
+{
+ const struct prog_dst_register *dstReg = &(inst->DstReg);
+ GLuint writeMask = dstReg->WriteMask;
+ GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine);
+
+ if (dstReg->CondMask != COND_TR) {
+ /* condition codes may turn off some writes */
+ if (writeMask & WRITEMASK_X) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_X;
+ }
+ if (writeMask & WRITEMASK_Y) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_Y;
+ }
+ if (writeMask & WRITEMASK_Z) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_Z;
+ }
+ if (writeMask & WRITEMASK_W) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
+ dstReg->CondMask))
+ writeMask &= ~WRITEMASK_W;
+ }
+ }
+
+ if (writeMask & WRITEMASK_X)
+ dst[0] = value[0];
+ if (writeMask & WRITEMASK_Y)
+ dst[1] = value[1];
+ if (writeMask & WRITEMASK_Z)
+ dst[2] = value[2];
+ if (writeMask & WRITEMASK_W)
+ dst[3] = value[3];
+
+ if (inst->CondUpdate) {
+ if (writeMask & WRITEMASK_X)
+ machine->CondCodes[0] = generate_cc((float)value[0]);
+ if (writeMask & WRITEMASK_Y)
+ machine->CondCodes[1] = generate_cc((float)value[1]);
+ if (writeMask & WRITEMASK_Z)
+ machine->CondCodes[2] = generate_cc((float)value[2]);
+ if (writeMask & WRITEMASK_W)
+ machine->CondCodes[3] = generate_cc((float)value[3]);
+#if DEBUG_PROG
+ printf("CondCodes=(%s,%s,%s,%s) for:\n",
+ _mesa_condcode_string(machine->CondCodes[0]),
+ _mesa_condcode_string(machine->CondCodes[1]),
+ _mesa_condcode_string(machine->CondCodes[2]),
+ _mesa_condcode_string(machine->CondCodes[3]));
+#endif
+ }
+}
+
+
+
+/**
+ * Execute the given vertex/fragment program.
+ *
+ * \param ctx rendering context
+ * \param program the program to execute
+ * \param machine machine state (must be initialized)
+ * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
+ */
+GLboolean
+_mesa_execute_program(struct gl_context * ctx,
+ const struct gl_program *program,
+ struct gl_program_machine *machine)
+{
+ const GLuint numInst = program->NumInstructions;
+ const GLuint maxExec = 65536;
+ GLuint pc, numExec = 0;
+
+ machine->CurProgram = program;
+
+ if (DEBUG_PROG) {
+ printf("execute program %u --------------------\n", program->Id);
+ }
+
+ if (program->Target == GL_VERTEX_PROGRAM_ARB) {
+ machine->EnvParams = ctx->VertexProgram.Parameters;
+ }
+ else {
+ machine->EnvParams = ctx->FragmentProgram.Parameters;
+ }
+
+ for (pc = 0; pc < numInst; pc++) {
+ const struct prog_instruction *inst = program->Instructions + pc;
+
+ if (DEBUG_PROG) {
+ _mesa_print_instruction(inst);
+ }
+
+ switch (inst->Opcode) {
+ case OPCODE_ABS:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = FABSF(a[0]);
+ result[1] = FABSF(a[1]);
+ result[2] = FABSF(a[2]);
+ result[3] = FABSF(a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_ADD:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[0] + b[0];
+ result[1] = a[1] + b[1];
+ result[2] = a[2] + b[2];
+ result[3] = a[3] + b[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_ARL:
+ {
+ GLfloat t[4];
+ fetch_vector4(&inst->SrcReg[0], machine, t);
+ machine->AddressReg[0][0] = IFLOOR(t[0]);
+ if (DEBUG_PROG) {
+ printf("ARL %d\n", machine->AddressReg[0][0]);
+ }
+ }
+ break;
+ case OPCODE_BGNLOOP:
+ /* no-op */
+ ASSERT(program->Instructions[inst->BranchTarget].Opcode
+ == OPCODE_ENDLOOP);
+ break;
+ case OPCODE_ENDLOOP:
+ /* subtract 1 here since pc is incremented by for(pc) loop */
+ ASSERT(program->Instructions[inst->BranchTarget].Opcode
+ == OPCODE_BGNLOOP);
+ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */
+ break;
+ case OPCODE_BGNSUB: /* begin subroutine */
+ break;
+ case OPCODE_ENDSUB: /* end subroutine */
+ break;
+ case OPCODE_BRK: /* break out of loop (conditional) */
+ ASSERT(program->Instructions[inst->BranchTarget].Opcode
+ == OPCODE_ENDLOOP);
+ if (eval_condition(machine, inst)) {
+ /* break out of loop */
+ /* pc++ at end of for-loop will put us after the ENDLOOP inst */
+ pc = inst->BranchTarget;
+ }
+ break;
+ case OPCODE_CONT: /* continue loop (conditional) */
+ ASSERT(program->Instructions[inst->BranchTarget].Opcode
+ == OPCODE_ENDLOOP);
+ if (eval_condition(machine, inst)) {
+ /* continue at ENDLOOP */
+ /* Subtract 1 here since we'll do pc++ at end of for-loop */
+ pc = inst->BranchTarget - 1;
+ }
+ break;
+ case OPCODE_CAL: /* Call subroutine (conditional) */
+ if (eval_condition(machine, inst)) {
+ /* call the subroutine */
+ if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
+ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
+ }
+ machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */
+ /* Subtract 1 here since we'll do pc++ at end of for-loop */
+ pc = inst->BranchTarget - 1;
+ }
+ break;
+ case OPCODE_CMP:
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] < 0.0F ? b[0] : c[0];
+ result[1] = a[1] < 0.0F ? b[1] : c[1];
+ result[2] = a[2] < 0.0F ? b[2] : c[2];
+ result[3] = a[3] < 0.0F ? b[3] : c[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("CMP (%g %g %g %g) = (%g %g %g %g) < 0 ? (%g %g %g %g) : (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3],
+ c[0], c[1], c[2], c[3]);
+ }
+ }
+ break;
+ case OPCODE_COS:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = result[1] = result[2] = result[3]
+ = (GLfloat) cos(a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_DDX: /* Partial derivative with respect to X */
+ {
+ GLfloat result[4];
+ fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
+ 'X', result);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_DDY: /* Partial derivative with respect to Y */
+ {
+ GLfloat result[4];
+ fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
+ 'Y', result);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_DP2:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3] = DOT2(a, b);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("DP2 %g = (%g %g) . (%g %g)\n",
+ result[0], a[0], a[1], b[0], b[1]);
+ }
+ }
+ break;
+ case OPCODE_DP3:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3] = DOT3(a, b);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("DP3 %g = (%g %g %g) . (%g %g %g)\n",
+ result[0], a[0], a[1], a[2], b[0], b[1], b[2]);
+ }
+ }
+ break;
+ case OPCODE_DP4:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3] = DOT4(a, b);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",
+ result[0], a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_DPH:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3] = DOT3(a, b) + b[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_DST: /* Distance vector */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = 1.0F;
+ result[1] = a[1] * b[1];
+ result[2] = a[2];
+ result[3] = b[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_EXP:
+ {
+ GLfloat t[4], q[4], floor_t0;
+ fetch_vector1(&inst->SrcReg[0], machine, t);
+ floor_t0 = FLOORF(t[0]);
+ if (floor_t0 > FLT_MAX_EXP) {
+ SET_POS_INFINITY(q[0]);
+ SET_POS_INFINITY(q[2]);
+ }
+ else if (floor_t0 < FLT_MIN_EXP) {
+ q[0] = 0.0F;
+ q[2] = 0.0F;
+ }
+ else {
+ q[0] = LDEXPF(1.0, (int) floor_t0);
+ /* Note: GL_NV_vertex_program expects
+ * result.z = result.x * APPX(result.y)
+ * We do what the ARB extension says.
+ */
+ q[2] = (GLfloat) pow(2.0, t[0]);
+ }
+ q[1] = t[0] - floor_t0;
+ q[3] = 1.0F;
+ store_vector4( inst, machine, q );
+ }
+ break;
+ case OPCODE_EX2: /* Exponential base 2 */
+ {
+ GLfloat a[4], result[4], val;
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ val = (GLfloat) pow(2.0, a[0]);
+ /*
+ if (IS_INF_OR_NAN(val))
+ val = 1.0e10;
+ */
+ result[0] = result[1] = result[2] = result[3] = val;
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_FLR:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = FLOORF(a[0]);
+ result[1] = FLOORF(a[1]);
+ result[2] = FLOORF(a[2]);
+ result[3] = FLOORF(a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_FRC:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = a[0] - FLOORF(a[0]);
+ result[1] = a[1] - FLOORF(a[1]);
+ result[2] = a[2] - FLOORF(a[2]);
+ result[3] = a[3] - FLOORF(a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_IF:
+ {
+ GLboolean cond;
+ ASSERT(program->Instructions[inst->BranchTarget].Opcode
+ == OPCODE_ELSE ||
+ program->Instructions[inst->BranchTarget].Opcode
+ == OPCODE_ENDIF);
+ /* eval condition */
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ GLfloat a[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ cond = (a[0] != 0.0);
+ }
+ else {
+ cond = eval_condition(machine, inst);
+ }
+ if (DEBUG_PROG) {
+ printf("IF: %d\n", cond);
+ }
+ /* do if/else */
+ if (cond) {
+ /* do if-clause (just continue execution) */
+ }
+ else {
+ /* go to the instruction after ELSE or ENDIF */
+ assert(inst->BranchTarget >= 0);
+ pc = inst->BranchTarget;
+ }
+ }
+ break;
+ case OPCODE_ELSE:
+ /* goto ENDIF */
+ ASSERT(program->Instructions[inst->BranchTarget].Opcode
+ == OPCODE_ENDIF);
+ assert(inst->BranchTarget >= 0);
+ pc = inst->BranchTarget;
+ break;
+ case OPCODE_ENDIF:
+ /* nothing */
+ break;
+ case OPCODE_KIL_NV: /* NV_f_p only (conditional) */
+ if (eval_condition(machine, inst)) {
+ return GL_FALSE;
+ }
+ break;
+ case OPCODE_KIL: /* ARB_f_p only */
+ {
+ GLfloat a[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ if (DEBUG_PROG) {
+ printf("KIL if (%g %g %g %g) <= 0.0\n",
+ a[0], a[1], a[2], a[3]);
+ }
+
+ if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
+ return GL_FALSE;
+ }
+ }
+ break;
+ case OPCODE_LG2: /* log base 2 */
+ {
+ GLfloat a[4], result[4], val;
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ /* The fast LOG2 macro doesn't meet the precision requirements.
+ */
+ if (a[0] == 0.0F) {
+ val = -FLT_MAX;
+ }
+ else {
+ val = (float)(log(a[0]) * 1.442695F);
+ }
+ result[0] = result[1] = result[2] = result[3] = val;
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_LIT:
+ {
+ const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = MAX2(a[0], 0.0F);
+ a[1] = MAX2(a[1], 0.0F);
+ /* XXX ARB version clamps a[3], NV version doesn't */
+ a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon));
+ result[0] = 1.0F;
+ result[1] = a[0];
+ /* XXX we could probably just use pow() here */
+ if (a[0] > 0.0F) {
+ if (a[1] == 0.0 && a[3] == 0.0)
+ result[2] = 1.0F;
+ else
+ result[2] = (GLfloat) pow(a[1], a[3]);
+ }
+ else {
+ result[2] = 0.0F;
+ }
+ result[3] = 1.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("LIT (%g %g %g %g) : (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3]);
+ }
+ }
+ break;
+ case OPCODE_LOG:
+ {
+ GLfloat t[4], q[4], abs_t0;
+ fetch_vector1(&inst->SrcReg[0], machine, t);
+ abs_t0 = FABSF(t[0]);
+ if (abs_t0 != 0.0F) {
+ if (IS_INF_OR_NAN(abs_t0))
+ {
+ SET_POS_INFINITY(q[0]);
+ q[1] = 1.0F;
+ SET_POS_INFINITY(q[2]);
+ }
+ else {
+ int exponent;
+ GLfloat mantissa = FREXPF(t[0], &exponent);
+ q[0] = (GLfloat) (exponent - 1);
+ q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
+
+ /* The fast LOG2 macro doesn't meet the precision
+ * requirements.
+ */
+ q[2] = (float)(log(t[0]) * 1.442695F);
+ }
+ }
+ else {
+ SET_NEG_INFINITY(q[0]);
+ q[1] = 1.0F;
+ SET_NEG_INFINITY(q[2]);
+ }
+ q[3] = 1.0;
+ store_vector4(inst, machine, q);
+ }
+ break;
+ case OPCODE_LRP:
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
+ result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
+ result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
+ result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("LRP (%g %g %g %g) = (%g %g %g %g), "
+ "(%g %g %g %g), (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
+ }
+ }
+ break;
+ case OPCODE_MAD:
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] * b[0] + c[0];
+ result[1] = a[1] * b[1] + c[1];
+ result[2] = a[2] * b[2] + c[2];
+ result[3] = a[3] * b[3] + c[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MAD (%g %g %g %g) = (%g %g %g %g) * "
+ "(%g %g %g %g) + (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
+ }
+ }
+ break;
+ case OPCODE_MAX:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = MAX2(a[0], b[0]);
+ result[1] = MAX2(a[1], b[1]);
+ result[2] = MAX2(a[2], b[2]);
+ result[3] = MAX2(a[3], b[3]);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_MIN:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = MIN2(a[0], b[0]);
+ result[1] = MIN2(a[1], b[1]);
+ result[2] = MIN2(a[2], b[2]);
+ result[3] = MIN2(a[3], b[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_MOV:
+ {
+ GLfloat result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, result);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MOV (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3]);
+ }
+ }
+ break;
+ case OPCODE_MUL:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[0] * b[0];
+ result[1] = a[1] * b[1];
+ result[2] = a[2] * b[2];
+ result[3] = a[3] * b[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_NOISE1:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = _mesa_noise1(a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOISE2:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] = result[3] = _mesa_noise2(a[0], a[1]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOISE3:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = _mesa_noise3(a[0], a[1], a[2]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOISE4:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = _mesa_noise4(a[0], a[1], a[2], a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOP:
+ break;
+ case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */
+ {
+ GLfloat a[4];
+ GLuint result[4];
+ GLhalfNV hx, hy;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ hx = _mesa_float_to_half(a[0]);
+ hy = _mesa_float_to_half(a[1]);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = hx | (hy << 16);
+ store_vector4ui(inst, machine, result);
+ }
+ break;
+ case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */
+ {
+ GLfloat a[4];
+ GLuint result[4], usx, usy;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = CLAMP(a[0], 0.0F, 1.0F);
+ a[1] = CLAMP(a[1], 0.0F, 1.0F);
+ usx = F_TO_I(a[0] * 65535.0F);
+ usy = F_TO_I(a[1] * 65535.0F);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = usx | (usy << 16);
+ store_vector4ui(inst, machine, result);
+ }
+ break;
+ case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */
+ {
+ GLfloat a[4];
+ GLuint result[4], ubx, uby, ubz, ubw;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
+ a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
+ a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
+ a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F);
+ ubx = F_TO_I(127.0F * a[0] + 128.0F);
+ uby = F_TO_I(127.0F * a[1] + 128.0F);
+ ubz = F_TO_I(127.0F * a[2] + 128.0F);
+ ubw = F_TO_I(127.0F * a[3] + 128.0F);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
+ store_vector4ui(inst, machine, result);
+ }
+ break;
+ case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */
+ {
+ GLfloat a[4];
+ GLuint result[4], ubx, uby, ubz, ubw;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = CLAMP(a[0], 0.0F, 1.0F);
+ a[1] = CLAMP(a[1], 0.0F, 1.0F);
+ a[2] = CLAMP(a[2], 0.0F, 1.0F);
+ a[3] = CLAMP(a[3], 0.0F, 1.0F);
+ ubx = F_TO_I(255.0F * a[0]);
+ uby = F_TO_I(255.0F * a[1]);
+ ubz = F_TO_I(255.0F * a[2]);
+ ubw = F_TO_I(255.0F * a[3]);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
+ store_vector4ui(inst, machine, result);
+ }
+ break;
+ case OPCODE_POW:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ fetch_vector1(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3]
+ = (GLfloat) pow(a[0], b[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+
+ case OPCODE_RCP:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ if (DEBUG_PROG) {
+ if (a[0] == 0)
+ printf("RCP(0)\n");
+ else if (IS_INF_OR_NAN(a[0]))
+ printf("RCP(inf)\n");
+ }
+ result[0] = result[1] = result[2] = result[3] = 1.0F / a[0];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_RET: /* return from subroutine (conditional) */
+ if (eval_condition(machine, inst)) {
+ if (machine->StackDepth == 0) {
+ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
+ }
+ /* subtract one because of pc++ in the for loop */
+ pc = machine->CallStack[--machine->StackDepth] - 1;
+ }
+ break;
+ case OPCODE_RFL: /* reflection vector */
+ {
+ GLfloat axis[4], dir[4], result[4], tmpX, tmpW;
+ fetch_vector4(&inst->SrcReg[0], machine, axis);
+ fetch_vector4(&inst->SrcReg[1], machine, dir);
+ tmpW = DOT3(axis, axis);
+ tmpX = (2.0F * DOT3(axis, dir)) / tmpW;
+ result[0] = tmpX * axis[0] - dir[0];
+ result[1] = tmpX * axis[1] - dir[1];
+ result[2] = tmpX * axis[2] - dir[2];
+ /* result[3] is never written! XXX enforce in parser! */
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_RSQ: /* 1 / sqrt() */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ a[0] = FABSF(a[0]);
+ result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]);
+ }
+ }
+ break;
+ case OPCODE_SCS: /* sine and cos */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = (GLfloat) cos(a[0]);
+ result[1] = (GLfloat) sin(a[0]);
+ result[2] = 0.0; /* undefined! */
+ result[3] = 0.0; /* undefined! */
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SEQ: /* set on equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] == b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SFL: /* set false, operands ignored */
+ {
+ static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SGE: /* set on greater or equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SGT: /* set on greater */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SIN:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = result[1] = result[2] = result[3]
+ = (GLfloat) sin(a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SLE: /* set on less or equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SLT: /* set on less */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] < b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SNE: /* set on not equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] != b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SSG: /* set sign (-1, 0 or +1) */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = (GLfloat) ((a[0] > 0.0F) - (a[0] < 0.0F));
+ result[1] = (GLfloat) ((a[1] > 0.0F) - (a[1] < 0.0F));
+ result[2] = (GLfloat) ((a[2] > 0.0F) - (a[2] < 0.0F));
+ result[3] = (GLfloat) ((a[3] > 0.0F) - (a[3] < 0.0F));
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_STR: /* set true, operands ignored */
+ {
+ static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SUB:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[0] - b[0];
+ result[1] = a[1] - b[1];
+ result[2] = a[2] - b[2];
+ result[3] = a[3] - b[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SWZ: /* extended swizzle */
+ {
+ const struct prog_src_register *source = &inst->SrcReg[0];
+ const GLfloat *src = get_src_register_pointer(source, machine);
+ GLfloat result[4];
+ GLuint i;
+ for (i = 0; i < 4; i++) {
+ const GLuint swz = GET_SWZ(source->Swizzle, i);
+ if (swz == SWIZZLE_ZERO)
+ result[i] = 0.0;
+ else if (swz == SWIZZLE_ONE)
+ result[i] = 1.0;
+ else {
+ ASSERT(swz >= 0);
+ ASSERT(swz <= 3);
+ result[i] = src[swz];
+ }
+ if (source->Negate & (1 << i))
+ result[i] = -result[i];
+ }
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_TEX: /* Both ARB and NV frag prog */
+ /* Simple texel lookup */
+ {
+ GLfloat texcoord[4], color[4];
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+ /* For TEX, texcoord.Q should not be used and its value should not
+ * matter (at most, we pass coord.xyz to texture3D() in GLSL).
+ * Set Q=1 so that FetchTexelDeriv() doesn't get a garbage value
+ * which is effectively what happens when the texcoord swizzle
+ * is .xyzz
+ */
+ texcoord[3] = 1.0f;
+
+ fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
+ if (DEBUG_PROG) {
+ printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n",
+ color[0], color[1], color[2], color[3],
+ inst->TexSrcUnit,
+ texcoord[0], texcoord[1], texcoord[2], texcoord[3]);
+ }
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXB: /* GL_ARB_fragment_program only */
+ /* Texel lookup with LOD bias */
+ {
+ GLfloat texcoord[4], color[4], lodBias;
+
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+ /* texcoord[3] is the bias to add to lambda */
+ lodBias = texcoord[3];
+
+ fetch_texel(ctx, machine, inst, texcoord, lodBias, color);
+
+ if (DEBUG_PROG) {
+ printf("TXB (%g, %g, %g, %g) = texture[%d][%g %g %g %g]"
+ " bias %g\n",
+ color[0], color[1], color[2], color[3],
+ inst->TexSrcUnit,
+ texcoord[0],
+ texcoord[1],
+ texcoord[2],
+ texcoord[3],
+ lodBias);
+ }
+
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXD: /* GL_NV_fragment_program only */
+ /* Texture lookup w/ partial derivatives for LOD */
+ {
+ GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+ fetch_vector4(&inst->SrcReg[1], machine, dtdx);
+ fetch_vector4(&inst->SrcReg[2], machine, dtdy);
+ machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy,
+ 0.0, /* lodBias */
+ inst->TexSrcUnit, color);
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXL:
+ /* Texel lookup with explicit LOD */
+ {
+ GLfloat texcoord[4], color[4], lod;
+
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+ /* texcoord[3] is the LOD */
+ lod = texcoord[3];
+
+ machine->FetchTexelLod(ctx, texcoord, lod,
+ machine->Samplers[inst->TexSrcUnit], color);
+
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXP: /* GL_ARB_fragment_program only */
+ /* Texture lookup w/ projective divide */
+ {
+ GLfloat texcoord[4], color[4];
+
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+ /* Not so sure about this test - if texcoord[3] is
+ * zero, we'd probably be fine except for an ASSERT in
+ * IROUND_POS() which gets triggered by the inf values created.
+ */
+ if (texcoord[3] != 0.0) {
+ texcoord[0] /= texcoord[3];
+ texcoord[1] /= texcoord[3];
+ texcoord[2] /= texcoord[3];
+ }
+
+ fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXP_NV: /* GL_NV_fragment_program only */
+ /* Texture lookup w/ projective divide, as above, but do not
+ * do the divide by w if sampling from a cube map.
+ */
+ {
+ GLfloat texcoord[4], color[4];
+
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+ if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
+ texcoord[3] != 0.0) {
+ texcoord[0] /= texcoord[3];
+ texcoord[1] /= texcoord[3];
+ texcoord[2] /= texcoord[3];
+ }
+
+ fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TRUNC: /* truncate toward zero */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = (GLfloat) (GLint) a[0];
+ result[1] = (GLfloat) (GLint) a[1];
+ result[2] = (GLfloat) (GLint) a[2];
+ result[3] = (GLfloat) (GLint) a[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_UP2H: /* unpack two 16-bit floats */
+ {
+ const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+ GLfloat result[4];
+ GLushort hx, hy;
+ hx = raw & 0xffff;
+ hy = raw >> 16;
+ result[0] = result[2] = _mesa_half_to_float(hx);
+ result[1] = result[3] = _mesa_half_to_float(hy);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_UP2US: /* unpack two GLushorts */
+ {
+ const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+ GLfloat result[4];
+ GLushort usx, usy;
+ usx = raw & 0xffff;
+ usy = raw >> 16;
+ result[0] = result[2] = usx * (1.0f / 65535.0f);
+ result[1] = result[3] = usy * (1.0f / 65535.0f);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_UP4B: /* unpack four GLbytes */
+ {
+ const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+ GLfloat result[4];
+ result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F;
+ result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F;
+ result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F;
+ result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F;
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_UP4UB: /* unpack four GLubytes */
+ {
+ const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+ GLfloat result[4];
+ result[0] = ((raw >> 0) & 0xff) / 255.0F;
+ result[1] = ((raw >> 8) & 0xff) / 255.0F;
+ result[2] = ((raw >> 16) & 0xff) / 255.0F;
+ result[3] = ((raw >> 24) & 0xff) / 255.0F;
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_XPD: /* cross product */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[1] * b[2] - a[2] * b[1];
+ result[1] = a[2] * b[0] - a[0] * b[2];
+ result[2] = a[0] * b[1] - a[1] * b[0];
+ result[3] = 1.0;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], b[0], b[1], b[2]);
+ }
+ }
+ break;
+ case OPCODE_X2D: /* 2-D matrix transform */
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
+ result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
+ result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
+ result[3] = a[3] + b[0] * c[2] + b[1] * c[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_END:
+ return GL_TRUE;
+ default:
+ _mesa_problem(ctx, "Bad opcode %d in _mesa_execute_program",
+ inst->Opcode);
+ return GL_TRUE; /* return value doesn't matter */
+ }
+
+ numExec++;
+ if (numExec > maxExec) {
+ static GLboolean reported = GL_FALSE;
+ if (!reported) {
+ _mesa_problem(ctx, "Infinite loop detected in fragment program");
+ reported = GL_TRUE;
+ }
+ return GL_TRUE;
+ }
+
+ } /* for pc */
+
+ return GL_TRUE;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_execute.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_execute.h
new file mode 100644
index 0000000..09542bf
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_execute.h
@@ -0,0 +1,91 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PROG_EXECUTE_H
+#define PROG_EXECUTE_H
+
+#include "main/config.h"
+#include "main/mtypes.h"
+
+
+typedef void (*FetchTexelLodFunc)(struct gl_context *ctx, const GLfloat texcoord[4],
+ GLfloat lambda, GLuint unit, GLfloat color[4]);
+
+typedef void (*FetchTexelDerivFunc)(struct gl_context *ctx, const GLfloat texcoord[4],
+ const GLfloat texdx[4],
+ const GLfloat texdy[4],
+ GLfloat lodBias,
+ GLuint unit, GLfloat color[4]);
+
+
+/** NOTE: This must match SWRAST_MAX_WIDTH */
+#define PROG_MAX_WIDTH 16384
+
+
+/**
+ * Virtual machine state used during execution of vertex/fragment programs.
+ */
+struct gl_program_machine
+{
+ const struct gl_program *CurProgram;
+
+ /** Fragment Input attributes */
+ GLfloat (*Attribs)[PROG_MAX_WIDTH][4];
+ GLfloat (*DerivX)[4];
+ GLfloat (*DerivY)[4];
+ GLuint NumDeriv; /**< Max index into DerivX/Y arrays */
+ GLuint CurElement; /**< Index into Attribs arrays */
+
+ /** Vertex Input attribs */
+ GLfloat VertAttribs[VERT_ATTRIB_MAX][4];
+
+ GLfloat Temporaries[MAX_PROGRAM_TEMPS][4];
+ GLfloat Outputs[MAX_PROGRAM_OUTPUTS][4];
+ GLfloat (*EnvParams)[4]; /**< Vertex or Fragment env parameters */
+ GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
+ GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
+ GLfloat SystemValues[SYSTEM_VALUE_MAX][4];
+
+ const GLubyte *Samplers; /** Array mapping sampler var to tex unit */
+
+ GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
+ GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
+
+ /** Texture fetch functions */
+ FetchTexelLodFunc FetchTexelLod;
+ FetchTexelDerivFunc FetchTexelDeriv;
+};
+
+
+extern void
+_mesa_get_program_register(struct gl_context *ctx, gl_register_file file,
+ GLuint index, GLfloat val[4]);
+
+extern GLboolean
+_mesa_execute_program(struct gl_context *ctx,
+ const struct gl_program *program,
+ struct gl_program_machine *machine);
+
+
+#endif /* PROG_EXECUTE_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_hash_table.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_hash_table.c
new file mode 100644
index 0000000..f45ed46
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_hash_table.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file hash_table.c
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "hash_table.h"
+
+struct node {
+ struct node *next;
+ struct node *prev;
+};
+
+struct hash_table {
+ hash_func_t hash;
+ hash_compare_func_t compare;
+
+ unsigned num_buckets;
+ struct node buckets[1];
+};
+
+
+struct hash_node {
+ struct node link;
+ const void *key;
+ void *data;
+};
+
+
+struct hash_table *
+hash_table_ctor(unsigned num_buckets, hash_func_t hash,
+ hash_compare_func_t compare)
+{
+ struct hash_table *ht;
+ unsigned i;
+
+
+ if (num_buckets < 16) {
+ num_buckets = 16;
+ }
+
+ ht = malloc(sizeof(*ht) + ((num_buckets - 1)
+ * sizeof(ht->buckets[0])));
+ if (ht != NULL) {
+ ht->hash = hash;
+ ht->compare = compare;
+ ht->num_buckets = num_buckets;
+
+ for (i = 0; i < num_buckets; i++) {
+ make_empty_list(& ht->buckets[i]);
+ }
+ }
+
+ return ht;
+}
+
+
+void
+hash_table_dtor(struct hash_table *ht)
+{
+ hash_table_clear(ht);
+ free(ht);
+}
+
+
+void
+hash_table_clear(struct hash_table *ht)
+{
+ struct node *node;
+ struct node *temp;
+ unsigned i;
+
+
+ for (i = 0; i < ht->num_buckets; i++) {
+ foreach_s(node, temp, & ht->buckets[i]) {
+ remove_from_list(node);
+ free(node);
+ }
+
+ assert(is_empty_list(& ht->buckets[i]));
+ }
+}
+
+
+static struct hash_node *
+get_node(struct hash_table *ht, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct node *node;
+
+ foreach(node, & ht->buckets[bucket]) {
+ struct hash_node *hn = (struct hash_node *) node;
+
+ if ((*ht->compare)(hn->key, key) == 0) {
+ return hn;
+ }
+ }
+
+ return NULL;
+}
+
+void *
+hash_table_find(struct hash_table *ht, const void *key)
+{
+ struct hash_node *hn = get_node(ht, key);
+
+ return (hn == NULL) ? NULL : hn->data;
+}
+
+void
+hash_table_insert(struct hash_table *ht, void *data, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct hash_node *node;
+
+ node = calloc(1, sizeof(*node));
+
+ node->data = data;
+ node->key = key;
+
+ insert_at_head(& ht->buckets[bucket], & node->link);
+}
+
+bool
+hash_table_replace(struct hash_table *ht, void *data, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct node *node;
+ struct hash_node *hn;
+
+ foreach(node, & ht->buckets[bucket]) {
+ hn = (struct hash_node *) node;
+
+ if ((*ht->compare)(hn->key, key) == 0) {
+ hn->data = data;
+ return true;
+ }
+ }
+
+ hn = calloc(1, sizeof(*hn));
+
+ hn->data = data;
+ hn->key = key;
+
+ insert_at_head(& ht->buckets[bucket], & hn->link);
+ return false;
+}
+
+void
+hash_table_remove(struct hash_table *ht, const void *key)
+{
+ struct node *node = (struct node *) get_node(ht, key);
+ if (node != NULL) {
+ remove_from_list(node);
+ free(node);
+ return;
+ }
+}
+
+void
+hash_table_call_foreach(struct hash_table *ht,
+ void (*callback)(const void *key,
+ void *data,
+ void *closure),
+ void *closure)
+{
+ unsigned bucket;
+
+ for (bucket = 0; bucket < ht->num_buckets; bucket++) {
+ struct node *node, *temp;
+ foreach_s(node, temp, &ht->buckets[bucket]) {
+ struct hash_node *hn = (struct hash_node *) node;
+
+ callback(hn->key, hn->data, closure);
+ }
+ }
+}
+
+unsigned
+hash_table_string_hash(const void *key)
+{
+ const char *str = (const char *) key;
+ unsigned hash = 5381;
+
+
+ while (*str != '\0') {
+ hash = (hash * 33) + *str;
+ str++;
+ }
+
+ return hash;
+}
+
+
+unsigned
+hash_table_pointer_hash(const void *key)
+{
+ return (unsigned)((uintptr_t) key / sizeof(void *));
+}
+
+
+int
+hash_table_pointer_compare(const void *key1, const void *key2)
+{
+ return key1 == key2 ? 0 : 1;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_instruction.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_instruction.c
new file mode 100644
index 0000000..dcfedb7
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_instruction.c
@@ -0,0 +1,334 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "prog_instruction.h"
+
+
+/**
+ * Initialize program instruction fields to defaults.
+ * \param inst first instruction to initialize
+ * \param count number of instructions to initialize
+ */
+void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
+{
+ GLuint i;
+
+ memset(inst, 0, count * sizeof(struct prog_instruction));
+
+ for (i = 0; i < count; i++) {
+ inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
+ inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+
+ inst[i].DstReg.File = PROGRAM_UNDEFINED;
+ inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ inst[i].DstReg.CondMask = COND_TR;
+ inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
+
+ inst[i].SaturateMode = SATURATE_OFF;
+ inst[i].Precision = FLOAT32;
+ }
+}
+
+
+/**
+ * Allocate an array of program instructions.
+ * \param numInst number of instructions
+ * \return pointer to instruction memory
+ */
+struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst)
+{
+ return
+ calloc(1, numInst * sizeof(struct prog_instruction));
+}
+
+
+/**
+ * Reallocate memory storing an array of program instructions.
+ * This is used when we need to append additional instructions onto an
+ * program.
+ * \param oldInst pointer to first of old/src instructions
+ * \param numOldInst number of instructions at <oldInst>
+ * \param numNewInst desired size of new instruction array.
+ * \return pointer to start of new instruction array.
+ */
+struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+ GLuint numOldInst, GLuint numNewInst)
+{
+ struct prog_instruction *newInst;
+
+ newInst = (struct prog_instruction *)
+ _mesa_realloc(oldInst,
+ numOldInst * sizeof(struct prog_instruction),
+ numNewInst * sizeof(struct prog_instruction));
+
+ return newInst;
+}
+
+
+/**
+ * Copy an array of program instructions.
+ * \param dest pointer to destination.
+ * \param src pointer to source.
+ * \param n number of instructions to copy.
+ * \return pointer to destination.
+ */
+struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+ const struct prog_instruction *src, GLuint n)
+{
+ GLuint i;
+ memcpy(dest, src, n * sizeof(struct prog_instruction));
+ for (i = 0; i < n; i++) {
+ if (src[i].Comment)
+ dest[i].Comment = _mesa_strdup(src[i].Comment);
+ }
+ return dest;
+}
+
+
+/**
+ * Free an array of instructions
+ */
+void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
+{
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ free((char *)inst[i].Comment);
+ }
+ free(inst);
+}
+
+
+/**
+ * Basic info about each instruction
+ */
+struct instruction_info
+{
+ gl_inst_opcode Opcode;
+ const char *Name;
+ GLuint NumSrcRegs;
+ GLuint NumDstRegs;
+};
+
+/**
+ * Instruction info
+ * \note Opcode should equal array index!
+ */
+static const struct instruction_info InstInfo[MAX_OPCODE] = {
+ { OPCODE_NOP, "NOP", 0, 0 },
+ { OPCODE_ABS, "ABS", 1, 1 },
+ { OPCODE_ADD, "ADD", 2, 1 },
+ { OPCODE_ARL, "ARL", 1, 1 },
+ { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
+ { OPCODE_BGNSUB, "BGNSUB", 0, 0 },
+ { OPCODE_BRK, "BRK", 0, 0 },
+ { OPCODE_CAL, "CAL", 0, 0 },
+ { OPCODE_CMP, "CMP", 3, 1 },
+ { OPCODE_CONT, "CONT", 0, 0 },
+ { OPCODE_COS, "COS", 1, 1 },
+ { OPCODE_DDX, "DDX", 1, 1 },
+ { OPCODE_DDY, "DDY", 1, 1 },
+ { OPCODE_DP2, "DP2", 2, 1 },
+ { OPCODE_DP3, "DP3", 2, 1 },
+ { OPCODE_DP4, "DP4", 2, 1 },
+ { OPCODE_DPH, "DPH", 2, 1 },
+ { OPCODE_DST, "DST", 2, 1 },
+ { OPCODE_ELSE, "ELSE", 0, 0 },
+ { OPCODE_END, "END", 0, 0 },
+ { OPCODE_ENDIF, "ENDIF", 0, 0 },
+ { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
+ { OPCODE_ENDSUB, "ENDSUB", 0, 0 },
+ { OPCODE_EX2, "EX2", 1, 1 },
+ { OPCODE_EXP, "EXP", 1, 1 },
+ { OPCODE_FLR, "FLR", 1, 1 },
+ { OPCODE_FRC, "FRC", 1, 1 },
+ { OPCODE_IF, "IF", 1, 0 },
+ { OPCODE_KIL, "KIL", 1, 0 },
+ { OPCODE_KIL_NV, "KIL_NV", 0, 0 },
+ { OPCODE_LG2, "LG2", 1, 1 },
+ { OPCODE_LIT, "LIT", 1, 1 },
+ { OPCODE_LOG, "LOG", 1, 1 },
+ { OPCODE_LRP, "LRP", 3, 1 },
+ { OPCODE_MAD, "MAD", 3, 1 },
+ { OPCODE_MAX, "MAX", 2, 1 },
+ { OPCODE_MIN, "MIN", 2, 1 },
+ { OPCODE_MOV, "MOV", 1, 1 },
+ { OPCODE_MUL, "MUL", 2, 1 },
+ { OPCODE_NOISE1, "NOISE1", 1, 1 },
+ { OPCODE_NOISE2, "NOISE2", 1, 1 },
+ { OPCODE_NOISE3, "NOISE3", 1, 1 },
+ { OPCODE_NOISE4, "NOISE4", 1, 1 },
+ { OPCODE_PK2H, "PK2H", 1, 1 },
+ { OPCODE_PK2US, "PK2US", 1, 1 },
+ { OPCODE_PK4B, "PK4B", 1, 1 },
+ { OPCODE_PK4UB, "PK4UB", 1, 1 },
+ { OPCODE_POW, "POW", 2, 1 },
+ { OPCODE_RCP, "RCP", 1, 1 },
+ { OPCODE_RET, "RET", 0, 0 },
+ { OPCODE_RFL, "RFL", 1, 1 },
+ { OPCODE_RSQ, "RSQ", 1, 1 },
+ { OPCODE_SCS, "SCS", 1, 1 },
+ { OPCODE_SEQ, "SEQ", 2, 1 },
+ { OPCODE_SFL, "SFL", 0, 1 },
+ { OPCODE_SGE, "SGE", 2, 1 },
+ { OPCODE_SGT, "SGT", 2, 1 },
+ { OPCODE_SIN, "SIN", 1, 1 },
+ { OPCODE_SLE, "SLE", 2, 1 },
+ { OPCODE_SLT, "SLT", 2, 1 },
+ { OPCODE_SNE, "SNE", 2, 1 },
+ { OPCODE_SSG, "SSG", 1, 1 },
+ { OPCODE_STR, "STR", 0, 1 },
+ { OPCODE_SUB, "SUB", 2, 1 },
+ { OPCODE_SWZ, "SWZ", 1, 1 },
+ { OPCODE_TEX, "TEX", 1, 1 },
+ { OPCODE_TXB, "TXB", 1, 1 },
+ { OPCODE_TXD, "TXD", 3, 1 },
+ { OPCODE_TXL, "TXL", 1, 1 },
+ { OPCODE_TXP, "TXP", 1, 1 },
+ { OPCODE_TXP_NV, "TXP_NV", 1, 1 },
+ { OPCODE_TRUNC, "TRUNC", 1, 1 },
+ { OPCODE_UP2H, "UP2H", 1, 1 },
+ { OPCODE_UP2US, "UP2US", 1, 1 },
+ { OPCODE_UP4B, "UP4B", 1, 1 },
+ { OPCODE_UP4UB, "UP4UB", 1, 1 },
+ { OPCODE_X2D, "X2D", 3, 1 },
+ { OPCODE_XPD, "XPD", 2, 1 }
+};
+
+
+/**
+ * Return the number of src registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode)
+{
+ ASSERT(opcode < MAX_OPCODE);
+ ASSERT(opcode == InstInfo[opcode].Opcode);
+ ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+ return InstInfo[opcode].NumSrcRegs;
+}
+
+
+/**
+ * Return the number of dst registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
+{
+ ASSERT(opcode < MAX_OPCODE);
+ ASSERT(opcode == InstInfo[opcode].Opcode);
+ ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+ return InstInfo[opcode].NumDstRegs;
+}
+
+
+GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode)
+{
+ return (opcode == OPCODE_TEX ||
+ opcode == OPCODE_TXB ||
+ opcode == OPCODE_TXD ||
+ opcode == OPCODE_TXL ||
+ opcode == OPCODE_TXP);
+}
+
+
+/**
+ * Check if there's a potential src/dst register data dependency when
+ * using SOA execution.
+ * Example:
+ * MOV T, T.yxwz;
+ * This would expand into:
+ * MOV t0, t1;
+ * MOV t1, t0;
+ * MOV t2, t3;
+ * MOV t3, t2;
+ * The second instruction will have the wrong value for t0 if executed as-is.
+ */
+GLboolean
+_mesa_check_soa_dependencies(const struct prog_instruction *inst)
+{
+ GLuint i, chan;
+
+ if (inst->DstReg.WriteMask == WRITEMASK_X ||
+ inst->DstReg.WriteMask == WRITEMASK_Y ||
+ inst->DstReg.WriteMask == WRITEMASK_Z ||
+ inst->DstReg.WriteMask == WRITEMASK_W ||
+ inst->DstReg.WriteMask == 0x0) {
+ /* no chance of data dependency */
+ return GL_FALSE;
+ }
+
+ /* loop over src regs */
+ for (i = 0; i < 3; i++) {
+ if (inst->SrcReg[i].File == inst->DstReg.File &&
+ inst->SrcReg[i].Index == inst->DstReg.Index) {
+ /* loop over dest channels */
+ GLuint channelsWritten = 0x0;
+ for (chan = 0; chan < 4; chan++) {
+ if (inst->DstReg.WriteMask & (1 << chan)) {
+ /* check if we're reading a channel that's been written */
+ GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
+ if (swizzle <= SWIZZLE_W &&
+ (channelsWritten & (1 << swizzle))) {
+ return GL_TRUE;
+ }
+
+ channelsWritten |= (1 << chan);
+ }
+ }
+ }
+ }
+ return GL_FALSE;
+}
+
+
+/**
+ * Return string name for given program opcode.
+ */
+const char *
+_mesa_opcode_string(gl_inst_opcode opcode)
+{
+ if (opcode < MAX_OPCODE)
+ return InstInfo[opcode].Name;
+ else {
+ static char s[20];
+ _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
+ return s;
+ }
+}
+
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_instruction.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_instruction.h
new file mode 100644
index 0000000..b9604e5
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_instruction.h
@@ -0,0 +1,430 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file prog_instruction.h
+ *
+ * Vertex/fragment program instruction datatypes and constants.
+ *
+ * \author Brian Paul
+ * \author Keith Whitwell
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+
+#ifndef PROG_INSTRUCTION_H
+#define PROG_INSTRUCTION_H
+
+
+#include "main/glheader.h"
+
+
+/**
+ * Swizzle indexes.
+ * Do not change!
+ */
+/*@{*/
+#define SWIZZLE_X 0
+#define SWIZZLE_Y 1
+#define SWIZZLE_Z 2
+#define SWIZZLE_W 3
+#define SWIZZLE_ZERO 4 /**< For SWZ instruction only */
+#define SWIZZLE_ONE 5 /**< For SWZ instruction only */
+#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */
+/*@}*/
+
+#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
+#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3)
+#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
+#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
+
+#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
+#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
+#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
+#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
+#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/**
+ * Writemask values, 1 bit per component.
+ */
+/*@{*/
+#define WRITEMASK_X 0x1
+#define WRITEMASK_Y 0x2
+#define WRITEMASK_XY 0x3
+#define WRITEMASK_Z 0x4
+#define WRITEMASK_XZ 0x5
+#define WRITEMASK_YZ 0x6
+#define WRITEMASK_XYZ 0x7
+#define WRITEMASK_W 0x8
+#define WRITEMASK_XW 0x9
+#define WRITEMASK_YW 0xa
+#define WRITEMASK_XYW 0xb
+#define WRITEMASK_ZW 0xc
+#define WRITEMASK_XZW 0xd
+#define WRITEMASK_YZW 0xe
+#define WRITEMASK_XYZW 0xf
+/*@}*/
+
+
+/**
+ * Condition codes
+ */
+/*@{*/
+#define COND_GT 1 /**< greater than zero */
+#define COND_EQ 2 /**< equal to zero */
+#define COND_LT 3 /**< less than zero */
+#define COND_UN 4 /**< unordered (NaN) */
+#define COND_GE 5 /**< greater than or equal to zero */
+#define COND_LE 6 /**< less than or equal to zero */
+#define COND_NE 7 /**< not equal to zero */
+#define COND_TR 8 /**< always true */
+#define COND_FL 9 /**< always false */
+/*@}*/
+
+
+/**
+ * Instruction precision for GL_NV_fragment_program
+ */
+/*@{*/
+#define FLOAT32 0x1
+#define FLOAT16 0x2
+#define FIXED12 0x4
+/*@}*/
+
+
+/**
+ * Saturation modes when storing values.
+ */
+/*@{*/
+#define SATURATE_OFF 0
+#define SATURATE_ZERO_ONE 1
+/*@}*/
+
+
+/**
+ * Per-component negation masks
+ */
+/*@{*/
+#define NEGATE_X 0x1
+#define NEGATE_Y 0x2
+#define NEGATE_Z 0x4
+#define NEGATE_W 0x8
+#define NEGATE_XYZ 0x7
+#define NEGATE_XYZW 0xf
+#define NEGATE_NONE 0x0
+/*@}*/
+
+
+/**
+ * Program instruction opcodes for vertex, fragment and geometry programs.
+ */
+typedef enum prog_opcode {
+ /* ARB_vp ARB_fp NV_vp NV_fp GLSL */
+ /*------------------------------------------*/
+ OPCODE_NOP = 0, /* X */
+ OPCODE_ABS, /* X X 1.1 X */
+ OPCODE_ADD, /* X X X X X */
+ OPCODE_ARL, /* X X X */
+ OPCODE_BGNLOOP, /* opt */
+ OPCODE_BGNSUB, /* opt */
+ OPCODE_BRK, /* 2 opt */
+ OPCODE_CAL, /* 2 2 opt */
+ OPCODE_CMP, /* X X */
+ OPCODE_CONT, /* opt */
+ OPCODE_COS, /* X 2 X X */
+ OPCODE_DDX, /* X X */
+ OPCODE_DDY, /* X X */
+ OPCODE_DP2, /* 2 X */
+ OPCODE_DP3, /* X X X X X */
+ OPCODE_DP4, /* X X X X X */
+ OPCODE_DPH, /* X X 1.1 */
+ OPCODE_DST, /* X X X X */
+ OPCODE_ELSE, /* opt */
+ OPCODE_END, /* X X X X opt */
+ OPCODE_ENDIF, /* opt */
+ OPCODE_ENDLOOP, /* opt */
+ OPCODE_ENDSUB, /* opt */
+ OPCODE_EX2, /* X X 2 X X */
+ OPCODE_EXP, /* X X */
+ OPCODE_FLR, /* X X 2 X X */
+ OPCODE_FRC, /* X X 2 X X */
+ OPCODE_IF, /* opt */
+ OPCODE_KIL, /* X X */
+ OPCODE_KIL_NV, /* X X */
+ OPCODE_LG2, /* X X 2 X X */
+ OPCODE_LIT, /* X X X X */
+ OPCODE_LOG, /* X X */
+ OPCODE_LRP, /* X X */
+ OPCODE_MAD, /* X X X X X */
+ OPCODE_MAX, /* X X X X X */
+ OPCODE_MIN, /* X X X X X */
+ OPCODE_MOV, /* X X X X X */
+ OPCODE_MUL, /* X X X X X */
+ OPCODE_NOISE1, /* X */
+ OPCODE_NOISE2, /* X */
+ OPCODE_NOISE3, /* X */
+ OPCODE_NOISE4, /* X */
+ OPCODE_PK2H, /* X */
+ OPCODE_PK2US, /* X */
+ OPCODE_PK4B, /* X */
+ OPCODE_PK4UB, /* X */
+ OPCODE_POW, /* X X X X */
+ OPCODE_RCP, /* X X X X X */
+ OPCODE_RET, /* 2 2 opt */
+ OPCODE_RFL, /* X */
+ OPCODE_RSQ, /* X X X X X */
+ OPCODE_SCS, /* X X */
+ OPCODE_SEQ, /* 2 X X */
+ OPCODE_SFL, /* 2 X */
+ OPCODE_SGE, /* X X X X X */
+ OPCODE_SGT, /* 2 X X */
+ OPCODE_SIN, /* X 2 X X */
+ OPCODE_SLE, /* 2 X X */
+ OPCODE_SLT, /* X X X X X */
+ OPCODE_SNE, /* 2 X X */
+ OPCODE_SSG, /* 2 X */
+ OPCODE_STR, /* 2 X */
+ OPCODE_SUB, /* X X 1.1 X X */
+ OPCODE_SWZ, /* X X X */
+ OPCODE_TEX, /* X 3 X X */
+ OPCODE_TXB, /* X 3 X */
+ OPCODE_TXD, /* X X */
+ OPCODE_TXL, /* 3 2 X */
+ OPCODE_TXP, /* X X */
+ OPCODE_TXP_NV, /* 3 X */
+ OPCODE_TRUNC, /* X */
+ OPCODE_UP2H, /* X */
+ OPCODE_UP2US, /* X */
+ OPCODE_UP4B, /* X */
+ OPCODE_UP4UB, /* X */
+ OPCODE_X2D, /* X */
+ OPCODE_XPD, /* X X */
+ MAX_OPCODE
+} gl_inst_opcode;
+
+
+/**
+ * Number of bits for the src/dst register Index field.
+ * This limits the size of temp/uniform register files.
+ */
+#define INST_INDEX_BITS 12
+
+
+/**
+ * Instruction source register.
+ */
+struct prog_src_register
+{
+ GLuint File:4; /**< One of the PROGRAM_* register file values. */
+ GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
+ * May be negative for relative addressing.
+ */
+ GLuint Swizzle:12;
+ GLuint RelAddr:1;
+
+ /** Take the component-wise absolute value */
+ GLuint Abs:1;
+
+ /**
+ * Post-Abs negation.
+ * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ
+ * instruction which allows per-component negation.
+ */
+ GLuint Negate:4;
+
+ /**
+ * Is the register two-dimensional.
+ * Two dimensional registers are of the
+ * REGISTER[index][index2] format.
+ * They are used by the geometry shaders where
+ * the first index is the index within an array
+ * and the second index is the semantic of the
+ * array, e.g. gl_PositionIn[index] would become
+ * INPUT[index][gl_PositionIn]
+ */
+ GLuint HasIndex2:1;
+ GLuint RelAddr2:1;
+ GLint Index2:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
+ * May be negative for relative
+ * addressing. */
+};
+
+
+/**
+ * Instruction destination register.
+ */
+struct prog_dst_register
+{
+ GLuint File:4; /**< One of the PROGRAM_* register file values */
+ GLuint Index:INST_INDEX_BITS; /**< Unsigned, never negative */
+ GLuint WriteMask:4;
+ GLuint RelAddr:1;
+
+ /**
+ * \name Conditional destination update control.
+ *
+ * \since
+ * NV_fragment_program_option, NV_vertex_program2, NV_vertex_program2_option.
+ */
+ /*@{*/
+ /**
+ * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
+ * NE, TR, or UN). Dest reg is only written to if the matching
+ * (swizzled) condition code value passes. When a conditional update mask
+ * is not specified, this will be \c COND_TR.
+ */
+ GLuint CondMask:4;
+
+ /**
+ * Condition code swizzle value.
+ */
+ GLuint CondSwizzle:12;
+};
+
+
+/**
+ * Vertex/fragment program instruction.
+ */
+struct prog_instruction
+{
+ gl_inst_opcode Opcode;
+ struct prog_src_register SrcReg[3];
+ struct prog_dst_register DstReg;
+
+ /**
+ * Indicates that the instruction should update the condition code
+ * register.
+ *
+ * \since
+ * NV_fragment_program_option, NV_vertex_program2, NV_vertex_program2_option.
+ */
+ GLuint CondUpdate:1;
+
+ /**
+ * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
+ * condition code register that is to be updated.
+ *
+ * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
+ * code register 0 is available. In GL_NV_vertex_program3 mode, condition
+ * code registers 0 and 1 are available.
+ *
+ * \since
+ * NV_fragment_program_option, NV_vertex_program2, NV_vertex_program2_option.
+ */
+ GLuint CondDst:1;
+
+ /**
+ * Saturate each value of the vectored result to the range [0,1] or the
+ * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is
+ * only available in NV_fragment_program2 mode.
+ * Value is one of the SATURATE_* tokens.
+ *
+ * \since
+ * NV_fragment_program_option, NV_vertex_program3.
+ */
+ GLuint SaturateMode:2;
+
+ /**
+ * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
+ *
+ * \since
+ * NV_fragment_program_option.
+ */
+ GLuint Precision:3;
+
+ /**
+ * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
+ */
+ /*@{*/
+ /** Source texture unit. */
+ GLuint TexSrcUnit:5;
+
+ /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
+ GLuint TexSrcTarget:4;
+
+ /** True if tex instruction should do shadow comparison */
+ GLuint TexShadow:1;
+ /*@}*/
+
+ /**
+ * For BRA and CAL instructions, the location to jump to.
+ * For BGNLOOP, points to ENDLOOP (and vice-versa).
+ * For BRK, points to ENDLOOP
+ * For IF, points to ELSE or ENDIF.
+ * For ELSE, points to ENDIF.
+ */
+ GLint BranchTarget;
+
+ /** for debugging purposes */
+ const char *Comment;
+
+ /** for driver use (try to remove someday) */
+ GLint Aux;
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
+
+extern struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst);
+
+extern struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+ GLuint numOldInst, GLuint numNewInst);
+
+extern struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+ const struct prog_instruction *src, GLuint n);
+
+extern void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
+
+extern GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode);
+
+extern GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_check_soa_dependencies(const struct prog_instruction *inst);
+
+extern const char *
+_mesa_opcode_string(gl_inst_opcode opcode);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PROG_INSTRUCTION_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_noise.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_noise.c
new file mode 100644
index 0000000..ac920c2
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_noise.c
@@ -0,0 +1,638 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * SimplexNoise1234
+ * Copyright (c) 2003-2005, Stefan Gustavson
+ *
+ * Contact: stegu@itn.liu.se
+ */
+
+/**
+ * \file
+ * \brief C implementation of Perlin Simplex Noise over 1, 2, 3 and 4 dims.
+ * \author Stefan Gustavson (stegu@itn.liu.se)
+ *
+ *
+ * This implementation is "Simplex Noise" as presented by
+ * Ken Perlin at a relatively obscure and not often cited course
+ * session "Real-Time Shading" at Siggraph 2001 (before real
+ * time shading actually took on), under the title "hardware noise".
+ * The 3D function is numerically equivalent to his Java reference
+ * code available in the PDF course notes, although I re-implemented
+ * it from scratch to get more readable code. The 1D, 2D and 4D cases
+ * were implemented from scratch by me from Ken Perlin's text.
+ *
+ * This file has no dependencies on any other file, not even its own
+ * header file. The header file is made for use by external code only.
+ */
+
+
+#include "main/imports.h"
+#include "prog_noise.h"
+
+#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) )
+
+/*
+ * ---------------------------------------------------------------------
+ * Static data
+ */
+
+/**
+ * Permutation table. This is just a random jumble of all numbers 0-255,
+ * repeated twice to avoid wrapping the index at 255 for each lookup.
+ * This needs to be exactly the same for all instances on all platforms,
+ * so it's easiest to just keep it as static explicit data.
+ * This also removes the need for any initialisation of this class.
+ *
+ * Note that making this an int[] instead of a char[] might make the
+ * code run faster on platforms with a high penalty for unaligned single
+ * byte addressing. Intel x86 is generally single-byte-friendly, but
+ * some other CPUs are faster with 4-aligned reads.
+ * However, a char[] is smaller, which avoids cache trashing, and that
+ * is probably the most important aspect on most architectures.
+ * This array is accessed a *lot* by the noise functions.
+ * A vector-valued noise over 3D accesses it 96 times, and a
+ * float-valued 4D noise 64 times. We want this to fit in the cache!
+ */
+static const unsigned char perm[512] = { 151, 160, 137, 91, 90, 15,
+ 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8,
+ 99, 37, 240, 21, 10, 23,
+ 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35,
+ 11, 32, 57, 177, 33,
+ 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
+ 134, 139, 48, 27, 166,
+ 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
+ 55, 46, 245, 40, 244,
+ 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
+ 18, 169, 200, 196,
+ 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217,
+ 226, 250, 124, 123,
+ 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,
+ 17, 182, 189, 28, 42,
+ 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155,
+ 167, 43, 172, 9,
+ 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
+ 218, 246, 97, 228,
+ 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235,
+ 249, 14, 239, 107,
+ 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45,
+ 127, 4, 150, 254,
+ 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66,
+ 215, 61, 156, 180,
+ 151, 160, 137, 91, 90, 15,
+ 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8,
+ 99, 37, 240, 21, 10, 23,
+ 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35,
+ 11, 32, 57, 177, 33,
+ 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
+ 134, 139, 48, 27, 166,
+ 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
+ 55, 46, 245, 40, 244,
+ 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
+ 18, 169, 200, 196,
+ 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217,
+ 226, 250, 124, 123,
+ 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,
+ 17, 182, 189, 28, 42,
+ 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155,
+ 167, 43, 172, 9,
+ 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
+ 218, 246, 97, 228,
+ 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235,
+ 249, 14, 239, 107,
+ 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45,
+ 127, 4, 150, 254,
+ 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66,
+ 215, 61, 156, 180
+};
+
+/*
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * Helper functions to compute gradients-dot-residualvectors (1D to 4D)
+ * Note that these generate gradients of more than unit length. To make
+ * a close match with the value range of classic Perlin noise, the final
+ * noise values need to be rescaled to fit nicely within [-1,1].
+ * (The simplex noise functions as such also have different scaling.)
+ * Note also that these noise functions are the most practical and useful
+ * signed version of Perlin noise. To return values according to the
+ * RenderMan specification from the SL noise() and pnoise() functions,
+ * the noise values need to be scaled and offset to [0,1], like this:
+ * float SLnoise = (SimplexNoise1234::noise(x,y,z) + 1.0) * 0.5;
+ */
+
+static float
+grad1(int hash, float x)
+{
+ int h = hash & 15;
+ float grad = 1.0f + (h & 7); /* Gradient value 1.0, 2.0, ..., 8.0 */
+ if (h & 8)
+ grad = -grad; /* Set a random sign for the gradient */
+ return (grad * x); /* Multiply the gradient with the distance */
+}
+
+static float
+grad2(int hash, float x, float y)
+{
+ int h = hash & 7; /* Convert low 3 bits of hash code */
+ float u = h < 4 ? x : y; /* into 8 simple gradient directions, */
+ float v = h < 4 ? y : x; /* and compute the dot product with (x,y). */
+ return ((h & 1) ? -u : u) + ((h & 2) ? -2.0f * v : 2.0f * v);
+}
+
+static float
+grad3(int hash, float x, float y, float z)
+{
+ int h = hash & 15; /* Convert low 4 bits of hash code into 12 simple */
+ float u = h < 8 ? x : y; /* gradient directions, and compute dot product. */
+ float v = h < 4 ? y : h == 12 || h == 14 ? x : z; /* Fix repeats at h = 12 to 15 */
+ return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
+}
+
+static float
+grad4(int hash, float x, float y, float z, float t)
+{
+ int h = hash & 31; /* Convert low 5 bits of hash code into 32 simple */
+ float u = h < 24 ? x : y; /* gradient directions, and compute dot product. */
+ float v = h < 16 ? y : z;
+ float w = h < 8 ? z : t;
+ return ((h & 1) ? -u : u) + ((h & 2) ? -v : v) + ((h & 4) ? -w : w);
+}
+
+/**
+ * A lookup table to traverse the simplex around a given point in 4D.
+ * Details can be found where this table is used, in the 4D noise method.
+ * TODO: This should not be required, backport it from Bill's GLSL code!
+ */
+static unsigned char simplex[64][4] = {
+ {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 0, 0, 0}, {0, 2, 3, 1},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 2, 3, 0},
+ {0, 2, 1, 3}, {0, 0, 0, 0}, {0, 3, 1, 2}, {0, 3, 2, 1},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 3, 2, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {1, 2, 0, 3}, {0, 0, 0, 0}, {1, 3, 0, 2}, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},
+ {1, 0, 2, 3}, {1, 0, 3, 2}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {2, 0, 3, 1}, {0, 0, 0, 0}, {2, 1, 3, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {2, 0, 1, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {3, 0, 1, 2}, {3, 0, 2, 1}, {0, 0, 0, 0}, {3, 1, 2, 0},
+ {2, 1, 0, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {3, 1, 0, 2}, {0, 0, 0, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}
+};
+
+
+/** 1D simplex noise */
+GLfloat
+_mesa_noise1(GLfloat x)
+{
+ int i0 = FASTFLOOR(x);
+ int i1 = i0 + 1;
+ float x0 = x - i0;
+ float x1 = x0 - 1.0f;
+ float t1 = 1.0f - x1 * x1;
+ float n0, n1;
+
+ float t0 = 1.0f - x0 * x0;
+/* if(t0 < 0.0f) t0 = 0.0f; // this never happens for the 1D case */
+ t0 *= t0;
+ n0 = t0 * t0 * grad1(perm[i0 & 0xff], x0);
+
+/* if(t1 < 0.0f) t1 = 0.0f; // this never happens for the 1D case */
+ t1 *= t1;
+ n1 = t1 * t1 * grad1(perm[i1 & 0xff], x1);
+ /* The maximum value of this noise is 8*(3/4)^4 = 2.53125 */
+ /* A factor of 0.395 would scale to fit exactly within [-1,1], but */
+ /* we want to match PRMan's 1D noise, so we scale it down some more. */
+ return 0.25f * (n0 + n1);
+}
+
+
+/** 2D simplex noise */
+GLfloat
+_mesa_noise2(GLfloat x, GLfloat y)
+{
+#define F2 0.366025403f /* F2 = 0.5*(sqrt(3.0)-1.0) */
+#define G2 0.211324865f /* G2 = (3.0-Math.sqrt(3.0))/6.0 */
+
+ float n0, n1, n2; /* Noise contributions from the three corners */
+
+ /* Skew the input space to determine which simplex cell we're in */
+ float s = (x + y) * F2; /* Hairy factor for 2D */
+ float xs = x + s;
+ float ys = y + s;
+ int i = FASTFLOOR(xs);
+ int j = FASTFLOOR(ys);
+
+ float t = (float) (i + j) * G2;
+ float X0 = i - t; /* Unskew the cell origin back to (x,y) space */
+ float Y0 = j - t;
+ float x0 = x - X0; /* The x,y distances from the cell origin */
+ float y0 = y - Y0;
+
+ float x1, y1, x2, y2;
+ unsigned int ii, jj;
+ float t0, t1, t2;
+
+ /* For the 2D case, the simplex shape is an equilateral triangle. */
+ /* Determine which simplex we are in. */
+ unsigned int i1, j1; /* Offsets for second (middle) corner of simplex in (i,j) coords */
+ if (x0 > y0) {
+ i1 = 1;
+ j1 = 0;
+ } /* lower triangle, XY order: (0,0)->(1,0)->(1,1) */
+ else {
+ i1 = 0;
+ j1 = 1;
+ } /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */
+
+ /* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and */
+ /* a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where */
+ /* c = (3-sqrt(3))/6 */
+
+ x1 = x0 - i1 + G2; /* Offsets for middle corner in (x,y) unskewed coords */
+ y1 = y0 - j1 + G2;
+ x2 = x0 - 1.0f + 2.0f * G2; /* Offsets for last corner in (x,y) unskewed coords */
+ y2 = y0 - 1.0f + 2.0f * G2;
+
+ /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */
+ ii = i & 0xff;
+ jj = j & 0xff;
+
+ /* Calculate the contribution from the three corners */
+ t0 = 0.5f - x0 * x0 - y0 * y0;
+ if (t0 < 0.0f)
+ n0 = 0.0f;
+ else {
+ t0 *= t0;
+ n0 = t0 * t0 * grad2(perm[ii + perm[jj]], x0, y0);
+ }
+
+ t1 = 0.5f - x1 * x1 - y1 * y1;
+ if (t1 < 0.0f)
+ n1 = 0.0f;
+ else {
+ t1 *= t1;
+ n1 = t1 * t1 * grad2(perm[ii + i1 + perm[jj + j1]], x1, y1);
+ }
+
+ t2 = 0.5f - x2 * x2 - y2 * y2;
+ if (t2 < 0.0f)
+ n2 = 0.0f;
+ else {
+ t2 *= t2;
+ n2 = t2 * t2 * grad2(perm[ii + 1 + perm[jj + 1]], x2, y2);
+ }
+
+ /* Add contributions from each corner to get the final noise value. */
+ /* The result is scaled to return values in the interval [-1,1]. */
+ return 40.0f * (n0 + n1 + n2); /* TODO: The scale factor is preliminary! */
+}
+
+
+/** 3D simplex noise */
+GLfloat
+_mesa_noise3(GLfloat x, GLfloat y, GLfloat z)
+{
+/* Simple skewing factors for the 3D case */
+#define F3 0.333333333f
+#define G3 0.166666667f
+
+ float n0, n1, n2, n3; /* Noise contributions from the four corners */
+
+ /* Skew the input space to determine which simplex cell we're in */
+ float s = (x + y + z) * F3; /* Very nice and simple skew factor for 3D */
+ float xs = x + s;
+ float ys = y + s;
+ float zs = z + s;
+ int i = FASTFLOOR(xs);
+ int j = FASTFLOOR(ys);
+ int k = FASTFLOOR(zs);
+
+ float t = (float) (i + j + k) * G3;
+ float X0 = i - t; /* Unskew the cell origin back to (x,y,z) space */
+ float Y0 = j - t;
+ float Z0 = k - t;
+ float x0 = x - X0; /* The x,y,z distances from the cell origin */
+ float y0 = y - Y0;
+ float z0 = z - Z0;
+
+ float x1, y1, z1, x2, y2, z2, x3, y3, z3;
+ unsigned int ii, jj, kk;
+ float t0, t1, t2, t3;
+
+ /* For the 3D case, the simplex shape is a slightly irregular tetrahedron. */
+ /* Determine which simplex we are in. */
+ unsigned int i1, j1, k1; /* Offsets for second corner of simplex in (i,j,k) coords */
+ unsigned int i2, j2, k2; /* Offsets for third corner of simplex in (i,j,k) coords */
+
+/* This code would benefit from a backport from the GLSL version! */
+ if (x0 >= y0) {
+ if (y0 >= z0) {
+ i1 = 1;
+ j1 = 0;
+ k1 = 0;
+ i2 = 1;
+ j2 = 1;
+ k2 = 0;
+ } /* X Y Z order */
+ else if (x0 >= z0) {
+ i1 = 1;
+ j1 = 0;
+ k1 = 0;
+ i2 = 1;
+ j2 = 0;
+ k2 = 1;
+ } /* X Z Y order */
+ else {
+ i1 = 0;
+ j1 = 0;
+ k1 = 1;
+ i2 = 1;
+ j2 = 0;
+ k2 = 1;
+ } /* Z X Y order */
+ }
+ else { /* x0<y0 */
+ if (y0 < z0) {
+ i1 = 0;
+ j1 = 0;
+ k1 = 1;
+ i2 = 0;
+ j2 = 1;
+ k2 = 1;
+ } /* Z Y X order */
+ else if (x0 < z0) {
+ i1 = 0;
+ j1 = 1;
+ k1 = 0;
+ i2 = 0;
+ j2 = 1;
+ k2 = 1;
+ } /* Y Z X order */
+ else {
+ i1 = 0;
+ j1 = 1;
+ k1 = 0;
+ i2 = 1;
+ j2 = 1;
+ k2 = 0;
+ } /* Y X Z order */
+ }
+
+ /* A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in
+ * (x,y,z), a step of (0,1,0) in (i,j,k) means a step of
+ * (-c,1-c,-c) in (x,y,z), and a step of (0,0,1) in (i,j,k) means a
+ * step of (-c,-c,1-c) in (x,y,z), where c = 1/6.
+ */
+
+ x1 = x0 - i1 + G3; /* Offsets for second corner in (x,y,z) coords */
+ y1 = y0 - j1 + G3;
+ z1 = z0 - k1 + G3;
+ x2 = x0 - i2 + 2.0f * G3; /* Offsets for third corner in (x,y,z) coords */
+ y2 = y0 - j2 + 2.0f * G3;
+ z2 = z0 - k2 + 2.0f * G3;
+ x3 = x0 - 1.0f + 3.0f * G3;/* Offsets for last corner in (x,y,z) coords */
+ y3 = y0 - 1.0f + 3.0f * G3;
+ z3 = z0 - 1.0f + 3.0f * G3;
+
+ /* Wrap the integer indices at 256 to avoid indexing perm[] out of bounds */
+ ii = i & 0xff;
+ jj = j & 0xff;
+ kk = k & 0xff;
+
+ /* Calculate the contribution from the four corners */
+ t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0;
+ if (t0 < 0.0f)
+ n0 = 0.0f;
+ else {
+ t0 *= t0;
+ n0 = t0 * t0 * grad3(perm[ii + perm[jj + perm[kk]]], x0, y0, z0);
+ }
+
+ t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1;
+ if (t1 < 0.0f)
+ n1 = 0.0f;
+ else {
+ t1 *= t1;
+ n1 =
+ t1 * t1 * grad3(perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]], x1,
+ y1, z1);
+ }
+
+ t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2;
+ if (t2 < 0.0f)
+ n2 = 0.0f;
+ else {
+ t2 *= t2;
+ n2 =
+ t2 * t2 * grad3(perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]], x2,
+ y2, z2);
+ }
+
+ t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3;
+ if (t3 < 0.0f)
+ n3 = 0.0f;
+ else {
+ t3 *= t3;
+ n3 =
+ t3 * t3 * grad3(perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]], x3, y3,
+ z3);
+ }
+
+ /* Add contributions from each corner to get the final noise value.
+ * The result is scaled to stay just inside [-1,1]
+ */
+ return 32.0f * (n0 + n1 + n2 + n3); /* TODO: The scale factor is preliminary! */
+}
+
+
+/** 4D simplex noise */
+GLfloat
+_mesa_noise4(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ /* The skewing and unskewing factors are hairy again for the 4D case */
+#define F4 0.309016994f /* F4 = (Math.sqrt(5.0)-1.0)/4.0 */
+#define G4 0.138196601f /* G4 = (5.0-Math.sqrt(5.0))/20.0 */
+
+ float n0, n1, n2, n3, n4; /* Noise contributions from the five corners */
+
+ /* Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in */
+ float s = (x + y + z + w) * F4; /* Factor for 4D skewing */
+ float xs = x + s;
+ float ys = y + s;
+ float zs = z + s;
+ float ws = w + s;
+ int i = FASTFLOOR(xs);
+ int j = FASTFLOOR(ys);
+ int k = FASTFLOOR(zs);
+ int l = FASTFLOOR(ws);
+
+ float t = (i + j + k + l) * G4; /* Factor for 4D unskewing */
+ float X0 = i - t; /* Unskew the cell origin back to (x,y,z,w) space */
+ float Y0 = j - t;
+ float Z0 = k - t;
+ float W0 = l - t;
+
+ float x0 = x - X0; /* The x,y,z,w distances from the cell origin */
+ float y0 = y - Y0;
+ float z0 = z - Z0;
+ float w0 = w - W0;
+
+ /* For the 4D case, the simplex is a 4D shape I won't even try to describe.
+ * To find out which of the 24 possible simplices we're in, we need to
+ * determine the magnitude ordering of x0, y0, z0 and w0.
+ * The method below is a good way of finding the ordering of x,y,z,w and
+ * then find the correct traversal order for the simplex we're in.
+ * First, six pair-wise comparisons are performed between each possible pair
+ * of the four coordinates, and the results are used to add up binary bits
+ * for an integer index.
+ */
+ int c1 = (x0 > y0) ? 32 : 0;
+ int c2 = (x0 > z0) ? 16 : 0;
+ int c3 = (y0 > z0) ? 8 : 0;
+ int c4 = (x0 > w0) ? 4 : 0;
+ int c5 = (y0 > w0) ? 2 : 0;
+ int c6 = (z0 > w0) ? 1 : 0;
+ int c = c1 + c2 + c3 + c4 + c5 + c6;
+
+ unsigned int i1, j1, k1, l1; /* The integer offsets for the second simplex corner */
+ unsigned int i2, j2, k2, l2; /* The integer offsets for the third simplex corner */
+ unsigned int i3, j3, k3, l3; /* The integer offsets for the fourth simplex corner */
+
+ float x1, y1, z1, w1, x2, y2, z2, w2, x3, y3, z3, w3, x4, y4, z4, w4;
+ unsigned int ii, jj, kk, ll;
+ float t0, t1, t2, t3, t4;
+
+ /*
+ * simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some
+ * order. Many values of c will never occur, since e.g. x>y>z>w
+ * makes x<z, y<w and x<w impossible. Only the 24 indices which
+ * have non-zero entries make any sense. We use a thresholding to
+ * set the coordinates in turn from the largest magnitude. The
+ * number 3 in the "simplex" array is at the position of the
+ * largest coordinate.
+ */
+ i1 = simplex[c][0] >= 3 ? 1 : 0;
+ j1 = simplex[c][1] >= 3 ? 1 : 0;
+ k1 = simplex[c][2] >= 3 ? 1 : 0;
+ l1 = simplex[c][3] >= 3 ? 1 : 0;
+ /* The number 2 in the "simplex" array is at the second largest coordinate. */
+ i2 = simplex[c][0] >= 2 ? 1 : 0;
+ j2 = simplex[c][1] >= 2 ? 1 : 0;
+ k2 = simplex[c][2] >= 2 ? 1 : 0;
+ l2 = simplex[c][3] >= 2 ? 1 : 0;
+ /* The number 1 in the "simplex" array is at the second smallest coordinate. */
+ i3 = simplex[c][0] >= 1 ? 1 : 0;
+ j3 = simplex[c][1] >= 1 ? 1 : 0;
+ k3 = simplex[c][2] >= 1 ? 1 : 0;
+ l3 = simplex[c][3] >= 1 ? 1 : 0;
+ /* The fifth corner has all coordinate offsets = 1, so no need to look that up. */
+
+ x1 = x0 - i1 + G4; /* Offsets for second corner in (x,y,z,w) coords */
+ y1 = y0 - j1 + G4;
+ z1 = z0 - k1 + G4;
+ w1 = w0 - l1 + G4;
+ x2 = x0 - i2 + 2.0f * G4; /* Offsets for third corner in (x,y,z,w) coords */
+ y2 = y0 - j2 + 2.0f * G4;
+ z2 = z0 - k2 + 2.0f * G4;
+ w2 = w0 - l2 + 2.0f * G4;
+ x3 = x0 - i3 + 3.0f * G4; /* Offsets for fourth corner in (x,y,z,w) coords */
+ y3 = y0 - j3 + 3.0f * G4;
+ z3 = z0 - k3 + 3.0f * G4;
+ w3 = w0 - l3 + 3.0f * G4;
+ x4 = x0 - 1.0f + 4.0f * G4; /* Offsets for last corner in (x,y,z,w) coords */
+ y4 = y0 - 1.0f + 4.0f * G4;
+ z4 = z0 - 1.0f + 4.0f * G4;
+ w4 = w0 - 1.0f + 4.0f * G4;
+
+ /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */
+ ii = i & 0xff;
+ jj = j & 0xff;
+ kk = k & 0xff;
+ ll = l & 0xff;
+
+ /* Calculate the contribution from the five corners */
+ t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
+ if (t0 < 0.0f)
+ n0 = 0.0f;
+ else {
+ t0 *= t0;
+ n0 =
+ t0 * t0 * grad4(perm[ii + perm[jj + perm[kk + perm[ll]]]], x0, y0,
+ z0, w0);
+ }
+
+ t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
+ if (t1 < 0.0f)
+ n1 = 0.0f;
+ else {
+ t1 *= t1;
+ n1 =
+ t1 * t1 *
+ grad4(perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]],
+ x1, y1, z1, w1);
+ }
+
+ t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
+ if (t2 < 0.0f)
+ n2 = 0.0f;
+ else {
+ t2 *= t2;
+ n2 =
+ t2 * t2 *
+ grad4(perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]],
+ x2, y2, z2, w2);
+ }
+
+ t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
+ if (t3 < 0.0f)
+ n3 = 0.0f;
+ else {
+ t3 *= t3;
+ n3 =
+ t3 * t3 *
+ grad4(perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]],
+ x3, y3, z3, w3);
+ }
+
+ t4 = 0.6f - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
+ if (t4 < 0.0f)
+ n4 = 0.0f;
+ else {
+ t4 *= t4;
+ n4 =
+ t4 * t4 *
+ grad4(perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]], x4,
+ y4, z4, w4);
+ }
+
+ /* Sum up and scale the result to cover the range [-1,1] */
+ return 27.0f * (n0 + n1 + n2 + n3 + n4); /* TODO: The scale factor is preliminary! */
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_noise.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_noise.h
new file mode 100644
index 0000000..51124ca
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_noise.h
@@ -0,0 +1,36 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PROG_NOISE
+#define PROG_NOISE
+
+#include "main/glheader.h"
+
+extern GLfloat _mesa_noise1(GLfloat);
+extern GLfloat _mesa_noise2(GLfloat, GLfloat);
+extern GLfloat _mesa_noise3(GLfloat, GLfloat, GLfloat);
+extern GLfloat _mesa_noise4(GLfloat, GLfloat, GLfloat, GLfloat);
+
+#endif
+
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_opt_constant_fold.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_opt_constant_fold.c
new file mode 100644
index 0000000..3811c0d
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_opt_constant_fold.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "program.h"
+#include "prog_instruction.h"
+#include "prog_optimize.h"
+#include "prog_parameter.h"
+#include <stdbool.h>
+
+static bool
+src_regs_are_constant(const struct prog_instruction *inst, unsigned num_srcs)
+{
+ unsigned i;
+
+ for (i = 0; i < num_srcs; i++) {
+ if (inst->SrcReg[i].File != PROGRAM_CONSTANT)
+ return false;
+ }
+
+ return true;
+}
+
+static struct prog_src_register
+src_reg_for_float(struct gl_program *prog, float val)
+{
+ struct prog_src_register src;
+ unsigned swiz;
+
+ memset(&src, 0, sizeof(src));
+
+ src.File = PROGRAM_CONSTANT;
+ src.Index = _mesa_add_unnamed_constant(prog->Parameters,
+ (gl_constant_value *) &val, 1, &swiz);
+ src.Swizzle = swiz;
+ return src;
+}
+
+static struct prog_src_register
+src_reg_for_vec4(struct gl_program *prog, const float *val)
+{
+ struct prog_src_register src;
+ unsigned swiz;
+
+ memset(&src, 0, sizeof(src));
+
+ src.File = PROGRAM_CONSTANT;
+ src.Index = _mesa_add_unnamed_constant(prog->Parameters,
+ (gl_constant_value *) val, 4, &swiz);
+ src.Swizzle = swiz;
+ return src;
+}
+
+static bool
+src_regs_are_same(const struct prog_src_register *a,
+ const struct prog_src_register *b)
+{
+ return (a->File == b->File)
+ && (a->Index == b->Index)
+ && (a->Swizzle == b->Swizzle)
+ && (a->Abs == b->Abs)
+ && (a->Negate == b->Negate)
+ && (a->RelAddr == 0)
+ && (b->RelAddr == 0);
+}
+
+static void
+get_value(struct gl_program *prog, struct prog_src_register *r, float *data)
+{
+ const gl_constant_value *const value =
+ prog->Parameters->ParameterValues[r->Index];
+
+ data[0] = value[GET_SWZ(r->Swizzle, 0)].f;
+ data[1] = value[GET_SWZ(r->Swizzle, 1)].f;
+ data[2] = value[GET_SWZ(r->Swizzle, 2)].f;
+ data[3] = value[GET_SWZ(r->Swizzle, 3)].f;
+
+ if (r->Abs) {
+ data[0] = fabsf(data[0]);
+ data[1] = fabsf(data[1]);
+ data[2] = fabsf(data[2]);
+ data[3] = fabsf(data[3]);
+ }
+
+ if (r->Negate & 0x01) {
+ data[0] = -data[0];
+ }
+
+ if (r->Negate & 0x02) {
+ data[1] = -data[1];
+ }
+
+ if (r->Negate & 0x04) {
+ data[2] = -data[2];
+ }
+
+ if (r->Negate & 0x08) {
+ data[3] = -data[3];
+ }
+}
+
+/**
+ * Try to replace instructions that produce a constant result with simple moves
+ *
+ * The hope is that a following copy propagation pass will eliminate the
+ * unnecessary move instructions.
+ */
+GLboolean
+_mesa_constant_fold(struct gl_program *prog)
+{
+ bool progress = false;
+ unsigned i;
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *const inst = &prog->Instructions[i];
+
+ switch (inst->Opcode) {
+ case OPCODE_ADD:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = a[0] + b[0];
+ result[1] = a[1] + b[1];
+ result[2] = a[2] + b[2];
+ result[3] = a[3] + b[3];
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_CMP:
+ /* FINISHME: We could also optimize CMP instructions where the first
+ * FINISHME: source is a constant that is either all < 0.0 or all
+ * FINISHME: >= 0.0.
+ */
+ if (src_regs_are_constant(inst, 3)) {
+ float a[4];
+ float b[4];
+ float c[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+ get_value(prog, &inst->SrcReg[2], c);
+
+ result[0] = a[0] < 0.0f ? b[0] : c[0];
+ result[1] = a[1] < 0.0f ? b[1] : c[1];
+ result[2] = a[2] < 0.0f ? b[2] : c[2];
+ result[3] = a[3] < 0.0f ? b[3] : c[3];
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ inst->SrcReg[2].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_DP2:
+ case OPCODE_DP3:
+ case OPCODE_DP4:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result;
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result = (a[0] * b[0]) + (a[1] * b[1]);
+
+ if (inst->Opcode >= OPCODE_DP3)
+ result += a[2] * b[2];
+
+ if (inst->Opcode == OPCODE_DP4)
+ result += a[3] * b[3];
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_float(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_MUL:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = a[0] * b[0];
+ result[1] = a[1] * b[1];
+ result[2] = a[2] * b[2];
+ result[3] = a[3] * b[3];
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_SEQ:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = (a[0] == b[0]) ? 1.0f : 0.0f;
+ result[1] = (a[1] == b[1]) ? 1.0f : 0.0f;
+ result[2] = (a[2] == b[2]) ? 1.0f : 0.0f;
+ result[3] = (a[3] == b[3]) ? 1.0f : 0.0f;
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ } else if (src_regs_are_same(&inst->SrcReg[0], &inst->SrcReg[1])) {
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_float(prog, 1.0f);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_SGE:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = (a[0] >= b[0]) ? 1.0f : 0.0f;
+ result[1] = (a[1] >= b[1]) ? 1.0f : 0.0f;
+ result[2] = (a[2] >= b[2]) ? 1.0f : 0.0f;
+ result[3] = (a[3] >= b[3]) ? 1.0f : 0.0f;
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ } else if (src_regs_are_same(&inst->SrcReg[0], &inst->SrcReg[1])) {
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_float(prog, 1.0f);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_SGT:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = (a[0] > b[0]) ? 1.0f : 0.0f;
+ result[1] = (a[1] > b[1]) ? 1.0f : 0.0f;
+ result[2] = (a[2] > b[2]) ? 1.0f : 0.0f;
+ result[3] = (a[3] > b[3]) ? 1.0f : 0.0f;
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ } else if (src_regs_are_same(&inst->SrcReg[0], &inst->SrcReg[1])) {
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_float(prog, 0.0f);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_SLE:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = (a[0] <= b[0]) ? 1.0f : 0.0f;
+ result[1] = (a[1] <= b[1]) ? 1.0f : 0.0f;
+ result[2] = (a[2] <= b[2]) ? 1.0f : 0.0f;
+ result[3] = (a[3] <= b[3]) ? 1.0f : 0.0f;
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ } else if (src_regs_are_same(&inst->SrcReg[0], &inst->SrcReg[1])) {
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_float(prog, 1.0f);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_SLT:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = (a[0] < b[0]) ? 1.0f : 0.0f;
+ result[1] = (a[1] < b[1]) ? 1.0f : 0.0f;
+ result[2] = (a[2] < b[2]) ? 1.0f : 0.0f;
+ result[3] = (a[3] < b[3]) ? 1.0f : 0.0f;
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ } else if (src_regs_are_same(&inst->SrcReg[0], &inst->SrcReg[1])) {
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_float(prog, 0.0f);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ case OPCODE_SNE:
+ if (src_regs_are_constant(inst, 2)) {
+ float a[4];
+ float b[4];
+ float result[4];
+
+ get_value(prog, &inst->SrcReg[0], a);
+ get_value(prog, &inst->SrcReg[1], b);
+
+ result[0] = (a[0] != b[0]) ? 1.0f : 0.0f;
+ result[1] = (a[1] != b[1]) ? 1.0f : 0.0f;
+ result[2] = (a[2] != b[2]) ? 1.0f : 0.0f;
+ result[3] = (a[3] != b[3]) ? 1.0f : 0.0f;
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_vec4(prog, result);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ } else if (src_regs_are_same(&inst->SrcReg[0], &inst->SrcReg[1])) {
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = src_reg_for_float(prog, 0.0f);
+
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ progress = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return progress;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_optimize.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_optimize.c
new file mode 100644
index 0000000..6153f5e
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_optimize.c
@@ -0,0 +1,1362 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "program.h"
+#include "prog_instruction.h"
+#include "prog_optimize.h"
+#include "prog_print.h"
+
+
+#define MAX_LOOP_NESTING 50
+/* MAX_PROGRAM_TEMPS is a low number (256), and we want to be able to
+ * register allocate many temporary values into that small number of
+ * temps. So allow large temporary indices coming into the register
+ * allocator.
+ */
+#define REG_ALLOCATE_MAX_PROGRAM_TEMPS ((1 << INST_INDEX_BITS) - 1)
+
+static GLboolean dbg = GL_FALSE;
+
+#define NO_MASK 0xf
+
+/**
+ * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which
+ * are read from the given src in this instruction, We also provide
+ * one optional masks which may mask other components in the dst
+ * register
+ */
+static GLuint
+get_src_arg_mask(const struct prog_instruction *inst,
+ GLuint arg, GLuint dst_mask)
+{
+ GLuint read_mask, channel_mask;
+ GLuint comp;
+
+ ASSERT(arg < _mesa_num_inst_src_regs(inst->Opcode));
+
+ /* Form the dst register, find the written channels */
+ if (inst->CondUpdate) {
+ channel_mask = WRITEMASK_XYZW;
+ }
+ else {
+ switch (inst->Opcode) {
+ case OPCODE_MOV:
+ case OPCODE_MIN:
+ case OPCODE_MAX:
+ case OPCODE_ABS:
+ case OPCODE_ADD:
+ case OPCODE_MAD:
+ case OPCODE_MUL:
+ case OPCODE_SUB:
+ case OPCODE_CMP:
+ case OPCODE_FLR:
+ case OPCODE_FRC:
+ case OPCODE_LRP:
+ case OPCODE_SEQ:
+ case OPCODE_SGE:
+ case OPCODE_SGT:
+ case OPCODE_SLE:
+ case OPCODE_SLT:
+ case OPCODE_SNE:
+ case OPCODE_SSG:
+ channel_mask = inst->DstReg.WriteMask & dst_mask;
+ break;
+ case OPCODE_RCP:
+ case OPCODE_SIN:
+ case OPCODE_COS:
+ case OPCODE_RSQ:
+ case OPCODE_POW:
+ case OPCODE_EX2:
+ case OPCODE_LOG:
+ channel_mask = WRITEMASK_X;
+ break;
+ case OPCODE_DP2:
+ channel_mask = WRITEMASK_XY;
+ break;
+ case OPCODE_DP3:
+ case OPCODE_XPD:
+ channel_mask = WRITEMASK_XYZ;
+ break;
+ default:
+ channel_mask = WRITEMASK_XYZW;
+ break;
+ }
+ }
+
+ /* Now, given the src swizzle and the written channels, find which
+ * components are actually read
+ */
+ read_mask = 0x0;
+ for (comp = 0; comp < 4; ++comp) {
+ const GLuint coord = GET_SWZ(inst->SrcReg[arg].Swizzle, comp);
+ ASSERT(coord < 4);
+ if (channel_mask & (1 << comp) && coord <= SWIZZLE_W)
+ read_mask |= 1 << coord;
+ }
+
+ return read_mask;
+}
+
+
+/**
+ * For a MOV instruction, compute a write mask when src register also has
+ * a mask
+ */
+static GLuint
+get_dst_mask_for_mov(const struct prog_instruction *mov, GLuint src_mask)
+{
+ const GLuint mask = mov->DstReg.WriteMask;
+ GLuint comp;
+ GLuint updated_mask = 0x0;
+
+ ASSERT(mov->Opcode == OPCODE_MOV);
+
+ for (comp = 0; comp < 4; ++comp) {
+ GLuint src_comp;
+ if ((mask & (1 << comp)) == 0)
+ continue;
+ src_comp = GET_SWZ(mov->SrcReg[0].Swizzle, comp);
+ if ((src_mask & (1 << src_comp)) == 0)
+ continue;
+ updated_mask |= 1 << comp;
+ }
+
+ return updated_mask;
+}
+
+
+/**
+ * Ensure that the swizzle is regular. That is, all of the swizzle
+ * terms are SWIZZLE_X,Y,Z,W and not SWIZZLE_ZERO or SWIZZLE_ONE.
+ */
+static GLboolean
+is_swizzle_regular(GLuint swz)
+{
+ return GET_SWZ(swz,0) <= SWIZZLE_W &&
+ GET_SWZ(swz,1) <= SWIZZLE_W &&
+ GET_SWZ(swz,2) <= SWIZZLE_W &&
+ GET_SWZ(swz,3) <= SWIZZLE_W;
+}
+
+
+/**
+ * In 'prog' remove instruction[i] if removeFlags[i] == TRUE.
+ * \return number of instructions removed
+ */
+static GLuint
+remove_instructions(struct gl_program *prog, const GLboolean *removeFlags)
+{
+ GLint i, removeEnd = 0, removeCount = 0;
+ GLuint totalRemoved = 0;
+
+ /* go backward */
+ for (i = prog->NumInstructions - 1; i >= 0; i--) {
+ if (removeFlags[i]) {
+ totalRemoved++;
+ if (removeCount == 0) {
+ /* begin a run of instructions to remove */
+ removeEnd = i;
+ removeCount = 1;
+ }
+ else {
+ /* extend the run of instructions to remove */
+ removeCount++;
+ }
+ }
+ else {
+ /* don't remove this instruction, but check if the preceeding
+ * instructions are to be removed.
+ */
+ if (removeCount > 0) {
+ GLint removeStart = removeEnd - removeCount + 1;
+ _mesa_delete_instructions(prog, removeStart, removeCount);
+ removeStart = removeCount = 0; /* reset removal info */
+ }
+ }
+ }
+ /* Finish removing if the first instruction was to be removed. */
+ if (removeCount > 0) {
+ GLint removeStart = removeEnd - removeCount + 1;
+ _mesa_delete_instructions(prog, removeStart, removeCount);
+ }
+ return totalRemoved;
+}
+
+
+/**
+ * Remap register indexes according to map.
+ * \param prog the program to search/replace
+ * \param file the type of register file to search/replace
+ * \param map maps old register indexes to new indexes
+ */
+static void
+replace_regs(struct gl_program *prog, gl_register_file file, const GLint map[])
+{
+ GLuint i;
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+ GLuint j;
+ for (j = 0; j < numSrc; j++) {
+ if (inst->SrcReg[j].File == file) {
+ GLuint index = inst->SrcReg[j].Index;
+ ASSERT(map[index] >= 0);
+ inst->SrcReg[j].Index = map[index];
+ }
+ }
+ if (inst->DstReg.File == file) {
+ const GLuint index = inst->DstReg.Index;
+ ASSERT(map[index] >= 0);
+ inst->DstReg.Index = map[index];
+ }
+ }
+}
+
+
+/**
+ * Remove dead instructions from the given program.
+ * This is very primitive for now. Basically look for temp registers
+ * that are written to but never read. Remove any instructions that
+ * write to such registers. Be careful with condition code setters.
+ */
+static GLboolean
+_mesa_remove_dead_code_global(struct gl_program *prog)
+{
+ GLboolean tempRead[REG_ALLOCATE_MAX_PROGRAM_TEMPS][4];
+ GLboolean *removeInst; /* per-instruction removal flag */
+ GLuint i, rem = 0, comp;
+
+ memset(tempRead, 0, sizeof(tempRead));
+
+ if (dbg) {
+ printf("Optimize: Begin dead code removal\n");
+ /*_mesa_print_program(prog);*/
+ }
+
+ removeInst =
+ calloc(1, prog->NumInstructions * sizeof(GLboolean));
+
+ /* Determine which temps are read and written */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+ GLuint j;
+
+ /* check src regs */
+ for (j = 0; j < numSrc; j++) {
+ if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+ const GLuint index = inst->SrcReg[j].Index;
+ GLuint read_mask;
+ ASSERT(index < REG_ALLOCATE_MAX_PROGRAM_TEMPS);
+ read_mask = get_src_arg_mask(inst, j, NO_MASK);
+
+ if (inst->SrcReg[j].RelAddr) {
+ if (dbg)
+ printf("abort remove dead code (indirect temp)\n");
+ goto done;
+ }
+
+ for (comp = 0; comp < 4; comp++) {
+ const GLuint swz = GET_SWZ(inst->SrcReg[j].Swizzle, comp);
+ ASSERT(swz < 4);
+ if ((read_mask & (1 << swz)) == 0)
+ continue;
+ if (swz <= SWIZZLE_W)
+ tempRead[index][swz] = GL_TRUE;
+ }
+ }
+ }
+
+ /* check dst reg */
+ if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+ const GLuint index = inst->DstReg.Index;
+ ASSERT(index < REG_ALLOCATE_MAX_PROGRAM_TEMPS);
+
+ if (inst->DstReg.RelAddr) {
+ if (dbg)
+ printf("abort remove dead code (indirect temp)\n");
+ goto done;
+ }
+
+ if (inst->CondUpdate) {
+ /* If we're writing to this register and setting condition
+ * codes we cannot remove the instruction. Prevent removal
+ * by setting the 'read' flag.
+ */
+ tempRead[index][0] = GL_TRUE;
+ tempRead[index][1] = GL_TRUE;
+ tempRead[index][2] = GL_TRUE;
+ tempRead[index][3] = GL_TRUE;
+ }
+ }
+ }
+
+ /* find instructions that write to dead registers, flag for removal */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint numDst = _mesa_num_inst_dst_regs(inst->Opcode);
+
+ if (numDst != 0 && inst->DstReg.File == PROGRAM_TEMPORARY) {
+ GLint chan, index = inst->DstReg.Index;
+
+ for (chan = 0; chan < 4; chan++) {
+ if (!tempRead[index][chan] &&
+ inst->DstReg.WriteMask & (1 << chan)) {
+ if (dbg) {
+ printf("Remove writemask on %u.%c\n", i,
+ chan == 3 ? 'w' : 'x' + chan);
+ }
+ inst->DstReg.WriteMask &= ~(1 << chan);
+ rem++;
+ }
+ }
+
+ if (inst->DstReg.WriteMask == 0) {
+ /* If we cleared all writes, the instruction can be removed. */
+ if (dbg)
+ printf("Remove instruction %u: \n", i);
+ removeInst[i] = GL_TRUE;
+ }
+ }
+ }
+
+ /* now remove the instructions which aren't needed */
+ rem = remove_instructions(prog, removeInst);
+
+ if (dbg) {
+ printf("Optimize: End dead code removal.\n");
+ printf(" %u channel writes removed\n", rem);
+ printf(" %u instructions removed\n", rem);
+ /*_mesa_print_program(prog);*/
+ }
+
+done:
+ free(removeInst);
+ return rem != 0;
+}
+
+
+enum inst_use
+{
+ READ,
+ WRITE,
+ FLOW,
+ END
+};
+
+
+/**
+ * Scan forward in program from 'start' for the next occurances of TEMP[index].
+ * We look if an instruction reads the component given by the masks and if they
+ * are overwritten.
+ * Return READ, WRITE, FLOW or END to indicate the next usage or an indicator
+ * that we can't look further.
+ */
+static enum inst_use
+find_next_use(const struct gl_program *prog,
+ GLuint start,
+ GLuint index,
+ GLuint mask)
+{
+ GLuint i;
+
+ for (i = start; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *inst = prog->Instructions + i;
+ switch (inst->Opcode) {
+ case OPCODE_BGNLOOP:
+ case OPCODE_BGNSUB:
+ case OPCODE_CAL:
+ case OPCODE_CONT:
+ case OPCODE_IF:
+ case OPCODE_ELSE:
+ case OPCODE_ENDIF:
+ case OPCODE_ENDLOOP:
+ case OPCODE_ENDSUB:
+ case OPCODE_RET:
+ return FLOW;
+ case OPCODE_END:
+ return END;
+ default:
+ {
+ const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+ GLuint j;
+ for (j = 0; j < numSrc; j++) {
+ if (inst->SrcReg[j].RelAddr ||
+ (inst->SrcReg[j].File == PROGRAM_TEMPORARY &&
+ inst->SrcReg[j].Index == index &&
+ (get_src_arg_mask(inst,j,NO_MASK) & mask)))
+ return READ;
+ }
+ if (_mesa_num_inst_dst_regs(inst->Opcode) == 1 &&
+ inst->DstReg.File == PROGRAM_TEMPORARY &&
+ inst->DstReg.Index == index) {
+ mask &= ~inst->DstReg.WriteMask;
+ if (mask == 0)
+ return WRITE;
+ }
+ }
+ }
+ }
+ return END;
+}
+
+
+/**
+ * Is the given instruction opcode a flow-control opcode?
+ * XXX maybe move this into prog_instruction.[ch]
+ */
+static GLboolean
+_mesa_is_flow_control_opcode(enum prog_opcode opcode)
+{
+ switch (opcode) {
+ case OPCODE_BGNLOOP:
+ case OPCODE_BGNSUB:
+ case OPCODE_CAL:
+ case OPCODE_CONT:
+ case OPCODE_IF:
+ case OPCODE_ELSE:
+ case OPCODE_END:
+ case OPCODE_ENDIF:
+ case OPCODE_ENDLOOP:
+ case OPCODE_ENDSUB:
+ case OPCODE_RET:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given instruction is a simple MOV (no conditional updating,
+ * not relative addressing, no negation/abs, etc).
+ */
+static GLboolean
+can_downward_mov_be_modifed(const struct prog_instruction *mov)
+{
+ return
+ mov->Opcode == OPCODE_MOV &&
+ mov->CondUpdate == GL_FALSE &&
+ mov->SrcReg[0].RelAddr == 0 &&
+ mov->SrcReg[0].Negate == 0 &&
+ mov->SrcReg[0].Abs == 0 &&
+ mov->SrcReg[0].HasIndex2 == 0 &&
+ mov->SrcReg[0].RelAddr2 == 0 &&
+ mov->DstReg.RelAddr == 0 &&
+ mov->DstReg.CondMask == COND_TR;
+}
+
+
+static GLboolean
+can_upward_mov_be_modifed(const struct prog_instruction *mov)
+{
+ return
+ can_downward_mov_be_modifed(mov) &&
+ mov->DstReg.File == PROGRAM_TEMPORARY &&
+ mov->SaturateMode == SATURATE_OFF;
+}
+
+
+/**
+ * Try to remove use of extraneous MOV instructions, to free them up for dead
+ * code removal.
+ */
+static void
+_mesa_remove_extra_move_use(struct gl_program *prog)
+{
+ GLuint i, j;
+
+ if (dbg) {
+ printf("Optimize: Begin remove extra move use\n");
+ _mesa_print_program(prog);
+ }
+
+ /*
+ * Look for sequences such as this:
+ * MOV tmpX, arg0;
+ * ...
+ * FOO tmpY, tmpX, arg1;
+ * and convert into:
+ * MOV tmpX, arg0;
+ * ...
+ * FOO tmpY, arg0, arg1;
+ */
+
+ for (i = 0; i + 1 < prog->NumInstructions; i++) {
+ const struct prog_instruction *mov = prog->Instructions + i;
+ GLuint dst_mask, src_mask;
+ if (can_upward_mov_be_modifed(mov) == GL_FALSE)
+ continue;
+
+ /* Scanning the code, we maintain the components which are still active in
+ * these two masks
+ */
+ dst_mask = mov->DstReg.WriteMask;
+ src_mask = get_src_arg_mask(mov, 0, NO_MASK);
+
+ /* Walk through remaining instructions until the or src reg gets
+ * rewritten or we get into some flow-control, eliminating the use of
+ * this MOV.
+ */
+ for (j = i + 1; j < prog->NumInstructions; j++) {
+ struct prog_instruction *inst2 = prog->Instructions + j;
+ GLuint arg;
+
+ if (_mesa_is_flow_control_opcode(inst2->Opcode))
+ break;
+
+ /* First rewrite this instruction's args if appropriate. */
+ for (arg = 0; arg < _mesa_num_inst_src_regs(inst2->Opcode); arg++) {
+ GLuint comp, read_mask;
+
+ if (inst2->SrcReg[arg].File != mov->DstReg.File ||
+ inst2->SrcReg[arg].Index != mov->DstReg.Index ||
+ inst2->SrcReg[arg].RelAddr ||
+ inst2->SrcReg[arg].Abs)
+ continue;
+ read_mask = get_src_arg_mask(inst2, arg, NO_MASK);
+
+ /* Adjust the swizzles of inst2 to point at MOV's source if ALL the
+ * components read still come from the mov instructions
+ */
+ if (is_swizzle_regular(inst2->SrcReg[arg].Swizzle) &&
+ (read_mask & dst_mask) == read_mask) {
+ for (comp = 0; comp < 4; comp++) {
+ const GLuint inst2_swz =
+ GET_SWZ(inst2->SrcReg[arg].Swizzle, comp);
+ const GLuint s = GET_SWZ(mov->SrcReg[0].Swizzle, inst2_swz);
+ inst2->SrcReg[arg].Swizzle &= ~(7 << (3 * comp));
+ inst2->SrcReg[arg].Swizzle |= s << (3 * comp);
+ inst2->SrcReg[arg].Negate ^= (((mov->SrcReg[0].Negate >>
+ inst2_swz) & 0x1) << comp);
+ }
+ inst2->SrcReg[arg].File = mov->SrcReg[0].File;
+ inst2->SrcReg[arg].Index = mov->SrcReg[0].Index;
+ }
+ }
+
+ /* The source of MOV is written. This potentially deactivates some
+ * components from the src and dst of the MOV instruction
+ */
+ if (inst2->DstReg.File == mov->DstReg.File &&
+ (inst2->DstReg.RelAddr ||
+ inst2->DstReg.Index == mov->DstReg.Index)) {
+ dst_mask &= ~inst2->DstReg.WriteMask;
+ src_mask = get_src_arg_mask(mov, 0, dst_mask);
+ }
+
+ /* Idem when the destination of mov is written */
+ if (inst2->DstReg.File == mov->SrcReg[0].File &&
+ (inst2->DstReg.RelAddr ||
+ inst2->DstReg.Index == mov->SrcReg[0].Index)) {
+ src_mask &= ~inst2->DstReg.WriteMask;
+ dst_mask &= get_dst_mask_for_mov(mov, src_mask);
+ }
+ if (dst_mask == 0)
+ break;
+ }
+ }
+
+ if (dbg) {
+ printf("Optimize: End remove extra move use.\n");
+ /*_mesa_print_program(prog);*/
+ }
+}
+
+
+/**
+ * Complements dead_code_global. Try to remove code in block of code by
+ * carefully monitoring the swizzles. Both functions should be merged into one
+ * with a proper control flow graph
+ */
+static GLboolean
+_mesa_remove_dead_code_local(struct gl_program *prog)
+{
+ GLboolean *removeInst;
+ GLuint i, arg, rem = 0;
+
+ removeInst =
+ calloc(1, prog->NumInstructions * sizeof(GLboolean));
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint index = inst->DstReg.Index;
+ const GLuint mask = inst->DstReg.WriteMask;
+ enum inst_use use;
+
+ /* We must deactivate the pass as soon as some indirection is used */
+ if (inst->DstReg.RelAddr)
+ goto done;
+ for (arg = 0; arg < _mesa_num_inst_src_regs(inst->Opcode); arg++)
+ if (inst->SrcReg[arg].RelAddr)
+ goto done;
+
+ if (_mesa_is_flow_control_opcode(inst->Opcode) ||
+ _mesa_num_inst_dst_regs(inst->Opcode) == 0 ||
+ inst->DstReg.File != PROGRAM_TEMPORARY ||
+ inst->DstReg.RelAddr)
+ continue;
+
+ use = find_next_use(prog, i+1, index, mask);
+ if (use == WRITE || use == END)
+ removeInst[i] = GL_TRUE;
+ }
+
+ rem = remove_instructions(prog, removeInst);
+
+done:
+ free(removeInst);
+ return rem != 0;
+}
+
+
+/**
+ * Try to inject the destination of mov as the destination of inst and recompute
+ * the swizzles operators for the sources of inst if required. Return GL_TRUE
+ * of the substitution was possible, GL_FALSE otherwise
+ */
+static GLboolean
+_mesa_merge_mov_into_inst(struct prog_instruction *inst,
+ const struct prog_instruction *mov)
+{
+ /* Indirection table which associates destination and source components for
+ * the mov instruction
+ */
+ const GLuint mask = get_src_arg_mask(mov, 0, NO_MASK);
+
+ /* Some components are not written by inst. We cannot remove the mov */
+ if (mask != (inst->DstReg.WriteMask & mask))
+ return GL_FALSE;
+
+ inst->SaturateMode |= mov->SaturateMode;
+
+ /* Depending on the instruction, we may need to recompute the swizzles.
+ * Also, some other instructions (like TEX) are not linear. We will only
+ * consider completely active sources and destinations
+ */
+ switch (inst->Opcode) {
+
+ /* Carstesian instructions: we compute the swizzle */
+ case OPCODE_MOV:
+ case OPCODE_MIN:
+ case OPCODE_MAX:
+ case OPCODE_ABS:
+ case OPCODE_ADD:
+ case OPCODE_MAD:
+ case OPCODE_MUL:
+ case OPCODE_SUB:
+ {
+ GLuint dst_to_src_comp[4] = {0,0,0,0};
+ GLuint dst_comp, arg;
+ for (dst_comp = 0; dst_comp < 4; ++dst_comp) {
+ if (mov->DstReg.WriteMask & (1 << dst_comp)) {
+ const GLuint src_comp = GET_SWZ(mov->SrcReg[0].Swizzle, dst_comp);
+ ASSERT(src_comp < 4);
+ dst_to_src_comp[dst_comp] = src_comp;
+ }
+ }
+
+ /* Patch each source of the instruction */
+ for (arg = 0; arg < _mesa_num_inst_src_regs(inst->Opcode); arg++) {
+ const GLuint arg_swz = inst->SrcReg[arg].Swizzle;
+ inst->SrcReg[arg].Swizzle = 0;
+
+ /* Reset each active component of the swizzle */
+ for (dst_comp = 0; dst_comp < 4; ++dst_comp) {
+ GLuint src_comp, arg_comp;
+ if ((mov->DstReg.WriteMask & (1 << dst_comp)) == 0)
+ continue;
+ src_comp = dst_to_src_comp[dst_comp];
+ ASSERT(src_comp < 4);
+ arg_comp = GET_SWZ(arg_swz, src_comp);
+ ASSERT(arg_comp < 4);
+ inst->SrcReg[arg].Swizzle |= arg_comp << (3*dst_comp);
+ }
+ }
+ inst->DstReg = mov->DstReg;
+ return GL_TRUE;
+ }
+
+ /* Dot products and scalar instructions: we only change the destination */
+ case OPCODE_RCP:
+ case OPCODE_SIN:
+ case OPCODE_COS:
+ case OPCODE_RSQ:
+ case OPCODE_POW:
+ case OPCODE_EX2:
+ case OPCODE_LOG:
+ case OPCODE_DP2:
+ case OPCODE_DP3:
+ case OPCODE_DP4:
+ inst->DstReg = mov->DstReg;
+ return GL_TRUE;
+
+ /* All other instructions require fully active components with no swizzle */
+ default:
+ if (mov->SrcReg[0].Swizzle != SWIZZLE_XYZW ||
+ inst->DstReg.WriteMask != WRITEMASK_XYZW)
+ return GL_FALSE;
+ inst->DstReg = mov->DstReg;
+ return GL_TRUE;
+ }
+}
+
+
+/**
+ * Try to remove extraneous MOV instructions from the given program.
+ */
+static GLboolean
+_mesa_remove_extra_moves(struct gl_program *prog)
+{
+ GLboolean *removeInst; /* per-instruction removal flag */
+ GLuint i, rem = 0, nesting = 0;
+
+ if (dbg) {
+ printf("Optimize: Begin remove extra moves\n");
+ _mesa_print_program(prog);
+ }
+
+ removeInst =
+ calloc(1, prog->NumInstructions * sizeof(GLboolean));
+
+ /*
+ * Look for sequences such as this:
+ * FOO tmpX, arg0, arg1;
+ * MOV tmpY, tmpX;
+ * and convert into:
+ * FOO tmpY, arg0, arg1;
+ */
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *mov = prog->Instructions + i;
+
+ switch (mov->Opcode) {
+ case OPCODE_BGNLOOP:
+ case OPCODE_BGNSUB:
+ case OPCODE_IF:
+ nesting++;
+ break;
+ case OPCODE_ENDLOOP:
+ case OPCODE_ENDSUB:
+ case OPCODE_ENDIF:
+ nesting--;
+ break;
+ case OPCODE_MOV:
+ if (i > 0 &&
+ can_downward_mov_be_modifed(mov) &&
+ mov->SrcReg[0].File == PROGRAM_TEMPORARY &&
+ nesting == 0)
+ {
+
+ /* see if this MOV can be removed */
+ const GLuint id = mov->SrcReg[0].Index;
+ struct prog_instruction *prevInst;
+ GLuint prevI;
+
+ /* get pointer to previous instruction */
+ prevI = i - 1;
+ while (prevI > 0 && removeInst[prevI])
+ prevI--;
+ prevInst = prog->Instructions + prevI;
+
+ if (prevInst->DstReg.File == PROGRAM_TEMPORARY &&
+ prevInst->DstReg.Index == id &&
+ prevInst->DstReg.RelAddr == 0 &&
+ prevInst->DstReg.CondMask == COND_TR) {
+
+ const GLuint dst_mask = prevInst->DstReg.WriteMask;
+ enum inst_use next_use = find_next_use(prog, i+1, id, dst_mask);
+
+ if (next_use == WRITE || next_use == END) {
+ /* OK, we can safely remove this MOV instruction.
+ * Transform:
+ * prevI: FOO tempIndex, x, y;
+ * i: MOV z, tempIndex;
+ * Into:
+ * prevI: FOO z, x, y;
+ */
+ if (_mesa_merge_mov_into_inst(prevInst, mov)) {
+ removeInst[i] = GL_TRUE;
+ if (dbg) {
+ printf("Remove MOV at %u\n", i);
+ printf("new prev inst %u: ", prevI);
+ _mesa_print_instruction(prevInst);
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ ; /* nothing */
+ }
+ }
+
+ /* now remove the instructions which aren't needed */
+ rem = remove_instructions(prog, removeInst);
+
+ free(removeInst);
+
+ if (dbg) {
+ printf("Optimize: End remove extra moves. %u instructions removed\n", rem);
+ /*_mesa_print_program(prog);*/
+ }
+
+ return rem != 0;
+}
+
+
+/** A live register interval */
+struct interval
+{
+ GLuint Reg; /** The temporary register index */
+ GLuint Start, End; /** Start/end instruction numbers */
+};
+
+
+/** A list of register intervals */
+struct interval_list
+{
+ GLuint Num;
+ struct interval Intervals[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+};
+
+
+static void
+append_interval(struct interval_list *list, const struct interval *inv)
+{
+ list->Intervals[list->Num++] = *inv;
+}
+
+
+/** Insert interval inv into list, sorted by interval end */
+static void
+insert_interval_by_end(struct interval_list *list, const struct interval *inv)
+{
+ /* XXX we could do a binary search insertion here since list is sorted */
+ GLint i = list->Num - 1;
+ while (i >= 0 && list->Intervals[i].End > inv->End) {
+ list->Intervals[i + 1] = list->Intervals[i];
+ i--;
+ }
+ list->Intervals[i + 1] = *inv;
+ list->Num++;
+
+#ifdef DEBUG
+ {
+ GLuint i;
+ for (i = 0; i + 1 < list->Num; i++) {
+ ASSERT(list->Intervals[i].End <= list->Intervals[i + 1].End);
+ }
+ }
+#endif
+}
+
+
+/** Remove the given interval from the interval list */
+static void
+remove_interval(struct interval_list *list, const struct interval *inv)
+{
+ /* XXX we could binary search since list is sorted */
+ GLuint k;
+ for (k = 0; k < list->Num; k++) {
+ if (list->Intervals[k].Reg == inv->Reg) {
+ /* found, remove it */
+ ASSERT(list->Intervals[k].Start == inv->Start);
+ ASSERT(list->Intervals[k].End == inv->End);
+ while (k < list->Num - 1) {
+ list->Intervals[k] = list->Intervals[k + 1];
+ k++;
+ }
+ list->Num--;
+ return;
+ }
+ }
+}
+
+
+/** called by qsort() */
+static int
+compare_start(const void *a, const void *b)
+{
+ const struct interval *ia = (const struct interval *) a;
+ const struct interval *ib = (const struct interval *) b;
+ if (ia->Start < ib->Start)
+ return -1;
+ else if (ia->Start > ib->Start)
+ return +1;
+ else
+ return 0;
+}
+
+
+/** sort the interval list according to interval starts */
+static void
+sort_interval_list_by_start(struct interval_list *list)
+{
+ qsort(list->Intervals, list->Num, sizeof(struct interval), compare_start);
+#ifdef DEBUG
+ {
+ GLuint i;
+ for (i = 0; i + 1 < list->Num; i++) {
+ ASSERT(list->Intervals[i].Start <= list->Intervals[i + 1].Start);
+ }
+ }
+#endif
+}
+
+struct loop_info
+{
+ GLuint Start, End; /**< Start, end instructions of loop */
+};
+
+/**
+ * Update the intermediate interval info for register 'index' and
+ * instruction 'ic'.
+ */
+static void
+update_interval(GLint intBegin[], GLint intEnd[],
+ struct loop_info *loopStack, GLuint loopStackDepth,
+ GLuint index, GLuint ic)
+{
+ int i;
+ GLuint begin = ic;
+ GLuint end = ic;
+
+ /* If the register is used in a loop, extend its lifetime through the end
+ * of the outermost loop that doesn't contain its definition.
+ */
+ for (i = 0; i < loopStackDepth; i++) {
+ if (intBegin[index] < loopStack[i].Start) {
+ end = loopStack[i].End;
+ break;
+ }
+ }
+
+ /* Variables that are live at the end of a loop will also be live at the
+ * beginning, so an instruction inside of a loop should have its live
+ * interval begin at the start of the outermost loop.
+ */
+ if (loopStackDepth > 0 && ic > loopStack[0].Start && ic < loopStack[0].End) {
+ begin = loopStack[0].Start;
+ }
+
+ ASSERT(index < REG_ALLOCATE_MAX_PROGRAM_TEMPS);
+ if (intBegin[index] == -1) {
+ ASSERT(intEnd[index] == -1);
+ intBegin[index] = begin;
+ intEnd[index] = end;
+ }
+ else {
+ intEnd[index] = end;
+ }
+}
+
+
+/**
+ * Find first/last instruction that references each temporary register.
+ */
+GLboolean
+_mesa_find_temp_intervals(const struct prog_instruction *instructions,
+ GLuint numInstructions,
+ GLint intBegin[REG_ALLOCATE_MAX_PROGRAM_TEMPS],
+ GLint intEnd[REG_ALLOCATE_MAX_PROGRAM_TEMPS])
+{
+ struct loop_info loopStack[MAX_LOOP_NESTING];
+ GLuint loopStackDepth = 0;
+ GLuint i;
+
+ for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++){
+ intBegin[i] = intEnd[i] = -1;
+ }
+
+ /* Scan instructions looking for temporary registers */
+ for (i = 0; i < numInstructions; i++) {
+ const struct prog_instruction *inst = instructions + i;
+ if (inst->Opcode == OPCODE_BGNLOOP) {
+ loopStack[loopStackDepth].Start = i;
+ loopStack[loopStackDepth].End = inst->BranchTarget;
+ loopStackDepth++;
+ }
+ else if (inst->Opcode == OPCODE_ENDLOOP) {
+ loopStackDepth--;
+ }
+ else if (inst->Opcode == OPCODE_CAL) {
+ return GL_FALSE;
+ }
+ else {
+ const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/
+ GLuint j;
+ for (j = 0; j < numSrc; j++) {
+ if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+ const GLuint index = inst->SrcReg[j].Index;
+ if (inst->SrcReg[j].RelAddr)
+ return GL_FALSE;
+ update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+ index, i);
+ }
+ }
+ if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+ const GLuint index = inst->DstReg.Index;
+ if (inst->DstReg.RelAddr)
+ return GL_FALSE;
+ update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+ index, i);
+ }
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Find the live intervals for each temporary register in the program.
+ * For register R, the interval [A,B] indicates that R is referenced
+ * from instruction A through instruction B.
+ * Special consideration is needed for loops and subroutines.
+ * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason
+ */
+static GLboolean
+find_live_intervals(struct gl_program *prog,
+ struct interval_list *liveIntervals)
+{
+ GLint intBegin[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+ GLint intEnd[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+ GLuint i;
+
+ /*
+ * Note: we'll return GL_FALSE below if we find relative indexing
+ * into the TEMP register file. We can't handle that yet.
+ * We also give up on subroutines for now.
+ */
+
+ if (dbg) {
+ printf("Optimize: Begin find intervals\n");
+ }
+
+ /* build intermediate arrays */
+ if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions,
+ intBegin, intEnd))
+ return GL_FALSE;
+
+ /* Build live intervals list from intermediate arrays */
+ liveIntervals->Num = 0;
+ for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++) {
+ if (intBegin[i] >= 0) {
+ struct interval inv;
+ inv.Reg = i;
+ inv.Start = intBegin[i];
+ inv.End = intEnd[i];
+ append_interval(liveIntervals, &inv);
+ }
+ }
+
+ /* Sort the list according to interval starts */
+ sort_interval_list_by_start(liveIntervals);
+
+ if (dbg) {
+ /* print interval info */
+ for (i = 0; i < liveIntervals->Num; i++) {
+ const struct interval *inv = liveIntervals->Intervals + i;
+ printf("Reg[%d] live [%d, %d]:",
+ inv->Reg, inv->Start, inv->End);
+ if (1) {
+ GLuint j;
+ for (j = 0; j < inv->Start; j++)
+ printf(" ");
+ for (j = inv->Start; j <= inv->End; j++)
+ printf("x");
+ }
+ printf("\n");
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+/** Scan the array of used register flags to find free entry */
+static GLint
+alloc_register(GLboolean usedRegs[REG_ALLOCATE_MAX_PROGRAM_TEMPS])
+{
+ GLuint k;
+ for (k = 0; k < REG_ALLOCATE_MAX_PROGRAM_TEMPS; k++) {
+ if (!usedRegs[k]) {
+ usedRegs[k] = GL_TRUE;
+ return k;
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * This function implements "Linear Scan Register Allocation" to reduce
+ * the number of temporary registers used by the program.
+ *
+ * We compute the "live interval" for all temporary registers then
+ * examine the overlap of the intervals to allocate new registers.
+ * Basically, if two intervals do not overlap, they can use the same register.
+ */
+static void
+_mesa_reallocate_registers(struct gl_program *prog)
+{
+ struct interval_list liveIntervals;
+ GLint registerMap[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+ GLboolean usedRegs[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+ GLuint i;
+ GLint maxTemp = -1;
+
+ if (dbg) {
+ printf("Optimize: Begin live-interval register reallocation\n");
+ _mesa_print_program(prog);
+ }
+
+ for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++){
+ registerMap[i] = -1;
+ usedRegs[i] = GL_FALSE;
+ }
+
+ if (!find_live_intervals(prog, &liveIntervals)) {
+ if (dbg)
+ printf("Aborting register reallocation\n");
+ return;
+ }
+
+ {
+ struct interval_list activeIntervals;
+ activeIntervals.Num = 0;
+
+ /* loop over live intervals, allocating a new register for each */
+ for (i = 0; i < liveIntervals.Num; i++) {
+ const struct interval *live = liveIntervals.Intervals + i;
+
+ if (dbg)
+ printf("Consider register %u\n", live->Reg);
+
+ /* Expire old intervals. Intervals which have ended with respect
+ * to the live interval can have their remapped registers freed.
+ */
+ {
+ GLint j;
+ for (j = 0; j < (GLint) activeIntervals.Num; j++) {
+ const struct interval *inv = activeIntervals.Intervals + j;
+ if (inv->End >= live->Start) {
+ /* Stop now. Since the activeInterval list is sorted
+ * we know we don't have to go further.
+ */
+ break;
+ }
+ else {
+ /* Interval 'inv' has expired */
+ const GLint regNew = registerMap[inv->Reg];
+ ASSERT(regNew >= 0);
+
+ if (dbg)
+ printf(" expire interval for reg %u\n", inv->Reg);
+
+ /* remove interval j from active list */
+ remove_interval(&activeIntervals, inv);
+ j--; /* counter-act j++ in for-loop above */
+
+ /* return register regNew to the free pool */
+ if (dbg)
+ printf(" free reg %d\n", regNew);
+ ASSERT(usedRegs[regNew] == GL_TRUE);
+ usedRegs[regNew] = GL_FALSE;
+ }
+ }
+ }
+
+ /* find a free register for this live interval */
+ {
+ const GLint k = alloc_register(usedRegs);
+ if (k < 0) {
+ /* out of registers, give up */
+ return;
+ }
+ registerMap[live->Reg] = k;
+ maxTemp = MAX2(maxTemp, k);
+ if (dbg)
+ printf(" remap register %u -> %d\n", live->Reg, k);
+ }
+
+ /* Insert this live interval into the active list which is sorted
+ * by increasing end points.
+ */
+ insert_interval_by_end(&activeIntervals, live);
+ }
+ }
+
+ if (maxTemp + 1 < (GLint) liveIntervals.Num) {
+ /* OK, we've reduced the number of registers needed.
+ * Scan the program and replace all the old temporary register
+ * indexes with the new indexes.
+ */
+ replace_regs(prog, PROGRAM_TEMPORARY, registerMap);
+
+ prog->NumTemporaries = maxTemp + 1;
+ }
+
+ if (dbg) {
+ printf("Optimize: End live-interval register reallocation\n");
+ printf("Num temp regs before: %u after: %u\n",
+ liveIntervals.Num, maxTemp + 1);
+ _mesa_print_program(prog);
+ }
+}
+
+
+#if 0
+static void
+print_it(struct gl_context *ctx, struct gl_program *program, const char *txt) {
+ fprintf(stderr, "%s (%u inst):\n", txt, program->NumInstructions);
+ _mesa_print_program(program);
+ _mesa_print_program_parameters(ctx, program);
+ fprintf(stderr, "\n\n");
+}
+#endif
+
+/**
+ * This pass replaces CMP T0, T1 T2 T0 with MOV T0, T2 when the CMP
+ * instruction is the first instruction to write to register T0. The are
+ * several lowering passes done in GLSL IR (e.g. branches and
+ * relative addressing) that create a large number of conditional assignments
+ * that ir_to_mesa converts to CMP instructions like the one mentioned above.
+ *
+ * Here is why this conversion is safe:
+ * CMP T0, T1 T2 T0 can be expanded to:
+ * if (T1 < 0.0)
+ * MOV T0, T2;
+ * else
+ * MOV T0, T0;
+ *
+ * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same
+ * as the original program. If (T1 < 0.0) evaluates to false, executing
+ * MOV T0, T0 will store a garbage value in T0 since T0 is uninitialized.
+ * Therefore, it doesn't matter that we are replacing MOV T0, T0 with MOV T0, T2
+ * because any instruction that was going to read from T0 after this was going
+ * to read a garbage value anyway.
+ */
+static void
+_mesa_simplify_cmp(struct gl_program * program)
+{
+ GLuint tempWrites[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+ GLuint outputWrites[MAX_PROGRAM_OUTPUTS];
+ GLuint i;
+
+ if (dbg) {
+ printf("Optimize: Begin reads without writes\n");
+ _mesa_print_program(program);
+ }
+
+ for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++) {
+ tempWrites[i] = 0;
+ }
+
+ for (i = 0; i < MAX_PROGRAM_OUTPUTS; i++) {
+ outputWrites[i] = 0;
+ }
+
+ for (i = 0; i < program->NumInstructions; i++) {
+ struct prog_instruction *inst = program->Instructions + i;
+ GLuint prevWriteMask;
+
+ /* Give up if we encounter relative addressing or flow control. */
+ if (_mesa_is_flow_control_opcode(inst->Opcode) || inst->DstReg.RelAddr) {
+ return;
+ }
+
+ if (inst->DstReg.File == PROGRAM_OUTPUT) {
+ assert(inst->DstReg.Index < MAX_PROGRAM_OUTPUTS);
+ prevWriteMask = outputWrites[inst->DstReg.Index];
+ outputWrites[inst->DstReg.Index] |= inst->DstReg.WriteMask;
+ } else if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+ assert(inst->DstReg.Index < REG_ALLOCATE_MAX_PROGRAM_TEMPS);
+ prevWriteMask = tempWrites[inst->DstReg.Index];
+ tempWrites[inst->DstReg.Index] |= inst->DstReg.WriteMask;
+ } else {
+ /* No other register type can be a destination register. */
+ continue;
+ }
+
+ /* For a CMP to be considered a conditional write, the destination
+ * register and source register two must be the same. */
+ if (inst->Opcode == OPCODE_CMP
+ && !(inst->DstReg.WriteMask & prevWriteMask)
+ && inst->SrcReg[2].File == inst->DstReg.File
+ && inst->SrcReg[2].Index == inst->DstReg.Index
+ && inst->DstReg.WriteMask == get_src_arg_mask(inst, 2, NO_MASK)) {
+
+ inst->Opcode = OPCODE_MOV;
+ inst->SrcReg[0] = inst->SrcReg[1];
+
+ /* Unused operands are expected to have the file set to
+ * PROGRAM_UNDEFINED. This is how _mesa_init_instructions initializes
+ * all of the sources.
+ */
+ inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ inst->SrcReg[2].File = PROGRAM_UNDEFINED;
+ inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
+ }
+ }
+ if (dbg) {
+ printf("Optimize: End reads without writes\n");
+ _mesa_print_program(program);
+ }
+}
+
+/**
+ * Apply optimizations to the given program to eliminate unnecessary
+ * instructions, temp regs, etc.
+ */
+void
+_mesa_optimize_program(struct gl_context *ctx, struct gl_program *program)
+{
+ GLboolean any_change;
+
+ _mesa_simplify_cmp(program);
+ /* Stop when no modifications were output */
+ do {
+ any_change = GL_FALSE;
+ _mesa_remove_extra_move_use(program);
+ if (_mesa_remove_dead_code_global(program))
+ any_change = GL_TRUE;
+ if (_mesa_remove_extra_moves(program))
+ any_change = GL_TRUE;
+ if (_mesa_remove_dead_code_local(program))
+ any_change = GL_TRUE;
+
+ any_change = _mesa_constant_fold(program) || any_change;
+ _mesa_reallocate_registers(program);
+ } while (any_change);
+}
+
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_optimize.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_optimize.h
new file mode 100644
index 0000000..7607bff
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_optimize.h
@@ -0,0 +1,49 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PROG_OPT_H
+#define PROG_OPT_H
+
+
+#include "main/config.h"
+#include "main/glheader.h"
+
+
+struct gl_context;
+struct gl_program;
+struct prog_instruction;
+
+
+extern GLboolean
+_mesa_find_temp_intervals(const struct prog_instruction *instructions,
+ GLuint numInstructions,
+ GLint intBegin[MAX_PROGRAM_TEMPS],
+ GLint intEnd[MAX_PROGRAM_TEMPS]);
+
+extern void
+_mesa_optimize_program(struct gl_context *ctx, struct gl_program *program);
+
+extern GLboolean
+_mesa_constant_fold(struct gl_program *prog);
+
+#endif
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter.c
new file mode 100644
index 0000000..54531d2
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter.c
@@ -0,0 +1,582 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_parameter.c
+ * Program parameter lists and functions.
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_statevars.h"
+
+
+struct gl_program_parameter_list *
+_mesa_new_parameter_list(void)
+{
+ return CALLOC_STRUCT(gl_program_parameter_list);
+}
+
+
+struct gl_program_parameter_list *
+_mesa_new_parameter_list_sized(unsigned size)
+{
+ struct gl_program_parameter_list *p = _mesa_new_parameter_list();
+
+ if ((p != NULL) && (size != 0)) {
+ p->Size = size;
+
+ /* alloc arrays */
+ p->Parameters = (struct gl_program_parameter *)
+ calloc(1, size * sizeof(struct gl_program_parameter));
+
+ p->ParameterValues = (gl_constant_value (*)[4])
+ _mesa_align_malloc(size * 4 *sizeof(gl_constant_value), 16);
+
+
+ if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) {
+ free(p->Parameters);
+ _mesa_align_free(p->ParameterValues);
+ free(p);
+ p = NULL;
+ }
+ }
+
+ return p;
+}
+
+
+/**
+ * Free a parameter list and all its parameters
+ */
+void
+_mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
+{
+ GLuint i;
+ for (i = 0; i < paramList->NumParameters; i++) {
+ free((void *)paramList->Parameters[i].Name);
+ }
+ free(paramList->Parameters);
+ _mesa_align_free(paramList->ParameterValues);
+ free(paramList);
+}
+
+
+/**
+ * Add a new parameter to a parameter list.
+ * Note that parameter values are usually 4-element GLfloat vectors.
+ * When size > 4 we'll allocate a sequential block of parameters to
+ * store all the values (in blocks of 4).
+ *
+ * \param paramList the list to add the parameter to
+ * \param type type of parameter, such as
+ * \param name the parameter name, will be duplicated/copied!
+ * \param size number of elements in 'values' vector (1..4, or more)
+ * \param datatype GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE.
+ * \param values initial parameter value, up to 4 gl_constant_values, or NULL
+ * \param state state indexes, or NULL
+ * \return index of new parameter in the list, or -1 if error (out of mem)
+ */
+GLint
+_mesa_add_parameter(struct gl_program_parameter_list *paramList,
+ gl_register_file type, const char *name,
+ GLuint size, GLenum datatype,
+ const gl_constant_value *values,
+ const gl_state_index state[STATE_LENGTH])
+{
+ const GLuint oldNum = paramList->NumParameters;
+ const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */
+
+ assert(size > 0);
+
+ if (oldNum + sz4 > paramList->Size) {
+ /* Need to grow the parameter list array (alloc some extra) */
+ paramList->Size = paramList->Size + 4 * sz4;
+
+ /* realloc arrays */
+ paramList->Parameters = (struct gl_program_parameter *)
+ _mesa_realloc(paramList->Parameters,
+ oldNum * sizeof(struct gl_program_parameter),
+ paramList->Size * sizeof(struct gl_program_parameter));
+
+ paramList->ParameterValues = (gl_constant_value (*)[4])
+ _mesa_align_realloc(paramList->ParameterValues, /* old buf */
+ oldNum * 4 * sizeof(gl_constant_value),/* old sz */
+ paramList->Size*4*sizeof(gl_constant_value),/*new*/
+ 16);
+ }
+
+ if (!paramList->Parameters ||
+ !paramList->ParameterValues) {
+ /* out of memory */
+ paramList->NumParameters = 0;
+ paramList->Size = 0;
+ return -1;
+ }
+ else {
+ GLuint i, j;
+
+ paramList->NumParameters = oldNum + sz4;
+
+ memset(¶mList->Parameters[oldNum], 0,
+ sz4 * sizeof(struct gl_program_parameter));
+
+ for (i = 0; i < sz4; i++) {
+ struct gl_program_parameter *p = paramList->Parameters + oldNum + i;
+ p->Name = name ? _mesa_strdup(name) : NULL;
+ p->Type = type;
+ p->Size = size;
+ p->DataType = datatype;
+ if (values) {
+ if (size >= 4) {
+ COPY_4V(paramList->ParameterValues[oldNum + i], values);
+ }
+ else {
+ /* copy 1, 2 or 3 values */
+ GLuint remaining = size % 4;
+ assert(remaining < 4);
+ for (j = 0; j < remaining; j++) {
+ paramList->ParameterValues[oldNum + i][j].f = values[j].f;
+ }
+ /* fill in remaining positions with zeros */
+ for (; j < 4; j++) {
+ paramList->ParameterValues[oldNum + i][j].f = 0.0f;
+ }
+ }
+ values += 4;
+ p->Initialized = GL_TRUE;
+ }
+ else {
+ /* silence valgrind */
+ for (j = 0; j < 4; j++)
+ paramList->ParameterValues[oldNum + i][j].f = 0;
+ }
+ size -= 4;
+ }
+
+ if (state) {
+ for (i = 0; i < STATE_LENGTH; i++)
+ paramList->Parameters[oldNum].StateIndexes[i] = state[i];
+ }
+
+ return (GLint) oldNum;
+ }
+}
+
+
+/**
+ * Add a new named constant to the parameter list.
+ * This will be used when the program contains something like this:
+ * PARAM myVals = { 0, 1, 2, 3 };
+ *
+ * \param paramList the parameter list
+ * \param name the name for the constant
+ * \param values four float values
+ * \return index/position of the new parameter in the parameter list
+ */
+GLint
+_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
+ const char *name, const gl_constant_value values[4],
+ GLuint size)
+{
+ /* first check if this is a duplicate constant */
+ GLint pos;
+ for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) {
+ const gl_constant_value *pvals = paramList->ParameterValues[pos];
+ if (pvals[0].u == values[0].u &&
+ pvals[1].u == values[1].u &&
+ pvals[2].u == values[2].u &&
+ pvals[3].u == values[3].u &&
+ strcmp(paramList->Parameters[pos].Name, name) == 0) {
+ /* Same name and value is already in the param list - reuse it */
+ return pos;
+ }
+ }
+ /* not found, add new parameter */
+ return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name,
+ size, GL_NONE, values, NULL);
+}
+
+
+/**
+ * Add a new unnamed constant to the parameter list. This will be used
+ * when a fragment/vertex program contains something like this:
+ * MOV r, { 0, 1, 2, 3 };
+ * If swizzleOut is non-null we'll search the parameter list for an
+ * existing instance of the constant which matches with a swizzle.
+ *
+ * \param paramList the parameter list
+ * \param values four float values
+ * \param swizzleOut returns swizzle mask for accessing the constant
+ * \return index/position of the new parameter in the parameter list.
+ */
+GLint
+_mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,
+ const gl_constant_value values[4], GLuint size,
+ GLenum datatype, GLuint *swizzleOut)
+{
+ GLint pos;
+ ASSERT(size >= 1);
+ ASSERT(size <= 4);
+
+ if (swizzleOut &&
+ _mesa_lookup_parameter_constant(paramList, values,
+ size, &pos, swizzleOut)) {
+ return pos;
+ }
+
+ /* Look for empty space in an already unnamed constant parameter
+ * to add this constant. This will only work for single-element
+ * constants because we rely on smearing (i.e. .yyyy or .zzzz).
+ */
+ if (size == 1 && swizzleOut) {
+ for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) {
+ struct gl_program_parameter *p = paramList->Parameters + pos;
+ if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) {
+ /* ok, found room */
+ gl_constant_value *pVal = paramList->ParameterValues[pos];
+ GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */
+ pVal[p->Size] = values[0];
+ p->Size++;
+ *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz);
+ return pos;
+ }
+ }
+ }
+
+ /* add a new parameter to store this constant */
+ pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL,
+ size, datatype, values, NULL);
+ if (pos >= 0 && swizzleOut) {
+ if (size == 1)
+ *swizzleOut = SWIZZLE_XXXX;
+ else
+ *swizzleOut = SWIZZLE_NOOP;
+ }
+ return pos;
+}
+
+/**
+ * Add a new unnamed constant to the parameter list. This will be used
+ * when a fragment/vertex program contains something like this:
+ * MOV r, { 0, 1, 2, 3 };
+ * If swizzleOut is non-null we'll search the parameter list for an
+ * existing instance of the constant which matches with a swizzle.
+ *
+ * \param paramList the parameter list
+ * \param values four float values
+ * \param swizzleOut returns swizzle mask for accessing the constant
+ * \return index/position of the new parameter in the parameter list.
+ * \sa _mesa_add_typed_unnamed_constant
+ */
+GLint
+_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
+ const gl_constant_value values[4], GLuint size,
+ GLuint *swizzleOut)
+{
+ return _mesa_add_typed_unnamed_constant(paramList, values, size, GL_NONE,
+ swizzleOut);
+}
+
+#if 0 /* not used yet */
+/**
+ * Returns the number of 4-component registers needed to store a piece
+ * of GL state. For matrices this may be as many as 4 registers,
+ * everything else needs
+ * just 1 register.
+ */
+static GLuint
+sizeof_state_reference(const GLint *stateTokens)
+{
+ if (stateTokens[0] == STATE_MATRIX) {
+ GLuint rows = stateTokens[4] - stateTokens[3] + 1;
+ assert(rows >= 1);
+ assert(rows <= 4);
+ return rows;
+ }
+ else {
+ return 1;
+ }
+}
+#endif
+
+
+/**
+ * Add a new state reference to the parameter list.
+ * This will be used when the program contains something like this:
+ * PARAM ambient = state.material.front.ambient;
+ *
+ * \param paramList the parameter list
+ * \param stateTokens an array of 5 (STATE_LENGTH) state tokens
+ * \return index of the new parameter.
+ */
+GLint
+_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
+ const gl_state_index stateTokens[STATE_LENGTH])
+{
+ const GLuint size = 4; /* XXX fix */
+ char *name;
+ GLint index;
+
+ /* Check if the state reference is already in the list */
+ for (index = 0; index < (GLint) paramList->NumParameters; index++) {
+ if (!memcmp(paramList->Parameters[index].StateIndexes,
+ stateTokens, STATE_LENGTH * sizeof(gl_state_index))) {
+ return index;
+ }
+ }
+
+ name = _mesa_program_state_string(stateTokens);
+ index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
+ size, GL_NONE,
+ NULL, (gl_state_index *) stateTokens);
+ paramList->StateFlags |= _mesa_program_state_flags(stateTokens);
+
+ /* free name string here since we duplicated it in add_parameter() */
+ free(name);
+
+ return index;
+}
+
+
+/**
+ * Lookup a parameter value by name in the given parameter list.
+ * \return pointer to the float[4] values.
+ */
+gl_constant_value *
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name)
+{
+ GLint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
+ if (i < 0)
+ return NULL;
+ else
+ return paramList->ParameterValues[i];
+}
+
+
+/**
+ * Given a program parameter name, find its position in the list of parameters.
+ * \param paramList the parameter list to search
+ * \param nameLen length of name (in chars).
+ * If length is negative, assume that name is null-terminated.
+ * \param name the name to search for
+ * \return index of parameter in the list.
+ */
+GLint
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name)
+{
+ GLint i;
+
+ if (!paramList)
+ return -1;
+
+ if (nameLen == -1) {
+ /* name is null-terminated */
+ for (i = 0; i < (GLint) paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Name &&
+ strcmp(paramList->Parameters[i].Name, name) == 0)
+ return i;
+ }
+ }
+ else {
+ /* name is not null-terminated, use nameLen */
+ for (i = 0; i < (GLint) paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Name &&
+ strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
+ && strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * Look for a float vector in the given parameter list. The float vector
+ * may be of length 1, 2, 3 or 4. If swizzleOut is non-null, we'll try
+ * swizzling to find a match.
+ * \param list the parameter list to search
+ * \param v the float vector to search for
+ * \param vSize number of element in v
+ * \param posOut returns the position of the constant, if found
+ * \param swizzleOut returns a swizzle mask describing location of the
+ * vector elements if found.
+ * \return GL_TRUE if found, GL_FALSE if not found
+ */
+GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
+ const gl_constant_value v[], GLuint vSize,
+ GLint *posOut, GLuint *swizzleOut)
+{
+ GLuint i;
+
+ assert(vSize >= 1);
+ assert(vSize <= 4);
+
+ if (!list) {
+ *posOut = -1;
+ return GL_FALSE;
+ }
+
+ for (i = 0; i < list->NumParameters; i++) {
+ if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
+ if (!swizzleOut) {
+ /* swizzle not allowed */
+ GLuint j, match = 0;
+ for (j = 0; j < vSize; j++) {
+ if (v[j].u == list->ParameterValues[i][j].u)
+ match++;
+ }
+ if (match == vSize) {
+ *posOut = i;
+ return GL_TRUE;
+ }
+ }
+ else {
+ /* try matching w/ swizzle */
+ if (vSize == 1) {
+ /* look for v[0] anywhere within float[4] value */
+ GLuint j;
+ for (j = 0; j < list->Parameters[i].Size; j++) {
+ if (list->ParameterValues[i][j].u == v[0].u) {
+ /* found it */
+ *posOut = i;
+ *swizzleOut = MAKE_SWIZZLE4(j, j, j, j);
+ return GL_TRUE;
+ }
+ }
+ }
+ else if (vSize <= list->Parameters[i].Size) {
+ /* see if we can match this constant (with a swizzle) */
+ GLuint swz[4];
+ GLuint match = 0, j, k;
+ for (j = 0; j < vSize; j++) {
+ if (v[j].u == list->ParameterValues[i][j].u) {
+ swz[j] = j;
+ match++;
+ }
+ else {
+ for (k = 0; k < list->Parameters[i].Size; k++) {
+ if (v[j].u == list->ParameterValues[i][k].u) {
+ swz[j] = k;
+ match++;
+ break;
+ }
+ }
+ }
+ }
+ /* smear last value to remaining positions */
+ for (; j < 4; j++)
+ swz[j] = swz[j-1];
+
+ if (match == vSize) {
+ *posOut = i;
+ *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
+ return GL_TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ *posOut = -1;
+ return GL_FALSE;
+}
+
+
+struct gl_program_parameter_list *
+_mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
+{
+ struct gl_program_parameter_list *clone;
+ GLuint i;
+
+ clone = _mesa_new_parameter_list();
+ if (!clone)
+ return NULL;
+
+ /** Not too efficient, but correct */
+ for (i = 0; i < list->NumParameters; i++) {
+ struct gl_program_parameter *p = list->Parameters + i;
+ struct gl_program_parameter *pCopy;
+ GLuint size = MIN2(p->Size, 4);
+ GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType,
+ list->ParameterValues[i], NULL);
+ ASSERT(j >= 0);
+ pCopy = clone->Parameters + j;
+ /* copy state indexes */
+ if (p->Type == PROGRAM_STATE_VAR) {
+ GLint k;
+ for (k = 0; k < STATE_LENGTH; k++) {
+ pCopy->StateIndexes[k] = p->StateIndexes[k];
+ }
+ }
+ else {
+ clone->Parameters[j].Size = p->Size;
+ }
+
+ }
+
+ clone->StateFlags = list->StateFlags;
+
+ return clone;
+}
+
+
+/**
+ * Return a new parameter list which is listA + listB.
+ */
+struct gl_program_parameter_list *
+_mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA,
+ const struct gl_program_parameter_list *listB)
+{
+ struct gl_program_parameter_list *list;
+
+ if (listA) {
+ list = _mesa_clone_parameter_list(listA);
+ if (list && listB) {
+ GLuint i;
+ for (i = 0; i < listB->NumParameters; i++) {
+ struct gl_program_parameter *param = listB->Parameters + i;
+ _mesa_add_parameter(list, param->Type, param->Name, param->Size,
+ param->DataType,
+ listB->ParameterValues[i],
+ param->StateIndexes);
+ }
+ }
+ }
+ else if (listB) {
+ list = _mesa_clone_parameter_list(listB);
+ }
+ else {
+ list = NULL;
+ }
+ return list;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter.h
new file mode 100644
index 0000000..6b3b3c2
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter.h
@@ -0,0 +1,158 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_parameter.c
+ * Program parameter lists and functions.
+ * \author Brian Paul
+ */
+
+#ifndef PROG_PARAMETER_H
+#define PROG_PARAMETER_H
+
+#include "main/mtypes.h"
+#include "prog_statevars.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Actual data for constant values of parameters.
+ */
+typedef union gl_constant_value
+{
+ GLfloat f;
+ GLint b;
+ GLint i;
+ GLuint u;
+} gl_constant_value;
+
+
+/**
+ * Program parameter.
+ * Used by shaders/programs for uniforms, constants, varying vars, etc.
+ */
+struct gl_program_parameter
+{
+ const char *Name; /**< Null-terminated string */
+ gl_register_file Type; /**< PROGRAM_CONSTANT or STATE_VAR */
+ GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
+ /**
+ * Number of components (1..4), or more.
+ * If the number of components is greater than 4,
+ * this parameter is part of a larger uniform like a GLSL matrix or array.
+ * The next program parameter's Size will be Size-4 of this parameter.
+ */
+ GLuint Size;
+ GLboolean Initialized; /**< debug: Has the ParameterValue[] been set? */
+ /**
+ * A sequence of STATE_* tokens and integers to identify GL state.
+ */
+ gl_state_index StateIndexes[STATE_LENGTH];
+};
+
+
+/**
+ * List of gl_program_parameter instances.
+ */
+struct gl_program_parameter_list
+{
+ GLuint Size; /**< allocated size of Parameters, ParameterValues */
+ GLuint NumParameters; /**< number of parameters in arrays */
+ struct gl_program_parameter *Parameters; /**< Array [Size] */
+ gl_constant_value (*ParameterValues)[4]; /**< Array [Size] of constant[4] */
+ GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
+ might invalidate ParameterValues[] */
+};
+
+
+extern struct gl_program_parameter_list *
+_mesa_new_parameter_list(void);
+
+extern struct gl_program_parameter_list *
+_mesa_new_parameter_list_sized(unsigned size);
+
+extern void
+_mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
+
+extern struct gl_program_parameter_list *
+_mesa_clone_parameter_list(const struct gl_program_parameter_list *list);
+
+extern struct gl_program_parameter_list *
+_mesa_combine_parameter_lists(const struct gl_program_parameter_list *a,
+ const struct gl_program_parameter_list *b);
+
+static inline GLuint
+_mesa_num_parameters(const struct gl_program_parameter_list *list)
+{
+ return list ? list->NumParameters : 0;
+}
+
+extern GLint
+_mesa_add_parameter(struct gl_program_parameter_list *paramList,
+ gl_register_file type, const char *name,
+ GLuint size, GLenum datatype,
+ const gl_constant_value *values,
+ const gl_state_index state[STATE_LENGTH]);
+
+extern GLint
+_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
+ const char *name, const gl_constant_value values[4],
+ GLuint size);
+
+extern GLint
+_mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,
+ const gl_constant_value values[4], GLuint size,
+ GLenum datatype, GLuint *swizzleOut);
+
+extern GLint
+_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
+ const gl_constant_value values[4], GLuint size,
+ GLuint *swizzleOut);
+
+extern GLint
+_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
+ const gl_state_index stateTokens[STATE_LENGTH]);
+
+extern gl_constant_value *
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name);
+
+extern GLint
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name);
+
+extern GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
+ const gl_constant_value v[], GLuint vSize,
+ GLint *posOut, GLuint *swizzleOut);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PROG_PARAMETER_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter_layout.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter_layout.c
new file mode 100644
index 0000000..e834690
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter_layout.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_parameter_layout.c
+ * \brief Helper functions to layout storage for program parameters
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "prog_parameter.h"
+#include "prog_parameter_layout.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+unsigned
+_mesa_combine_swizzles(unsigned base, unsigned applied)
+{
+ unsigned swiz = 0;
+ unsigned i;
+
+ for (i = 0; i < 4; i++) {
+ const unsigned s = GET_SWZ(applied, i);
+
+ swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3);
+ }
+
+ return swiz;
+}
+
+
+/**
+ * Copy indirect access array from one parameter list to another
+ *
+ * \param src Parameter array copied from
+ * \param dst Parameter array copied to
+ * \param first Index of first element in \c src to copy
+ * \param count Number of elements to copy
+ *
+ * \return
+ * The location in \c dst of the first element copied from \c src on
+ * success. -1 on failure.
+ *
+ * \warning
+ * This function assumes that there is already enough space available in
+ * \c dst to hold all of the elements that will be copied over.
+ */
+static int
+copy_indirect_accessed_array(struct gl_program_parameter_list *src,
+ struct gl_program_parameter_list *dst,
+ unsigned first, unsigned count)
+{
+ const int base = dst->NumParameters;
+ unsigned i, j;
+
+ for (i = first; i < (first + count); i++) {
+ struct gl_program_parameter *curr = & src->Parameters[i];
+
+ if (curr->Type == PROGRAM_CONSTANT) {
+ j = dst->NumParameters;
+ } else {
+ for (j = 0; j < dst->NumParameters; j++) {
+ if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes,
+ sizeof(curr->StateIndexes)) == 0) {
+ return -1;
+ }
+ }
+ }
+
+ assert(j == dst->NumParameters);
+
+ /* copy src parameter [i] to dest parameter [j] */
+ memcpy(& dst->Parameters[j], curr,
+ sizeof(dst->Parameters[j]));
+ memcpy(dst->ParameterValues[j], src->ParameterValues[i],
+ sizeof(GLfloat) * 4);
+
+ /* Pointer to the string name was copied. Null-out src param name
+ * to prevent double free later.
+ */
+ curr->Name = NULL;
+
+ dst->NumParameters++;
+ }
+
+ return base;
+}
+
+
+/**
+ * XXX description???
+ * \return GL_TRUE for success, GL_FALSE for failure
+ */
+GLboolean
+_mesa_layout_parameters(struct asm_parser_state *state)
+{
+ struct gl_program_parameter_list *layout;
+ struct asm_instruction *inst;
+ unsigned i;
+
+ layout =
+ _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
+
+ /* PASS 1: Move any parameters that are accessed indirectly from the
+ * original parameter list to the new parameter list.
+ */
+ for (inst = state->inst_head; inst != NULL; inst = inst->next) {
+ for (i = 0; i < 3; i++) {
+ if (inst->SrcReg[i].Base.RelAddr) {
+ /* Only attempt to add the to the new parameter list once.
+ */
+ if (!inst->SrcReg[i].Symbol->pass1_done) {
+ const int new_begin =
+ copy_indirect_accessed_array(state->prog->Parameters, layout,
+ inst->SrcReg[i].Symbol->param_binding_begin,
+ inst->SrcReg[i].Symbol->param_binding_length);
+
+ if (new_begin < 0) {
+ _mesa_free_parameter_list(layout);
+ return GL_FALSE;
+ }
+
+ inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
+ inst->SrcReg[i].Symbol->pass1_done = 1;
+ }
+
+ /* Previously the Index was just the offset from the parameter
+ * array. Now that the base of the parameter array is known, the
+ * index can be updated to its actual value.
+ */
+ inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
+ inst->Base.SrcReg[i].Index +=
+ inst->SrcReg[i].Symbol->param_binding_begin;
+ }
+ }
+ }
+
+ /* PASS 2: Move any parameters that are not accessed indirectly from the
+ * original parameter list to the new parameter list.
+ */
+ for (inst = state->inst_head; inst != NULL; inst = inst->next) {
+ for (i = 0; i < 3; i++) {
+ const struct gl_program_parameter *p;
+ const int idx = inst->SrcReg[i].Base.Index;
+ unsigned swizzle = SWIZZLE_NOOP;
+
+ /* All relative addressed operands were processed on the first
+ * pass. Just skip them here.
+ */
+ if (inst->SrcReg[i].Base.RelAddr) {
+ continue;
+ }
+
+ if ((inst->SrcReg[i].Base.File <= PROGRAM_OUTPUT)
+ || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
+ continue;
+ }
+
+ inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
+ p = & state->prog->Parameters->Parameters[idx];
+
+ switch (p->Type) {
+ case PROGRAM_CONSTANT: {
+ const gl_constant_value *const v =
+ state->prog->Parameters->ParameterValues[idx];
+
+ inst->Base.SrcReg[i].Index =
+ _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
+
+ inst->Base.SrcReg[i].Swizzle =
+ _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
+ break;
+ }
+
+ case PROGRAM_STATE_VAR:
+ inst->Base.SrcReg[i].Index =
+ _mesa_add_state_reference(layout, p->StateIndexes);
+ break;
+
+ default:
+ break;
+ }
+
+ inst->SrcReg[i].Base.File = p->Type;
+ inst->Base.SrcReg[i].File = p->Type;
+ }
+ }
+
+ layout->StateFlags = state->prog->Parameters->StateFlags;
+ _mesa_free_parameter_list(state->prog->Parameters);
+ state->prog->Parameters = layout;
+
+ return GL_TRUE;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter_layout.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter_layout.h
new file mode 100644
index 0000000..99a7b6c
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_parameter_layout.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_parameter_layout.h
+ * \brief Helper functions to layout storage for program parameters
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#pragma once
+
+#ifndef PROG_PARAMETER_LAYOUT_H
+#define PROG_PARAMETER_LAYOUT_H
+
+extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied);
+
+struct asm_parser_state;
+
+extern GLboolean _mesa_layout_parameters(struct asm_parser_state *state);
+
+#endif /* PROG_PARAMETER_LAYOUT_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_print.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_print.c
new file mode 100644
index 0000000..4a5c1c1
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_print.c
@@ -0,0 +1,1092 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_print.c
+ * Print vertex/fragment programs - for debugging.
+ * \author Brian Paul
+ */
+
+#include <inttypes.h> /* for PRIx64 macro */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "prog_statevars.h"
+
+
+
+/**
+ * Return string name for given program/register file.
+ */
+const char *
+_mesa_register_file_name(gl_register_file f)
+{
+ switch (f) {
+ case PROGRAM_TEMPORARY:
+ return "TEMP";
+ case PROGRAM_STATE_VAR:
+ return "STATE";
+ case PROGRAM_INPUT:
+ return "INPUT";
+ case PROGRAM_OUTPUT:
+ return "OUTPUT";
+ case PROGRAM_CONSTANT:
+ return "CONST";
+ case PROGRAM_UNIFORM:
+ return "UNIFORM";
+ case PROGRAM_ADDRESS:
+ return "ADDR";
+ case PROGRAM_SAMPLER:
+ return "SAMPLER";
+ case PROGRAM_SYSTEM_VALUE:
+ return "SYSVAL";
+ case PROGRAM_UNDEFINED:
+ return "UNDEFINED";
+ default:
+ {
+ static char s[20];
+ _mesa_snprintf(s, sizeof(s), "FILE%u", f);
+ return s;
+ }
+ }
+}
+
+
+/**
+ * Return ARB_v/f_prog-style input attrib string.
+ */
+static const char *
+arb_input_attrib_string(GLint index, GLenum progType)
+{
+ /*
+ * These strings should match the VERT_ATTRIB_x and VARYING_SLOT_x tokens.
+ */
+ static const char *const vertAttribs[] = {
+ "vertex.position",
+ "vertex.weight",
+ "vertex.normal",
+ "vertex.color.primary",
+ "vertex.color.secondary",
+ "vertex.fogcoord",
+ "vertex.(six)", /* VERT_ATTRIB_COLOR_INDEX */
+ "vertex.(seven)", /* VERT_ATTRIB_EDGEFLAG */
+ "vertex.texcoord[0]",
+ "vertex.texcoord[1]",
+ "vertex.texcoord[2]",
+ "vertex.texcoord[3]",
+ "vertex.texcoord[4]",
+ "vertex.texcoord[5]",
+ "vertex.texcoord[6]",
+ "vertex.texcoord[7]",
+ "vertex.(sixteen)", /* VERT_ATTRIB_POINT_SIZE */
+ "vertex.attrib[0]",
+ "vertex.attrib[1]",
+ "vertex.attrib[2]",
+ "vertex.attrib[3]",
+ "vertex.attrib[4]",
+ "vertex.attrib[5]",
+ "vertex.attrib[6]",
+ "vertex.attrib[7]",
+ "vertex.attrib[8]",
+ "vertex.attrib[9]",
+ "vertex.attrib[10]",
+ "vertex.attrib[11]",
+ "vertex.attrib[12]",
+ "vertex.attrib[13]",
+ "vertex.attrib[14]",
+ "vertex.attrib[15]" /* MAX_VARYING = 16 */
+ };
+ static const char *const fragAttribs[] = {
+ "fragment.position",
+ "fragment.color.primary",
+ "fragment.color.secondary",
+ "fragment.fogcoord",
+ "fragment.texcoord[0]",
+ "fragment.texcoord[1]",
+ "fragment.texcoord[2]",
+ "fragment.texcoord[3]",
+ "fragment.texcoord[4]",
+ "fragment.texcoord[5]",
+ "fragment.texcoord[6]",
+ "fragment.texcoord[7]",
+ "fragment.(twelve)", /* VARYING_SLOT_PSIZ */
+ "fragment.(thirteen)", /* VARYING_SLOT_BFC0 */
+ "fragment.(fourteen)", /* VARYING_SLOT_BFC1 */
+ "fragment.(fifteen)", /* VARYING_SLOT_EDGE */
+ "fragment.(sixteen)", /* VARYING_SLOT_CLIP_VERTEX */
+ "fragment.(seventeen)", /* VARYING_SLOT_CLIP_DIST0 */
+ "fragment.(eighteen)", /* VARYING_SLOT_CLIP_DIST1 */
+ "fragment.(nineteen)", /* VARYING_SLOT_PRIMITIVE_ID */
+ "fragment.(twenty)", /* VARYING_SLOT_LAYER */
+ "fragment.(twenty-one)", /* VARYING_SLOT_VIEWPORT */
+ "fragment.(twenty-two)", /* VARYING_SLOT_FACE */
+ "fragment.(twenty-three)", /* VARYING_SLOT_PNTC */
+ "fragment.varying[0]",
+ "fragment.varying[1]",
+ "fragment.varying[2]",
+ "fragment.varying[3]",
+ "fragment.varying[4]",
+ "fragment.varying[5]",
+ "fragment.varying[6]",
+ "fragment.varying[7]",
+ "fragment.varying[8]",
+ "fragment.varying[9]",
+ "fragment.varying[10]",
+ "fragment.varying[11]",
+ "fragment.varying[12]",
+ "fragment.varying[13]",
+ "fragment.varying[14]",
+ "fragment.varying[15]",
+ "fragment.varying[16]",
+ "fragment.varying[17]",
+ "fragment.varying[18]",
+ "fragment.varying[19]",
+ "fragment.varying[20]",
+ "fragment.varying[21]",
+ "fragment.varying[22]",
+ "fragment.varying[23]",
+ "fragment.varying[24]",
+ "fragment.varying[25]",
+ "fragment.varying[26]",
+ "fragment.varying[27]",
+ "fragment.varying[28]",
+ "fragment.varying[29]",
+ "fragment.varying[30]",
+ "fragment.varying[31]", /* MAX_VARYING = 32 */
+ };
+
+ /* sanity checks */
+ STATIC_ASSERT(Elements(vertAttribs) == VERT_ATTRIB_MAX);
+ STATIC_ASSERT(Elements(fragAttribs) == VARYING_SLOT_MAX);
+ assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0);
+ assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0);
+ assert(strcmp(fragAttribs[VARYING_SLOT_TEX0], "fragment.texcoord[0]") == 0);
+ assert(strcmp(fragAttribs[VARYING_SLOT_VAR0+15], "fragment.varying[15]") == 0);
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert(index < Elements(vertAttribs));
+ return vertAttribs[index];
+ }
+ else {
+ assert(progType == GL_FRAGMENT_PROGRAM_ARB);
+ assert(index < Elements(fragAttribs));
+ return fragAttribs[index];
+ }
+}
+
+
+/**
+ * Print a vertex program's InputsRead field in human-readable format.
+ * For debugging.
+ */
+void
+_mesa_print_vp_inputs(GLbitfield inputs)
+{
+ printf("VP Inputs 0x%x: \n", inputs);
+ while (inputs) {
+ GLint attr = ffs(inputs) - 1;
+ const char *name = arb_input_attrib_string(attr,
+ GL_VERTEX_PROGRAM_ARB);
+ printf(" %d: %s\n", attr, name);
+ inputs &= ~(1 << attr);
+ }
+}
+
+
+/**
+ * Print a fragment program's InputsRead field in human-readable format.
+ * For debugging.
+ */
+void
+_mesa_print_fp_inputs(GLbitfield inputs)
+{
+ printf("FP Inputs 0x%x: \n", inputs);
+ while (inputs) {
+ GLint attr = ffs(inputs) - 1;
+ const char *name = arb_input_attrib_string(attr,
+ GL_FRAGMENT_PROGRAM_ARB);
+ printf(" %d: %s\n", attr, name);
+ inputs &= ~(1 << attr);
+ }
+}
+
+
+
+/**
+ * Return ARB_v/f_prog-style output attrib string.
+ */
+static const char *
+arb_output_attrib_string(GLint index, GLenum progType)
+{
+ /*
+ * These strings should match the VARYING_SLOT_x and FRAG_RESULT_x tokens.
+ */
+ static const char *const vertResults[] = {
+ "result.position",
+ "result.color.primary",
+ "result.color.secondary",
+ "result.fogcoord",
+ "result.texcoord[0]",
+ "result.texcoord[1]",
+ "result.texcoord[2]",
+ "result.texcoord[3]",
+ "result.texcoord[4]",
+ "result.texcoord[5]",
+ "result.texcoord[6]",
+ "result.texcoord[7]",
+ "result.pointsize", /* VARYING_SLOT_PSIZ */
+ "result.(thirteen)", /* VARYING_SLOT_BFC0 */
+ "result.(fourteen)", /* VARYING_SLOT_BFC1 */
+ "result.(fifteen)", /* VARYING_SLOT_EDGE */
+ "result.(sixteen)", /* VARYING_SLOT_CLIP_VERTEX */
+ "result.(seventeen)", /* VARYING_SLOT_CLIP_DIST0 */
+ "result.(eighteen)", /* VARYING_SLOT_CLIP_DIST1 */
+ "result.(nineteen)", /* VARYING_SLOT_PRIMITIVE_ID */
+ "result.(twenty)", /* VARYING_SLOT_LAYER */
+ "result.(twenty-one)", /* VARYING_SLOT_VIEWPORT */
+ "result.(twenty-two)", /* VARYING_SLOT_FACE */
+ "result.(twenty-three)", /* VARYING_SLOT_PNTC */
+ "result.varying[0]",
+ "result.varying[1]",
+ "result.varying[2]",
+ "result.varying[3]",
+ "result.varying[4]",
+ "result.varying[5]",
+ "result.varying[6]",
+ "result.varying[7]",
+ "result.varying[8]",
+ "result.varying[9]",
+ "result.varying[10]",
+ "result.varying[11]",
+ "result.varying[12]",
+ "result.varying[13]",
+ "result.varying[14]",
+ "result.varying[15]",
+ "result.varying[16]",
+ "result.varying[17]",
+ "result.varying[18]",
+ "result.varying[19]",
+ "result.varying[20]",
+ "result.varying[21]",
+ "result.varying[22]",
+ "result.varying[23]",
+ "result.varying[24]",
+ "result.varying[25]",
+ "result.varying[26]",
+ "result.varying[27]",
+ "result.varying[28]",
+ "result.varying[29]",
+ "result.varying[30]",
+ "result.varying[31]", /* MAX_VARYING = 32 */
+ };
+ static const char *const fragResults[] = {
+ "result.depth", /* FRAG_RESULT_DEPTH */
+ "result.(one)", /* FRAG_RESULT_STENCIL */
+ "result.color", /* FRAG_RESULT_COLOR */
+ "result.samplemask", /* FRAG_RESULT_SAMPLE_MASK */
+ "result.color[0]", /* FRAG_RESULT_DATA0 (named for GLSL's gl_FragData) */
+ "result.color[1]",
+ "result.color[2]",
+ "result.color[3]",
+ "result.color[4]",
+ "result.color[5]",
+ "result.color[6]",
+ "result.color[7]" /* MAX_DRAW_BUFFERS = 8 */
+ };
+
+ /* sanity checks */
+ STATIC_ASSERT(Elements(vertResults) == VARYING_SLOT_MAX);
+ STATIC_ASSERT(Elements(fragResults) == FRAG_RESULT_MAX);
+ assert(strcmp(vertResults[VARYING_SLOT_POS], "result.position") == 0);
+ assert(strcmp(vertResults[VARYING_SLOT_VAR0], "result.varying[0]") == 0);
+ assert(strcmp(fragResults[FRAG_RESULT_DATA0], "result.color[0]") == 0);
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert(index < Elements(vertResults));
+ return vertResults[index];
+ }
+ else {
+ assert(progType == GL_FRAGMENT_PROGRAM_ARB);
+ assert(index < Elements(fragResults));
+ return fragResults[index];
+ }
+}
+
+
+/**
+ * Return string representation of the given register.
+ * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
+ * by the ARB/NV program languages so we've taken some liberties here.
+ * \param f the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
+ * \param index number of the register in the register file
+ * \param mode the output format/mode/style
+ * \param prog pointer to containing program
+ */
+static const char *
+reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
+ GLboolean relAddr, const struct gl_program *prog,
+ GLboolean hasIndex2, GLboolean relAddr2, GLint index2)
+{
+ static char str[100];
+ const char *addr = relAddr ? "ADDR+" : "";
+
+ str[0] = 0;
+
+ switch (mode) {
+ case PROG_PRINT_DEBUG:
+ sprintf(str, "%s[%s%d]",
+ _mesa_register_file_name(f), addr, index);
+ if (hasIndex2) {
+ int offset = strlen(str);
+ const char *addr2 = relAddr2 ? "ADDR+" : "";
+ sprintf(str+offset, "[%s%d]", addr2, index2);
+ }
+ break;
+
+ case PROG_PRINT_ARB:
+ switch (f) {
+ case PROGRAM_INPUT:
+ sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_OUTPUT:
+ sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_TEMPORARY:
+ sprintf(str, "temp%d", index);
+ break;
+ case PROGRAM_CONSTANT: /* extension */
+ sprintf(str, "constant[%s%d]", addr, index);
+ break;
+ case PROGRAM_UNIFORM: /* extension */
+ sprintf(str, "uniform[%s%d]", addr, index);
+ break;
+ case PROGRAM_SYSTEM_VALUE:
+ sprintf(str, "sysvalue[%s%d]", addr, index);
+ break;
+ case PROGRAM_STATE_VAR:
+ {
+ struct gl_program_parameter *param
+ = prog->Parameters->Parameters + index;
+ char *state = _mesa_program_state_string(param->StateIndexes);
+ sprintf(str, "%s", state);
+ free(state);
+ }
+ break;
+ case PROGRAM_ADDRESS:
+ sprintf(str, "A%d", index);
+ break;
+ default:
+ _mesa_problem(NULL, "bad file in reg_string()");
+ }
+ break;
+
+ default:
+ _mesa_problem(NULL, "bad mode in reg_string()");
+ }
+
+ return str;
+}
+
+
+/**
+ * Return a string representation of the given swizzle word.
+ * If extended is true, use extended (comma-separated) format.
+ * \param swizzle the swizzle field
+ * \param negateBase 4-bit negation vector
+ * \param extended if true, also allow 0, 1 values
+ */
+const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateMask, GLboolean extended)
+{
+ static const char swz[] = "xyzw01!?"; /* See SWIZZLE_x definitions */
+ static char s[20];
+ GLuint i = 0;
+
+ if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0)
+ return ""; /* no swizzle/negation */
+
+ if (!extended)
+ s[i++] = '.';
+
+ if (negateMask & NEGATE_X)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 0)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateMask & NEGATE_Y)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 1)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateMask & NEGATE_Z)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 2)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateMask & NEGATE_W)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 3)];
+
+ s[i] = 0;
+ return s;
+}
+
+
+void
+_mesa_print_swizzle(GLuint swizzle)
+{
+ if (swizzle == SWIZZLE_XYZW) {
+ printf(".xyzw\n");
+ }
+ else {
+ const char *s = _mesa_swizzle_string(swizzle, 0, 0);
+ printf("%s\n", s);
+ }
+}
+
+
+const char *
+_mesa_writemask_string(GLuint writeMask)
+{
+ static char s[10];
+ GLuint i = 0;
+
+ if (writeMask == WRITEMASK_XYZW)
+ return "";
+
+ s[i++] = '.';
+ if (writeMask & WRITEMASK_X)
+ s[i++] = 'x';
+ if (writeMask & WRITEMASK_Y)
+ s[i++] = 'y';
+ if (writeMask & WRITEMASK_Z)
+ s[i++] = 'z';
+ if (writeMask & WRITEMASK_W)
+ s[i++] = 'w';
+
+ s[i] = 0;
+ return s;
+}
+
+
+const char *
+_mesa_condcode_string(GLuint condcode)
+{
+ switch (condcode) {
+ case COND_GT: return "GT";
+ case COND_EQ: return "EQ";
+ case COND_LT: return "LT";
+ case COND_UN: return "UN";
+ case COND_GE: return "GE";
+ case COND_LE: return "LE";
+ case COND_NE: return "NE";
+ case COND_TR: return "TR";
+ case COND_FL: return "FL";
+ default: return "cond???";
+ }
+}
+
+
+static void
+fprint_dst_reg(FILE * f,
+ const struct prog_dst_register *dstReg,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ fprintf(f, "%s%s",
+ reg_string((gl_register_file) dstReg->File,
+ dstReg->Index, mode, dstReg->RelAddr, prog,
+ GL_FALSE, GL_FALSE, 0),
+ _mesa_writemask_string(dstReg->WriteMask));
+
+ if (dstReg->CondMask != COND_TR) {
+ fprintf(f, " (%s.%s)",
+ _mesa_condcode_string(dstReg->CondMask),
+ _mesa_swizzle_string(dstReg->CondSwizzle,
+ GL_FALSE, GL_FALSE));
+ }
+
+#if 0
+ fprintf(f, "%s[%d]%s",
+ _mesa_register_file_name((gl_register_file) dstReg->File),
+ dstReg->Index,
+ _mesa_writemask_string(dstReg->WriteMask));
+#endif
+}
+
+
+static void
+fprint_src_reg(FILE *f,
+ const struct prog_src_register *srcReg,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ const char *abs = srcReg->Abs ? "|" : "";
+
+ fprintf(f, "%s%s%s%s",
+ abs,
+ reg_string((gl_register_file) srcReg->File,
+ srcReg->Index, mode, srcReg->RelAddr, prog,
+ srcReg->HasIndex2, srcReg->RelAddr2, srcReg->Index2),
+ _mesa_swizzle_string(srcReg->Swizzle,
+ srcReg->Negate, GL_FALSE),
+ abs);
+#if 0
+ fprintf(f, "%s[%d]%s",
+ _mesa_register_file_name((gl_register_file) srcReg->File),
+ srcReg->Index,
+ _mesa_swizzle_string(srcReg->Swizzle,
+ srcReg->Negate, GL_FALSE));
+#endif
+}
+
+
+static void
+fprint_comment(FILE *f, const struct prog_instruction *inst)
+{
+ if (inst->Comment)
+ fprintf(f, "; # %s\n", inst->Comment);
+ else
+ fprintf(f, ";\n");
+}
+
+
+void
+_mesa_fprint_alu_instruction(FILE *f,
+ const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ GLuint j;
+
+ fprintf(f, "%s", opcode_string);
+ if (inst->CondUpdate)
+ fprintf(f, ".C");
+
+ /* frag prog only */
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ fprintf(f, "_SAT");
+
+ fprintf(f, " ");
+ if (inst->DstReg.File != PROGRAM_UNDEFINED) {
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ }
+ else {
+ fprintf(f, " ???");
+ }
+
+ if (numRegs > 0)
+ fprintf(f, ", ");
+
+ for (j = 0; j < numRegs; j++) {
+ fprint_src_reg(f, inst->SrcReg + j, mode, prog);
+ if (j + 1 < numRegs)
+ fprintf(f, ", ");
+ }
+
+ fprint_comment(f, inst);
+}
+
+
+void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs)
+{
+ _mesa_fprint_alu_instruction(stderr, inst, opcode_string,
+ numRegs, PROG_PRINT_DEBUG, NULL);
+}
+
+
+/**
+ * Print a single vertex/fragment program instruction.
+ */
+GLint
+_mesa_fprint_instruction_opt(FILE *f,
+ const struct prog_instruction *inst,
+ GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ GLint i;
+
+ if (inst->Opcode == OPCODE_ELSE ||
+ inst->Opcode == OPCODE_ENDIF ||
+ inst->Opcode == OPCODE_ENDLOOP ||
+ inst->Opcode == OPCODE_ENDSUB) {
+ indent -= 3;
+ }
+ for (i = 0; i < indent; i++) {
+ fprintf(f, " ");
+ }
+
+ switch (inst->Opcode) {
+ case OPCODE_SWZ:
+ fprintf(f, "SWZ");
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ fprintf(f, "_SAT");
+ fprintf(f, " ");
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ fprintf(f, ", %s[%d], %s",
+ _mesa_register_file_name((gl_register_file) inst->SrcReg[0].File),
+ inst->SrcReg[0].Index,
+ _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+ inst->SrcReg[0].Negate, GL_TRUE));
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_TEX:
+ case OPCODE_TXP:
+ case OPCODE_TXL:
+ case OPCODE_TXB:
+ case OPCODE_TXD:
+ fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ fprintf(f, "_SAT");
+ fprintf(f, " ");
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ fprintf(f, ", ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ if (inst->Opcode == OPCODE_TXD) {
+ fprintf(f, ", ");
+ fprint_src_reg(f, &inst->SrcReg[1], mode, prog);
+ fprintf(f, ", ");
+ fprint_src_reg(f, &inst->SrcReg[2], mode, prog);
+ }
+ fprintf(f, ", texture[%d], ", inst->TexSrcUnit);
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX: fprintf(f, "1D"); break;
+ case TEXTURE_2D_INDEX: fprintf(f, "2D"); break;
+ case TEXTURE_3D_INDEX: fprintf(f, "3D"); break;
+ case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE"); break;
+ case TEXTURE_RECT_INDEX: fprintf(f, "RECT"); break;
+ case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break;
+ case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break;
+ default:
+ ;
+ }
+ if (inst->TexShadow)
+ fprintf(f, " SHADOW");
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_KIL:
+ fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+ fprintf(f, " ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_KIL_NV:
+ fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+ fprintf(f, " ");
+ fprintf(f, "%s.%s",
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+ GL_FALSE, GL_FALSE));
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_ARL:
+ fprintf(f, "ARL ");
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ fprintf(f, ", ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_IF:
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ /* Use ordinary register */
+ fprintf(f, "IF ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ fprintf(f, "; ");
+ }
+ else {
+ /* Use cond codes */
+ fprintf(f, "IF (%s%s);",
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+ 0, GL_FALSE));
+ }
+ fprintf(f, " # (if false, goto %d)", inst->BranchTarget);
+ fprint_comment(f, inst);
+ return indent + 3;
+ case OPCODE_ELSE:
+ fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget);
+ return indent + 3;
+ case OPCODE_ENDIF:
+ fprintf(f, "ENDIF;\n");
+ break;
+ case OPCODE_BGNLOOP:
+ fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget);
+ return indent + 3;
+ case OPCODE_ENDLOOP:
+ fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget);
+ break;
+ case OPCODE_BRK:
+ case OPCODE_CONT:
+ fprintf(f, "%s (%s%s); # (goto %d)",
+ _mesa_opcode_string(inst->Opcode),
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+ inst->BranchTarget);
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_BGNSUB:
+ fprintf(f, "BGNSUB");
+ fprint_comment(f, inst);
+ return indent + 3;
+ case OPCODE_ENDSUB:
+ if (mode == PROG_PRINT_DEBUG) {
+ fprintf(f, "ENDSUB");
+ fprint_comment(f, inst);
+ }
+ break;
+ case OPCODE_CAL:
+ fprintf(f, "CAL %u", inst->BranchTarget);
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_RET:
+ fprintf(f, "RET (%s%s)",
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_END:
+ fprintf(f, "END\n");
+ break;
+ case OPCODE_NOP:
+ if (mode == PROG_PRINT_DEBUG) {
+ fprintf(f, "NOP");
+ fprint_comment(f, inst);
+ }
+ else if (inst->Comment) {
+ /* ARB/NV extensions don't have NOP instruction */
+ fprintf(f, "# %s\n", inst->Comment);
+ }
+ break;
+ /* XXX may need other special-case instructions */
+ default:
+ if (inst->Opcode < MAX_OPCODE) {
+ /* typical alu instruction */
+ _mesa_fprint_alu_instruction(f, inst,
+ _mesa_opcode_string(inst->Opcode),
+ _mesa_num_inst_src_regs(inst->Opcode),
+ mode, prog);
+ }
+ else {
+ _mesa_fprint_alu_instruction(f, inst,
+ _mesa_opcode_string(inst->Opcode),
+ 3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
+ mode, prog);
+ }
+ break;
+ }
+ return indent;
+}
+
+
+GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst,
+ GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog);
+}
+
+
+void
+_mesa_print_instruction(const struct prog_instruction *inst)
+{
+ /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
+ _mesa_fprint_instruction_opt(stderr, inst, 0, PROG_PRINT_DEBUG, NULL);
+}
+
+
+
+/**
+ * Print program, with options.
+ */
+void
+_mesa_fprint_program_opt(FILE *f,
+ const struct gl_program *prog,
+ gl_prog_print_mode mode,
+ GLboolean lineNumbers)
+{
+ GLuint i, indent = 0;
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ if (mode == PROG_PRINT_ARB)
+ fprintf(f, "!!ARBvp1.0\n");
+ else
+ fprintf(f, "# Vertex Program/Shader %u\n", prog->Id);
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ if (mode == PROG_PRINT_ARB)
+ fprintf(f, "!!ARBfp1.0\n");
+ else
+ fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
+ break;
+ case MESA_GEOMETRY_PROGRAM:
+ fprintf(f, "# Geometry Shader\n");
+ }
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ if (lineNumbers)
+ fprintf(f, "%3d: ", i);
+ indent = _mesa_fprint_instruction_opt(f, prog->Instructions + i,
+ indent, mode, prog);
+ }
+}
+
+
+/**
+ * Print program to stderr, default options.
+ */
+void
+_mesa_print_program(const struct gl_program *prog)
+{
+ _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
+}
+
+
+/**
+ * Return binary representation of 64-bit value (as a string).
+ * Insert a comma to separate each group of 8 bits.
+ * Note we return a pointer to local static storage so this is not
+ * re-entrant, etc.
+ * XXX move to imports.[ch] if useful elsewhere.
+ */
+static const char *
+binary(GLbitfield64 val)
+{
+ static char buf[80];
+ GLint i, len = 0;
+ for (i = 63; i >= 0; --i) {
+ if (val & (BITFIELD64_BIT(i)))
+ buf[len++] = '1';
+ else if (len > 0 || i == 0)
+ buf[len++] = '0';
+ if (len > 0 && ((i-1) % 8) == 7)
+ buf[len++] = ',';
+ }
+ buf[len] = '\0';
+ return buf;
+}
+
+
+/**
+ * Print all of a program's parameters/fields to given file.
+ */
+static void
+_mesa_fprint_program_parameters(FILE *f,
+ struct gl_context *ctx,
+ const struct gl_program *prog)
+{
+ GLuint i;
+
+ fprintf(f, "InputsRead: %" PRIx64 " (0b%s)\n",
+ (uint64_t) prog->InputsRead, binary(prog->InputsRead));
+ fprintf(f, "OutputsWritten: %" PRIx64 " (0b%s)\n",
+ (uint64_t) prog->OutputsWritten, binary(prog->OutputsWritten));
+ fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
+ fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
+ fprintf(f, "NumParameters=%d\n", prog->NumParameters);
+ fprintf(f, "NumAttributes=%d\n", prog->NumAttributes);
+ fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs);
+ fprintf(f, "IndirectRegisterFiles: 0x%x (0b%s)\n",
+ prog->IndirectRegisterFiles, binary(prog->IndirectRegisterFiles));
+ fprintf(f, "SamplersUsed: 0x%x (0b%s)\n",
+ prog->SamplersUsed, binary(prog->SamplersUsed));
+ fprintf(f, "Samplers=[ ");
+ for (i = 0; i < MAX_SAMPLERS; i++) {
+ fprintf(f, "%d ", prog->SamplerUnits[i]);
+ }
+ fprintf(f, "]\n");
+
+ _mesa_load_state_parameters(ctx, prog->Parameters);
+
+#if 0
+ fprintf(f, "Local Params:\n");
+ for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
+ const GLfloat *p = prog->LocalParams[i];
+ fprintf(f, "%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
+ }
+#endif
+ _mesa_print_parameter_list(prog->Parameters);
+}
+
+
+/**
+ * Print all of a program's parameters/fields to stderr.
+ */
+void
+_mesa_print_program_parameters(struct gl_context *ctx, const struct gl_program *prog)
+{
+ _mesa_fprint_program_parameters(stderr, ctx, prog);
+}
+
+
+/**
+ * Print a program parameter list to given file.
+ */
+static void
+_mesa_fprint_parameter_list(FILE *f,
+ const struct gl_program_parameter_list *list)
+{
+ GLuint i;
+
+ if (!list)
+ return;
+
+ if (0)
+ fprintf(f, "param list %p\n", (void *) list);
+ fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags);
+ for (i = 0; i < list->NumParameters; i++){
+ struct gl_program_parameter *param = list->Parameters + i;
+ const GLfloat *v = (GLfloat *) list->ParameterValues[i];
+ fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}",
+ i, param->Size,
+ _mesa_register_file_name(list->Parameters[i].Type),
+ param->Name, v[0], v[1], v[2], v[3]);
+ fprintf(f, "\n");
+ }
+}
+
+
+/**
+ * Print a program parameter list to stderr.
+ */
+void
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
+{
+ _mesa_fprint_parameter_list(stderr, list);
+}
+
+
+/**
+ * Write shader and associated info to a file.
+ */
+void
+_mesa_write_shader_to_file(const struct gl_shader *shader)
+{
+ const char *type = "????";
+ char filename[100];
+ FILE *f;
+
+ switch (shader->Stage) {
+ case MESA_SHADER_FRAGMENT:
+ type = "frag";
+ break;
+ case MESA_SHADER_VERTEX:
+ type = "vert";
+ break;
+ case MESA_SHADER_GEOMETRY:
+ type = "geom";
+ break;
+ case MESA_SHADER_COMPUTE:
+ type = "comp";
+ break;
+ }
+
+ _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+ f = fopen(filename, "w");
+ if (!f) {
+ fprintf(stderr, "Unable to open %s for writing\n", filename);
+ return;
+ }
+
+ fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
+ fputs(shader->Source, f);
+ fprintf(f, "\n");
+
+ fprintf(f, "/* Compile status: %s */\n",
+ shader->CompileStatus ? "ok" : "fail");
+ fprintf(f, "/* Log Info: */\n");
+ if (shader->InfoLog) {
+ fputs(shader->InfoLog, f);
+ }
+ if (shader->CompileStatus && shader->Program) {
+ fprintf(f, "/* GPU code */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
+ fprintf(f, "*/\n");
+ fprintf(f, "/* Parameters / constants */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_parameter_list(f, shader->Program->Parameters);
+ fprintf(f, "*/\n");
+ }
+
+ fclose(f);
+}
+
+
+/**
+ * Append the shader's uniform info/values to the shader log file.
+ * The log file will typically have been created by the
+ * _mesa_write_shader_to_file function.
+ */
+void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader)
+{
+ const struct gl_program *const prog = shader->Program;
+ const char *type;
+ char filename[100];
+ FILE *f;
+
+ if (shader->Stage == MESA_SHADER_FRAGMENT)
+ type = "frag";
+ else
+ type = "vert";
+
+ _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+ f = fopen(filename, "a"); /* append */
+ if (!f) {
+ fprintf(stderr, "Unable to open %s for appending\n", filename);
+ return;
+ }
+
+ fprintf(f, "/* First-draw parameters / constants */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_parameter_list(f, prog->Parameters);
+ fprintf(f, "*/\n");
+
+ fclose(f);
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_print.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_print.h
new file mode 100644
index 0000000..cd61568
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_print.h
@@ -0,0 +1,118 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef PROG_PRINT_H
+#define PROG_PRINT_H
+
+#include <stdio.h>
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+
+struct gl_program;
+struct gl_program_parameter_list;
+struct gl_shader;
+struct prog_instruction;
+
+
+/**
+ * The output style to use when printing programs.
+ */
+typedef enum {
+ PROG_PRINT_ARB,
+ PROG_PRINT_DEBUG
+} gl_prog_print_mode;
+
+
+extern const char *
+_mesa_register_file_name(gl_register_file f);
+
+extern void
+_mesa_print_vp_inputs(GLbitfield inputs);
+
+extern void
+_mesa_print_fp_inputs(GLbitfield inputs);
+
+extern const char *
+_mesa_condcode_string(GLuint condcode);
+
+extern const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
+
+const char *
+_mesa_writemask_string(GLuint writeMask);
+
+extern void
+_mesa_print_swizzle(GLuint swizzle);
+
+extern void
+_mesa_fprint_alu_instruction(FILE *f,
+ const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
+
+extern void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs);
+
+extern void
+_mesa_print_instruction(const struct prog_instruction *inst);
+
+extern GLint
+_mesa_fprint_instruction_opt(FILE *f,
+ const struct prog_instruction *inst,
+ GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
+
+extern GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
+
+extern void
+_mesa_print_program(const struct gl_program *prog);
+
+extern void
+_mesa_fprint_program_opt(FILE *f,
+ const struct gl_program *prog, gl_prog_print_mode mode,
+ GLboolean lineNumbers);
+
+extern void
+_mesa_print_program_parameters(struct gl_context *ctx, const struct gl_program *prog);
+
+extern void
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list);
+
+
+extern void
+_mesa_write_shader_to_file(const struct gl_shader *shader);
+
+extern void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader);
+
+
+#endif /* PROG_PRINT_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_statevars.c b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_statevars.c
new file mode 100644
index 0000000..5dda8e2
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_statevars.c
@@ -0,0 +1,1104 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_statevars.c
+ * Program state variable management.
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/blend.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/fbobject.h"
+#include "prog_statevars.h"
+#include "prog_parameter.h"
+#include "main/samplerobj.h"
+
+
+/**
+ * Use the list of tokens in the state[] array to find global GL state
+ * and return it in <value>. Usually, four values are returned in <value>
+ * but matrix queries may return as many as 16 values.
+ * This function is used for ARB vertex/fragment programs.
+ * The program parser will produce the state[] values.
+ */
+static void
+_mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
+ GLfloat *value)
+{
+ switch (state[0]) {
+ case STATE_MATERIAL:
+ {
+ /* state[1] is either 0=front or 1=back side */
+ const GLuint face = (GLuint) state[1];
+ const struct gl_material *mat = &ctx->Light.Material;
+ ASSERT(face == 0 || face == 1);
+ /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
+ ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
+ /* XXX we could get rid of this switch entirely with a little
+ * work in arbprogparse.c's parse_state_single_item().
+ */
+ /* state[2] is the material attribute */
+ switch (state[2]) {
+ case STATE_AMBIENT:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
+ return;
+ case STATE_DIFFUSE:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
+ return;
+ case STATE_SPECULAR:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
+ return;
+ case STATE_EMISSION:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
+ return;
+ case STATE_SHININESS:
+ value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
+ value[1] = 0.0F;
+ value[2] = 0.0F;
+ value[3] = 1.0F;
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid material state in fetch_state");
+ return;
+ }
+ }
+ case STATE_LIGHT:
+ {
+ /* state[1] is the light number */
+ const GLuint ln = (GLuint) state[1];
+ /* state[2] is the light attribute */
+ switch (state[2]) {
+ case STATE_AMBIENT:
+ COPY_4V(value, ctx->Light.Light[ln].Ambient);
+ return;
+ case STATE_DIFFUSE:
+ COPY_4V(value, ctx->Light.Light[ln].Diffuse);
+ return;
+ case STATE_SPECULAR:
+ COPY_4V(value, ctx->Light.Light[ln].Specular);
+ return;
+ case STATE_POSITION:
+ COPY_4V(value, ctx->Light.Light[ln].EyePosition);
+ return;
+ case STATE_ATTENUATION:
+ value[0] = ctx->Light.Light[ln].ConstantAttenuation;
+ value[1] = ctx->Light.Light[ln].LinearAttenuation;
+ value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
+ value[3] = ctx->Light.Light[ln].SpotExponent;
+ return;
+ case STATE_SPOT_DIRECTION:
+ COPY_3V(value, ctx->Light.Light[ln].SpotDirection);
+ value[3] = ctx->Light.Light[ln]._CosCutoff;
+ return;
+ case STATE_SPOT_CUTOFF:
+ value[0] = ctx->Light.Light[ln].SpotCutoff;
+ return;
+ case STATE_HALF_VECTOR:
+ {
+ static const GLfloat eye_z[] = {0, 0, 1};
+ GLfloat p[3];
+ /* Compute infinite half angle vector:
+ * halfVector = normalize(normalize(lightPos) + (0, 0, 1))
+ * light.EyePosition.w should be 0 for infinite lights.
+ */
+ COPY_3V(p, ctx->Light.Light[ln].EyePosition);
+ NORMALIZE_3FV(p);
+ ADD_3V(value, p, eye_z);
+ NORMALIZE_3FV(value);
+ value[3] = 1.0;
+ }
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid light state in fetch_state");
+ return;
+ }
+ }
+ case STATE_LIGHTMODEL_AMBIENT:
+ COPY_4V(value, ctx->Light.Model.Ambient);
+ return;
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ if (state[1] == 0) {
+ /* front */
+ GLint i;
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Model.Ambient[i]
+ * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
+ + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
+ }
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
+ }
+ else {
+ /* back */
+ GLint i;
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Model.Ambient[i]
+ * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
+ + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
+ }
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
+ }
+ return;
+ case STATE_LIGHTPROD:
+ {
+ const GLuint ln = (GLuint) state[1];
+ const GLuint face = (GLuint) state[2];
+ GLint i;
+ ASSERT(face == 0 || face == 1);
+ switch (state[3]) {
+ case STATE_AMBIENT:
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Light[ln].Ambient[i] *
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
+ }
+ /* [3] = material alpha */
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];
+ return;
+ case STATE_DIFFUSE:
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Light[ln].Diffuse[i] *
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
+ }
+ /* [3] = material alpha */
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
+ return;
+ case STATE_SPECULAR:
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Light[ln].Specular[i] *
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
+ }
+ /* [3] = material alpha */
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
+ return;
+ }
+ }
+ case STATE_TEXGEN:
+ {
+ /* state[1] is the texture unit */
+ const GLuint unit = (GLuint) state[1];
+ /* state[2] is the texgen attribute */
+ switch (state[2]) {
+ case STATE_TEXGEN_EYE_S:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenS.EyePlane);
+ return;
+ case STATE_TEXGEN_EYE_T:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane);
+ return;
+ case STATE_TEXGEN_EYE_R:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane);
+ return;
+ case STATE_TEXGEN_EYE_Q:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane);
+ return;
+ case STATE_TEXGEN_OBJECT_S:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane);
+ return;
+ case STATE_TEXGEN_OBJECT_T:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane);
+ return;
+ case STATE_TEXGEN_OBJECT_R:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane);
+ return;
+ case STATE_TEXGEN_OBJECT_Q:
+ COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane);
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid texgen state in fetch_state");
+ return;
+ }
+ }
+ case STATE_TEXENV_COLOR:
+ {
+ /* state[1] is the texture unit */
+ const GLuint unit = (GLuint) state[1];
+ if (_mesa_get_clamp_fragment_color(ctx))
+ COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
+ else
+ COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped);
+ }
+ return;
+ case STATE_FOG_COLOR:
+ if (_mesa_get_clamp_fragment_color(ctx))
+ COPY_4V(value, ctx->Fog.Color);
+ else
+ COPY_4V(value, ctx->Fog.ColorUnclamped);
+ return;
+ case STATE_FOG_PARAMS:
+ value[0] = ctx->Fog.Density;
+ value[1] = ctx->Fog.Start;
+ value[2] = ctx->Fog.End;
+ value[3] = 1.0f / (ctx->Fog.End - ctx->Fog.Start);
+ return;
+ case STATE_CLIPPLANE:
+ {
+ const GLuint plane = (GLuint) state[1];
+ COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
+ }
+ return;
+ case STATE_POINT_SIZE:
+ value[0] = ctx->Point.Size;
+ value[1] = ctx->Point.MinSize;
+ value[2] = ctx->Point.MaxSize;
+ value[3] = ctx->Point.Threshold;
+ return;
+ case STATE_POINT_ATTENUATION:
+ value[0] = ctx->Point.Params[0];
+ value[1] = ctx->Point.Params[1];
+ value[2] = ctx->Point.Params[2];
+ value[3] = 1.0F;
+ return;
+ case STATE_MODELVIEW_MATRIX:
+ case STATE_PROJECTION_MATRIX:
+ case STATE_MVP_MATRIX:
+ case STATE_TEXTURE_MATRIX:
+ case STATE_PROGRAM_MATRIX:
+ {
+ /* state[0] = modelview, projection, texture, etc. */
+ /* state[1] = which texture matrix or program matrix */
+ /* state[2] = first row to fetch */
+ /* state[3] = last row to fetch */
+ /* state[4] = transpose, inverse or invtrans */
+ const GLmatrix *matrix;
+ const gl_state_index mat = state[0];
+ const GLuint index = (GLuint) state[1];
+ const GLuint firstRow = (GLuint) state[2];
+ const GLuint lastRow = (GLuint) state[3];
+ const gl_state_index modifier = state[4];
+ const GLfloat *m;
+ GLuint row, i;
+ ASSERT(firstRow >= 0);
+ ASSERT(firstRow < 4);
+ ASSERT(lastRow >= 0);
+ ASSERT(lastRow < 4);
+ if (mat == STATE_MODELVIEW_MATRIX) {
+ matrix = ctx->ModelviewMatrixStack.Top;
+ }
+ else if (mat == STATE_PROJECTION_MATRIX) {
+ matrix = ctx->ProjectionMatrixStack.Top;
+ }
+ else if (mat == STATE_MVP_MATRIX) {
+ matrix = &ctx->_ModelProjectMatrix;
+ }
+ else if (mat == STATE_TEXTURE_MATRIX) {
+ ASSERT(index < Elements(ctx->TextureMatrixStack));
+ matrix = ctx->TextureMatrixStack[index].Top;
+ }
+ else if (mat == STATE_PROGRAM_MATRIX) {
+ ASSERT(index < Elements(ctx->ProgramMatrixStack));
+ matrix = ctx->ProgramMatrixStack[index].Top;
+ }
+ else {
+ _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
+ return;
+ }
+ if (modifier == STATE_MATRIX_INVERSE ||
+ modifier == STATE_MATRIX_INVTRANS) {
+ /* Be sure inverse is up to date:
+ */
+ _math_matrix_analyse( (GLmatrix*) matrix );
+ m = matrix->inv;
+ }
+ else {
+ m = matrix->m;
+ }
+ if (modifier == STATE_MATRIX_TRANSPOSE ||
+ modifier == STATE_MATRIX_INVTRANS) {
+ for (i = 0, row = firstRow; row <= lastRow; row++) {
+ value[i++] = m[row * 4 + 0];
+ value[i++] = m[row * 4 + 1];
+ value[i++] = m[row * 4 + 2];
+ value[i++] = m[row * 4 + 3];
+ }
+ }
+ else {
+ for (i = 0, row = firstRow; row <= lastRow; row++) {
+ value[i++] = m[row + 0];
+ value[i++] = m[row + 4];
+ value[i++] = m[row + 8];
+ value[i++] = m[row + 12];
+ }
+ }
+ }
+ return;
+ case STATE_NUM_SAMPLES:
+ ((int *)value)[0] = ctx->DrawBuffer->Visual.samples;
+ return;
+ case STATE_DEPTH_RANGE:
+ value[0] = ctx->ViewportArray[0].Near; /* near */
+ value[1] = ctx->ViewportArray[0].Far; /* far */
+ value[2] = ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near; /* far - near */
+ value[3] = 1.0;
+ return;
+ case STATE_FRAGMENT_PROGRAM:
+ {
+ /* state[1] = {STATE_ENV, STATE_LOCAL} */
+ /* state[2] = parameter index */
+ const int idx = (int) state[2];
+ switch (state[1]) {
+ case STATE_ENV:
+ COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
+ return;
+ case STATE_LOCAL:
+ if (!ctx->FragmentProgram.Current->Base.LocalParams) {
+ ctx->FragmentProgram.Current->Base.LocalParams =
+ calloc(MAX_PROGRAM_LOCAL_PARAMS, sizeof(float[4]));
+ if (!ctx->FragmentProgram.Current->Base.LocalParams)
+ return;
+ }
+
+ COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
+ return;
+ default:
+ _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+ return;
+ }
+ }
+ return;
+
+ case STATE_VERTEX_PROGRAM:
+ {
+ /* state[1] = {STATE_ENV, STATE_LOCAL} */
+ /* state[2] = parameter index */
+ const int idx = (int) state[2];
+ switch (state[1]) {
+ case STATE_ENV:
+ COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
+ return;
+ case STATE_LOCAL:
+ if (!ctx->VertexProgram.Current->Base.LocalParams) {
+ ctx->VertexProgram.Current->Base.LocalParams =
+ calloc(MAX_PROGRAM_LOCAL_PARAMS, sizeof(float[4]));
+ if (!ctx->VertexProgram.Current->Base.LocalParams)
+ return;
+ }
+
+ COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
+ return;
+ default:
+ _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+ return;
+ }
+ }
+ return;
+
+ case STATE_NORMAL_SCALE:
+ ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
+ return;
+
+ case STATE_INTERNAL:
+ switch (state[1]) {
+ case STATE_CURRENT_ATTRIB:
+ {
+ const GLuint idx = (GLuint) state[2];
+ COPY_4V(value, ctx->Current.Attrib[idx]);
+ }
+ return;
+
+ case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
+ {
+ const GLuint idx = (GLuint) state[2];
+ if(ctx->Light._ClampVertexColor &&
+ (idx == VERT_ATTRIB_COLOR0 ||
+ idx == VERT_ATTRIB_COLOR1)) {
+ value[0] = CLAMP(ctx->Current.Attrib[idx][0], 0.0f, 1.0f);
+ value[1] = CLAMP(ctx->Current.Attrib[idx][1], 0.0f, 1.0f);
+ value[2] = CLAMP(ctx->Current.Attrib[idx][2], 0.0f, 1.0f);
+ value[3] = CLAMP(ctx->Current.Attrib[idx][3], 0.0f, 1.0f);
+ }
+ else
+ COPY_4V(value, ctx->Current.Attrib[idx]);
+ }
+ return;
+
+ case STATE_NORMAL_SCALE:
+ ASSIGN_4V(value,
+ ctx->_ModelViewInvScale,
+ ctx->_ModelViewInvScale,
+ ctx->_ModelViewInvScale,
+ 1);
+ return;
+
+ case STATE_TEXRECT_SCALE:
+ /* Value = { 1/texWidth, 1/texHeight, 0, 1 }.
+ * Used to convert unnormalized texcoords to normalized texcoords.
+ */
+ {
+ const int unit = (int) state[2];
+ const struct gl_texture_object *texObj
+ = ctx->Texture.Unit[unit]._Current;
+ if (texObj) {
+ struct gl_texture_image *texImage = texObj->Image[0][0];
+ ASSIGN_4V(value,
+ (GLfloat) (1.0 / texImage->Width),
+ (GLfloat) (1.0 / texImage->Height),
+ 0.0f, 1.0f);
+ }
+ }
+ return;
+
+ case STATE_FOG_PARAMS_OPTIMIZED:
+ /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog)
+ * might be more expensive than EX2 on some hw, plus it needs
+ * another constant (e) anyway. Linear fog can now be done with a
+ * single MAD.
+ * linear: fogcoord * -1/(end-start) + end/(end-start)
+ * exp: 2^-(density/ln(2) * fogcoord)
+ * exp2: 2^-((density/(ln(2)^2) * fogcoord)^2)
+ */
+ value[0] = (ctx->Fog.End == ctx->Fog.Start)
+ ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start));
+ value[1] = ctx->Fog.End * -value[0];
+ value[2] = (GLfloat)(ctx->Fog.Density * M_LOG2E); /* M_LOG2E == 1/ln(2) */
+ value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2);
+ return;
+
+ case STATE_POINT_SIZE_CLAMPED:
+ {
+ /* this includes implementation dependent limits, to avoid
+ * another potentially necessary clamp.
+ * Note: for sprites, point smooth (point AA) is ignored
+ * and we'll clamp to MinPointSizeAA and MaxPointSize, because we
+ * expect drivers will want to say their minimum for AA size is 0.0
+ * but for non-AA it's 1.0 (because normal points with size below 1.0
+ * need to get rounded up to 1.0, hence never disappear). GL does
+ * not specify max clamp size for sprites, other than it needs to be
+ * at least as large as max AA size, hence use non-AA size there.
+ */
+ GLfloat minImplSize;
+ GLfloat maxImplSize;
+ if (ctx->Point.PointSprite) {
+ minImplSize = ctx->Const.MinPointSizeAA;
+ maxImplSize = ctx->Const.MaxPointSize;
+ }
+ else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
+ minImplSize = ctx->Const.MinPointSizeAA;
+ maxImplSize = ctx->Const.MaxPointSizeAA;
+ }
+ else {
+ minImplSize = ctx->Const.MinPointSize;
+ maxImplSize = ctx->Const.MaxPointSize;
+ }
+ value[0] = ctx->Point.Size;
+ value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize;
+ value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize;
+ value[3] = ctx->Point.Threshold;
+ }
+ return;
+ case STATE_LIGHT_SPOT_DIR_NORMALIZED:
+ {
+ /* here, state[2] is the light number */
+ /* pre-normalize spot dir */
+ const GLuint ln = (GLuint) state[2];
+ COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection);
+ value[3] = ctx->Light.Light[ln]._CosCutoff;
+ }
+ return;
+
+ case STATE_LIGHT_POSITION:
+ {
+ const GLuint ln = (GLuint) state[2];
+ COPY_4V(value, ctx->Light.Light[ln]._Position);
+ }
+ return;
+
+ case STATE_LIGHT_POSITION_NORMALIZED:
+ {
+ const GLuint ln = (GLuint) state[2];
+ COPY_4V(value, ctx->Light.Light[ln]._Position);
+ NORMALIZE_3FV( value );
+ }
+ return;
+
+ case STATE_LIGHT_HALF_VECTOR:
+ {
+ const GLuint ln = (GLuint) state[2];
+ GLfloat p[3];
+ /* Compute infinite half angle vector:
+ * halfVector = normalize(normalize(lightPos) + (0, 0, 1))
+ * light.EyePosition.w should be 0 for infinite lights.
+ */
+ COPY_3V(p, ctx->Light.Light[ln]._Position);
+ NORMALIZE_3FV(p);
+ ADD_3V(value, p, ctx->_EyeZDir);
+ NORMALIZE_3FV(value);
+ value[3] = 1.0;
+ }
+ return;
+
+ case STATE_PT_SCALE:
+ value[0] = ctx->Pixel.RedScale;
+ value[1] = ctx->Pixel.GreenScale;
+ value[2] = ctx->Pixel.BlueScale;
+ value[3] = ctx->Pixel.AlphaScale;
+ return;
+
+ case STATE_PT_BIAS:
+ value[0] = ctx->Pixel.RedBias;
+ value[1] = ctx->Pixel.GreenBias;
+ value[2] = ctx->Pixel.BlueBias;
+ value[3] = ctx->Pixel.AlphaBias;
+ return;
+
+ case STATE_FB_SIZE:
+ value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1);
+ value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
+ value[2] = 0.0F;
+ value[3] = 0.0F;
+ return;
+
+ case STATE_FB_WPOS_Y_TRANSFORM:
+ /* A driver may negate this conditional by using ZW swizzle
+ * instead of XY (based on e.g. some other state). */
+ if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
+ /* Identity (XY) followed by flipping Y upside down (ZW). */
+ value[0] = 1.0F;
+ value[1] = 0.0F;
+ value[2] = -1.0F;
+ value[3] = (GLfloat) ctx->DrawBuffer->Height;
+ } else {
+ /* Flipping Y upside down (XY) followed by identity (ZW). */
+ value[0] = -1.0F;
+ value[1] = (GLfloat) ctx->DrawBuffer->Height;
+ value[2] = 1.0F;
+ value[3] = 0.0F;
+ }
+ return;
+
+ case STATE_ROT_MATRIX_0:
+ {
+ const int unit = (int) state[2];
+ GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
+ value[0] = rotMat22[0];
+ value[1] = rotMat22[2];
+ value[2] = 0.0;
+ value[3] = 0.0;
+ }
+ return;
+
+ case STATE_ROT_MATRIX_1:
+ {
+ const int unit = (int) state[2];
+ GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
+ value[0] = rotMat22[1];
+ value[1] = rotMat22[3];
+ value[2] = 0.0;
+ value[3] = 0.0;
+ }
+ return;
+
+ /* XXX: make sure new tokens added here are also handled in the
+ * _mesa_program_state_flags() switch, below.
+ */
+ default:
+ /* Unknown state indexes are silently ignored here.
+ * Drivers may do something special.
+ */
+ return;
+ }
+ return;
+
+ default:
+ _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
+ return;
+ }
+}
+
+
+/**
+ * Return a bitmask of the Mesa state flags (_NEW_* values) which would
+ * indicate that the given context state may have changed.
+ * The bitmask is used during validation to determine if we need to update
+ * vertex/fragment program parameters (like "state.material.color") when
+ * some GL state has changed.
+ */
+GLbitfield
+_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
+{
+ switch (state[0]) {
+ case STATE_MATERIAL:
+ case STATE_LIGHTPROD:
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ /* these can be effected by glColor when colormaterial mode is used */
+ return _NEW_LIGHT | _NEW_CURRENT_ATTRIB;
+
+ case STATE_LIGHT:
+ case STATE_LIGHTMODEL_AMBIENT:
+ return _NEW_LIGHT;
+
+ case STATE_TEXGEN:
+ return _NEW_TEXTURE;
+ case STATE_TEXENV_COLOR:
+ return _NEW_TEXTURE | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
+
+ case STATE_FOG_COLOR:
+ return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
+ case STATE_FOG_PARAMS:
+ return _NEW_FOG;
+
+ case STATE_CLIPPLANE:
+ return _NEW_TRANSFORM;
+
+ case STATE_POINT_SIZE:
+ case STATE_POINT_ATTENUATION:
+ return _NEW_POINT;
+
+ case STATE_MODELVIEW_MATRIX:
+ return _NEW_MODELVIEW;
+ case STATE_PROJECTION_MATRIX:
+ return _NEW_PROJECTION;
+ case STATE_MVP_MATRIX:
+ return _NEW_MODELVIEW | _NEW_PROJECTION;
+ case STATE_TEXTURE_MATRIX:
+ return _NEW_TEXTURE_MATRIX;
+ case STATE_PROGRAM_MATRIX:
+ return _NEW_TRACK_MATRIX;
+
+ case STATE_NUM_SAMPLES:
+ return _NEW_BUFFERS;
+
+ case STATE_DEPTH_RANGE:
+ return _NEW_VIEWPORT;
+
+ case STATE_FRAGMENT_PROGRAM:
+ case STATE_VERTEX_PROGRAM:
+ return _NEW_PROGRAM;
+
+ case STATE_NORMAL_SCALE:
+ return _NEW_MODELVIEW;
+
+ case STATE_INTERNAL:
+ switch (state[1]) {
+ case STATE_CURRENT_ATTRIB:
+ return _NEW_CURRENT_ATTRIB;
+ case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
+ return _NEW_CURRENT_ATTRIB | _NEW_LIGHT | _NEW_BUFFERS;
+
+ case STATE_NORMAL_SCALE:
+ return _NEW_MODELVIEW;
+
+ case STATE_TEXRECT_SCALE:
+ case STATE_ROT_MATRIX_0:
+ case STATE_ROT_MATRIX_1:
+ return _NEW_TEXTURE;
+ case STATE_FOG_PARAMS_OPTIMIZED:
+ return _NEW_FOG;
+ case STATE_POINT_SIZE_CLAMPED:
+ return _NEW_POINT | _NEW_MULTISAMPLE;
+ case STATE_LIGHT_SPOT_DIR_NORMALIZED:
+ case STATE_LIGHT_POSITION:
+ case STATE_LIGHT_POSITION_NORMALIZED:
+ case STATE_LIGHT_HALF_VECTOR:
+ return _NEW_LIGHT;
+
+ case STATE_PT_SCALE:
+ case STATE_PT_BIAS:
+ return _NEW_PIXEL;
+
+ case STATE_FB_SIZE:
+ case STATE_FB_WPOS_Y_TRANSFORM:
+ return _NEW_BUFFERS;
+
+ default:
+ /* unknown state indexes are silently ignored and
+ * no flag set, since it is handled by the driver.
+ */
+ return 0;
+ }
+
+ default:
+ _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
+ return 0;
+ }
+}
+
+
+static void
+append(char *dst, const char *src)
+{
+ while (*dst)
+ dst++;
+ while (*src)
+ *dst++ = *src++;
+ *dst = 0;
+}
+
+
+/**
+ * Convert token 'k' to a string, append it onto 'dst' string.
+ */
+static void
+append_token(char *dst, gl_state_index k)
+{
+ switch (k) {
+ case STATE_MATERIAL:
+ append(dst, "material");
+ break;
+ case STATE_LIGHT:
+ append(dst, "light");
+ break;
+ case STATE_LIGHTMODEL_AMBIENT:
+ append(dst, "lightmodel.ambient");
+ break;
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ break;
+ case STATE_LIGHTPROD:
+ append(dst, "lightprod");
+ break;
+ case STATE_TEXGEN:
+ append(dst, "texgen");
+ break;
+ case STATE_FOG_COLOR:
+ append(dst, "fog.color");
+ break;
+ case STATE_FOG_PARAMS:
+ append(dst, "fog.params");
+ break;
+ case STATE_CLIPPLANE:
+ append(dst, "clip");
+ break;
+ case STATE_POINT_SIZE:
+ append(dst, "point.size");
+ break;
+ case STATE_POINT_ATTENUATION:
+ append(dst, "point.attenuation");
+ break;
+ case STATE_MODELVIEW_MATRIX:
+ append(dst, "matrix.modelview");
+ break;
+ case STATE_PROJECTION_MATRIX:
+ append(dst, "matrix.projection");
+ break;
+ case STATE_MVP_MATRIX:
+ append(dst, "matrix.mvp");
+ break;
+ case STATE_TEXTURE_MATRIX:
+ append(dst, "matrix.texture");
+ break;
+ case STATE_PROGRAM_MATRIX:
+ append(dst, "matrix.program");
+ break;
+ case STATE_MATRIX_INVERSE:
+ append(dst, ".inverse");
+ break;
+ case STATE_MATRIX_TRANSPOSE:
+ append(dst, ".transpose");
+ break;
+ case STATE_MATRIX_INVTRANS:
+ append(dst, ".invtrans");
+ break;
+ case STATE_AMBIENT:
+ append(dst, ".ambient");
+ break;
+ case STATE_DIFFUSE:
+ append(dst, ".diffuse");
+ break;
+ case STATE_SPECULAR:
+ append(dst, ".specular");
+ break;
+ case STATE_EMISSION:
+ append(dst, ".emission");
+ break;
+ case STATE_SHININESS:
+ append(dst, "lshininess");
+ break;
+ case STATE_HALF_VECTOR:
+ append(dst, ".half");
+ break;
+ case STATE_POSITION:
+ append(dst, ".position");
+ break;
+ case STATE_ATTENUATION:
+ append(dst, ".attenuation");
+ break;
+ case STATE_SPOT_DIRECTION:
+ append(dst, ".spot.direction");
+ break;
+ case STATE_SPOT_CUTOFF:
+ append(dst, ".spot.cutoff");
+ break;
+ case STATE_TEXGEN_EYE_S:
+ append(dst, ".eye.s");
+ break;
+ case STATE_TEXGEN_EYE_T:
+ append(dst, ".eye.t");
+ break;
+ case STATE_TEXGEN_EYE_R:
+ append(dst, ".eye.r");
+ break;
+ case STATE_TEXGEN_EYE_Q:
+ append(dst, ".eye.q");
+ break;
+ case STATE_TEXGEN_OBJECT_S:
+ append(dst, ".object.s");
+ break;
+ case STATE_TEXGEN_OBJECT_T:
+ append(dst, ".object.t");
+ break;
+ case STATE_TEXGEN_OBJECT_R:
+ append(dst, ".object.r");
+ break;
+ case STATE_TEXGEN_OBJECT_Q:
+ append(dst, ".object.q");
+ break;
+ case STATE_TEXENV_COLOR:
+ append(dst, "texenv");
+ break;
+ case STATE_NUM_SAMPLES:
+ append(dst, "numsamples");
+ break;
+ case STATE_DEPTH_RANGE:
+ append(dst, "depth.range");
+ break;
+ case STATE_VERTEX_PROGRAM:
+ case STATE_FRAGMENT_PROGRAM:
+ break;
+ case STATE_ENV:
+ append(dst, "env");
+ break;
+ case STATE_LOCAL:
+ append(dst, "local");
+ break;
+ /* BEGIN internal state vars */
+ case STATE_INTERNAL:
+ append(dst, ".internal.");
+ break;
+ case STATE_CURRENT_ATTRIB:
+ append(dst, "current");
+ break;
+ case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
+ append(dst, "currentAttribMaybeVPClamped");
+ break;
+ case STATE_NORMAL_SCALE:
+ append(dst, "normalScale");
+ break;
+ case STATE_TEXRECT_SCALE:
+ append(dst, "texrectScale");
+ break;
+ case STATE_FOG_PARAMS_OPTIMIZED:
+ append(dst, "fogParamsOptimized");
+ break;
+ case STATE_POINT_SIZE_CLAMPED:
+ append(dst, "pointSizeClamped");
+ break;
+ case STATE_LIGHT_SPOT_DIR_NORMALIZED:
+ append(dst, "lightSpotDirNormalized");
+ break;
+ case STATE_LIGHT_POSITION:
+ append(dst, "lightPosition");
+ break;
+ case STATE_LIGHT_POSITION_NORMALIZED:
+ append(dst, "light.position.normalized");
+ break;
+ case STATE_LIGHT_HALF_VECTOR:
+ append(dst, "lightHalfVector");
+ break;
+ case STATE_PT_SCALE:
+ append(dst, "PTscale");
+ break;
+ case STATE_PT_BIAS:
+ append(dst, "PTbias");
+ break;
+ case STATE_FB_SIZE:
+ append(dst, "FbSize");
+ break;
+ case STATE_FB_WPOS_Y_TRANSFORM:
+ append(dst, "FbWposYTransform");
+ break;
+ case STATE_ROT_MATRIX_0:
+ append(dst, "rotMatrixRow0");
+ break;
+ case STATE_ROT_MATRIX_1:
+ append(dst, "rotMatrixRow1");
+ break;
+ default:
+ /* probably STATE_INTERNAL_DRIVER+i (driver private state) */
+ append(dst, "driverState");
+ }
+}
+
+static void
+append_face(char *dst, GLint face)
+{
+ if (face == 0)
+ append(dst, "front.");
+ else
+ append(dst, "back.");
+}
+
+static void
+append_index(char *dst, GLint index)
+{
+ char s[20];
+ sprintf(s, "[%d]", index);
+ append(dst, s);
+}
+
+/**
+ * Make a string from the given state vector.
+ * For example, return "state.matrix.texture[2].inverse".
+ * Use free() to deallocate the string.
+ */
+char *
+_mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
+{
+ char str[1000] = "";
+ char tmp[30];
+
+ append(str, "state.");
+ append_token(str, state[0]);
+
+ switch (state[0]) {
+ case STATE_MATERIAL:
+ append_face(str, state[1]);
+ append_token(str, state[2]);
+ break;
+ case STATE_LIGHT:
+ append_index(str, state[1]); /* light number [i]. */
+ append_token(str, state[2]); /* coefficients */
+ break;
+ case STATE_LIGHTMODEL_AMBIENT:
+ append(str, "lightmodel.ambient");
+ break;
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ if (state[1] == 0) {
+ append(str, "lightmodel.front.scenecolor");
+ }
+ else {
+ append(str, "lightmodel.back.scenecolor");
+ }
+ break;
+ case STATE_LIGHTPROD:
+ append_index(str, state[1]); /* light number [i]. */
+ append_face(str, state[2]);
+ append_token(str, state[3]);
+ break;
+ case STATE_TEXGEN:
+ append_index(str, state[1]); /* tex unit [i] */
+ append_token(str, state[2]); /* plane coef */
+ break;
+ case STATE_TEXENV_COLOR:
+ append_index(str, state[1]); /* tex unit [i] */
+ append(str, "color");
+ break;
+ case STATE_CLIPPLANE:
+ append_index(str, state[1]); /* plane [i] */
+ append(str, ".plane");
+ break;
+ case STATE_MODELVIEW_MATRIX:
+ case STATE_PROJECTION_MATRIX:
+ case STATE_MVP_MATRIX:
+ case STATE_TEXTURE_MATRIX:
+ case STATE_PROGRAM_MATRIX:
+ {
+ /* state[0] = modelview, projection, texture, etc. */
+ /* state[1] = which texture matrix or program matrix */
+ /* state[2] = first row to fetch */
+ /* state[3] = last row to fetch */
+ /* state[4] = transpose, inverse or invtrans */
+ const gl_state_index mat = state[0];
+ const GLuint index = (GLuint) state[1];
+ const GLuint firstRow = (GLuint) state[2];
+ const GLuint lastRow = (GLuint) state[3];
+ const gl_state_index modifier = state[4];
+ if (index ||
+ mat == STATE_TEXTURE_MATRIX ||
+ mat == STATE_PROGRAM_MATRIX)
+ append_index(str, index);
+ if (modifier)
+ append_token(str, modifier);
+ if (firstRow == lastRow)
+ sprintf(tmp, ".row[%d]", firstRow);
+ else
+ sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
+ append(str, tmp);
+ }
+ break;
+ case STATE_POINT_SIZE:
+ break;
+ case STATE_POINT_ATTENUATION:
+ break;
+ case STATE_FOG_PARAMS:
+ break;
+ case STATE_FOG_COLOR:
+ break;
+ case STATE_NUM_SAMPLES:
+ break;
+ case STATE_DEPTH_RANGE:
+ break;
+ case STATE_FRAGMENT_PROGRAM:
+ case STATE_VERTEX_PROGRAM:
+ /* state[1] = {STATE_ENV, STATE_LOCAL} */
+ /* state[2] = parameter index */
+ append_token(str, state[1]);
+ append_index(str, state[2]);
+ break;
+ case STATE_NORMAL_SCALE:
+ break;
+ case STATE_INTERNAL:
+ append_token(str, state[1]);
+ if (state[1] == STATE_CURRENT_ATTRIB)
+ append_index(str, state[2]);
+ break;
+ default:
+ _mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
+ break;
+ }
+
+ return _mesa_strdup(str);
+}
+
+
+/**
+ * Loop over all the parameters in a parameter list. If the parameter
+ * is a GL state reference, look up the current value of that state
+ * variable and put it into the parameter's Value[4] array.
+ * Other parameter types never change or are explicitly set by the user
+ * with glUniform() or glProgramParameter(), etc.
+ * This would be called at glBegin time.
+ */
+void
+_mesa_load_state_parameters(struct gl_context *ctx,
+ struct gl_program_parameter_list *paramList)
+{
+ GLuint i;
+
+ if (!paramList)
+ return;
+
+ for (i = 0; i < paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
+ _mesa_fetch_state(ctx,
+ paramList->Parameters[i].StateIndexes,
+ ¶mList->ParameterValues[i][0].f);
+ }
+ }
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/prog_statevars.h b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_statevars.h
new file mode 100644
index 0000000..23a9f48
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/prog_statevars.h
@@ -0,0 +1,156 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PROG_STATEVARS_H
+#define PROG_STATEVARS_H
+
+
+#include "main/glheader.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct gl_context;
+struct gl_program_parameter_list;
+
+/**
+ * Number of STATE_* values we need to address any GL state.
+ * Used to dimension arrays.
+ */
+#define STATE_LENGTH 5
+
+
+/**
+ * Used for describing GL state referenced from inside ARB vertex and
+ * fragment programs.
+ * A string such as "state.light[0].ambient" gets translated into a
+ * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ].
+ *
+ * For state that's an array, like STATE_CLIPPLANE, the 2nd token [1] should
+ * always be the array index.
+ */
+typedef enum gl_state_index_ {
+ STATE_MATERIAL = 100, /* start at 100 so small ints are seen as ints */
+
+ STATE_LIGHT,
+ STATE_LIGHTMODEL_AMBIENT,
+ STATE_LIGHTMODEL_SCENECOLOR,
+ STATE_LIGHTPROD,
+
+ STATE_TEXGEN,
+
+ STATE_FOG_COLOR,
+ STATE_FOG_PARAMS,
+
+ STATE_CLIPPLANE,
+
+ STATE_POINT_SIZE,
+ STATE_POINT_ATTENUATION,
+
+ STATE_MODELVIEW_MATRIX,
+ STATE_PROJECTION_MATRIX,
+ STATE_MVP_MATRIX,
+ STATE_TEXTURE_MATRIX,
+ STATE_PROGRAM_MATRIX,
+ STATE_MATRIX_INVERSE,
+ STATE_MATRIX_TRANSPOSE,
+ STATE_MATRIX_INVTRANS,
+
+ STATE_AMBIENT,
+ STATE_DIFFUSE,
+ STATE_SPECULAR,
+ STATE_EMISSION,
+ STATE_SHININESS,
+ STATE_HALF_VECTOR,
+
+ STATE_POSITION, /**< xyzw = position */
+ STATE_ATTENUATION, /**< xyz = attenuation, w = spot exponent */
+ STATE_SPOT_DIRECTION, /**< xyz = direction, w = cos(cutoff) */
+ STATE_SPOT_CUTOFF, /**< x = cutoff, yzw = undefined */
+
+ STATE_TEXGEN_EYE_S,
+ STATE_TEXGEN_EYE_T,
+ STATE_TEXGEN_EYE_R,
+ STATE_TEXGEN_EYE_Q,
+ STATE_TEXGEN_OBJECT_S,
+ STATE_TEXGEN_OBJECT_T,
+ STATE_TEXGEN_OBJECT_R,
+ STATE_TEXGEN_OBJECT_Q,
+
+ STATE_TEXENV_COLOR,
+
+ STATE_NUM_SAMPLES, /* An integer, not a float like the other state vars */
+
+ STATE_DEPTH_RANGE,
+
+ STATE_VERTEX_PROGRAM,
+ STATE_FRAGMENT_PROGRAM,
+
+ STATE_ENV,
+ STATE_LOCAL,
+
+ STATE_INTERNAL, /* Mesa additions */
+ STATE_CURRENT_ATTRIB, /* ctx->Current vertex attrib value */
+ STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, /* ctx->Current vertex attrib value after passthrough vertex processing */
+ STATE_NORMAL_SCALE,
+ STATE_TEXRECT_SCALE,
+ STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */
+ STATE_POINT_SIZE_CLAMPED, /* includes implementation dependent size clamp */
+ STATE_LIGHT_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */
+ STATE_LIGHT_POSITION, /* object vs eye space */
+ STATE_LIGHT_POSITION_NORMALIZED, /* object vs eye space */
+ STATE_LIGHT_HALF_VECTOR, /* object vs eye space */
+ STATE_PT_SCALE, /**< Pixel transfer RGBA scale */
+ STATE_PT_BIAS, /**< Pixel transfer RGBA bias */
+ STATE_FB_SIZE, /**< (width-1, height-1, 0, 0) */
+ STATE_FB_WPOS_Y_TRANSFORM, /**< (1, 0, -1, height) if a FBO is bound, (-1, height, 1, 0) otherwise */
+ STATE_ROT_MATRIX_0, /**< ATI_envmap_bumpmap, rot matrix row 0 */
+ STATE_ROT_MATRIX_1, /**< ATI_envmap_bumpmap, rot matrix row 1 */
+ STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */
+} gl_state_index;
+
+
+
+extern void
+_mesa_load_state_parameters(struct gl_context *ctx,
+ struct gl_program_parameter_list *paramList);
+
+
+extern GLbitfield
+_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]);
+
+
+extern char *
+_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PROG_STATEVARS_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program.c b/icd/intel/compiler/mesa-utils/src/mesa/program/program.c
new file mode 100644
index 0000000..bb97352
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program.c
@@ -0,0 +1,1081 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file program.c
+ * Vertex and fragment program support functions.
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/macros.h"
+#include "program.h"
+#include "prog_cache.h"
+#include "prog_parameter.h"
+#include "prog_instruction.h"
+
+
+/**
+ * A pointer to this dummy program is put into the hash table when
+ * glGenPrograms is called.
+ */
+struct gl_program _mesa_DummyProgram;
+
+
+/**
+ * Init context's vertex/fragment program state
+ */
+void
+_mesa_init_program(struct gl_context *ctx)
+{
+ /*
+ * If this assertion fails, we need to increase the field
+ * size for register indexes (see INST_INDEX_BITS).
+ */
+ ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
+ <= (1 << INST_INDEX_BITS));
+ ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
+ <= (1 << INST_INDEX_BITS));
+
+ ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
+ ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
+ ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
+ ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
+
+ ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
+ ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
+
+ ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
+ ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
+
+ /* If this fails, increase prog_instruction::TexSrcUnit size */
+ STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
+
+ /* If this fails, increase prog_instruction::TexSrcTarget size */
+ STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
+
+ ctx->Program.ErrorPos = -1;
+ ctx->Program.ErrorString = _mesa_strdup("");
+
+ ctx->VertexProgram.Enabled = GL_FALSE;
+ ctx->VertexProgram.PointSizeEnabled =
+ (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
+ ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ ctx->Shared->DefaultVertexProgram);
+ assert(ctx->VertexProgram.Current);
+ ctx->VertexProgram.Cache = _mesa_new_program_cache();
+
+ ctx->FragmentProgram.Enabled = GL_FALSE;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ ctx->Shared->DefaultFragmentProgram);
+ assert(ctx->FragmentProgram.Current);
+ ctx->FragmentProgram.Cache = _mesa_new_program_cache();
+
+ ctx->GeometryProgram.Enabled = GL_FALSE;
+ /* right now by default we don't have a geometry program */
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+ NULL);
+ ctx->GeometryProgram.Cache = _mesa_new_program_cache();
+
+ /* XXX probably move this stuff */
+ ctx->ATIFragmentShader.Enabled = GL_FALSE;
+ ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
+ assert(ctx->ATIFragmentShader.Current);
+ ctx->ATIFragmentShader.Current->RefCount++;
+}
+
+
+/**
+ * Free a context's vertex/fragment program state
+ */
+void
+_mesa_free_program_data(struct gl_context *ctx)
+{
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+ _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+ _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
+ _mesa_delete_program_cache(ctx, ctx->GeometryProgram.Cache);
+
+ /* XXX probably move this stuff */
+ if (ctx->ATIFragmentShader.Current) {
+ ctx->ATIFragmentShader.Current->RefCount--;
+ if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
+ free(ctx->ATIFragmentShader.Current);
+ }
+ }
+
+ free((void *) ctx->Program.ErrorString);
+}
+
+
+/**
+ * Update the default program objects in the given context to reference those
+ * specified in the shared state and release those referencing the old
+ * shared state.
+ */
+void
+_mesa_update_default_objects_program(struct gl_context *ctx)
+{
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ ctx->Shared->DefaultVertexProgram);
+ assert(ctx->VertexProgram.Current);
+
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ ctx->Shared->DefaultFragmentProgram);
+ assert(ctx->FragmentProgram.Current);
+
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+ ctx->Shared->DefaultGeometryProgram);
+
+ /* XXX probably move this stuff */
+ if (ctx->ATIFragmentShader.Current) {
+ ctx->ATIFragmentShader.Current->RefCount--;
+ if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
+ free(ctx->ATIFragmentShader.Current);
+ }
+ }
+ ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
+ assert(ctx->ATIFragmentShader.Current);
+ ctx->ATIFragmentShader.Current->RefCount++;
+}
+
+
+/**
+ * Set the vertex/fragment program error state (position and error string).
+ * This is generally called from within the parsers.
+ */
+void
+_mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
+{
+ ctx->Program.ErrorPos = pos;
+ free((void *) ctx->Program.ErrorString);
+ if (!string)
+ string = "";
+ ctx->Program.ErrorString = _mesa_strdup(string);
+}
+
+
+/**
+ * Find the line number and column for 'pos' within 'string'.
+ * Return a copy of the line which contains 'pos'. Free the line with
+ * free().
+ * \param string the program string
+ * \param pos the position within the string
+ * \param line returns the line number corresponding to 'pos'.
+ * \param col returns the column number corresponding to 'pos'.
+ * \return copy of the line containing 'pos'.
+ */
+const GLubyte *
+_mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
+ GLint *line, GLint *col)
+{
+ const GLubyte *lineStart = string;
+ const GLubyte *p = string;
+ GLubyte *s;
+ int len;
+
+ *line = 1;
+
+ while (p != pos) {
+ if (*p == (GLubyte) '\n') {
+ (*line)++;
+ lineStart = p + 1;
+ }
+ p++;
+ }
+
+ *col = (pos - lineStart) + 1;
+
+ /* return copy of this line */
+ while (*p != 0 && *p != '\n')
+ p++;
+ len = p - lineStart;
+ s = malloc(len + 1);
+ memcpy(s, lineStart, len);
+ s[len] = 0;
+
+ return s;
+}
+
+
+/**
+ * Initialize a new vertex/fragment program object.
+ */
+static struct gl_program *
+_mesa_init_program_struct( struct gl_context *ctx, struct gl_program *prog,
+ GLenum target, GLuint id)
+{
+ (void) ctx;
+ if (prog) {
+ GLuint i;
+ memset(prog, 0, sizeof(*prog));
+ prog->Id = id;
+ prog->Target = target;
+ prog->RefCount = 1;
+ prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+
+ /* default mapping from samplers to texture units */
+ for (i = 0; i < MAX_SAMPLERS; i++)
+ prog->SamplerUnits[i] = i;
+ }
+
+ return prog;
+}
+
+
+/**
+ * Initialize a new fragment program object.
+ */
+struct gl_program *
+_mesa_init_fragment_program( struct gl_context *ctx, struct gl_fragment_program *prog,
+ GLenum target, GLuint id)
+{
+ if (prog)
+ return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+ else
+ return NULL;
+}
+
+
+/**
+ * Initialize a new vertex program object.
+ */
+struct gl_program *
+_mesa_init_vertex_program( struct gl_context *ctx, struct gl_vertex_program *prog,
+ GLenum target, GLuint id)
+{
+ if (prog)
+ return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+ else
+ return NULL;
+}
+
+
+/**
+ * Initialize a new compute program object.
+ */
+struct gl_program *
+_mesa_init_compute_program(struct gl_context *ctx,
+ struct gl_compute_program *prog, GLenum target,
+ GLuint id)
+{
+ if (prog)
+ return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+ else
+ return NULL;
+}
+
+
+/**
+ * Initialize a new geometry program object.
+ */
+struct gl_program *
+_mesa_init_geometry_program( struct gl_context *ctx, struct gl_geometry_program *prog,
+ GLenum target, GLuint id)
+{
+ if (prog)
+ return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+ else
+ return NULL;
+}
+
+
+/**
+ * Allocate and initialize a new fragment/vertex program object but
+ * don't put it into the program hash table. Called via
+ * ctx->Driver.NewProgram. May be overridden (ie. replaced) by a
+ * device driver function to implement OO deriviation with additional
+ * types not understood by this function.
+ *
+ * \param ctx context
+ * \param id program id/number
+ * \param target program target/type
+ * \return pointer to new program object
+ */
+struct gl_program *
+_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id)
+{
+ struct gl_program *prog;
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
+ prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
+ target, id );
+ break;
+ case GL_FRAGMENT_PROGRAM_NV:
+ case GL_FRAGMENT_PROGRAM_ARB:
+ prog =_mesa_init_fragment_program(ctx,
+ CALLOC_STRUCT(gl_fragment_program),
+ target, id );
+ break;
+ case MESA_GEOMETRY_PROGRAM:
+ prog = _mesa_init_geometry_program(ctx,
+ CALLOC_STRUCT(gl_geometry_program),
+ target, id);
+ break;
+ case GL_COMPUTE_PROGRAM_NV:
+ prog = _mesa_init_compute_program(ctx,
+ CALLOC_STRUCT(gl_compute_program),
+ target, id);
+ break;
+ default:
+ _mesa_problem(ctx, "bad target in _mesa_new_program");
+ prog = NULL;
+ }
+ return prog;
+}
+
+
+/**
+ * Delete a program and remove it from the hash table, ignoring the
+ * reference count.
+ * Called via ctx->Driver.DeleteProgram. May be wrapped (OO deriviation)
+ * by a device driver function.
+ */
+void
+_mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
+{
+ (void) ctx;
+ ASSERT(prog);
+ ASSERT(prog->RefCount==0);
+
+ if (prog == &_mesa_DummyProgram)
+ return;
+
+ free(prog->String);
+ free(prog->LocalParams);
+
+ if (prog->Instructions) {
+ _mesa_free_instructions(prog->Instructions, prog->NumInstructions);
+ }
+ if (prog->Parameters) {
+ _mesa_free_parameter_list(prog->Parameters);
+ }
+
+ free(prog);
+}
+
+
+/**
+ * Return the gl_program object for a given ID.
+ * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
+ * casts elsewhere.
+ */
+struct gl_program *
+_mesa_lookup_program(struct gl_context *ctx, GLuint id)
+{
+ if (id)
+ return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
+ else
+ return NULL;
+}
+
+
+/**
+ * Reference counting for vertex/fragment programs
+ * This is normally only called from the _mesa_reference_program() macro
+ * when there's a real pointer change.
+ */
+void
+_mesa_reference_program_(struct gl_context *ctx,
+ struct gl_program **ptr,
+ struct gl_program *prog)
+{
+#ifndef NDEBUG
+ assert(ptr);
+ if (*ptr && prog) {
+ /* sanity check */
+ if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
+ ASSERT(prog->Target == GL_VERTEX_PROGRAM_ARB);
+ else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
+ ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
+ prog->Target == GL_FRAGMENT_PROGRAM_NV);
+ else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM)
+ ASSERT(prog->Target == MESA_GEOMETRY_PROGRAM);
+ }
+#endif
+
+ if (*ptr) {
+ GLboolean deleteFlag;
+
+ /*mtx_lock(&(*ptr)->Mutex);*/
+#if 0
+ printf("Program %p ID=%u Target=%s Refcount-- to %d\n",
+ *ptr, (*ptr)->Id,
+ ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+ ((*ptr)->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
+ (*ptr)->RefCount - 1);
+#endif
+ ASSERT((*ptr)->RefCount > 0);
+ (*ptr)->RefCount--;
+
+ deleteFlag = ((*ptr)->RefCount == 0);
+ /*mtx_lock(&(*ptr)->Mutex);*/
+
+ if (deleteFlag) {
+ ASSERT(ctx);
+ ctx->Driver.DeleteProgram(ctx, *ptr);
+ }
+
+ *ptr = NULL;
+ }
+
+ assert(!*ptr);
+ if (prog) {
+ /*mtx_lock(&prog->Mutex);*/
+ prog->RefCount++;
+#if 0
+ printf("Program %p ID=%u Target=%s Refcount++ to %d\n",
+ prog, prog->Id,
+ (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+ (prog->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
+ prog->RefCount);
+#endif
+ /*mtx_unlock(&prog->Mutex);*/
+ }
+
+ *ptr = prog;
+}
+
+
+/**
+ * Return a copy of a program.
+ * XXX Problem here if the program object is actually OO-derivation
+ * made by a device driver.
+ */
+struct gl_program *
+_mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog)
+{
+ struct gl_program *clone;
+
+ clone = ctx->Driver.NewProgram(ctx, prog->Target, prog->Id);
+ if (!clone)
+ return NULL;
+
+ assert(clone->Target == prog->Target);
+ assert(clone->RefCount == 1);
+
+ clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
+ clone->Format = prog->Format;
+ clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
+ if (!clone->Instructions) {
+ _mesa_reference_program(ctx, &clone, NULL);
+ return NULL;
+ }
+ _mesa_copy_instructions(clone->Instructions, prog->Instructions,
+ prog->NumInstructions);
+ clone->InputsRead = prog->InputsRead;
+ clone->OutputsWritten = prog->OutputsWritten;
+ clone->SamplersUsed = prog->SamplersUsed;
+ clone->ShadowSamplers = prog->ShadowSamplers;
+ memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed));
+
+ if (prog->Parameters)
+ clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
+ if (prog->LocalParams) {
+ clone->LocalParams = malloc(MAX_PROGRAM_LOCAL_PARAMS *
+ sizeof(float[4]));
+ if (!clone->LocalParams) {
+ _mesa_reference_program(ctx, &clone, NULL);
+ return NULL;
+ }
+ memcpy(clone->LocalParams, prog->LocalParams,
+ MAX_PROGRAM_LOCAL_PARAMS * sizeof(float[4]));
+ }
+ clone->IndirectRegisterFiles = prog->IndirectRegisterFiles;
+ clone->NumInstructions = prog->NumInstructions;
+ clone->NumTemporaries = prog->NumTemporaries;
+ clone->NumParameters = prog->NumParameters;
+ clone->NumAttributes = prog->NumAttributes;
+ clone->NumAddressRegs = prog->NumAddressRegs;
+ clone->NumNativeInstructions = prog->NumNativeInstructions;
+ clone->NumNativeTemporaries = prog->NumNativeTemporaries;
+ clone->NumNativeParameters = prog->NumNativeParameters;
+ clone->NumNativeAttributes = prog->NumNativeAttributes;
+ clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
+ clone->NumAluInstructions = prog->NumAluInstructions;
+ clone->NumTexInstructions = prog->NumTexInstructions;
+ clone->NumTexIndirections = prog->NumTexIndirections;
+ clone->NumNativeAluInstructions = prog->NumNativeAluInstructions;
+ clone->NumNativeTexInstructions = prog->NumNativeTexInstructions;
+ clone->NumNativeTexIndirections = prog->NumNativeTexIndirections;
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ {
+ const struct gl_vertex_program *vp = gl_vertex_program_const(prog);
+ struct gl_vertex_program *vpc = gl_vertex_program(clone);
+ vpc->IsPositionInvariant = vp->IsPositionInvariant;
+ }
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ {
+ const struct gl_fragment_program *fp = gl_fragment_program_const(prog);
+ struct gl_fragment_program *fpc = gl_fragment_program(clone);
+ fpc->UsesKill = fp->UsesKill;
+ fpc->UsesDFdy = fp->UsesDFdy;
+ fpc->OriginUpperLeft = fp->OriginUpperLeft;
+ fpc->PixelCenterInteger = fp->PixelCenterInteger;
+ }
+ break;
+ case MESA_GEOMETRY_PROGRAM:
+ {
+ const struct gl_geometry_program *gp = gl_geometry_program_const(prog);
+ struct gl_geometry_program *gpc = gl_geometry_program(clone);
+ gpc->VerticesOut = gp->VerticesOut;
+ gpc->InputType = gp->InputType;
+ gpc->Invocations = gp->Invocations;
+ gpc->OutputType = gp->OutputType;
+ gpc->UsesEndPrimitive = gp->UsesEndPrimitive;
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
+ }
+
+ return clone;
+}
+
+
+/**
+ * Insert 'count' NOP instructions at 'start' in the given program.
+ * Adjust branch targets accordingly.
+ */
+GLboolean
+_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
+{
+ const GLuint origLen = prog->NumInstructions;
+ const GLuint newLen = origLen + count;
+ struct prog_instruction *newInst;
+ GLuint i;
+
+ /* adjust branches */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ if (inst->BranchTarget > 0) {
+ if ((GLuint)inst->BranchTarget >= start) {
+ inst->BranchTarget += count;
+ }
+ }
+ }
+
+ /* Alloc storage for new instructions */
+ newInst = _mesa_alloc_instructions(newLen);
+ if (!newInst) {
+ return GL_FALSE;
+ }
+
+ /* Copy 'start' instructions into new instruction buffer */
+ _mesa_copy_instructions(newInst, prog->Instructions, start);
+
+ /* init the new instructions */
+ _mesa_init_instructions(newInst + start, count);
+
+ /* Copy the remaining/tail instructions to new inst buffer */
+ _mesa_copy_instructions(newInst + start + count,
+ prog->Instructions + start,
+ origLen - start);
+
+ /* free old instructions */
+ _mesa_free_instructions(prog->Instructions, origLen);
+
+ /* install new instructions */
+ prog->Instructions = newInst;
+ prog->NumInstructions = newLen;
+
+ return GL_TRUE;
+}
+
+/**
+ * Delete 'count' instructions at 'start' in the given program.
+ * Adjust branch targets accordingly.
+ */
+GLboolean
+_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
+{
+ const GLuint origLen = prog->NumInstructions;
+ const GLuint newLen = origLen - count;
+ struct prog_instruction *newInst;
+ GLuint i;
+
+ /* adjust branches */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ if (inst->BranchTarget > 0) {
+ if (inst->BranchTarget > (GLint) start) {
+ inst->BranchTarget -= count;
+ }
+ }
+ }
+
+ /* Alloc storage for new instructions */
+ newInst = _mesa_alloc_instructions(newLen);
+ if (!newInst) {
+ return GL_FALSE;
+ }
+
+ /* Copy 'start' instructions into new instruction buffer */
+ _mesa_copy_instructions(newInst, prog->Instructions, start);
+
+ /* Copy the remaining/tail instructions to new inst buffer */
+ _mesa_copy_instructions(newInst + start,
+ prog->Instructions + start + count,
+ newLen - start);
+
+ /* free old instructions */
+ _mesa_free_instructions(prog->Instructions, origLen);
+
+ /* install new instructions */
+ prog->Instructions = newInst;
+ prog->NumInstructions = newLen;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Search instructions for registers that match (oldFile, oldIndex),
+ * replacing them with (newFile, newIndex).
+ */
+static void
+replace_registers(struct prog_instruction *inst, GLuint numInst,
+ GLuint oldFile, GLuint oldIndex,
+ GLuint newFile, GLuint newIndex)
+{
+ GLuint i, j;
+ for (i = 0; i < numInst; i++) {
+ /* src regs */
+ for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
+ if (inst[i].SrcReg[j].File == oldFile &&
+ inst[i].SrcReg[j].Index == oldIndex) {
+ inst[i].SrcReg[j].File = newFile;
+ inst[i].SrcReg[j].Index = newIndex;
+ }
+ }
+ /* dst reg */
+ if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
+ inst[i].DstReg.File = newFile;
+ inst[i].DstReg.Index = newIndex;
+ }
+ }
+}
+
+
+/**
+ * Search instructions for references to program parameters. When found,
+ * increment the parameter index by 'offset'.
+ * Used when combining programs.
+ */
+static void
+adjust_param_indexes(struct prog_instruction *inst, GLuint numInst,
+ GLuint offset)
+{
+ GLuint i, j;
+ for (i = 0; i < numInst; i++) {
+ for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
+ GLuint f = inst[i].SrcReg[j].File;
+ if (f == PROGRAM_CONSTANT ||
+ f == PROGRAM_UNIFORM ||
+ f == PROGRAM_STATE_VAR) {
+ inst[i].SrcReg[j].Index += offset;
+ }
+ }
+ }
+}
+
+
+/**
+ * Combine two programs into one. Fix instructions so the outputs of
+ * the first program go to the inputs of the second program.
+ */
+struct gl_program *
+_mesa_combine_programs(struct gl_context *ctx,
+ const struct gl_program *progA,
+ const struct gl_program *progB)
+{
+ struct prog_instruction *newInst;
+ struct gl_program *newProg;
+ const GLuint lenA = progA->NumInstructions - 1; /* omit END instr */
+ const GLuint lenB = progB->NumInstructions;
+ const GLuint numParamsA = _mesa_num_parameters(progA->Parameters);
+ const GLuint newLength = lenA + lenB;
+ GLboolean usedTemps[MAX_PROGRAM_TEMPS];
+ GLuint firstTemp = 0;
+ GLbitfield64 inputsB;
+ GLuint i;
+
+ ASSERT(progA->Target == progB->Target);
+
+ newInst = _mesa_alloc_instructions(newLength);
+ if (!newInst)
+ return GL_FALSE;
+
+ _mesa_copy_instructions(newInst, progA->Instructions, lenA);
+ _mesa_copy_instructions(newInst + lenA, progB->Instructions, lenB);
+
+ /* adjust branch / instruction addresses for B's instructions */
+ for (i = 0; i < lenB; i++) {
+ newInst[lenA + i].BranchTarget += lenA;
+ }
+
+ newProg = ctx->Driver.NewProgram(ctx, progA->Target, 0);
+ newProg->Instructions = newInst;
+ newProg->NumInstructions = newLength;
+
+ /* find used temp regs (we may need new temps below) */
+ _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY,
+ usedTemps, MAX_PROGRAM_TEMPS);
+
+ if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
+ const struct gl_fragment_program *fprogA, *fprogB;
+ struct gl_fragment_program *newFprog;
+ GLbitfield64 progB_inputsRead = progB->InputsRead;
+ GLint progB_colorFile, progB_colorIndex;
+
+ fprogA = gl_fragment_program_const(progA);
+ fprogB = gl_fragment_program_const(progB);
+ newFprog = gl_fragment_program(newProg);
+
+ newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
+ newFprog->UsesDFdy = fprogA->UsesDFdy || fprogB->UsesDFdy;
+
+ /* We'll do a search and replace for instances
+ * of progB_colorFile/progB_colorIndex below...
+ */
+ progB_colorFile = PROGRAM_INPUT;
+ progB_colorIndex = VARYING_SLOT_COL0;
+
+ /*
+ * The fragment program may get color from a state var rather than
+ * a fragment input (vertex output) if it's constant.
+ * See the texenvprogram.c code.
+ * So, search the program's parameter list now to see if the program
+ * gets color from a state var instead of a conventional fragment
+ * input register.
+ */
+ for (i = 0; i < progB->Parameters->NumParameters; i++) {
+ struct gl_program_parameter *p = &progB->Parameters->Parameters[i];
+ if (p->Type == PROGRAM_STATE_VAR &&
+ p->StateIndexes[0] == STATE_INTERNAL &&
+ p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
+ (int) p->StateIndexes[2] == (int) VERT_ATTRIB_COLOR0) {
+ progB_inputsRead |= VARYING_BIT_COL0;
+ progB_colorFile = PROGRAM_STATE_VAR;
+ progB_colorIndex = i;
+ break;
+ }
+ }
+
+ /* Connect color outputs of fprogA to color inputs of fprogB, via a
+ * new temporary register.
+ */
+ if ((progA->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
+ (progB_inputsRead & VARYING_BIT_COL0)) {
+ GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS,
+ firstTemp);
+ if (tempReg < 0) {
+ _mesa_problem(ctx, "No free temp regs found in "
+ "_mesa_combine_programs(), using 31");
+ tempReg = 31;
+ }
+ firstTemp = tempReg + 1;
+
+ /* replace writes to result.color[0] with tempReg */
+ replace_registers(newInst, lenA,
+ PROGRAM_OUTPUT, FRAG_RESULT_COLOR,
+ PROGRAM_TEMPORARY, tempReg);
+ /* replace reads from the input color with tempReg */
+ replace_registers(newInst + lenA, lenB,
+ progB_colorFile, progB_colorIndex, /* search for */
+ PROGRAM_TEMPORARY, tempReg /* replace with */ );
+ }
+
+ /* compute combined program's InputsRead */
+ inputsB = progB_inputsRead;
+ if (progA->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
+ inputsB &= ~(1 << VARYING_SLOT_COL0);
+ }
+ newProg->InputsRead = progA->InputsRead | inputsB;
+ newProg->OutputsWritten = progB->OutputsWritten;
+ newProg->SamplersUsed = progA->SamplersUsed | progB->SamplersUsed;
+ }
+ else {
+ /* vertex program */
+ assert(0); /* XXX todo */
+ }
+
+ /*
+ * Merge parameters (uniforms, constants, etc)
+ */
+ newProg->Parameters = _mesa_combine_parameter_lists(progA->Parameters,
+ progB->Parameters);
+
+ adjust_param_indexes(newInst + lenA, lenB, numParamsA);
+
+
+ return newProg;
+}
+
+
+/**
+ * Populate the 'used' array with flags indicating which registers (TEMPs,
+ * INPUTs, OUTPUTs, etc, are used by the given program.
+ * \param file type of register to scan for
+ * \param used returns true/false flags for in use / free
+ * \param usedSize size of the 'used' array
+ */
+void
+_mesa_find_used_registers(const struct gl_program *prog,
+ gl_register_file file,
+ GLboolean used[], GLuint usedSize)
+{
+ GLuint i, j;
+
+ memset(used, 0, usedSize);
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
+
+ if (inst->DstReg.File == file) {
+ ASSERT(inst->DstReg.Index < usedSize);
+ if(inst->DstReg.Index < usedSize)
+ used[inst->DstReg.Index] = GL_TRUE;
+ }
+
+ for (j = 0; j < n; j++) {
+ if (inst->SrcReg[j].File == file) {
+ ASSERT(inst->SrcReg[j].Index < (GLint) usedSize);
+ if (inst->SrcReg[j].Index < (GLint) usedSize)
+ used[inst->SrcReg[j].Index] = GL_TRUE;
+ }
+ }
+ }
+}
+
+
+/**
+ * Scan the given 'used' register flag array for the first entry
+ * that's >= firstReg.
+ * \param used vector of flags indicating registers in use (as returned
+ * by _mesa_find_used_registers())
+ * \param usedSize size of the 'used' array
+ * \param firstReg first register to start searching at
+ * \return index of unused register, or -1 if none.
+ */
+GLint
+_mesa_find_free_register(const GLboolean used[],
+ GLuint usedSize, GLuint firstReg)
+{
+ GLuint i;
+
+ assert(firstReg < usedSize);
+
+ for (i = firstReg; i < usedSize; i++)
+ if (!used[i])
+ return i;
+
+ return -1;
+}
+
+
+
+/**
+ * Check if the given register index is valid (doesn't exceed implementation-
+ * dependent limits).
+ * \return GL_TRUE if OK, GL_FALSE if bad index
+ */
+GLboolean
+_mesa_valid_register_index(const struct gl_context *ctx,
+ gl_shader_stage shaderType,
+ gl_register_file file, GLint index)
+{
+ const struct gl_program_constants *c;
+
+ assert(0 <= shaderType && shaderType < MESA_SHADER_STAGES);
+ c = &ctx->Const.Program[shaderType];
+
+ switch (file) {
+ case PROGRAM_UNDEFINED:
+ return GL_TRUE; /* XXX or maybe false? */
+
+ case PROGRAM_TEMPORARY:
+ return index >= 0 && index < (GLint) c->MaxTemps;
+
+ case PROGRAM_UNIFORM:
+ case PROGRAM_STATE_VAR:
+ /* aka constant buffer */
+ return index >= 0 && index < (GLint) c->MaxUniformComponents / 4;
+
+ case PROGRAM_CONSTANT:
+ /* constant buffer w/ possible relative negative addressing */
+ return (index > (int) c->MaxUniformComponents / -4 &&
+ index < (int) c->MaxUniformComponents / 4);
+
+ case PROGRAM_INPUT:
+ if (index < 0)
+ return GL_FALSE;
+
+ switch (shaderType) {
+ case MESA_SHADER_VERTEX:
+ return index < VERT_ATTRIB_GENERIC0 + (GLint) c->MaxAttribs;
+ case MESA_SHADER_FRAGMENT:
+ return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
+ case MESA_SHADER_GEOMETRY:
+ return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
+ default:
+ return GL_FALSE;
+ }
+
+ case PROGRAM_OUTPUT:
+ if (index < 0)
+ return GL_FALSE;
+
+ switch (shaderType) {
+ case MESA_SHADER_VERTEX:
+ return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
+ case MESA_SHADER_FRAGMENT:
+ return index < FRAG_RESULT_DATA0 + (GLint) ctx->Const.MaxDrawBuffers;
+ case MESA_SHADER_GEOMETRY:
+ return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
+ default:
+ return GL_FALSE;
+ }
+
+ case PROGRAM_ADDRESS:
+ return index >= 0 && index < (GLint) c->MaxAddressRegs;
+
+ default:
+ _mesa_problem(ctx,
+ "unexpected register file in _mesa_valid_register_index()");
+ return GL_FALSE;
+ }
+}
+
+
+
+/**
+ * "Post-process" a GPU program. This is intended to be used for debugging.
+ * Example actions include no-op'ing instructions or changing instruction
+ * behaviour.
+ */
+void
+_mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog)
+{
+ static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 };
+ GLuint i;
+ GLuint whiteSwizzle;
+ GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters,
+ (gl_constant_value *) white,
+ 4, &whiteSwizzle);
+
+ (void) whiteIndex;
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
+
+ (void) n;
+
+ if (_mesa_is_tex_instruction(inst->Opcode)) {
+#if 0
+ /* replace TEX/TXP/TXB with MOV */
+ inst->Opcode = OPCODE_MOV;
+ inst->DstReg.WriteMask = WRITEMASK_XYZW;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+ inst->SrcReg[0].Negate = NEGATE_NONE;
+#endif
+
+#if 0
+ /* disable shadow texture mode */
+ inst->TexShadow = 0;
+#endif
+ }
+
+ if (inst->Opcode == OPCODE_TXP) {
+#if 0
+ inst->Opcode = OPCODE_MOV;
+ inst->DstReg.WriteMask = WRITEMASK_XYZW;
+ inst->SrcReg[0].File = PROGRAM_CONSTANT;
+ inst->SrcReg[0].Index = whiteIndex;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+ inst->SrcReg[0].Negate = NEGATE_NONE;
+#endif
+#if 0
+ inst->TexShadow = 0;
+#endif
+#if 0
+ inst->Opcode = OPCODE_TEX;
+ inst->TexShadow = 0;
+#endif
+ }
+
+ }
+}
+
+/* Gets the minimum number of shader invocations per fragment.
+ * This function is useful to determine if we need to do per
+ * sample shading or per fragment shading.
+ */
+GLint
+_mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
+ const struct gl_fragment_program *prog,
+ bool ignore_sample_qualifier)
+{
+ /* From ARB_sample_shading specification:
+ * "Using gl_SampleID in a fragment shader causes the entire shader
+ * to be evaluated per-sample."
+ *
+ * "Using gl_SamplePosition in a fragment shader causes the entire
+ * shader to be evaluated per-sample."
+ *
+ * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading
+ * has no effect."
+ */
+ if (ctx->Multisample.Enabled) {
+ // LunarG REM:
+ /* /\* The ARB_gpu_shader5 specification says: */
+ /* * */
+ /* * "Use of the "sample" qualifier on a fragment shader input */
+ /* * forces per-sample shading" */
+ /* *\/ */
+ /* if (prog->IsSample && !ignore_sample_qualifier) */
+ /* return MAX2(ctx->DrawBuffer->Visual.samples, 1); */
+
+ /* if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID | */
+ /* SYSTEM_BIT_SAMPLE_POS)) */
+ /* return MAX2(ctx->DrawBuffer->Visual.samples, 1); */
+ /* else if (ctx->Multisample.SampleShading) */
+ /* return MAX2(ceil(ctx->Multisample.MinSampleShadingValue * */
+ /* ctx->DrawBuffer->Visual.samples), 1); */
+ /* else */
+ return 1;
+ }
+ return 1;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program.h b/icd/intel/compiler/mesa-utils/src/mesa/program/program.h
new file mode 100644
index 0000000..ef69824
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program.h
@@ -0,0 +1,283 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file program.c
+ * Vertex and fragment program support functions.
+ * \author Brian Paul
+ */
+
+
+/**
+ * \mainpage Mesa vertex and fragment program module
+ *
+ * This module or directory contains most of the code for vertex and
+ * fragment programs and shaders, including state management, parsers,
+ * and (some) software routines for executing programs
+ */
+
+#ifndef PROGRAM_H
+#define PROGRAM_H
+
+#include "main/compiler.h"
+#include "main/mtypes.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct gl_program _mesa_DummyProgram;
+
+
+extern void
+_mesa_init_program(struct gl_context *ctx);
+
+extern void
+_mesa_free_program_data(struct gl_context *ctx);
+
+extern void
+_mesa_update_default_objects_program(struct gl_context *ctx);
+
+extern void
+_mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string);
+
+extern const GLubyte *
+_mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
+ GLint *line, GLint *col);
+
+
+extern struct gl_program *
+_mesa_init_vertex_program(struct gl_context *ctx,
+ struct gl_vertex_program *prog,
+ GLenum target, GLuint id);
+
+extern struct gl_program *
+_mesa_init_fragment_program(struct gl_context *ctx,
+ struct gl_fragment_program *prog,
+ GLenum target, GLuint id);
+
+extern struct gl_program *
+_mesa_init_geometry_program(struct gl_context *ctx,
+ struct gl_geometry_program *prog,
+ GLenum target, GLuint id);
+
+extern struct gl_program *
+_mesa_init_compute_program(struct gl_context *ctx,
+ struct gl_compute_program *prog,
+ GLenum target, GLuint id);
+
+extern struct gl_program *
+_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id);
+
+extern void
+_mesa_delete_program(struct gl_context *ctx, struct gl_program *prog);
+
+extern struct gl_program *
+_mesa_lookup_program(struct gl_context *ctx, GLuint id);
+
+extern void
+_mesa_reference_program_(struct gl_context *ctx,
+ struct gl_program **ptr,
+ struct gl_program *prog);
+
+static inline void
+_mesa_reference_program(struct gl_context *ctx,
+ struct gl_program **ptr,
+ struct gl_program *prog)
+{
+ if (*ptr != prog)
+ _mesa_reference_program_(ctx, ptr, prog);
+}
+
+static inline void
+_mesa_reference_vertprog(struct gl_context *ctx,
+ struct gl_vertex_program **ptr,
+ struct gl_vertex_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+static inline void
+_mesa_reference_fragprog(struct gl_context *ctx,
+ struct gl_fragment_program **ptr,
+ struct gl_fragment_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+static inline void
+_mesa_reference_geomprog(struct gl_context *ctx,
+ struct gl_geometry_program **ptr,
+ struct gl_geometry_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+extern struct gl_program *
+_mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog);
+
+static inline struct gl_vertex_program *
+_mesa_clone_vertex_program(struct gl_context *ctx,
+ const struct gl_vertex_program *prog)
+{
+ return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+static inline struct gl_geometry_program *
+_mesa_clone_geometry_program(struct gl_context *ctx,
+ const struct gl_geometry_program *prog)
+{
+ return (struct gl_geometry_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+static inline struct gl_fragment_program *
+_mesa_clone_fragment_program(struct gl_context *ctx,
+ const struct gl_fragment_program *prog)
+{
+ return (struct gl_fragment_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+
+extern GLboolean
+_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count);
+
+extern GLboolean
+_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count);
+
+extern struct gl_program *
+_mesa_combine_programs(struct gl_context *ctx,
+ const struct gl_program *progA,
+ const struct gl_program *progB);
+
+extern void
+_mesa_find_used_registers(const struct gl_program *prog,
+ gl_register_file file,
+ GLboolean used[], GLuint usedSize);
+
+extern GLint
+_mesa_find_free_register(const GLboolean used[],
+ GLuint maxRegs, GLuint firstReg);
+
+
+extern GLboolean
+_mesa_valid_register_index(const struct gl_context *ctx,
+ gl_shader_stage shaderType,
+ gl_register_file file, GLint index);
+
+extern void
+_mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog);
+
+extern GLint
+_mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
+ const struct gl_fragment_program *prog,
+ bool ignore_sample_qualifier);
+
+static inline GLuint
+_mesa_program_enum_to_shader_stage(GLenum v)
+{
+ switch (v) {
+ case GL_VERTEX_PROGRAM_ARB:
+ return MESA_SHADER_VERTEX;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ return MESA_SHADER_FRAGMENT;
+ case GL_GEOMETRY_PROGRAM_NV:
+ return MESA_SHADER_GEOMETRY;
+ case GL_COMPUTE_PROGRAM_NV:
+ return MESA_SHADER_COMPUTE;
+ default:
+ ASSERT(0);
+ return ~0;
+ }
+}
+
+
+static inline GLenum
+_mesa_shader_stage_to_program(unsigned stage)
+{
+ switch (stage) {
+ case MESA_SHADER_VERTEX:
+ return GL_VERTEX_PROGRAM_ARB;
+ case MESA_SHADER_FRAGMENT:
+ return GL_FRAGMENT_PROGRAM_ARB;
+ case MESA_SHADER_GEOMETRY:
+ return GL_GEOMETRY_PROGRAM_NV;
+ case MESA_SHADER_COMPUTE:
+ return GL_COMPUTE_PROGRAM_NV;
+ }
+
+ assert(!"Unexpected shader stage in _mesa_shader_stage_to_program");
+ return GL_VERTEX_PROGRAM_ARB;
+}
+
+
+/* Cast wrappers from gl_program to gl_vertex/geometry/fragment_program */
+
+static inline struct gl_fragment_program *
+gl_fragment_program(struct gl_program *prog)
+{
+ return (struct gl_fragment_program *) prog;
+}
+
+static inline const struct gl_fragment_program *
+gl_fragment_program_const(const struct gl_program *prog)
+{
+ return (const struct gl_fragment_program *) prog;
+}
+
+
+static inline struct gl_vertex_program *
+gl_vertex_program(struct gl_program *prog)
+{
+ return (struct gl_vertex_program *) prog;
+}
+
+static inline const struct gl_vertex_program *
+gl_vertex_program_const(const struct gl_program *prog)
+{
+ return (const struct gl_vertex_program *) prog;
+}
+
+
+static inline struct gl_geometry_program *
+gl_geometry_program(struct gl_program *prog)
+{
+ return (struct gl_geometry_program *) prog;
+}
+
+static inline const struct gl_geometry_program *
+gl_geometry_program_const(const struct gl_program *prog)
+{
+ return (const struct gl_geometry_program *) prog;
+}
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PROGRAM_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program_lexer.l b/icd/intel/compiler/mesa-utils/src/mesa/program/program_lexer.l
new file mode 100644
index 0000000..d5dbcf3
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program_lexer.l
@@ -0,0 +1,508 @@
+%{
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "program/prog_instruction.h"
+#include "program/prog_statevars.h"
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+#include "program/program_parse.tab.h"
+
+#define require_ARB_vp (yyextra->mode == ARB_vertex)
+#define require_ARB_fp (yyextra->mode == ARB_fragment)
+#define require_NV_fp (yyextra->option.NV_fragment)
+#define require_shadow (yyextra->option.Shadow)
+#define require_rect (yyextra->option.TexRect)
+#define require_texarray (yyextra->option.TexArray)
+
+#ifndef HAVE_UNISTD_H
+#define YY_NO_UNISTD_H
+#endif
+
+#define return_token_or_IDENTIFIER(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ return handle_ident(yyextra, yytext, yylval); \
+ } \
+ } while (0)
+
+#define return_token_or_DOT(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ yyless(1); \
+ return DOT; \
+ } \
+ } while (0)
+
+
+#define return_opcode(condition, token, opcode, len) \
+ do { \
+ if (condition && \
+ _mesa_parse_instruction_suffix(yyextra, \
+ yytext + len, \
+ & yylval->temp_inst)) { \
+ yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
+ return token; \
+ } else { \
+ return handle_ident(yyextra, yytext, yylval); \
+ } \
+ } while (0)
+
+#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
+ SWIZZLE_NIL, SWIZZLE_NIL)
+
+static unsigned
+mask_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return WRITEMASK_X;
+ case 'y':
+ case 'g':
+ return WRITEMASK_Y;
+ case 'z':
+ case 'b':
+ return WRITEMASK_Z;
+ case 'w':
+ case 'a':
+ return WRITEMASK_W;
+ }
+
+ return 0;
+}
+
+static unsigned
+swiz_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return SWIZZLE_X;
+ case 'y':
+ case 'g':
+ return SWIZZLE_Y;
+ case 'z':
+ case 'b':
+ return SWIZZLE_Z;
+ case 'w':
+ case 'a':
+ return SWIZZLE_W;
+ }
+
+ return 0;
+}
+
+static int
+handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
+{
+ lval->string = strdup(text);
+
+ return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
+ ? IDENTIFIER : USED_IDENTIFIER;
+}
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->first_column = yylloc->last_column; \
+ yylloc->last_column += yyleng; \
+ if ((yylloc->first_line == 1) \
+ && (yylloc->first_column == 1)) { \
+ yylloc->position = 1; \
+ } else { \
+ yylloc->position += yylloc->last_column - yylloc->first_column; \
+ } \
+ } while(0);
+
+#define YY_NO_INPUT
+
+/* Yes, this is intentionally doing nothing. We have this line of code
+here only to avoid the compiler complaining about an unput function
+that is defined, but never called. */
+#define YY_USER_INIT while (0) { unput(0); }
+
+#define YY_EXTRA_TYPE struct asm_parser_state *
+
+/* Flex defines a couple of functions with no declarations nor the
+static keyword. Declare them here to avoid a compiler warning. */
+int yyget_column (yyscan_t yyscanner);
+void yyset_column (int column_no , yyscan_t yyscanner);
+
+%}
+
+num [0-9]+
+exp [Ee][-+]?[0-9]+
+frac "."[0-9]+
+dot "."[ \t]*
+
+sz [HRX]?
+szf [HR]?
+cc C?
+sat (_SAT)?
+
+%option prefix="_mesa_program_lexer_"
+%option bison-bridge bison-locations reentrant noyywrap
+%%
+
+"!!ARBvp1.0" { return ARBvp_10; }
+"!!ARBfp1.0" { return ARBfp_10; }
+ADDRESS {
+ yylval->integer = at_address;
+ return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
+}
+ALIAS { return ALIAS; }
+ATTRIB { return ATTRIB; }
+END { return END; }
+OPTION { return OPTION; }
+OUTPUT { return OUTPUT; }
+PARAM { return PARAM; }
+TEMP { yylval->integer = at_temp; return TEMP; }
+
+ABS{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); }
+ADD{sz}{cc}{sat} { return_opcode( 1, BIN_OP, ADD, 3); }
+ARL { return_opcode(require_ARB_vp, ARL, ARL, 3); }
+
+CMP{sat} { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
+COS{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
+
+DDX{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); }
+DDY{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
+DP3{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP3, 3); }
+DP4{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP4, 3); }
+DPH{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DPH, 3); }
+DST{szf}{cc}{sat} { return_opcode( 1, BIN_OP, DST, 3); }
+
+EX2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); }
+EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
+
+FLR{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FLR, 3); }
+FRC{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FRC, 3); }
+
+KIL { return_opcode(require_ARB_fp, KIL, KIL, 3); }
+
+LIT{szf}{cc}{sat} { return_opcode( 1, VECTOR_OP, LIT, 3); }
+LG2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); }
+LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
+LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
+
+MAD{sz}{cc}{sat} { return_opcode( 1, TRI_OP, MAD, 3); }
+MAX{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MAX, 3); }
+MIN{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MIN, 3); }
+MOV{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); }
+MUL{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MUL, 3); }
+
+PK2H { return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); }
+PK2US { return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); }
+PK4B { return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); }
+PK4UB { return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); }
+POW{szf}{cc}{sat} { return_opcode( 1, BINSC_OP, POW, 3); }
+
+RCP{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); }
+RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, RFL, 3); }
+RSQ{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RSQ, 3); }
+
+SCS{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
+SEQ{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 3); }
+SFL{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SFL, 3); }
+SGE{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SGE, 3); }
+SGT{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
+SIN{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
+SLE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
+SLT{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SLT, 3); }
+SNE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 3); }
+STR{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, STR, 3); }
+SUB{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SUB, 3); }
+SWZ{sat} { return_opcode( 1, SWZ, SWZ, 3); }
+
+TEX{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
+TXB{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
+TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
+TXP{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
+
+UP2H{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); }
+UP2US{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); }
+UP4B{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); }
+UP4UB{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); }
+
+X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, TRI_OP, X2D, 3); }
+XPD{sat} { return_opcode( 1, BIN_OP, XPD, 3); }
+
+vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
+fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
+program { return PROGRAM; }
+state { return STATE; }
+result { return RESULT; }
+
+{dot}ambient { return AMBIENT; }
+{dot}attenuation { return ATTENUATION; }
+{dot}back { return BACK; }
+{dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); }
+{dot}color { return COLOR; }
+{dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); }
+{dot}diffuse { return DIFFUSE; }
+{dot}direction { return DIRECTION; }
+{dot}emission { return EMISSION; }
+{dot}env { return ENV; }
+{dot}eye { return EYE; }
+{dot}fogcoord { return FOGCOORD; }
+{dot}fog { return FOG; }
+{dot}front { return FRONT; }
+{dot}half { return HALF; }
+{dot}inverse { return INVERSE; }
+{dot}invtrans { return INVTRANS; }
+{dot}light { return LIGHT; }
+{dot}lightmodel { return LIGHTMODEL; }
+{dot}lightprod { return LIGHTPROD; }
+{dot}local { return LOCAL; }
+{dot}material { return MATERIAL; }
+{dot}program { return MAT_PROGRAM; }
+{dot}matrix { return MATRIX; }
+{dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
+{dot}modelview { return MODELVIEW; }
+{dot}mvp { return MVP; }
+{dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); }
+{dot}object { return OBJECT; }
+{dot}palette { return PALETTE; }
+{dot}params { return PARAMS; }
+{dot}plane { return PLANE; }
+{dot}point { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
+{dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
+{dot}position { return POSITION; }
+{dot}primary { return PRIMARY; }
+{dot}projection { return PROJECTION; }
+{dot}range { return_token_or_DOT(require_ARB_fp, RANGE); }
+{dot}row { return ROW; }
+{dot}scenecolor { return SCENECOLOR; }
+{dot}secondary { return SECONDARY; }
+{dot}shininess { return SHININESS; }
+{dot}size { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
+{dot}specular { return SPECULAR; }
+{dot}spot { return SPOT; }
+{dot}texcoord { return TEXCOORD; }
+{dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); }
+{dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); }
+{dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
+{dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
+{dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
+{dot}texture { return TEXTURE; }
+{dot}transpose { return TRANSPOSE; }
+{dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
+{dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); }
+
+texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
+1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
+2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
+3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
+CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
+RECT { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
+SHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
+SHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
+SHADOWRECT { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
+ARRAY1D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
+ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
+ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
+ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
+
+[_a-zA-Z$][_a-zA-Z0-9$]* { return handle_ident(yyextra, yytext, yylval); }
+
+".." { return DOT_DOT; }
+
+{num} {
+ yylval->integer = strtol(yytext, NULL, 10);
+ return INTEGER;
+}
+{num}?{frac}{exp}? {
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+{num}"."/[^.] {
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+{num}{exp} {
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+{num}"."{exp} {
+ yylval->real = _mesa_strtof(yytext, NULL);
+ return REAL;
+}
+
+".xyzw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return MASK4;
+}
+
+".xy"[zw] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return MASK3;
+}
+".xzw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return MASK3;
+}
+".yzw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return MASK3;
+}
+
+".x"[yzw] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+".y"[zw] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+".zw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return MASK2;
+}
+
+"."[xyzw] {
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return MASK1;
+}
+
+"."[xyzw]{4} {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return SWIZZLE;
+}
+
+".rgba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return_token_or_DOT(require_ARB_fp, MASK4);
+}
+
+".rg"[ba] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+".rba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+".gba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+
+".r"[gba] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+".g"[ba] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+".ba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+
+"."[gba] {
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return_token_or_DOT(require_ARB_fp, MASK1);
+}
+
+
+".r" {
+ if (require_ARB_vp) {
+ return TEXGEN_R;
+ } else {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
+ SWIZZLE_X, SWIZZLE_X);
+ yylval->swiz_mask.mask = WRITEMASK_X;
+ return MASK1;
+ }
+}
+
+"."[rgba]{4} {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return_token_or_DOT(require_ARB_fp, SWIZZLE);
+}
+
+"." { return DOT; }
+
+\n {
+ yylloc->first_line++;
+ yylloc->first_column = 1;
+ yylloc->last_line++;
+ yylloc->last_column = 1;
+ yylloc->position++;
+}
+[ \t\r]+ /* eat whitespace */ ;
+#.*$ /* eat comments */ ;
+. { return yytext[0]; }
+%%
+
+void
+_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
+ const char *string, size_t len)
+{
+ yylex_init_extra(state, scanner);
+ yy_scan_bytes(string, len, *scanner);
+}
+
+void
+_mesa_program_lexer_dtor(void *scanner)
+{
+ yylex_destroy(scanner);
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.tab.c b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.tab.c
new file mode 100644
index 0000000..74979fe
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.tab.c
@@ -0,0 +1,5674 @@
+/* A Bison parser, made by GNU Bison 2.7.12-4996. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.7.12-4996"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+/* Substitute the variable and function names. */
+#define yyparse _mesa_program_parse
+#define yylex _mesa_program_lex
+#define yyerror _mesa_program_error
+#define yylval _mesa_program_lval
+#define yychar _mesa_program_char
+#define yydebug _mesa_program_debug
+#define yynerrs _mesa_program_nerrs
+#define yylloc _mesa_program_lloc
+
+/* Copy the first part of user declarations. */
+/* Line 371 of yacc.c */
+#line 1 "program/program_parse.y"
+
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_parameter_layout.h"
+#include "program/prog_statevars.h"
+#include "program/prog_instruction.h"
+
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+
+extern void *yy_scan_string(char *);
+extern void yy_delete_buffer(void *);
+
+static struct asm_symbol *declare_variable(struct asm_parser_state *state,
+ char *name, enum asm_type t, struct YYLTYPE *locp);
+
+static int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var, const struct asm_vector *vec,
+ GLboolean allowSwizzle);
+
+static int yyparse(struct asm_parser_state *state);
+
+static char *make_error_string(const char *fmt, ...);
+
+static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
+ const char *s);
+
+static int validate_inputs(struct YYLTYPE *locp,
+ struct asm_parser_state *state);
+
+static void init_dst_reg(struct prog_dst_register *r);
+
+static void set_dst_reg(struct prog_dst_register *r,
+ gl_register_file file, GLint index);
+
+static void init_src_reg(struct asm_src_register *r);
+
+static void set_src_reg(struct asm_src_register *r,
+ gl_register_file file, GLint index);
+
+static void set_src_reg_swz(struct asm_src_register *r,
+ gl_register_file file, GLint index, GLuint swizzle);
+
+static void asm_instruction_set_operands(struct asm_instruction *inst,
+ const struct prog_dst_register *dst, const struct asm_src_register *src0,
+ const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst, const struct asm_src_register *src0,
+ const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_copy_ctor(
+ const struct prog_instruction *base, const struct prog_dst_register *dst,
+ const struct asm_src_register *src0, const struct asm_src_register *src1,
+ const struct asm_src_register *src2);
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (N) { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 1).position; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
+ } else { \
+ (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).last_line = (Current).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \
+ (Current).last_column = (Current).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 0).position \
+ + (Current).first_column; \
+ } \
+ } while(0)
+
+/* Line 371 of yacc.c */
+#line 193 "./program/program_parse.tab.c"
+
+# ifndef YY_NULL
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULL nullptr
+# else
+# define YY_NULL 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "program_parse.tab.h". */
+#ifndef YY__MESA_PROGRAM_PROGRAM_PROGRAM_PARSE_TAB_H_INCLUDED
+# define YY__MESA_PROGRAM_PROGRAM_PROGRAM_PARSE_TAB_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int _mesa_program_debug;
+#endif
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ARBvp_10 = 258,
+ ARBfp_10 = 259,
+ ADDRESS = 260,
+ ALIAS = 261,
+ ATTRIB = 262,
+ OPTION = 263,
+ OUTPUT = 264,
+ PARAM = 265,
+ TEMP = 266,
+ END = 267,
+ BIN_OP = 268,
+ BINSC_OP = 269,
+ SAMPLE_OP = 270,
+ SCALAR_OP = 271,
+ TRI_OP = 272,
+ VECTOR_OP = 273,
+ ARL = 274,
+ KIL = 275,
+ SWZ = 276,
+ TXD_OP = 277,
+ INTEGER = 278,
+ REAL = 279,
+ AMBIENT = 280,
+ ATTENUATION = 281,
+ BACK = 282,
+ CLIP = 283,
+ COLOR = 284,
+ DEPTH = 285,
+ DIFFUSE = 286,
+ DIRECTION = 287,
+ EMISSION = 288,
+ ENV = 289,
+ EYE = 290,
+ FOG = 291,
+ FOGCOORD = 292,
+ FRAGMENT = 293,
+ FRONT = 294,
+ HALF = 295,
+ INVERSE = 296,
+ INVTRANS = 297,
+ LIGHT = 298,
+ LIGHTMODEL = 299,
+ LIGHTPROD = 300,
+ LOCAL = 301,
+ MATERIAL = 302,
+ MAT_PROGRAM = 303,
+ MATRIX = 304,
+ MATRIXINDEX = 305,
+ MODELVIEW = 306,
+ MVP = 307,
+ NORMAL = 308,
+ OBJECT = 309,
+ PALETTE = 310,
+ PARAMS = 311,
+ PLANE = 312,
+ POINT_TOK = 313,
+ POINTSIZE = 314,
+ POSITION = 315,
+ PRIMARY = 316,
+ PROGRAM = 317,
+ PROJECTION = 318,
+ RANGE = 319,
+ RESULT = 320,
+ ROW = 321,
+ SCENECOLOR = 322,
+ SECONDARY = 323,
+ SHININESS = 324,
+ SIZE_TOK = 325,
+ SPECULAR = 326,
+ SPOT = 327,
+ STATE = 328,
+ TEXCOORD = 329,
+ TEXENV = 330,
+ TEXGEN = 331,
+ TEXGEN_Q = 332,
+ TEXGEN_R = 333,
+ TEXGEN_S = 334,
+ TEXGEN_T = 335,
+ TEXTURE = 336,
+ TRANSPOSE = 337,
+ TEXTURE_UNIT = 338,
+ TEX_1D = 339,
+ TEX_2D = 340,
+ TEX_3D = 341,
+ TEX_CUBE = 342,
+ TEX_RECT = 343,
+ TEX_SHADOW1D = 344,
+ TEX_SHADOW2D = 345,
+ TEX_SHADOWRECT = 346,
+ TEX_ARRAY1D = 347,
+ TEX_ARRAY2D = 348,
+ TEX_ARRAYSHADOW1D = 349,
+ TEX_ARRAYSHADOW2D = 350,
+ VERTEX = 351,
+ VTXATTRIB = 352,
+ WEIGHT = 353,
+ IDENTIFIER = 354,
+ USED_IDENTIFIER = 355,
+ MASK4 = 356,
+ MASK3 = 357,
+ MASK2 = 358,
+ MASK1 = 359,
+ SWIZZLE = 360,
+ DOT_DOT = 361,
+ DOT = 362
+ };
+#endif
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+/* Line 387 of yacc.c */
+#line 124 "program/program_parse.y"
+
+ struct asm_instruction *inst;
+ struct asm_symbol *sym;
+ struct asm_symbol temp_sym;
+ struct asm_swizzle_mask swiz_mask;
+ struct asm_src_register src_reg;
+ struct prog_dst_register dst_reg;
+ struct prog_instruction temp_inst;
+ char *string;
+ unsigned result;
+ unsigned attrib;
+ int integer;
+ float real;
+ gl_state_index state[STATE_LENGTH];
+ int negate;
+ struct asm_vector vector;
+ gl_inst_opcode opcode;
+
+ struct {
+ unsigned swz;
+ unsigned rgba_valid:1;
+ unsigned xyzw_valid:1;
+ unsigned negate:1;
+ } ext_swizzle;
+
+
+/* Line 387 of yacc.c */
+#line 370 "./program/program_parse.tab.c"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int _mesa_program_parse (void *YYPARSE_PARAM);
+#else
+int _mesa_program_parse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int _mesa_program_parse (struct asm_parser_state *state);
+#else
+int _mesa_program_parse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY__MESA_PROGRAM_PROGRAM_PROGRAM_PARSE_TAB_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+/* Line 390 of yacc.c */
+#line 269 "program/program_parse.y"
+
+extern int
+_mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ void *yyscanner);
+
+static int
+yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ struct asm_parser_state *state)
+{
+ return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner);
+}
+
+/* Line 390 of yacc.c */
+#line 423 "./program/program_parse.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if (! defined __GNUC__ || __GNUC__ < 2 \
+ || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
+# define __attribute__(Spec) /* empty */
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(N) (N)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 5
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 402
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 120
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 143
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 283
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 478
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 362
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 115, 116, 2, 113, 109, 114, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 108,
+ 2, 117, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 111, 2, 112, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 118, 110, 119, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 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,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 8, 10, 12, 15, 16, 20, 23,
+ 24, 27, 30, 32, 34, 36, 38, 40, 42, 44,
+ 46, 48, 50, 52, 54, 59, 64, 69, 76, 83,
+ 92, 101, 104, 107, 120, 123, 125, 127, 129, 131,
+ 133, 135, 137, 139, 141, 143, 145, 147, 154, 157,
+ 162, 165, 167, 171, 177, 181, 184, 192, 195, 197,
+ 199, 201, 203, 208, 210, 212, 214, 216, 218, 220,
+ 222, 226, 227, 230, 233, 235, 237, 239, 241, 243,
+ 245, 247, 249, 251, 252, 254, 256, 258, 260, 261,
+ 265, 269, 270, 273, 276, 278, 280, 282, 284, 286,
+ 288, 290, 292, 297, 300, 303, 305, 308, 310, 313,
+ 315, 318, 323, 328, 330, 331, 335, 337, 339, 342,
+ 344, 347, 349, 351, 355, 362, 363, 365, 368, 373,
+ 375, 379, 381, 383, 385, 387, 389, 391, 393, 395,
+ 397, 399, 402, 405, 408, 411, 414, 417, 420, 423,
+ 426, 429, 432, 435, 439, 441, 443, 445, 451, 453,
+ 455, 457, 460, 462, 464, 467, 469, 472, 479, 481,
+ 485, 487, 489, 491, 493, 495, 500, 502, 504, 506,
+ 508, 510, 512, 515, 517, 519, 525, 527, 530, 532,
+ 534, 540, 543, 544, 551, 555, 556, 558, 560, 562,
+ 564, 566, 569, 571, 573, 576, 581, 586, 587, 591,
+ 593, 595, 597, 600, 602, 604, 606, 608, 614, 616,
+ 620, 626, 632, 634, 638, 644, 646, 648, 650, 652,
+ 654, 656, 658, 660, 662, 666, 672, 680, 690, 693,
+ 696, 698, 700, 701, 702, 707, 709, 710, 711, 715,
+ 719, 721, 727, 730, 733, 736, 739, 743, 746, 750,
+ 751, 755, 757, 759, 760, 762, 764, 765, 767, 769,
+ 770, 772, 774, 775, 779, 780, 784, 785, 789, 791,
+ 793, 795, 800, 802
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 121, 0, -1, 122, 123, 125, 12, -1, 3, -1,
+ 4, -1, 123, 124, -1, -1, 8, 262, 108, -1,
+ 125, 126, -1, -1, 127, 108, -1, 170, 108, -1,
+ 128, -1, 129, -1, 130, -1, 131, -1, 132, -1,
+ 133, -1, 134, -1, 135, -1, 141, -1, 136, -1,
+ 137, -1, 138, -1, 19, 146, 109, 142, -1, 18,
+ 145, 109, 144, -1, 16, 145, 109, 142, -1, 14,
+ 145, 109, 142, 109, 142, -1, 13, 145, 109, 144,
+ 109, 144, -1, 17, 145, 109, 144, 109, 144, 109,
+ 144, -1, 15, 145, 109, 144, 109, 139, 109, 140,
+ -1, 20, 144, -1, 20, 166, -1, 22, 145, 109,
+ 144, 109, 144, 109, 144, 109, 139, 109, 140, -1,
+ 83, 256, -1, 84, -1, 85, -1, 86, -1, 87,
+ -1, 88, -1, 89, -1, 90, -1, 91, -1, 92,
+ -1, 93, -1, 94, -1, 95, -1, 21, 145, 109,
+ 150, 109, 147, -1, 241, 143, -1, 241, 110, 143,
+ 110, -1, 150, 162, -1, 238, -1, 241, 150, 163,
+ -1, 241, 110, 150, 163, 110, -1, 151, 164, 165,
+ -1, 159, 161, -1, 148, 109, 148, 109, 148, 109,
+ 148, -1, 241, 149, -1, 23, -1, 262, -1, 100,
+ -1, 172, -1, 152, 111, 153, 112, -1, 186, -1,
+ 249, -1, 100, -1, 100, -1, 154, -1, 155, -1,
+ 23, -1, 159, 160, 156, -1, -1, 113, 157, -1,
+ 114, 158, -1, 23, -1, 23, -1, 100, -1, 104,
+ -1, 104, -1, 104, -1, 104, -1, 101, -1, 105,
+ -1, -1, 101, -1, 102, -1, 103, -1, 104, -1,
+ -1, 115, 166, 116, -1, 115, 167, 116, -1, -1,
+ 168, 163, -1, 169, 163, -1, 99, -1, 100, -1,
+ 171, -1, 178, -1, 242, -1, 245, -1, 248, -1,
+ 261, -1, 7, 99, 117, 172, -1, 96, 173, -1,
+ 38, 177, -1, 60, -1, 98, 175, -1, 53, -1,
+ 29, 254, -1, 37, -1, 74, 255, -1, 50, 111,
+ 176, 112, -1, 97, 111, 174, 112, -1, 23, -1,
+ -1, 111, 176, 112, -1, 23, -1, 60, -1, 29,
+ 254, -1, 37, -1, 74, 255, -1, 179, -1, 180,
+ -1, 10, 99, 182, -1, 10, 99, 111, 181, 112,
+ 183, -1, -1, 23, -1, 117, 185, -1, 117, 118,
+ 184, 119, -1, 187, -1, 184, 109, 187, -1, 189,
+ -1, 225, -1, 235, -1, 189, -1, 225, -1, 236,
+ -1, 188, -1, 226, -1, 235, -1, 189, -1, 73,
+ 213, -1, 73, 190, -1, 73, 192, -1, 73, 195,
+ -1, 73, 197, -1, 73, 203, -1, 73, 199, -1,
+ 73, 206, -1, 73, 208, -1, 73, 210, -1, 73,
+ 212, -1, 73, 224, -1, 47, 253, 191, -1, 201,
+ -1, 33, -1, 69, -1, 43, 111, 202, 112, 193,
+ -1, 201, -1, 60, -1, 26, -1, 72, 194, -1,
+ 40, -1, 32, -1, 44, 196, -1, 25, -1, 253,
+ 67, -1, 45, 111, 202, 112, 253, 198, -1, 201,
+ -1, 75, 257, 200, -1, 29, -1, 25, -1, 31,
+ -1, 71, -1, 23, -1, 76, 255, 204, 205, -1,
+ 35, -1, 54, -1, 79, -1, 80, -1, 78, -1,
+ 77, -1, 36, 207, -1, 29, -1, 56, -1, 28,
+ 111, 209, 112, 57, -1, 23, -1, 58, 211, -1,
+ 70, -1, 26, -1, 215, 66, 111, 218, 112, -1,
+ 215, 214, -1, -1, 66, 111, 218, 106, 218, 112,
+ -1, 49, 219, 216, -1, -1, 217, -1, 41, -1,
+ 82, -1, 42, -1, 23, -1, 51, 220, -1, 63,
+ -1, 52, -1, 81, 255, -1, 55, 111, 222, 112,
+ -1, 48, 111, 223, 112, -1, -1, 111, 221, 112,
+ -1, 23, -1, 23, -1, 23, -1, 30, 64, -1,
+ 229, -1, 232, -1, 227, -1, 230, -1, 62, 34,
+ 111, 228, 112, -1, 233, -1, 233, 106, 233, -1,
+ 62, 34, 111, 233, 112, -1, 62, 46, 111, 231,
+ 112, -1, 234, -1, 234, 106, 234, -1, 62, 46,
+ 111, 234, 112, -1, 23, -1, 23, -1, 237, -1,
+ 239, -1, 238, -1, 239, -1, 240, -1, 24, -1,
+ 23, -1, 118, 240, 119, -1, 118, 240, 109, 240,
+ 119, -1, 118, 240, 109, 240, 109, 240, 119, -1,
+ 118, 240, 109, 240, 109, 240, 109, 240, 119, -1,
+ 241, 24, -1, 241, 23, -1, 113, -1, 114, -1,
+ -1, -1, 244, 11, 243, 247, -1, 262, -1, -1,
+ -1, 5, 246, 247, -1, 247, 109, 99, -1, 99,
+ -1, 244, 9, 99, 117, 249, -1, 65, 60, -1,
+ 65, 37, -1, 65, 250, -1, 65, 59, -1, 65,
+ 74, 255, -1, 65, 30, -1, 29, 251, 252, -1,
+ -1, 111, 23, 112, -1, 39, -1, 27, -1, -1,
+ 61, -1, 68, -1, -1, 39, -1, 27, -1, -1,
+ 61, -1, 68, -1, -1, 111, 258, 112, -1, -1,
+ 111, 259, 112, -1, -1, 111, 260, 112, -1, 23,
+ -1, 23, -1, 23, -1, 6, 99, 117, 100, -1,
+ 99, -1, 100, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 284, 284, 287, 295, 307, 308, 311, 335, 336,
+ 339, 354, 357, 362, 369, 370, 371, 372, 373, 374,
+ 375, 378, 379, 380, 383, 389, 397, 403, 410, 416,
+ 423, 467, 472, 481, 525, 531, 532, 533, 534, 535,
+ 536, 537, 538, 539, 540, 541, 542, 545, 557, 565,
+ 582, 589, 608, 619, 639, 663, 670, 703, 710, 726,
+ 785, 828, 837, 859, 869, 873, 902, 921, 921, 923,
+ 930, 942, 943, 944, 947, 961, 975, 995, 1006, 1018,
+ 1020, 1021, 1022, 1023, 1026, 1026, 1026, 1026, 1027, 1030,
+ 1034, 1039, 1045, 1052, 1059, 1081, 1103, 1104, 1105, 1106,
+ 1107, 1108, 1111, 1130, 1134, 1140, 1144, 1148, 1152, 1156,
+ 1160, 1164, 1169, 1175, 1186, 1186, 1187, 1189, 1193, 1197,
+ 1201, 1207, 1207, 1209, 1227, 1253, 1256, 1271, 1277, 1283,
+ 1284, 1291, 1297, 1303, 1311, 1317, 1323, 1331, 1337, 1343,
+ 1351, 1352, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362,
+ 1363, 1364, 1365, 1368, 1377, 1381, 1385, 1391, 1400, 1404,
+ 1408, 1417, 1421, 1427, 1433, 1440, 1445, 1453, 1463, 1465,
+ 1473, 1479, 1483, 1487, 1493, 1504, 1513, 1517, 1522, 1526,
+ 1530, 1534, 1540, 1547, 1551, 1557, 1565, 1576, 1583, 1587,
+ 1593, 1603, 1614, 1618, 1636, 1645, 1648, 1654, 1658, 1662,
+ 1668, 1679, 1684, 1689, 1694, 1699, 1704, 1712, 1715, 1720,
+ 1733, 1741, 1752, 1760, 1760, 1762, 1762, 1764, 1774, 1779,
+ 1786, 1796, 1805, 1810, 1817, 1827, 1837, 1849, 1849, 1850,
+ 1850, 1852, 1862, 1870, 1880, 1888, 1896, 1905, 1916, 1920,
+ 1926, 1927, 1928, 1931, 1931, 1934, 1969, 1973, 1973, 1976,
+ 1983, 1992, 2006, 2015, 2024, 2028, 2037, 2046, 2057, 2064,
+ 2074, 2102, 2111, 2123, 2126, 2135, 2146, 2147, 2148, 2151,
+ 2152, 2153, 2156, 2157, 2160, 2161, 2164, 2165, 2168, 2179,
+ 2190, 2201, 2227, 2228
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 1
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "ARBvp_10", "ARBfp_10", "ADDRESS",
+ "ALIAS", "ATTRIB", "OPTION", "OUTPUT", "PARAM", "TEMP", "END", "BIN_OP",
+ "BINSC_OP", "SAMPLE_OP", "SCALAR_OP", "TRI_OP", "VECTOR_OP", "ARL",
+ "KIL", "SWZ", "TXD_OP", "INTEGER", "REAL", "AMBIENT", "ATTENUATION",
+ "BACK", "CLIP", "COLOR", "DEPTH", "DIFFUSE", "DIRECTION", "EMISSION",
+ "ENV", "EYE", "FOG", "FOGCOORD", "FRAGMENT", "FRONT", "HALF", "INVERSE",
+ "INVTRANS", "LIGHT", "LIGHTMODEL", "LIGHTPROD", "LOCAL", "MATERIAL",
+ "MAT_PROGRAM", "MATRIX", "MATRIXINDEX", "MODELVIEW", "MVP", "NORMAL",
+ "OBJECT", "PALETTE", "PARAMS", "PLANE", "POINT_TOK", "POINTSIZE",
+ "POSITION", "PRIMARY", "PROGRAM", "PROJECTION", "RANGE", "RESULT", "ROW",
+ "SCENECOLOR", "SECONDARY", "SHININESS", "SIZE_TOK", "SPECULAR", "SPOT",
+ "STATE", "TEXCOORD", "TEXENV", "TEXGEN", "TEXGEN_Q", "TEXGEN_R",
+ "TEXGEN_S", "TEXGEN_T", "TEXTURE", "TRANSPOSE", "TEXTURE_UNIT", "TEX_1D",
+ "TEX_2D", "TEX_3D", "TEX_CUBE", "TEX_RECT", "TEX_SHADOW1D",
+ "TEX_SHADOW2D", "TEX_SHADOWRECT", "TEX_ARRAY1D", "TEX_ARRAY2D",
+ "TEX_ARRAYSHADOW1D", "TEX_ARRAYSHADOW2D", "VERTEX", "VTXATTRIB",
+ "WEIGHT", "IDENTIFIER", "USED_IDENTIFIER", "MASK4", "MASK3", "MASK2",
+ "MASK1", "SWIZZLE", "DOT_DOT", "DOT", "';'", "','", "'|'", "'['", "']'",
+ "'+'", "'-'", "'('", "')'", "'='", "'{'", "'}'", "$accept", "program",
+ "language", "optionSequence", "option", "statementSequence", "statement",
+ "instruction", "ALU_instruction", "TexInstruction", "ARL_instruction",
+ "VECTORop_instruction", "SCALARop_instruction", "BINSCop_instruction",
+ "BINop_instruction", "TRIop_instruction", "SAMPLE_instruction",
+ "KIL_instruction", "TXD_instruction", "texImageUnit", "texTarget",
+ "SWZ_instruction", "scalarSrcReg", "scalarUse", "swizzleSrcReg",
+ "maskedDstReg", "maskedAddrReg", "extendedSwizzle", "extSwizComp",
+ "extSwizSel", "srcReg", "dstReg", "progParamArray", "progParamArrayMem",
+ "progParamArrayAbs", "progParamArrayRel", "addrRegRelOffset",
+ "addrRegPosOffset", "addrRegNegOffset", "addrReg", "addrComponent",
+ "addrWriteMask", "scalarSuffix", "swizzleSuffix", "optionalMask",
+ "optionalCcMask", "ccTest", "ccTest2", "ccMaskRule", "ccMaskRule2",
+ "namingStatement", "ATTRIB_statement", "attribBinding", "vtxAttribItem",
+ "vtxAttribNum", "vtxOptWeightNum", "vtxWeightNum", "fragAttribItem",
+ "PARAM_statement", "PARAM_singleStmt", "PARAM_multipleStmt",
+ "optArraySize", "paramSingleInit", "paramMultipleInit",
+ "paramMultInitList", "paramSingleItemDecl", "paramSingleItemUse",
+ "paramMultipleItem", "stateMultipleItem", "stateSingleItem",
+ "stateMaterialItem", "stateMatProperty", "stateLightItem",
+ "stateLightProperty", "stateSpotProperty", "stateLightModelItem",
+ "stateLModProperty", "stateLightProdItem", "stateLProdProperty",
+ "stateTexEnvItem", "stateTexEnvProperty", "ambDiffSpecProperty",
+ "stateLightNumber", "stateTexGenItem", "stateTexGenType",
+ "stateTexGenCoord", "stateFogItem", "stateFogProperty",
+ "stateClipPlaneItem", "stateClipPlaneNum", "statePointItem",
+ "statePointProperty", "stateMatrixRow", "stateMatrixRows",
+ "optMatrixRows", "stateMatrixItem", "stateOptMatModifier",
+ "stateMatModifier", "stateMatrixRowNum", "stateMatrixName",
+ "stateOptModMatNum", "stateModMatNum", "statePaletteMatNum",
+ "stateProgramMatNum", "stateDepthItem", "programSingleItem",
+ "programMultipleItem", "progEnvParams", "progEnvParamNums",
+ "progEnvParam", "progLocalParams", "progLocalParamNums",
+ "progLocalParam", "progEnvParamNum", "progLocalParamNum",
+ "paramConstDecl", "paramConstUse", "paramConstScalarDecl",
+ "paramConstScalarUse", "paramConstVector", "signedFloatConstant",
+ "optionalSign", "TEMP_statement", "@1", "optVarSize",
+ "ADDRESS_statement", "@2", "varNameList", "OUTPUT_statement",
+ "resultBinding", "resultColBinding", "optResultFaceType",
+ "optResultColorType", "optFaceType", "optColorType",
+ "optTexCoordUnitNum", "optTexImageUnitNum", "optLegacyTexUnitNum",
+ "texCoordUnitNum", "texImageUnitNum", "legacyTexUnitNum",
+ "ALIAS_statement", "string", YY_NULL
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 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, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 59, 44,
+ 124, 91, 93, 43, 45, 40, 41, 61, 123, 125
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint16 yyr1[] =
+{
+ 0, 120, 121, 122, 122, 123, 123, 124, 125, 125,
+ 126, 126, 127, 127, 128, 128, 128, 128, 128, 128,
+ 128, 129, 129, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 137, 138, 139, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 141, 142, 142,
+ 143, 143, 144, 144, 145, 146, 147, 148, 149, 149,
+ 150, 150, 150, 150, 151, 151, 152, 153, 153, 154,
+ 155, 156, 156, 156, 157, 158, 159, 160, 161, 162,
+ 163, 163, 163, 163, 164, 164, 164, 164, 164, 165,
+ 165, 165, 166, 167, 168, 169, 170, 170, 170, 170,
+ 170, 170, 171, 172, 172, 173, 173, 173, 173, 173,
+ 173, 173, 173, 174, 175, 175, 176, 177, 177, 177,
+ 177, 178, 178, 179, 180, 181, 181, 182, 183, 184,
+ 184, 185, 185, 185, 186, 186, 186, 187, 187, 187,
+ 188, 188, 189, 189, 189, 189, 189, 189, 189, 189,
+ 189, 189, 189, 190, 191, 191, 191, 192, 193, 193,
+ 193, 193, 193, 194, 195, 196, 196, 197, 198, 199,
+ 200, 201, 201, 201, 202, 203, 204, 204, 205, 205,
+ 205, 205, 206, 207, 207, 208, 209, 210, 211, 211,
+ 212, 213, 214, 214, 215, 216, 216, 217, 217, 217,
+ 218, 219, 219, 219, 219, 219, 219, 220, 220, 221,
+ 222, 223, 224, 225, 225, 226, 226, 227, 228, 228,
+ 229, 230, 231, 231, 232, 233, 234, 235, 235, 236,
+ 236, 237, 238, 238, 239, 239, 239, 239, 240, 240,
+ 241, 241, 241, 243, 242, 244, 244, 246, 245, 247,
+ 247, 248, 249, 249, 249, 249, 249, 249, 250, 251,
+ 251, 251, 251, 252, 252, 252, 253, 253, 253, 254,
+ 254, 254, 255, 255, 256, 256, 257, 257, 258, 259,
+ 260, 261, 262, 262
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 4, 1, 1, 2, 0, 3, 2, 0,
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 4, 4, 4, 6, 6, 8,
+ 8, 2, 2, 12, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 6, 2, 4,
+ 2, 1, 3, 5, 3, 2, 7, 2, 1, 1,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 3, 0, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 1, 1, 1, 1, 0, 3,
+ 3, 0, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 4, 2, 2, 1, 2, 1, 2, 1,
+ 2, 4, 4, 1, 0, 3, 1, 1, 2, 1,
+ 2, 1, 1, 3, 6, 0, 1, 2, 4, 1,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 3, 1, 1, 1, 5, 1, 1,
+ 1, 2, 1, 1, 2, 1, 2, 6, 1, 3,
+ 1, 1, 1, 1, 1, 4, 1, 1, 1, 1,
+ 1, 1, 2, 1, 1, 5, 1, 2, 1, 1,
+ 5, 2, 0, 6, 3, 0, 1, 1, 1, 1,
+ 1, 2, 1, 1, 2, 4, 4, 0, 3, 1,
+ 1, 1, 2, 1, 1, 1, 1, 5, 1, 3,
+ 5, 5, 1, 3, 5, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 5, 7, 9, 2, 2,
+ 1, 1, 0, 0, 4, 1, 0, 0, 3, 3,
+ 1, 5, 2, 2, 2, 2, 3, 2, 3, 0,
+ 3, 1, 1, 0, 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 3, 0, 3, 0, 3, 1, 1,
+ 1, 4, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 0, 3, 4, 0, 6, 1, 9, 0, 5, 246,
+ 282, 283, 0, 247, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 242, 0, 0, 8, 0,
+ 12, 13, 14, 15, 16, 17, 18, 19, 21, 22,
+ 23, 20, 0, 96, 97, 121, 122, 98, 0, 99,
+ 100, 101, 245, 7, 0, 0, 0, 0, 0, 65,
+ 0, 88, 64, 0, 0, 0, 0, 0, 76, 0,
+ 0, 94, 240, 241, 31, 32, 83, 0, 0, 0,
+ 10, 11, 0, 243, 250, 248, 0, 0, 125, 242,
+ 123, 259, 257, 253, 255, 252, 272, 254, 242, 84,
+ 85, 86, 87, 91, 242, 242, 242, 242, 242, 242,
+ 78, 55, 81, 80, 82, 92, 233, 232, 0, 0,
+ 0, 0, 60, 0, 242, 83, 0, 61, 63, 134,
+ 135, 213, 214, 136, 229, 230, 0, 242, 0, 0,
+ 0, 281, 102, 126, 0, 127, 131, 132, 133, 227,
+ 228, 231, 0, 262, 261, 0, 263, 0, 256, 0,
+ 0, 54, 0, 0, 0, 26, 0, 25, 24, 269,
+ 119, 117, 272, 104, 0, 0, 0, 0, 0, 0,
+ 266, 0, 266, 0, 0, 276, 272, 142, 143, 144,
+ 145, 147, 146, 148, 149, 150, 151, 0, 152, 269,
+ 109, 0, 107, 105, 272, 0, 114, 103, 83, 0,
+ 52, 0, 0, 0, 0, 244, 249, 0, 239, 238,
+ 0, 264, 265, 258, 278, 0, 242, 95, 0, 0,
+ 83, 242, 0, 48, 0, 51, 0, 242, 270, 271,
+ 118, 120, 0, 0, 0, 212, 183, 184, 182, 0,
+ 165, 268, 267, 164, 0, 0, 0, 0, 207, 203,
+ 0, 202, 272, 195, 189, 188, 187, 0, 0, 0,
+ 0, 108, 0, 110, 0, 0, 106, 0, 242, 234,
+ 69, 0, 67, 68, 0, 242, 242, 251, 0, 124,
+ 260, 273, 28, 89, 90, 93, 27, 0, 79, 50,
+ 274, 0, 0, 225, 0, 226, 0, 186, 0, 174,
+ 0, 166, 0, 171, 172, 155, 156, 173, 153, 154,
+ 0, 0, 201, 0, 204, 197, 199, 198, 194, 196,
+ 280, 0, 170, 169, 176, 177, 0, 0, 116, 0,
+ 113, 0, 0, 53, 0, 62, 77, 71, 47, 0,
+ 0, 0, 242, 49, 0, 34, 0, 242, 220, 224,
+ 0, 0, 266, 211, 0, 209, 0, 210, 0, 277,
+ 181, 180, 178, 179, 175, 200, 0, 111, 112, 115,
+ 242, 235, 0, 0, 70, 242, 58, 57, 59, 242,
+ 0, 0, 0, 129, 137, 140, 138, 215, 216, 139,
+ 279, 0, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 30, 29, 185, 160, 162, 159,
+ 0, 157, 158, 0, 206, 208, 205, 190, 0, 74,
+ 72, 75, 73, 0, 0, 0, 0, 141, 192, 242,
+ 128, 275, 163, 161, 167, 168, 242, 236, 242, 0,
+ 0, 0, 0, 191, 130, 0, 0, 0, 0, 218,
+ 0, 222, 0, 237, 242, 0, 217, 0, 221, 0,
+ 0, 56, 33, 219, 223, 0, 0, 193
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 3, 4, 6, 8, 9, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 301,
+ 414, 41, 162, 233, 74, 60, 69, 348, 349, 387,
+ 234, 61, 126, 281, 282, 283, 384, 430, 432, 70,
+ 347, 111, 299, 115, 103, 161, 75, 229, 76, 230,
+ 42, 43, 127, 207, 341, 276, 339, 173, 44, 45,
+ 46, 144, 90, 289, 392, 145, 128, 393, 394, 129,
+ 187, 318, 188, 421, 443, 189, 253, 190, 444, 191,
+ 333, 319, 310, 192, 336, 374, 193, 248, 194, 308,
+ 195, 266, 196, 437, 453, 197, 328, 329, 376, 263,
+ 322, 366, 368, 364, 198, 130, 396, 397, 458, 131,
+ 398, 460, 132, 304, 306, 399, 133, 149, 134, 135,
+ 151, 77, 47, 139, 48, 49, 54, 85, 50, 62,
+ 97, 156, 223, 254, 240, 158, 355, 268, 225, 401,
+ 331, 51, 12
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -398
+static const yytype_int16 yypact[] =
+{
+ 52, -398, -398, 14, -398, -398, 67, 152, -398, 24,
+ -398, -398, 5, -398, 47, 81, 99, -398, -1, -1,
+ -1, -1, -1, -1, 43, 56, -1, -1, -398, 97,
+ -398, -398, -398, -398, -398, -398, -398, -398, -398, -398,
+ -398, -398, 112, -398, -398, -398, -398, -398, 156, -398,
+ -398, -398, -398, -398, 111, 98, 141, 95, 127, -398,
+ 84, 142, -398, 146, 150, 153, 157, 158, -398, 159,
+ 165, -398, -398, -398, -398, -398, 113, -13, 161, 163,
+ -398, -398, 162, -398, -398, 164, 174, 10, 252, -3,
+ -398, -11, -398, -398, -398, -398, 166, -398, -20, -398,
+ -398, -398, -398, 167, -20, -20, -20, -20, -20, -20,
+ -398, -398, -398, -398, -398, -398, -398, -398, 137, 70,
+ 132, 85, 168, 34, -20, 113, 169, -398, -398, -398,
+ -398, -398, -398, -398, -398, -398, 34, -20, 171, 111,
+ 179, -398, -398, -398, 172, -398, -398, -398, -398, -398,
+ -398, -398, 216, -398, -398, 253, 76, 258, -398, 176,
+ 154, -398, 178, 29, 180, -398, 181, -398, -398, 110,
+ -398, -398, 166, -398, 175, 182, 183, 219, 32, 184,
+ 177, 186, 94, 140, 7, 187, 166, -398, -398, -398,
+ -398, -398, -398, -398, -398, -398, -398, 226, -398, 110,
+ -398, 188, -398, -398, 166, 189, 190, -398, 113, 9,
+ -398, 1, 193, 195, 240, 164, -398, 191, -398, -398,
+ 194, -398, -398, -398, -398, 197, -20, -398, 196, 198,
+ 113, -20, 34, -398, 203, 206, 228, -20, -398, -398,
+ -398, -398, 290, 292, 293, -398, -398, -398, -398, 294,
+ -398, -398, -398, -398, 251, 294, 48, 208, 209, -398,
+ 210, -398, 166, 21, -398, -398, -398, 299, 295, 12,
+ 212, -398, 302, -398, 304, 302, -398, 218, -20, -398,
+ -398, 217, -398, -398, 227, -20, -20, -398, 214, -398,
+ -398, -398, -398, -398, -398, -398, -398, 220, -398, -398,
+ 222, 225, 229, -398, 223, -398, 224, -398, 230, -398,
+ 231, -398, 233, -398, -398, -398, -398, -398, -398, -398,
+ 314, 316, -398, 317, -398, -398, -398, -398, -398, -398,
+ -398, 234, -398, -398, -398, -398, 170, 318, -398, 235,
+ -398, 236, 237, -398, 44, -398, -398, 143, -398, 244,
+ -15, 245, 36, -398, 332, -398, 138, -20, -398, -398,
+ 301, 101, 94, -398, 248, -398, 249, -398, 250, -398,
+ -398, -398, -398, -398, -398, -398, 254, -398, -398, -398,
+ -20, -398, 333, 340, -398, -20, -398, -398, -398, -20,
+ 102, 132, 75, -398, -398, -398, -398, -398, -398, -398,
+ -398, 255, -398, -398, -398, -398, -398, -398, -398, -398,
+ -398, -398, -398, -398, -398, -398, -398, -398, -398, -398,
+ 336, -398, -398, 49, -398, -398, -398, -398, 90, -398,
+ -398, -398, -398, 256, 260, 259, 261, -398, 298, 36,
+ -398, -398, -398, -398, -398, -398, -20, -398, -20, 228,
+ 290, 292, 262, -398, -398, 257, 265, 268, 266, 273,
+ 269, 274, 318, -398, -20, 138, -398, 290, -398, 292,
+ 107, -398, -398, -398, -398, 318, 270, -398
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -398, -398, -398, -398, -398, -398, -398, -398, -398, -398,
+ -398, -398, -398, -398, -398, -398, -398, -398, -398, -78,
+ -82, -398, -100, 155, -86, 215, -398, -398, -372, -398,
+ -54, -398, -398, -398, -398, -398, -398, -398, -398, 173,
+ -398, -398, -398, -118, -398, -398, 232, -398, -398, -398,
+ -398, -398, 303, -398, -398, -398, 114, -398, -398, -398,
+ -398, -398, -398, -398, -398, -398, -398, -53, -398, -88,
+ -398, -398, -398, -398, -398, -398, -398, -398, -398, -398,
+ -398, -334, 130, -398, -398, -398, -398, -398, -398, -398,
+ -398, -398, -398, -398, -398, 0, -398, -398, -397, -398,
+ -398, -398, -398, -398, -398, 305, -398, -398, -398, -398,
+ -398, -398, -398, -396, -383, 306, -398, -398, -137, -87,
+ -120, -89, -398, -398, -398, -398, -398, 263, -398, 185,
+ -398, -398, -398, -177, 199, -154, -398, -398, -398, -398,
+ -398, -398, -6
+};
+
+/* 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 YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -230
+static const yytype_int16 yytable[] =
+{
+ 152, 146, 150, 52, 209, 256, 165, 210, 386, 168,
+ 116, 117, 159, 433, 5, 163, 153, 163, 241, 164,
+ 163, 166, 167, 125, 280, 118, 235, 422, 154, 13,
+ 14, 15, 269, 264, 16, 152, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 334, 118, 119,
+ 273, 213, 116, 117, 459, 1, 2, 116, 117, 119,
+ 120, 246, 325, 326, 58, 470, 335, 118, 461, 208,
+ 120, 473, 118, 313, 313, 7, 456, 265, 476, 314,
+ 314, 315, 212, 121, 10, 11, 474, 122, 247, 445,
+ 277, 119, 471, 72, 73, 235, 119, 123, 390, 59,
+ 155, 68, 120, 327, 174, 124, 121, 120, 324, 391,
+ 72, 73, 295, 53, 199, 124, 175, 316, 278, 317,
+ 317, 251, 200, 10, 11, 121, 313, 417, 279, 122,
+ 121, 296, 314, 252, 122, 201, 435, 221, 202, 232,
+ 292, 418, 163, 68, 222, 203, 55, 124, 436, 72,
+ 73, 302, 124, 380, 124, 71, 91, 92, 344, 204,
+ 176, 419, 177, 381, 93, 82, 169, 83, 178, 72,
+ 73, 238, 317, 420, 170, 179, 180, 181, 239, 182,
+ 56, 183, 205, 206, 439, 423, 94, 95, 257, 152,
+ 184, 258, 259, 98, 440, 260, 350, 171, 57, 446,
+ 351, 96, 250, 261, 251, 80, 88, 185, 186, 447,
+ 84, 172, 89, 475, 112, 86, 252, 113, 114, 427,
+ 81, 262, 402, 403, 404, 405, 406, 407, 408, 409,
+ 410, 411, 412, 413, 63, 64, 65, 66, 67, 218,
+ 219, 78, 79, 99, 100, 101, 102, 370, 371, 372,
+ 373, 10, 11, 71, 227, 104, 382, 383, 87, 105,
+ 428, 138, 106, 152, 395, 150, 107, 108, 109, 110,
+ 136, 415, 137, 140, 141, 143, 220, 157, 216, -66,
+ 211, 224, 160, 245, 217, 226, 242, 231, 214, 236,
+ 237, 152, 270, 243, 244, 249, 350, 255, 267, 272,
+ 274, 275, 285, 434, 286, 58, 290, 298, 288, 291,
+ -229, 300, 293, 303, 294, 305, 307, 309, 311, 320,
+ 321, 323, 330, 337, 332, 338, 455, 340, 343, 345,
+ 353, 346, 352, 354, 356, 358, 359, 363, 357, 365,
+ 367, 375, 360, 361, 388, 362, 369, 377, 378, 379,
+ 152, 395, 150, 385, 389, 400, 429, 152, 416, 350,
+ 424, 425, 426, 431, 452, 448, 427, 441, 442, 449,
+ 450, 457, 451, 462, 464, 350, 463, 465, 466, 467,
+ 469, 468, 477, 472, 284, 312, 454, 297, 0, 342,
+ 142, 438, 228, 0, 147, 148, 0, 0, 271, 287,
+ 0, 0, 215
+};
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-398)))
+
+#define yytable_value_is_error(Yytable_value) \
+ YYID (0)
+
+static const yytype_int16 yycheck[] =
+{
+ 89, 89, 89, 9, 124, 182, 106, 125, 23, 109,
+ 23, 24, 98, 385, 0, 104, 27, 106, 172, 105,
+ 109, 107, 108, 77, 23, 38, 163, 361, 39, 5,
+ 6, 7, 186, 26, 10, 124, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 35, 38, 62,
+ 204, 137, 23, 24, 450, 3, 4, 23, 24, 62,
+ 73, 29, 41, 42, 65, 462, 54, 38, 451, 123,
+ 73, 467, 38, 25, 25, 8, 448, 70, 475, 31,
+ 31, 33, 136, 96, 99, 100, 469, 100, 56, 423,
+ 208, 62, 464, 113, 114, 232, 62, 110, 62, 100,
+ 111, 100, 73, 82, 34, 118, 96, 73, 262, 73,
+ 113, 114, 230, 108, 29, 118, 46, 69, 109, 71,
+ 71, 27, 37, 99, 100, 96, 25, 26, 119, 100,
+ 96, 231, 31, 39, 100, 50, 34, 61, 53, 110,
+ 226, 40, 231, 100, 68, 60, 99, 118, 46, 113,
+ 114, 237, 118, 109, 118, 99, 29, 30, 278, 74,
+ 28, 60, 30, 119, 37, 9, 29, 11, 36, 113,
+ 114, 61, 71, 72, 37, 43, 44, 45, 68, 47,
+ 99, 49, 97, 98, 109, 362, 59, 60, 48, 278,
+ 58, 51, 52, 109, 119, 55, 285, 60, 99, 109,
+ 286, 74, 25, 63, 27, 108, 111, 75, 76, 119,
+ 99, 74, 117, 106, 101, 117, 39, 104, 105, 112,
+ 108, 81, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 19, 20, 21, 22, 23, 23,
+ 24, 26, 27, 101, 102, 103, 104, 77, 78, 79,
+ 80, 99, 100, 99, 100, 109, 113, 114, 117, 109,
+ 380, 99, 109, 352, 352, 352, 109, 109, 109, 104,
+ 109, 357, 109, 109, 100, 23, 23, 111, 99, 111,
+ 111, 23, 115, 64, 112, 109, 111, 109, 117, 109,
+ 109, 380, 66, 111, 111, 111, 385, 111, 111, 111,
+ 111, 111, 109, 389, 109, 65, 112, 104, 117, 112,
+ 104, 83, 116, 23, 116, 23, 23, 23, 67, 111,
+ 111, 111, 23, 111, 29, 23, 446, 23, 110, 112,
+ 110, 104, 118, 111, 109, 112, 112, 23, 109, 23,
+ 23, 23, 112, 112, 350, 112, 112, 112, 112, 112,
+ 439, 439, 439, 109, 109, 23, 23, 446, 57, 448,
+ 112, 112, 112, 23, 66, 109, 112, 112, 32, 109,
+ 111, 449, 111, 111, 109, 464, 119, 109, 112, 106,
+ 106, 112, 112, 465, 211, 255, 439, 232, -1, 275,
+ 87, 391, 160, -1, 89, 89, -1, -1, 199, 214,
+ -1, -1, 139
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint16 yystos[] =
+{
+ 0, 3, 4, 121, 122, 0, 123, 8, 124, 125,
+ 99, 100, 262, 5, 6, 7, 10, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
+ 138, 141, 170, 171, 178, 179, 180, 242, 244, 245,
+ 248, 261, 262, 108, 246, 99, 99, 99, 65, 100,
+ 145, 151, 249, 145, 145, 145, 145, 145, 100, 146,
+ 159, 99, 113, 114, 144, 166, 168, 241, 145, 145,
+ 108, 108, 9, 11, 99, 247, 117, 117, 111, 117,
+ 182, 29, 30, 37, 59, 60, 74, 250, 109, 101,
+ 102, 103, 104, 164, 109, 109, 109, 109, 109, 109,
+ 104, 161, 101, 104, 105, 163, 23, 24, 38, 62,
+ 73, 96, 100, 110, 118, 150, 152, 172, 186, 189,
+ 225, 229, 232, 236, 238, 239, 109, 109, 99, 243,
+ 109, 100, 172, 23, 181, 185, 189, 225, 235, 237,
+ 239, 240, 241, 27, 39, 111, 251, 111, 255, 144,
+ 115, 165, 142, 241, 144, 142, 144, 144, 142, 29,
+ 37, 60, 74, 177, 34, 46, 28, 30, 36, 43,
+ 44, 45, 47, 49, 58, 75, 76, 190, 192, 195,
+ 197, 199, 203, 206, 208, 210, 212, 215, 224, 29,
+ 37, 50, 53, 60, 74, 97, 98, 173, 150, 240,
+ 163, 111, 150, 144, 117, 247, 99, 112, 23, 24,
+ 23, 61, 68, 252, 23, 258, 109, 100, 166, 167,
+ 169, 109, 110, 143, 150, 238, 109, 109, 61, 68,
+ 254, 255, 111, 111, 111, 64, 29, 56, 207, 111,
+ 25, 27, 39, 196, 253, 111, 253, 48, 51, 52,
+ 55, 63, 81, 219, 26, 70, 211, 111, 257, 255,
+ 66, 254, 111, 255, 111, 111, 175, 163, 109, 119,
+ 23, 153, 154, 155, 159, 109, 109, 249, 117, 183,
+ 112, 112, 144, 116, 116, 163, 142, 143, 104, 162,
+ 83, 139, 144, 23, 233, 23, 234, 23, 209, 23,
+ 202, 67, 202, 25, 31, 33, 69, 71, 191, 201,
+ 111, 111, 220, 111, 255, 41, 42, 82, 216, 217,
+ 23, 260, 29, 200, 35, 54, 204, 111, 23, 176,
+ 23, 174, 176, 110, 240, 112, 104, 160, 147, 148,
+ 241, 144, 118, 110, 111, 256, 109, 109, 112, 112,
+ 112, 112, 112, 23, 223, 23, 221, 23, 222, 112,
+ 77, 78, 79, 80, 205, 23, 218, 112, 112, 112,
+ 109, 119, 113, 114, 156, 109, 23, 149, 262, 109,
+ 62, 73, 184, 187, 188, 189, 226, 227, 230, 235,
+ 23, 259, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 140, 144, 57, 26, 40, 60,
+ 72, 193, 201, 253, 112, 112, 112, 112, 240, 23,
+ 157, 23, 158, 148, 144, 34, 46, 213, 215, 109,
+ 119, 112, 32, 194, 198, 201, 109, 119, 109, 109,
+ 111, 111, 66, 214, 187, 240, 148, 139, 228, 233,
+ 231, 234, 111, 119, 109, 109, 112, 106, 112, 106,
+ 218, 148, 140, 233, 234, 106, 218, 112
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. However,
+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated
+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+ discussed. */
+
+#define YYFAIL goto yyerrlab
+#if defined YYFAIL
+ /* This is here to suppress warnings from the GCC cpp's
+ -Wunused-macros. Normally we don't worry about that warning, but
+ some users do, and we want to make it easy for users to remove
+ YYFAIL uses, which will produce warnings from Bison 2.5. */
+#endif
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
+
+__attribute__((__unused__))
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static unsigned
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
+#else
+static unsigned
+yy_location_print_ (yyo, yylocp)
+ FILE *yyo;
+ YYLTYPE const * const yylocp;
+#endif
+{
+ unsigned res = 0;
+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+ if (0 <= yylocp->first_line)
+ {
+ res += fprintf (yyo, "%d", yylocp->first_line);
+ if (0 <= yylocp->first_column)
+ res += fprintf (yyo, ".%d", yylocp->first_column);
+ }
+ if (0 <= yylocp->last_line)
+ {
+ if (yylocp->first_line < yylocp->last_line)
+ {
+ res += fprintf (yyo, "-%d", yylocp->last_line);
+ if (0 <= end_col)
+ res += fprintf (yyo, ".%d", end_col);
+ }
+ else if (0 <= end_col && yylocp->first_column < end_col)
+ res += fprintf (yyo, "-%d", end_col);
+ }
+ return res;
+ }
+
+# define YY_LOCATION_PRINT(File, Loc) \
+ yy_location_print_ (File, &(Loc))
+
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, state)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location, state); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct asm_parser_state *state;
+#endif
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+ YYUSE (state);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct asm_parser_state *state;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct asm_parser_state *state)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, state)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+ struct asm_parser_state *state;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) , state);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule, state); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULL;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - Assume YYFAIL is not used. It's too flawed to consider. See
+ <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+ for details. YYERROR is fine as it does not invoke this
+ function.
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct asm_parser_state *state)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, state)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+ struct asm_parser_state *state;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ YYUSE (state);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YYUSE (yytype);
+}
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (struct asm_parser_state *state)
+#else
+int
+yyparse (state)
+ struct asm_parser_state *state;
+#endif
+#endif
+{
+/* The lookahead symbol. */
+int yychar;
+
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+/* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+static YYSTYPE yyval_default;
+# define YY_INITIAL_VALUE(Value) = Value
+#endif
+static YYLTYPE yyloc_default
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ = { 1, 1, 1, 1 }
+# endif
+;
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
+
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc = yyloc_default;
+
+
+ /* Number of syntax errors so far. */
+ int yynerrs;
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+ `yyls': related to locations.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[3];
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yylsp = yyls = yylsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ yylsp[0] = yylloc;
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 3:
+/* Line 1787 of yacc.c */
+#line 288 "program/program_parse.y"
+ {
+ if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid fragment program header");
+
+ }
+ state->mode = ARB_vertex;
+ }
+ break;
+
+ case 4:
+/* Line 1787 of yacc.c */
+#line 296 "program/program_parse.y"
+ {
+ if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex program header");
+ }
+ state->mode = ARB_fragment;
+
+ state->option.TexRect =
+ (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
+ }
+ break;
+
+ case 7:
+/* Line 1787 of yacc.c */
+#line 312 "program/program_parse.y"
+ {
+ int valid = 0;
+
+ if (state->mode == ARB_vertex) {
+ valid = _mesa_ARBvp_parse_option(state, (yyvsp[(2) - (3)].string));
+ } else if (state->mode == ARB_fragment) {
+ valid = _mesa_ARBfp_parse_option(state, (yyvsp[(2) - (3)].string));
+ }
+
+
+ free((yyvsp[(2) - (3)].string));
+
+ if (!valid) {
+ const char *const err_str = (state->mode == ARB_vertex)
+ ? "invalid ARB vertex program option"
+ : "invalid ARB fragment program option";
+
+ yyerror(& (yylsp[(2) - (3)]), state, err_str);
+ YYERROR;
+ }
+ }
+ break;
+
+ case 10:
+/* Line 1787 of yacc.c */
+#line 340 "program/program_parse.y"
+ {
+ if ((yyvsp[(1) - (2)].inst) != NULL) {
+ if (state->inst_tail == NULL) {
+ state->inst_head = (yyvsp[(1) - (2)].inst);
+ } else {
+ state->inst_tail->next = (yyvsp[(1) - (2)].inst);
+ }
+
+ state->inst_tail = (yyvsp[(1) - (2)].inst);
+ (yyvsp[(1) - (2)].inst)->next = NULL;
+
+ state->prog->NumInstructions++;
+ }
+ }
+ break;
+
+ case 12:
+/* Line 1787 of yacc.c */
+#line 358 "program/program_parse.y"
+ {
+ (yyval.inst) = (yyvsp[(1) - (1)].inst);
+ state->prog->NumAluInstructions++;
+ }
+ break;
+
+ case 13:
+/* Line 1787 of yacc.c */
+#line 363 "program/program_parse.y"
+ {
+ (yyval.inst) = (yyvsp[(1) - (1)].inst);
+ state->prog->NumTexInstructions++;
+ }
+ break;
+
+ case 24:
+/* Line 1787 of yacc.c */
+#line 384 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor(OPCODE_ARL, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+ }
+ break;
+
+ case 25:
+/* Line 1787 of yacc.c */
+#line 390 "program/program_parse.y"
+ {
+ if ((yyvsp[(1) - (4)].temp_inst).Opcode == OPCODE_DDY)
+ state->fragment.UsesDFdy = 1;
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+ }
+ break;
+
+ case 26:
+/* Line 1787 of yacc.c */
+#line 398 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+ }
+ break;
+
+ case 27:
+/* Line 1787 of yacc.c */
+#line 404 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
+ }
+ break;
+
+ case 28:
+/* Line 1787 of yacc.c */
+#line 411 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
+ }
+ break;
+
+ case 29:
+/* Line 1787 of yacc.c */
+#line 418 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), & (yyvsp[(6) - (8)].src_reg), & (yyvsp[(8) - (8)].src_reg));
+ }
+ break;
+
+ case 30:
+/* Line 1787 of yacc.c */
+#line 424 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), NULL, NULL);
+ if ((yyval.inst) != NULL) {
+ const GLbitfield tex_mask = (1U << (yyvsp[(6) - (8)].integer));
+ GLbitfield shadow_tex = 0;
+ GLbitfield target_mask = 0;
+
+
+ (yyval.inst)->Base.TexSrcUnit = (yyvsp[(6) - (8)].integer);
+
+ if ((yyvsp[(8) - (8)].integer) < 0) {
+ shadow_tex = tex_mask;
+
+ (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(8) - (8)].integer);
+ (yyval.inst)->Base.TexShadow = 1;
+ } else {
+ (yyval.inst)->Base.TexSrcTarget = (yyvsp[(8) - (8)].integer);
+ }
+
+ target_mask = (1U << (yyval.inst)->Base.TexSrcTarget);
+
+ /* If this texture unit was previously accessed and that access
+ * had a different texture target, generate an error.
+ *
+ * If this texture unit was previously accessed and that access
+ * had a different shadow mode, generate an error.
+ */
+ if ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != 0)
+ && ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != target_mask)
+ || ((state->prog->ShadowSamplers & tex_mask)
+ != shadow_tex))) {
+ yyerror(& (yylsp[(8) - (8)]), state,
+ "multiple targets used on one texture image unit");
+ YYERROR;
+ }
+
+
+ state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] |= target_mask;
+ state->prog->ShadowSamplers |= shadow_tex;
+ }
+ }
+ break;
+
+ case 31:
+/* Line 1787 of yacc.c */
+#line 468 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor(OPCODE_KIL, NULL, & (yyvsp[(2) - (2)].src_reg), NULL, NULL);
+ state->fragment.UsesKill = 1;
+ }
+ break;
+
+ case 32:
+/* Line 1787 of yacc.c */
+#line 473 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
+ (yyval.inst)->Base.DstReg.CondMask = (yyvsp[(2) - (2)].dst_reg).CondMask;
+ (yyval.inst)->Base.DstReg.CondSwizzle = (yyvsp[(2) - (2)].dst_reg).CondSwizzle;
+ state->fragment.UsesKill = 1;
+ }
+ break;
+
+ case 33:
+/* Line 1787 of yacc.c */
+#line 482 "program/program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (12)].temp_inst), & (yyvsp[(2) - (12)].dst_reg), & (yyvsp[(4) - (12)].src_reg), & (yyvsp[(6) - (12)].src_reg), & (yyvsp[(8) - (12)].src_reg));
+ if ((yyval.inst) != NULL) {
+ const GLbitfield tex_mask = (1U << (yyvsp[(10) - (12)].integer));
+ GLbitfield shadow_tex = 0;
+ GLbitfield target_mask = 0;
+
+
+ (yyval.inst)->Base.TexSrcUnit = (yyvsp[(10) - (12)].integer);
+
+ if ((yyvsp[(12) - (12)].integer) < 0) {
+ shadow_tex = tex_mask;
+
+ (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(12) - (12)].integer);
+ (yyval.inst)->Base.TexShadow = 1;
+ } else {
+ (yyval.inst)->Base.TexSrcTarget = (yyvsp[(12) - (12)].integer);
+ }
+
+ target_mask = (1U << (yyval.inst)->Base.TexSrcTarget);
+
+ /* If this texture unit was previously accessed and that access
+ * had a different texture target, generate an error.
+ *
+ * If this texture unit was previously accessed and that access
+ * had a different shadow mode, generate an error.
+ */
+ if ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != 0)
+ && ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != target_mask)
+ || ((state->prog->ShadowSamplers & tex_mask)
+ != shadow_tex))) {
+ yyerror(& (yylsp[(12) - (12)]), state,
+ "multiple targets used on one texture image unit");
+ YYERROR;
+ }
+
+
+ state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] |= target_mask;
+ state->prog->ShadowSamplers |= shadow_tex;
+ }
+ }
+ break;
+
+ case 34:
+/* Line 1787 of yacc.c */
+#line 526 "program/program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 35:
+/* Line 1787 of yacc.c */
+#line 531 "program/program_parse.y"
+ { (yyval.integer) = TEXTURE_1D_INDEX; }
+ break;
+
+ case 36:
+/* Line 1787 of yacc.c */
+#line 532 "program/program_parse.y"
+ { (yyval.integer) = TEXTURE_2D_INDEX; }
+ break;
+
+ case 37:
+/* Line 1787 of yacc.c */
+#line 533 "program/program_parse.y"
+ { (yyval.integer) = TEXTURE_3D_INDEX; }
+ break;
+
+ case 38:
+/* Line 1787 of yacc.c */
+#line 534 "program/program_parse.y"
+ { (yyval.integer) = TEXTURE_CUBE_INDEX; }
+ break;
+
+ case 39:
+/* Line 1787 of yacc.c */
+#line 535 "program/program_parse.y"
+ { (yyval.integer) = TEXTURE_RECT_INDEX; }
+ break;
+
+ case 40:
+/* Line 1787 of yacc.c */
+#line 536 "program/program_parse.y"
+ { (yyval.integer) = -TEXTURE_1D_INDEX; }
+ break;
+
+ case 41:
+/* Line 1787 of yacc.c */
+#line 537 "program/program_parse.y"
+ { (yyval.integer) = -TEXTURE_2D_INDEX; }
+ break;
+
+ case 42:
+/* Line 1787 of yacc.c */
+#line 538 "program/program_parse.y"
+ { (yyval.integer) = -TEXTURE_RECT_INDEX; }
+ break;
+
+ case 43:
+/* Line 1787 of yacc.c */
+#line 539 "program/program_parse.y"
+ { (yyval.integer) = TEXTURE_1D_ARRAY_INDEX; }
+ break;
+
+ case 44:
+/* Line 1787 of yacc.c */
+#line 540 "program/program_parse.y"
+ { (yyval.integer) = TEXTURE_2D_ARRAY_INDEX; }
+ break;
+
+ case 45:
+/* Line 1787 of yacc.c */
+#line 541 "program/program_parse.y"
+ { (yyval.integer) = -TEXTURE_1D_ARRAY_INDEX; }
+ break;
+
+ case 46:
+/* Line 1787 of yacc.c */
+#line 542 "program/program_parse.y"
+ { (yyval.integer) = -TEXTURE_2D_ARRAY_INDEX; }
+ break;
+
+ case 47:
+/* Line 1787 of yacc.c */
+#line 546 "program/program_parse.y"
+ {
+ /* FIXME: Is this correct? Should the extenedSwizzle be applied
+ * FIXME: to the existing swizzle?
+ */
+ (yyvsp[(4) - (6)].src_reg).Base.Swizzle = (yyvsp[(6) - (6)].swiz_mask).swizzle;
+ (yyvsp[(4) - (6)].src_reg).Base.Negate = (yyvsp[(6) - (6)].swiz_mask).mask;
+
+ (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), NULL, NULL);
+ }
+ break;
+
+ case 48:
+/* Line 1787 of yacc.c */
+#line 558 "program/program_parse.y"
+ {
+ (yyval.src_reg) = (yyvsp[(2) - (2)].src_reg);
+
+ if ((yyvsp[(1) - (2)].negate)) {
+ (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+ }
+ }
+ break;
+
+ case 49:
+/* Line 1787 of yacc.c */
+#line 566 "program/program_parse.y"
+ {
+ (yyval.src_reg) = (yyvsp[(3) - (4)].src_reg);
+
+ if (!state->option.NV_fragment) {
+ yyerror(& (yylsp[(2) - (4)]), state, "unexpected character '|'");
+ YYERROR;
+ }
+
+ if ((yyvsp[(1) - (4)].negate)) {
+ (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+ }
+
+ (yyval.src_reg).Base.Abs = 1;
+ }
+ break;
+
+ case 50:
+/* Line 1787 of yacc.c */
+#line 583 "program/program_parse.y"
+ {
+ (yyval.src_reg) = (yyvsp[(1) - (2)].src_reg);
+
+ (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+ (yyvsp[(2) - (2)].swiz_mask).swizzle);
+ }
+ break;
+
+ case 51:
+/* Line 1787 of yacc.c */
+#line 590 "program/program_parse.y"
+ {
+ struct asm_symbol temp_sym;
+
+ if (!state->option.NV_fragment) {
+ yyerror(& (yylsp[(1) - (1)]), state, "expected scalar suffix");
+ YYERROR;
+ }
+
+ memset(& temp_sym, 0, sizeof(temp_sym));
+ temp_sym.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & temp_sym, & (yyvsp[(1) - (1)].vector), GL_TRUE);
+
+ set_src_reg_swz(& (yyval.src_reg), PROGRAM_CONSTANT,
+ temp_sym.param_binding_begin,
+ temp_sym.param_binding_swizzle);
+ }
+ break;
+
+ case 52:
+/* Line 1787 of yacc.c */
+#line 609 "program/program_parse.y"
+ {
+ (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg);
+
+ if ((yyvsp[(1) - (3)].negate)) {
+ (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+ }
+
+ (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+ (yyvsp[(3) - (3)].swiz_mask).swizzle);
+ }
+ break;
+
+ case 53:
+/* Line 1787 of yacc.c */
+#line 620 "program/program_parse.y"
+ {
+ (yyval.src_reg) = (yyvsp[(3) - (5)].src_reg);
+
+ if (!state->option.NV_fragment) {
+ yyerror(& (yylsp[(2) - (5)]), state, "unexpected character '|'");
+ YYERROR;
+ }
+
+ if ((yyvsp[(1) - (5)].negate)) {
+ (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+ }
+
+ (yyval.src_reg).Base.Abs = 1;
+ (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+ (yyvsp[(4) - (5)].swiz_mask).swizzle);
+ }
+ break;
+
+ case 54:
+/* Line 1787 of yacc.c */
+#line 640 "program/program_parse.y"
+ {
+ (yyval.dst_reg) = (yyvsp[(1) - (3)].dst_reg);
+ (yyval.dst_reg).WriteMask = (yyvsp[(2) - (3)].swiz_mask).mask;
+ (yyval.dst_reg).CondMask = (yyvsp[(3) - (3)].dst_reg).CondMask;
+ (yyval.dst_reg).CondSwizzle = (yyvsp[(3) - (3)].dst_reg).CondSwizzle;
+
+ if ((yyval.dst_reg).File == PROGRAM_OUTPUT) {
+ /* Technically speaking, this should check that it is in
+ * vertex program mode. However, PositionInvariant can never be
+ * set in fragment program mode, so it is somewhat irrelevant.
+ */
+ if (state->option.PositionInvariant
+ && ((yyval.dst_reg).Index == VARYING_SLOT_POS)) {
+ yyerror(& (yylsp[(1) - (3)]), state, "position-invariant programs cannot "
+ "write position");
+ YYERROR;
+ }
+
+ state->prog->OutputsWritten |= BITFIELD64_BIT((yyval.dst_reg).Index);
+ }
+ }
+ break;
+
+ case 55:
+/* Line 1787 of yacc.c */
+#line 664 "program/program_parse.y"
+ {
+ set_dst_reg(& (yyval.dst_reg), PROGRAM_ADDRESS, 0);
+ (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask;
+ }
+ break;
+
+ case 56:
+/* Line 1787 of yacc.c */
+#line 671 "program/program_parse.y"
+ {
+ const unsigned xyzw_valid =
+ ((yyvsp[(1) - (7)].ext_swizzle).xyzw_valid << 0)
+ | ((yyvsp[(3) - (7)].ext_swizzle).xyzw_valid << 1)
+ | ((yyvsp[(5) - (7)].ext_swizzle).xyzw_valid << 2)
+ | ((yyvsp[(7) - (7)].ext_swizzle).xyzw_valid << 3);
+ const unsigned rgba_valid =
+ ((yyvsp[(1) - (7)].ext_swizzle).rgba_valid << 0)
+ | ((yyvsp[(3) - (7)].ext_swizzle).rgba_valid << 1)
+ | ((yyvsp[(5) - (7)].ext_swizzle).rgba_valid << 2)
+ | ((yyvsp[(7) - (7)].ext_swizzle).rgba_valid << 3);
+
+ /* All of the swizzle components have to be valid in either RGBA
+ * or XYZW. Note that 0 and 1 are valid in both, so both masks
+ * can have some bits set.
+ *
+ * We somewhat deviate from the spec here. It would be really hard
+ * to figure out which component is the error, and there probably
+ * isn't a lot of benefit.
+ */
+ if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
+ yyerror(& (yylsp[(1) - (7)]), state, "cannot combine RGBA and XYZW swizzle "
+ "components");
+ YYERROR;
+ }
+
+ (yyval.swiz_mask).swizzle = MAKE_SWIZZLE4((yyvsp[(1) - (7)].ext_swizzle).swz, (yyvsp[(3) - (7)].ext_swizzle).swz, (yyvsp[(5) - (7)].ext_swizzle).swz, (yyvsp[(7) - (7)].ext_swizzle).swz);
+ (yyval.swiz_mask).mask = ((yyvsp[(1) - (7)].ext_swizzle).negate) | ((yyvsp[(3) - (7)].ext_swizzle).negate << 1) | ((yyvsp[(5) - (7)].ext_swizzle).negate << 2)
+ | ((yyvsp[(7) - (7)].ext_swizzle).negate << 3);
+ }
+ break;
+
+ case 57:
+/* Line 1787 of yacc.c */
+#line 704 "program/program_parse.y"
+ {
+ (yyval.ext_swizzle) = (yyvsp[(2) - (2)].ext_swizzle);
+ (yyval.ext_swizzle).negate = ((yyvsp[(1) - (2)].negate)) ? 1 : 0;
+ }
+ break;
+
+ case 58:
+/* Line 1787 of yacc.c */
+#line 711 "program/program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) != 0) && ((yyvsp[(1) - (1)].integer) != 1)) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ (yyval.ext_swizzle).swz = ((yyvsp[(1) - (1)].integer) == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+ (yyval.ext_swizzle).negate = 0;
+
+ /* 0 and 1 are valid for both RGBA swizzle names and XYZW
+ * swizzle names.
+ */
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ }
+ break;
+
+ case 59:
+/* Line 1787 of yacc.c */
+#line 727 "program/program_parse.y"
+ {
+ char s;
+
+ if (strlen((yyvsp[(1) - (1)].string)) > 1) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ s = (yyvsp[(1) - (1)].string)[0];
+ free((yyvsp[(1) - (1)].string));
+
+ (yyval.ext_swizzle).rgba_valid = 0;
+ (yyval.ext_swizzle).xyzw_valid = 0;
+ (yyval.ext_swizzle).negate = 0;
+
+ switch (s) {
+ case 'x':
+ (yyval.ext_swizzle).swz = SWIZZLE_X;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+ case 'y':
+ (yyval.ext_swizzle).swz = SWIZZLE_Y;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+ case 'z':
+ (yyval.ext_swizzle).swz = SWIZZLE_Z;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+ case 'w':
+ (yyval.ext_swizzle).swz = SWIZZLE_W;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+
+ case 'r':
+ (yyval.ext_swizzle).swz = SWIZZLE_X;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+ case 'g':
+ (yyval.ext_swizzle).swz = SWIZZLE_Y;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+ case 'b':
+ (yyval.ext_swizzle).swz = SWIZZLE_Z;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+ case 'a':
+ (yyval.ext_swizzle).swz = SWIZZLE_W;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+
+ default:
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+ YYERROR;
+ break;
+ }
+ }
+ break;
+
+ case 60:
+/* Line 1787 of yacc.c */
+#line 786 "program/program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ free((yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) && (s->type != at_temp)
+ && (s->type != at_attrib)) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type == at_param) && s->param_is_array) {
+ yyerror(& (yylsp[(1) - (1)]), state, "non-array access to array PARAM");
+ YYERROR;
+ }
+
+ init_src_reg(& (yyval.src_reg));
+ switch (s->type) {
+ case at_temp:
+ set_src_reg(& (yyval.src_reg), PROGRAM_TEMPORARY, s->temp_binding);
+ break;
+ case at_param:
+ set_src_reg_swz(& (yyval.src_reg), s->param_binding_type,
+ s->param_binding_begin,
+ s->param_binding_swizzle);
+ break;
+ case at_attrib:
+ set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, s->attrib_binding);
+ state->prog->InputsRead |= BITFIELD64_BIT((yyval.src_reg).Base.Index);
+
+ if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
+ YYERROR;
+ }
+ break;
+
+ default:
+ YYERROR;
+ break;
+ }
+ }
+ break;
+
+ case 61:
+/* Line 1787 of yacc.c */
+#line 829 "program/program_parse.y"
+ {
+ set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, (yyvsp[(1) - (1)].attrib));
+ state->prog->InputsRead |= BITFIELD64_BIT((yyval.src_reg).Base.Index);
+
+ if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
+ YYERROR;
+ }
+ }
+ break;
+
+ case 62:
+/* Line 1787 of yacc.c */
+#line 838 "program/program_parse.y"
+ {
+ if (! (yyvsp[(3) - (4)].src_reg).Base.RelAddr
+ && ((unsigned) (yyvsp[(3) - (4)].src_reg).Base.Index >= (yyvsp[(1) - (4)].sym)->param_binding_length)) {
+ yyerror(& (yylsp[(3) - (4)]), state, "out of bounds array access");
+ YYERROR;
+ }
+
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.File = (yyvsp[(1) - (4)].sym)->param_binding_type;
+
+ if ((yyvsp[(3) - (4)].src_reg).Base.RelAddr) {
+ state->prog->IndirectRegisterFiles |= (1 << (yyval.src_reg).Base.File);
+ (yyvsp[(1) - (4)].sym)->param_accessed_indirectly = 1;
+
+ (yyval.src_reg).Base.RelAddr = 1;
+ (yyval.src_reg).Base.Index = (yyvsp[(3) - (4)].src_reg).Base.Index;
+ (yyval.src_reg).Symbol = (yyvsp[(1) - (4)].sym);
+ } else {
+ (yyval.src_reg).Base.Index = (yyvsp[(1) - (4)].sym)->param_binding_begin + (yyvsp[(3) - (4)].src_reg).Base.Index;
+ }
+ }
+ break;
+
+ case 63:
+/* Line 1787 of yacc.c */
+#line 860 "program/program_parse.y"
+ {
+ gl_register_file file = ((yyvsp[(1) - (1)].temp_sym).name != NULL)
+ ? (yyvsp[(1) - (1)].temp_sym).param_binding_type
+ : PROGRAM_CONSTANT;
+ set_src_reg_swz(& (yyval.src_reg), file, (yyvsp[(1) - (1)].temp_sym).param_binding_begin,
+ (yyvsp[(1) - (1)].temp_sym).param_binding_swizzle);
+ }
+ break;
+
+ case 64:
+/* Line 1787 of yacc.c */
+#line 870 "program/program_parse.y"
+ {
+ set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, (yyvsp[(1) - (1)].result));
+ }
+ break;
+
+ case 65:
+/* Line 1787 of yacc.c */
+#line 874 "program/program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ free((yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_output) && (s->type != at_temp)) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ }
+
+ switch (s->type) {
+ case at_temp:
+ set_dst_reg(& (yyval.dst_reg), PROGRAM_TEMPORARY, s->temp_binding);
+ break;
+ case at_output:
+ set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, s->output_binding);
+ break;
+ default:
+ set_dst_reg(& (yyval.dst_reg), s->param_binding_type, s->param_binding_begin);
+ break;
+ }
+ }
+ break;
+
+ case 66:
+/* Line 1787 of yacc.c */
+#line 903 "program/program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ free((yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) || !s->param_is_array) {
+ yyerror(& (yylsp[(1) - (1)]), state, "array access to non-PARAM variable");
+ YYERROR;
+ } else {
+ (yyval.sym) = s;
+ }
+ }
+ break;
+
+ case 69:
+/* Line 1787 of yacc.c */
+#line 924 "program/program_parse.y"
+ {
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 70:
+/* Line 1787 of yacc.c */
+#line 931 "program/program_parse.y"
+ {
+ /* FINISHME: Add support for multiple address registers.
+ */
+ /* FINISHME: Add support for 4-component address registers.
+ */
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.RelAddr = 1;
+ (yyval.src_reg).Base.Index = (yyvsp[(3) - (3)].integer);
+ }
+ break;
+
+ case 71:
+/* Line 1787 of yacc.c */
+#line 942 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 72:
+/* Line 1787 of yacc.c */
+#line 943 "program/program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (2)].integer); }
+ break;
+
+ case 73:
+/* Line 1787 of yacc.c */
+#line 944 "program/program_parse.y"
+ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); }
+ break;
+
+ case 74:
+/* Line 1787 of yacc.c */
+#line 948 "program/program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > (state->limits->MaxAddressOffset - 1))) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
+ yyerror(& (yylsp[(1) - (1)]), state, s);
+ YYERROR;
+ } else {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ }
+ break;
+
+ case 75:
+/* Line 1787 of yacc.c */
+#line 962 "program/program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > state->limits->MaxAddressOffset)) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
+ yyerror(& (yylsp[(1) - (1)]), state, s);
+ YYERROR;
+ } else {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ }
+ break;
+
+ case 76:
+/* Line 1787 of yacc.c */
+#line 976 "program/program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ free((yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid array member");
+ YYERROR;
+ } else if (s->type != at_address) {
+ yyerror(& (yylsp[(1) - (1)]), state,
+ "invalid variable for indexed array access");
+ YYERROR;
+ } else {
+ (yyval.sym) = s;
+ }
+ }
+ break;
+
+ case 77:
+/* Line 1787 of yacc.c */
+#line 996 "program/program_parse.y"
+ {
+ if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector");
+ YYERROR;
+ } else {
+ (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
+ }
+ }
+ break;
+
+ case 78:
+/* Line 1787 of yacc.c */
+#line 1007 "program/program_parse.y"
+ {
+ if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
+ yyerror(& (yylsp[(1) - (1)]), state,
+ "address register write mask must be \".x\"");
+ YYERROR;
+ } else {
+ (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
+ }
+ }
+ break;
+
+ case 83:
+/* Line 1787 of yacc.c */
+#line 1023 "program/program_parse.y"
+ { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; }
+ break;
+
+ case 88:
+/* Line 1787 of yacc.c */
+#line 1027 "program/program_parse.y"
+ { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; }
+ break;
+
+ case 89:
+/* Line 1787 of yacc.c */
+#line 1031 "program/program_parse.y"
+ {
+ (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
+ }
+ break;
+
+ case 90:
+/* Line 1787 of yacc.c */
+#line 1035 "program/program_parse.y"
+ {
+ (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
+ }
+ break;
+
+ case 91:
+/* Line 1787 of yacc.c */
+#line 1039 "program/program_parse.y"
+ {
+ (yyval.dst_reg).CondMask = COND_TR;
+ (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
+ }
+ break;
+
+ case 92:
+/* Line 1787 of yacc.c */
+#line 1046 "program/program_parse.y"
+ {
+ (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
+ (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
+ }
+ break;
+
+ case 93:
+/* Line 1787 of yacc.c */
+#line 1053 "program/program_parse.y"
+ {
+ (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
+ (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
+ }
+ break;
+
+ case 94:
+/* Line 1787 of yacc.c */
+#line 1060 "program/program_parse.y"
+ {
+ const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
+ if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
+ char *const err_str =
+ make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string));
+
+ yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
+ ? err_str : "invalid condition code");
+
+ if (err_str != NULL) {
+ free(err_str);
+ }
+
+ YYERROR;
+ }
+
+ (yyval.dst_reg).CondMask = cond;
+ (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
+ }
+ break;
+
+ case 95:
+/* Line 1787 of yacc.c */
+#line 1082 "program/program_parse.y"
+ {
+ const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
+ if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
+ char *const err_str =
+ make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string));
+
+ yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
+ ? err_str : "invalid condition code");
+
+ if (err_str != NULL) {
+ free(err_str);
+ }
+
+ YYERROR;
+ }
+
+ (yyval.dst_reg).CondMask = cond;
+ (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
+ }
+ break;
+
+ case 102:
+/* Line 1787 of yacc.c */
+#line 1112 "program/program_parse.y"
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)]));
+
+ if (s == NULL) {
+ free((yyvsp[(2) - (4)].string));
+ YYERROR;
+ } else {
+ s->attrib_binding = (yyvsp[(4) - (4)].attrib);
+ state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
+
+ if (!validate_inputs(& (yylsp[(4) - (4)]), state)) {
+ YYERROR;
+ }
+ }
+ }
+ break;
+
+ case 103:
+/* Line 1787 of yacc.c */
+#line 1131 "program/program_parse.y"
+ {
+ (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
+ }
+ break;
+
+ case 104:
+/* Line 1787 of yacc.c */
+#line 1135 "program/program_parse.y"
+ {
+ (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
+ }
+ break;
+
+ case 105:
+/* Line 1787 of yacc.c */
+#line 1141 "program/program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_POS;
+ }
+ break;
+
+ case 106:
+/* Line 1787 of yacc.c */
+#line 1145 "program/program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_WEIGHT;
+ }
+ break;
+
+ case 107:
+/* Line 1787 of yacc.c */
+#line 1149 "program/program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_NORMAL;
+ }
+ break;
+
+ case 108:
+/* Line 1787 of yacc.c */
+#line 1153 "program/program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_COLOR0 + (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 109:
+/* Line 1787 of yacc.c */
+#line 1157 "program/program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_FOG;
+ }
+ break;
+
+ case 110:
+/* Line 1787 of yacc.c */
+#line 1161 "program/program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 111:
+/* Line 1787 of yacc.c */
+#line 1165 "program/program_parse.y"
+ {
+ yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ }
+ break;
+
+ case 112:
+/* Line 1787 of yacc.c */
+#line 1170 "program/program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer);
+ }
+ break;
+
+ case 113:
+/* Line 1787 of yacc.c */
+#line 1176 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 117:
+/* Line 1787 of yacc.c */
+#line 1190 "program/program_parse.y"
+ {
+ (yyval.attrib) = VARYING_SLOT_POS;
+ }
+ break;
+
+ case 118:
+/* Line 1787 of yacc.c */
+#line 1194 "program/program_parse.y"
+ {
+ (yyval.attrib) = VARYING_SLOT_COL0 + (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 119:
+/* Line 1787 of yacc.c */
+#line 1198 "program/program_parse.y"
+ {
+ (yyval.attrib) = VARYING_SLOT_FOGC;
+ }
+ break;
+
+ case 120:
+/* Line 1787 of yacc.c */
+#line 1202 "program/program_parse.y"
+ {
+ (yyval.attrib) = VARYING_SLOT_TEX0 + (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 123:
+/* Line 1787 of yacc.c */
+#line 1210 "program/program_parse.y"
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)]));
+
+ if (s == NULL) {
+ free((yyvsp[(2) - (3)].string));
+ YYERROR;
+ } else {
+ s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type;
+ s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin;
+ s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length;
+ s->param_binding_swizzle = (yyvsp[(3) - (3)].temp_sym).param_binding_swizzle;
+ s->param_is_array = 0;
+ }
+ }
+ break;
+
+ case 124:
+/* Line 1787 of yacc.c */
+#line 1228 "program/program_parse.y"
+ {
+ if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) {
+ free((yyvsp[(2) - (6)].string));
+ yyerror(& (yylsp[(4) - (6)]), state,
+ "parameter array size and number of bindings must match");
+ YYERROR;
+ } else {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(2) - (6)].string), (yyvsp[(6) - (6)].temp_sym).type, & (yylsp[(2) - (6)]));
+
+ if (s == NULL) {
+ free((yyvsp[(2) - (6)].string));
+ YYERROR;
+ } else {
+ s->param_binding_type = (yyvsp[(6) - (6)].temp_sym).param_binding_type;
+ s->param_binding_begin = (yyvsp[(6) - (6)].temp_sym).param_binding_begin;
+ s->param_binding_length = (yyvsp[(6) - (6)].temp_sym).param_binding_length;
+ s->param_binding_swizzle = SWIZZLE_XYZW;
+ s->param_is_array = 1;
+ }
+ }
+ }
+ break;
+
+ case 125:
+/* Line 1787 of yacc.c */
+#line 1253 "program/program_parse.y"
+ {
+ (yyval.integer) = 0;
+ }
+ break;
+
+ case 126:
+/* Line 1787 of yacc.c */
+#line 1257 "program/program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) > state->limits->MaxParameters)) {
+ char msg[100];
+ _mesa_snprintf(msg, sizeof(msg),
+ "invalid parameter array size (size=%d max=%u)",
+ (yyvsp[(1) - (1)].integer), state->limits->MaxParameters);
+ yyerror(& (yylsp[(1) - (1)]), state, msg);
+ YYERROR;
+ } else {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ }
+ break;
+
+ case 127:
+/* Line 1787 of yacc.c */
+#line 1272 "program/program_parse.y"
+ {
+ (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym);
+ }
+ break;
+
+ case 128:
+/* Line 1787 of yacc.c */
+#line 1278 "program/program_parse.y"
+ {
+ (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym);
+ }
+ break;
+
+ case 130:
+/* Line 1787 of yacc.c */
+#line 1285 "program/program_parse.y"
+ {
+ (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length;
+ (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym);
+ }
+ break;
+
+ case 131:
+/* Line 1787 of yacc.c */
+#line 1292 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ }
+ break;
+
+ case 132:
+/* Line 1787 of yacc.c */
+#line 1298 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ }
+ break;
+
+ case 133:
+/* Line 1787 of yacc.c */
+#line 1304 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
+ }
+ break;
+
+ case 134:
+/* Line 1787 of yacc.c */
+#line 1312 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ }
+ break;
+
+ case 135:
+/* Line 1787 of yacc.c */
+#line 1318 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ }
+ break;
+
+ case 136:
+/* Line 1787 of yacc.c */
+#line 1324 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
+ }
+ break;
+
+ case 137:
+/* Line 1787 of yacc.c */
+#line 1332 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ }
+ break;
+
+ case 138:
+/* Line 1787 of yacc.c */
+#line 1338 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ }
+ break;
+
+ case 139:
+/* Line 1787 of yacc.c */
+#line 1344 "program/program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_FALSE);
+ }
+ break;
+
+ case 140:
+/* Line 1787 of yacc.c */
+#line 1351 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); }
+ break;
+
+ case 141:
+/* Line 1787 of yacc.c */
+#line 1352 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 142:
+/* Line 1787 of yacc.c */
+#line 1355 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 143:
+/* Line 1787 of yacc.c */
+#line 1356 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 144:
+/* Line 1787 of yacc.c */
+#line 1357 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 145:
+/* Line 1787 of yacc.c */
+#line 1358 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 146:
+/* Line 1787 of yacc.c */
+#line 1359 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 147:
+/* Line 1787 of yacc.c */
+#line 1360 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 148:
+/* Line 1787 of yacc.c */
+#line 1361 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 149:
+/* Line 1787 of yacc.c */
+#line 1362 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 150:
+/* Line 1787 of yacc.c */
+#line 1363 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 151:
+/* Line 1787 of yacc.c */
+#line 1364 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 152:
+/* Line 1787 of yacc.c */
+#line 1365 "program/program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); }
+ break;
+
+ case 153:
+/* Line 1787 of yacc.c */
+#line 1369 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_MATERIAL;
+ (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
+ (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
+ }
+ break;
+
+ case 154:
+/* Line 1787 of yacc.c */
+#line 1378 "program/program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 155:
+/* Line 1787 of yacc.c */
+#line 1382 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_EMISSION;
+ }
+ break;
+
+ case 156:
+/* Line 1787 of yacc.c */
+#line 1386 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_SHININESS;
+ }
+ break;
+
+ case 157:
+/* Line 1787 of yacc.c */
+#line 1392 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHT;
+ (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
+ (yyval.state)[2] = (yyvsp[(5) - (5)].integer);
+ }
+ break;
+
+ case 158:
+/* Line 1787 of yacc.c */
+#line 1401 "program/program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 159:
+/* Line 1787 of yacc.c */
+#line 1405 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_POSITION;
+ }
+ break;
+
+ case 160:
+/* Line 1787 of yacc.c */
+#line 1409 "program/program_parse.y"
+ {
+ if (!state->ctx->Extensions.EXT_point_parameters) {
+ yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported");
+ YYERROR;
+ }
+
+ (yyval.integer) = STATE_ATTENUATION;
+ }
+ break;
+
+ case 161:
+/* Line 1787 of yacc.c */
+#line 1418 "program/program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 162:
+/* Line 1787 of yacc.c */
+#line 1422 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_HALF_VECTOR;
+ }
+ break;
+
+ case 163:
+/* Line 1787 of yacc.c */
+#line 1428 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_SPOT_DIRECTION;
+ }
+ break;
+
+ case 164:
+/* Line 1787 of yacc.c */
+#line 1434 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0];
+ (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1];
+ }
+ break;
+
+ case 165:
+/* Line 1787 of yacc.c */
+#line 1441 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT;
+ }
+ break;
+
+ case 166:
+/* Line 1787 of yacc.c */
+#line 1446 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR;
+ (yyval.state)[1] = (yyvsp[(1) - (2)].integer);
+ }
+ break;
+
+ case 167:
+/* Line 1787 of yacc.c */
+#line 1454 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHTPROD;
+ (yyval.state)[1] = (yyvsp[(3) - (6)].integer);
+ (yyval.state)[2] = (yyvsp[(5) - (6)].integer);
+ (yyval.state)[3] = (yyvsp[(6) - (6)].integer);
+ }
+ break;
+
+ case 169:
+/* Line 1787 of yacc.c */
+#line 1466 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = (yyvsp[(3) - (3)].integer);
+ (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
+ }
+ break;
+
+ case 170:
+/* Line 1787 of yacc.c */
+#line 1474 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXENV_COLOR;
+ }
+ break;
+
+ case 171:
+/* Line 1787 of yacc.c */
+#line 1480 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_AMBIENT;
+ }
+ break;
+
+ case 172:
+/* Line 1787 of yacc.c */
+#line 1484 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_DIFFUSE;
+ }
+ break;
+
+ case 173:
+/* Line 1787 of yacc.c */
+#line 1488 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_SPECULAR;
+ }
+ break;
+
+ case 174:
+/* Line 1787 of yacc.c */
+#line 1494 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 175:
+/* Line 1787 of yacc.c */
+#line 1505 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_TEXGEN;
+ (yyval.state)[1] = (yyvsp[(2) - (4)].integer);
+ (yyval.state)[2] = (yyvsp[(3) - (4)].integer) + (yyvsp[(4) - (4)].integer);
+ }
+ break;
+
+ case 176:
+/* Line 1787 of yacc.c */
+#line 1514 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_S;
+ }
+ break;
+
+ case 177:
+/* Line 1787 of yacc.c */
+#line 1518 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_OBJECT_S;
+ }
+ break;
+
+ case 178:
+/* Line 1787 of yacc.c */
+#line 1523 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
+ }
+ break;
+
+ case 179:
+/* Line 1787 of yacc.c */
+#line 1527 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
+ }
+ break;
+
+ case 180:
+/* Line 1787 of yacc.c */
+#line 1531 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
+ }
+ break;
+
+ case 181:
+/* Line 1787 of yacc.c */
+#line 1535 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
+ }
+ break;
+
+ case 182:
+/* Line 1787 of yacc.c */
+#line 1541 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 183:
+/* Line 1787 of yacc.c */
+#line 1548 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_FOG_COLOR;
+ }
+ break;
+
+ case 184:
+/* Line 1787 of yacc.c */
+#line 1552 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_FOG_PARAMS;
+ }
+ break;
+
+ case 185:
+/* Line 1787 of yacc.c */
+#line 1558 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_CLIPPLANE;
+ (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
+ }
+ break;
+
+ case 186:
+/* Line 1787 of yacc.c */
+#line 1566 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 187:
+/* Line 1787 of yacc.c */
+#line 1577 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 188:
+/* Line 1787 of yacc.c */
+#line 1584 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_POINT_SIZE;
+ }
+ break;
+
+ case 189:
+/* Line 1787 of yacc.c */
+#line 1588 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_POINT_ATTENUATION;
+ }
+ break;
+
+ case 190:
+/* Line 1787 of yacc.c */
+#line 1594 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0];
+ (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1];
+ (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[4] = (yyvsp[(1) - (5)].state)[2];
+ }
+ break;
+
+ case 191:
+/* Line 1787 of yacc.c */
+#line 1604 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0];
+ (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1];
+ (yyval.state)[2] = (yyvsp[(2) - (2)].state)[2];
+ (yyval.state)[3] = (yyvsp[(2) - (2)].state)[3];
+ (yyval.state)[4] = (yyvsp[(1) - (2)].state)[2];
+ }
+ break;
+
+ case 192:
+/* Line 1787 of yacc.c */
+#line 1614 "program/program_parse.y"
+ {
+ (yyval.state)[2] = 0;
+ (yyval.state)[3] = 3;
+ }
+ break;
+
+ case 193:
+/* Line 1787 of yacc.c */
+#line 1619 "program/program_parse.y"
+ {
+ /* It seems logical that the matrix row range specifier would have
+ * to specify a range or more than one row (i.e., $5 > $3).
+ * However, the ARB_vertex_program spec says "a program will fail
+ * to load if <a> is greater than <b>." This means that $3 == $5
+ * is valid.
+ */
+ if ((yyvsp[(3) - (6)].integer) > (yyvsp[(5) - (6)].integer)) {
+ yyerror(& (yylsp[(3) - (6)]), state, "invalid matrix row range");
+ YYERROR;
+ }
+
+ (yyval.state)[2] = (yyvsp[(3) - (6)].integer);
+ (yyval.state)[3] = (yyvsp[(5) - (6)].integer);
+ }
+ break;
+
+ case 194:
+/* Line 1787 of yacc.c */
+#line 1637 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0];
+ (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1];
+ (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
+ }
+ break;
+
+ case 195:
+/* Line 1787 of yacc.c */
+#line 1645 "program/program_parse.y"
+ {
+ (yyval.integer) = 0;
+ }
+ break;
+
+ case 196:
+/* Line 1787 of yacc.c */
+#line 1649 "program/program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 197:
+/* Line 1787 of yacc.c */
+#line 1655 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_MATRIX_INVERSE;
+ }
+ break;
+
+ case 198:
+/* Line 1787 of yacc.c */
+#line 1659 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_MATRIX_TRANSPOSE;
+ }
+ break;
+
+ case 199:
+/* Line 1787 of yacc.c */
+#line 1663 "program/program_parse.y"
+ {
+ (yyval.integer) = STATE_MATRIX_INVTRANS;
+ }
+ break;
+
+ case 200:
+/* Line 1787 of yacc.c */
+#line 1669 "program/program_parse.y"
+ {
+ if ((yyvsp[(1) - (1)].integer) > 3) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 201:
+/* Line 1787 of yacc.c */
+#line 1680 "program/program_parse.y"
+ {
+ (yyval.state)[0] = STATE_MODELVIEW_MATRIX;
+ (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 202:
+/* Line 1787 of yacc.c */
+#line 1685 "program/program_parse.y"
+ {
+ (yyval.state)[0] = STATE_PROJECTION_MATRIX;
+ (yyval.state)[1] = 0;
+ }
+ break;
+
+ case 203:
+/* Line 1787 of yacc.c */
+#line 1690 "program/program_parse.y"
+ {
+ (yyval.state)[0] = STATE_MVP_MATRIX;
+ (yyval.state)[1] = 0;
+ }
+ break;
+
+ case 204:
+/* Line 1787 of yacc.c */
+#line 1695 "program/program_parse.y"
+ {
+ (yyval.state)[0] = STATE_TEXTURE_MATRIX;
+ (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
+ }
+ break;
+
+ case 205:
+/* Line 1787 of yacc.c */
+#line 1700 "program/program_parse.y"
+ {
+ yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ }
+ break;
+
+ case 206:
+/* Line 1787 of yacc.c */
+#line 1705 "program/program_parse.y"
+ {
+ (yyval.state)[0] = STATE_PROGRAM_MATRIX;
+ (yyval.state)[1] = (yyvsp[(3) - (4)].integer);
+ }
+ break;
+
+ case 207:
+/* Line 1787 of yacc.c */
+#line 1712 "program/program_parse.y"
+ {
+ (yyval.integer) = 0;
+ }
+ break;
+
+ case 208:
+/* Line 1787 of yacc.c */
+#line 1716 "program/program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(2) - (3)].integer);
+ }
+ break;
+
+ case 209:
+/* Line 1787 of yacc.c */
+#line 1721 "program/program_parse.y"
+ {
+ /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
+ * zero is valid.
+ */
+ if ((yyvsp[(1) - (1)].integer) != 0) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid modelview matrix index");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 210:
+/* Line 1787 of yacc.c */
+#line 1734 "program/program_parse.y"
+ {
+ /* Since GL_ARB_matrix_palette isn't supported, just let any value
+ * through here. The error will be generated later.
+ */
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 211:
+/* Line 1787 of yacc.c */
+#line 1742 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 212:
+/* Line 1787 of yacc.c */
+#line 1753 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_DEPTH_RANGE;
+ }
+ break;
+
+ case 217:
+/* Line 1787 of yacc.c */
+#line 1765 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_ENV;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
+ (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
+ }
+ break;
+
+ case 218:
+/* Line 1787 of yacc.c */
+#line 1775 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
+ (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 219:
+/* Line 1787 of yacc.c */
+#line 1780 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
+ (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
+ }
+ break;
+
+ case 220:
+/* Line 1787 of yacc.c */
+#line 1787 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_ENV;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+ }
+ break;
+
+ case 221:
+/* Line 1787 of yacc.c */
+#line 1797 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_LOCAL;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
+ (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
+ }
+ break;
+
+ case 222:
+/* Line 1787 of yacc.c */
+#line 1806 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
+ (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 223:
+/* Line 1787 of yacc.c */
+#line 1811 "program/program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
+ (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
+ }
+ break;
+
+ case 224:
+/* Line 1787 of yacc.c */
+#line 1818 "program/program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_LOCAL;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+ }
+ break;
+
+ case 225:
+/* Line 1787 of yacc.c */
+#line 1828 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference");
+ YYERROR;
+ }
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 226:
+/* Line 1787 of yacc.c */
+#line 1838 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference");
+ YYERROR;
+ }
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 231:
+/* Line 1787 of yacc.c */
+#line 1853 "program/program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0].f = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[1].f = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[2].f = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[3].f = (yyvsp[(1) - (1)].real);
+ }
+ break;
+
+ case 232:
+/* Line 1787 of yacc.c */
+#line 1863 "program/program_parse.y"
+ {
+ (yyval.vector).count = 1;
+ (yyval.vector).data[0].f = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[1].f = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[2].f = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[3].f = (yyvsp[(1) - (1)].real);
+ }
+ break;
+
+ case 233:
+/* Line 1787 of yacc.c */
+#line 1871 "program/program_parse.y"
+ {
+ (yyval.vector).count = 1;
+ (yyval.vector).data[0].f = (float) (yyvsp[(1) - (1)].integer);
+ (yyval.vector).data[1].f = (float) (yyvsp[(1) - (1)].integer);
+ (yyval.vector).data[2].f = (float) (yyvsp[(1) - (1)].integer);
+ (yyval.vector).data[3].f = (float) (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 234:
+/* Line 1787 of yacc.c */
+#line 1881 "program/program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0].f = (yyvsp[(2) - (3)].real);
+ (yyval.vector).data[1].f = 0.0f;
+ (yyval.vector).data[2].f = 0.0f;
+ (yyval.vector).data[3].f = 1.0f;
+ }
+ break;
+
+ case 235:
+/* Line 1787 of yacc.c */
+#line 1889 "program/program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0].f = (yyvsp[(2) - (5)].real);
+ (yyval.vector).data[1].f = (yyvsp[(4) - (5)].real);
+ (yyval.vector).data[2].f = 0.0f;
+ (yyval.vector).data[3].f = 1.0f;
+ }
+ break;
+
+ case 236:
+/* Line 1787 of yacc.c */
+#line 1898 "program/program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0].f = (yyvsp[(2) - (7)].real);
+ (yyval.vector).data[1].f = (yyvsp[(4) - (7)].real);
+ (yyval.vector).data[2].f = (yyvsp[(6) - (7)].real);
+ (yyval.vector).data[3].f = 1.0f;
+ }
+ break;
+
+ case 237:
+/* Line 1787 of yacc.c */
+#line 1907 "program/program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0].f = (yyvsp[(2) - (9)].real);
+ (yyval.vector).data[1].f = (yyvsp[(4) - (9)].real);
+ (yyval.vector).data[2].f = (yyvsp[(6) - (9)].real);
+ (yyval.vector).data[3].f = (yyvsp[(8) - (9)].real);
+ }
+ break;
+
+ case 238:
+/* Line 1787 of yacc.c */
+#line 1917 "program/program_parse.y"
+ {
+ (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real);
+ }
+ break;
+
+ case 239:
+/* Line 1787 of yacc.c */
+#line 1921 "program/program_parse.y"
+ {
+ (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer));
+ }
+ break;
+
+ case 240:
+/* Line 1787 of yacc.c */
+#line 1926 "program/program_parse.y"
+ { (yyval.negate) = FALSE; }
+ break;
+
+ case 241:
+/* Line 1787 of yacc.c */
+#line 1927 "program/program_parse.y"
+ { (yyval.negate) = TRUE; }
+ break;
+
+ case 242:
+/* Line 1787 of yacc.c */
+#line 1928 "program/program_parse.y"
+ { (yyval.negate) = FALSE; }
+ break;
+
+ case 243:
+/* Line 1787 of yacc.c */
+#line 1931 "program/program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (2)].integer); }
+ break;
+
+ case 245:
+/* Line 1787 of yacc.c */
+#line 1935 "program/program_parse.y"
+ {
+ /* NV_fragment_program_option defines the size qualifiers in a
+ * fairly broken way. "SHORT" or "LONG" can optionally be used
+ * before TEMP or OUTPUT. However, neither is a reserved word!
+ * This means that we have to parse it as an identifier, then check
+ * to make sure it's one of the valid values. *sigh*
+ *
+ * In addition, the grammar in the extension spec does *not* allow
+ * the size specifier to be optional, but all known implementations
+ * do.
+ */
+ if (!state->option.NV_fragment) {
+ yyerror(& (yylsp[(1) - (1)]), state, "unexpected IDENTIFIER");
+ YYERROR;
+ }
+
+ if (strcmp("SHORT", (yyvsp[(1) - (1)].string)) == 0) {
+ } else if (strcmp("LONG", (yyvsp[(1) - (1)].string)) == 0) {
+ } else {
+ char *const err_str =
+ make_error_string("invalid storage size specifier \"%s\"",
+ (yyvsp[(1) - (1)].string));
+
+ yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
+ ? err_str : "invalid storage size specifier");
+
+ if (err_str != NULL) {
+ free(err_str);
+ }
+
+ YYERROR;
+ }
+ }
+ break;
+
+ case 246:
+/* Line 1787 of yacc.c */
+#line 1969 "program/program_parse.y"
+ {
+ }
+ break;
+
+ case 247:
+/* Line 1787 of yacc.c */
+#line 1973 "program/program_parse.y"
+ { (yyval.integer) = (yyvsp[(1) - (1)].integer); }
+ break;
+
+ case 249:
+/* Line 1787 of yacc.c */
+#line 1977 "program/program_parse.y"
+ {
+ if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) {
+ free((yyvsp[(3) - (3)].string));
+ YYERROR;
+ }
+ }
+ break;
+
+ case 250:
+/* Line 1787 of yacc.c */
+#line 1984 "program/program_parse.y"
+ {
+ if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) {
+ free((yyvsp[(1) - (1)].string));
+ YYERROR;
+ }
+ }
+ break;
+
+ case 251:
+/* Line 1787 of yacc.c */
+#line 1993 "program/program_parse.y"
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(3) - (5)].string), at_output, & (yylsp[(3) - (5)]));
+
+ if (s == NULL) {
+ free((yyvsp[(3) - (5)].string));
+ YYERROR;
+ } else {
+ s->output_binding = (yyvsp[(5) - (5)].result);
+ }
+ }
+ break;
+
+ case 252:
+/* Line 1787 of yacc.c */
+#line 2007 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VARYING_SLOT_POS;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 253:
+/* Line 1787 of yacc.c */
+#line 2016 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VARYING_SLOT_FOGC;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 254:
+/* Line 1787 of yacc.c */
+#line 2025 "program/program_parse.y"
+ {
+ (yyval.result) = (yyvsp[(2) - (2)].result);
+ }
+ break;
+
+ case 255:
+/* Line 1787 of yacc.c */
+#line 2029 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VARYING_SLOT_PSIZ;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 256:
+/* Line 1787 of yacc.c */
+#line 2038 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VARYING_SLOT_TEX0 + (yyvsp[(3) - (3)].integer);
+ } else {
+ yyerror(& (yylsp[(2) - (3)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 257:
+/* Line 1787 of yacc.c */
+#line 2047 "program/program_parse.y"
+ {
+ if (state->mode == ARB_fragment) {
+ (yyval.result) = FRAG_RESULT_DEPTH;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 258:
+/* Line 1787 of yacc.c */
+#line 2058 "program/program_parse.y"
+ {
+ (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer);
+ }
+ break;
+
+ case 259:
+/* Line 1787 of yacc.c */
+#line 2064 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = VARYING_SLOT_COL0;
+ } else {
+ if (state->option.DrawBuffers)
+ (yyval.integer) = FRAG_RESULT_DATA0;
+ else
+ (yyval.integer) = FRAG_RESULT_COLOR;
+ }
+ }
+ break;
+
+ case 260:
+/* Line 1787 of yacc.c */
+#line 2075 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ yyerror(& (yylsp[(1) - (3)]), state, "invalid program result name");
+ YYERROR;
+ } else {
+ if (!state->option.DrawBuffers) {
+ /* From the ARB_draw_buffers spec (same text exists
+ * for ATI_draw_buffers):
+ *
+ * If this option is not specified, a fragment
+ * program that attempts to bind
+ * "result.color[n]" will fail to load, and only
+ * "result.color" will be allowed.
+ */
+ yyerror(& (yylsp[(1) - (3)]), state,
+ "result.color[] used without "
+ "`OPTION ARB_draw_buffers' or "
+ "`OPTION ATI_draw_buffers'");
+ YYERROR;
+ } else if ((yyvsp[(2) - (3)].integer) >= state->MaxDrawBuffers) {
+ yyerror(& (yylsp[(1) - (3)]), state,
+ "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
+ YYERROR;
+ }
+ (yyval.integer) = FRAG_RESULT_DATA0 + (yyvsp[(2) - (3)].integer);
+ }
+ }
+ break;
+
+ case 261:
+/* Line 1787 of yacc.c */
+#line 2103 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = VARYING_SLOT_COL0;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 262:
+/* Line 1787 of yacc.c */
+#line 2112 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = VARYING_SLOT_BFC0;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 263:
+/* Line 1787 of yacc.c */
+#line 2123 "program/program_parse.y"
+ {
+ (yyval.integer) = 0;
+ }
+ break;
+
+ case 264:
+/* Line 1787 of yacc.c */
+#line 2127 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = 0;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 265:
+/* Line 1787 of yacc.c */
+#line 2136 "program/program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = 1;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 266:
+/* Line 1787 of yacc.c */
+#line 2146 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 267:
+/* Line 1787 of yacc.c */
+#line 2147 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 268:
+/* Line 1787 of yacc.c */
+#line 2148 "program/program_parse.y"
+ { (yyval.integer) = 1; }
+ break;
+
+ case 269:
+/* Line 1787 of yacc.c */
+#line 2151 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 270:
+/* Line 1787 of yacc.c */
+#line 2152 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 271:
+/* Line 1787 of yacc.c */
+#line 2153 "program/program_parse.y"
+ { (yyval.integer) = 1; }
+ break;
+
+ case 272:
+/* Line 1787 of yacc.c */
+#line 2156 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 273:
+/* Line 1787 of yacc.c */
+#line 2157 "program/program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (3)].integer); }
+ break;
+
+ case 274:
+/* Line 1787 of yacc.c */
+#line 2160 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 275:
+/* Line 1787 of yacc.c */
+#line 2161 "program/program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (3)].integer); }
+ break;
+
+ case 276:
+/* Line 1787 of yacc.c */
+#line 2164 "program/program_parse.y"
+ { (yyval.integer) = 0; }
+ break;
+
+ case 277:
+/* Line 1787 of yacc.c */
+#line 2165 "program/program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (3)].integer); }
+ break;
+
+ case 278:
+/* Line 1787 of yacc.c */
+#line 2169 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 279:
+/* Line 1787 of yacc.c */
+#line 2180 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 280:
+/* Line 1787 of yacc.c */
+#line 2191 "program/program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ break;
+
+ case 281:
+/* Line 1787 of yacc.c */
+#line 2202 "program/program_parse.y"
+ {
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string));
+ struct asm_symbol *target = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(4) - (4)].string));
+
+ free((yyvsp[(4) - (4)].string));
+
+ if (exist != NULL) {
+ char m[1000];
+ _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", (yyvsp[(2) - (4)].string));
+ free((yyvsp[(2) - (4)].string));
+ yyerror(& (yylsp[(2) - (4)]), state, m);
+ YYERROR;
+ } else if (target == NULL) {
+ free((yyvsp[(2) - (4)].string));
+ yyerror(& (yylsp[(4) - (4)]), state,
+ "undefined variable binding in ALIAS statement");
+ YYERROR;
+ } else {
+ _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target);
+ }
+ }
+ break;
+
+
+/* Line 1787 of yacc.c */
+#line 4857 "./program/program_parse.tab.c"
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, state, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (&yylloc, state, yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+ yyerror_range[1] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc, state);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[1] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp, state);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ yyerror_range[2] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, state, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc, state);
+ }
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp, state);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+/* Line 2050 of yacc.c */
+#line 2231 "program/program_parse.y"
+
+
+void
+asm_instruction_set_operands(struct asm_instruction *inst,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ /* In the core ARB extensions only the KIL instruction doesn't have a
+ * destination register.
+ */
+ if (dst == NULL) {
+ init_dst_reg(& inst->Base.DstReg);
+ } else {
+ inst->Base.DstReg = *dst;
+ }
+
+ /* The only instruction that doesn't have any source registers is the
+ * condition-code based KIL instruction added by NV_fragment_program_option.
+ */
+ if (src0 != NULL) {
+ inst->Base.SrcReg[0] = src0->Base;
+ inst->SrcReg[0] = *src0;
+ } else {
+ init_src_reg(& inst->SrcReg[0]);
+ }
+
+ if (src1 != NULL) {
+ inst->Base.SrcReg[1] = src1->Base;
+ inst->SrcReg[1] = *src1;
+ } else {
+ init_src_reg(& inst->SrcReg[1]);
+ }
+
+ if (src2 != NULL) {
+ inst->Base.SrcReg[2] = src2->Base;
+ inst->SrcReg[2] = *src2;
+ } else {
+ init_src_reg(& inst->SrcReg[2]);
+ }
+}
+
+
+struct asm_instruction *
+asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+ if (inst) {
+ _mesa_init_instructions(& inst->Base, 1);
+ inst->Base.Opcode = op;
+
+ asm_instruction_set_operands(inst, dst, src0, src1, src2);
+ }
+
+ return inst;
+}
+
+
+struct asm_instruction *
+asm_instruction_copy_ctor(const struct prog_instruction *base,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+ if (inst) {
+ _mesa_init_instructions(& inst->Base, 1);
+ inst->Base.Opcode = base->Opcode;
+ inst->Base.CondUpdate = base->CondUpdate;
+ inst->Base.CondDst = base->CondDst;
+ inst->Base.SaturateMode = base->SaturateMode;
+ inst->Base.Precision = base->Precision;
+
+ asm_instruction_set_operands(inst, dst, src0, src1, src2);
+ }
+
+ return inst;
+}
+
+
+void
+init_dst_reg(struct prog_dst_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->File = PROGRAM_UNDEFINED;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+/** Like init_dst_reg() but set the File and Index fields. */
+void
+set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
+{
+ const GLint maxIndex = 1 << INST_INDEX_BITS;
+ const GLint minIndex = 0;
+ ASSERT(index >= minIndex);
+ (void) minIndex;
+ ASSERT(index <= maxIndex);
+ (void) maxIndex;
+ ASSERT(file == PROGRAM_TEMPORARY ||
+ file == PROGRAM_ADDRESS ||
+ file == PROGRAM_OUTPUT);
+ memset(r, 0, sizeof(*r));
+ r->File = file;
+ r->Index = index;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+void
+init_src_reg(struct asm_src_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->Base.File = PROGRAM_UNDEFINED;
+ r->Base.Swizzle = SWIZZLE_NOOP;
+ r->Symbol = NULL;
+}
+
+
+/** Like init_src_reg() but set the File and Index fields.
+ * \return GL_TRUE if a valid src register, GL_FALSE otherwise
+ */
+void
+set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
+{
+ set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
+}
+
+
+void
+set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
+ GLuint swizzle)
+{
+ const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
+ const GLint minIndex = -(1 << INST_INDEX_BITS);
+ ASSERT(file < PROGRAM_FILE_MAX);
+ ASSERT(index >= minIndex);
+ (void) minIndex;
+ ASSERT(index <= maxIndex);
+ (void) maxIndex;
+ memset(r, 0, sizeof(*r));
+ r->Base.File = file;
+ r->Base.Index = index;
+ r->Base.Swizzle = swizzle;
+ r->Symbol = NULL;
+}
+
+
+/**
+ * Validate the set of inputs used by a program
+ *
+ * Validates that legal sets of inputs are used by the program. In this case
+ * "used" included both reading the input or binding the input to a name using
+ * the \c ATTRIB command.
+ *
+ * \return
+ * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
+ */
+int
+validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
+{
+ const GLbitfield64 inputs = state->prog->InputsRead | state->InputsBound;
+
+ if (((inputs & VERT_BIT_FF_ALL) & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
+ yyerror(locp, state, "illegal use of generic attribute and name attribute");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+struct asm_symbol *
+declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
+ struct YYLTYPE *locp)
+{
+ struct asm_symbol *s = NULL;
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, name);
+
+
+ if (exist != NULL) {
+ yyerror(locp, state, "redeclared identifier");
+ } else {
+ s = calloc(1, sizeof(struct asm_symbol));
+ s->name = name;
+ s->type = t;
+
+ switch (t) {
+ case at_temp:
+ if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+ yyerror(locp, state, "too many temporaries declared");
+ free(s);
+ return NULL;
+ }
+
+ s->temp_binding = state->prog->NumTemporaries;
+ state->prog->NumTemporaries++;
+ break;
+
+ case at_address:
+ if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+ yyerror(locp, state, "too many address registers declared");
+ free(s);
+ return NULL;
+ }
+
+ /* FINISHME: Add support for multiple address registers.
+ */
+ state->prog->NumAddressRegs++;
+ break;
+
+ default:
+ break;
+ }
+
+ _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+ s->next = state->sym;
+ state->sym = s;
+ }
+
+ return s;
+}
+
+
+int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ const GLuint size = 4; /* XXX fix */
+ char *name;
+ GLint index;
+
+ name = _mesa_program_state_string(tokens);
+ index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
+ size, GL_NONE, NULL, tokens);
+ param_list->StateFlags |= _mesa_program_state_flags(tokens);
+
+ /* free name string here since we duplicated it in add_parameter() */
+ free(name);
+
+ return index;
+}
+
+
+int
+initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+ /* If we are adding a STATE_MATRIX that has multiple rows, we need to
+ * unroll it and call add_state_reference() for each row
+ */
+ if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
+ state_tokens[0] == STATE_PROJECTION_MATRIX ||
+ state_tokens[0] == STATE_MVP_MATRIX ||
+ state_tokens[0] == STATE_TEXTURE_MATRIX ||
+ state_tokens[0] == STATE_PROGRAM_MATRIX)
+ && (state_tokens[2] != state_tokens[3])) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+int
+initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
+ || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
+ assert((state_tokens[1] == STATE_ENV)
+ || (state_tokens[1] == STATE_LOCAL));
+
+ /*
+ * The param type is STATE_VAR. The program parameter entry will
+ * effectively be a pointer into the LOCAL or ENV parameter array.
+ */
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+ /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
+ * we need to unroll it and call add_state_reference() for each row
+ */
+ if (state_tokens[2] != state_tokens[3]) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+/**
+ * Put a float/vector constant/literal into the parameter list.
+ * \param param_var returns info about the parameter/constant's location,
+ * binding, type, etc.
+ * \param vec the vector/constant to add
+ * \param allowSwizzle if true, try to consolidate constants which only differ
+ * by a swizzle. We don't want to do this when building
+ * arrays of constants that may be indexed indirectly.
+ * \return index of the constant in the parameter list.
+ */
+int
+initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const struct asm_vector *vec,
+ GLboolean allowSwizzle)
+{
+ unsigned swizzle;
+ const int idx = _mesa_add_unnamed_constant(prog->Parameters,
+ vec->data, vec->count,
+ allowSwizzle ? &swizzle : NULL);
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_CONSTANT;
+
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+
+ return idx;
+}
+
+
+char *
+make_error_string(const char *fmt, ...)
+{
+ int length;
+ char *str;
+ va_list args;
+
+
+ /* Call vsnprintf once to determine how large the final string is. Call it
+ * again to do the actual formatting. from the vsnprintf manual page:
+ *
+ * Upon successful return, these functions return the number of
+ * characters printed (not including the trailing '\0' used to end
+ * output to strings).
+ */
+ va_start(args, fmt);
+ length = 1 + vsnprintf(NULL, 0, fmt, args);
+ va_end(args);
+
+ str = malloc(length);
+ if (str) {
+ va_start(args, fmt);
+ vsnprintf(str, length, fmt, args);
+ va_end(args);
+ }
+
+ return str;
+}
+
+
+void
+yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
+{
+ char *err_str;
+
+
+ err_str = make_error_string("glProgramStringARB(%s)\n", s);
+ if (err_str) {
+ _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str);
+ free(err_str);
+ }
+
+ err_str = make_error_string("line %u, char %u: error: %s\n",
+ locp->first_line, locp->first_column, s);
+ _mesa_set_program_error(state->ctx, locp->position, err_str);
+
+ if (err_str) {
+ free(err_str);
+ }
+}
+
+
+GLboolean
+_mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str,
+ GLsizei len, struct asm_parser_state *state)
+{
+ struct asm_instruction *inst;
+ unsigned i;
+ GLubyte *strz;
+ GLboolean result = GL_FALSE;
+ void *temp;
+ struct asm_symbol *sym;
+
+ state->ctx = ctx;
+ state->prog->Target = target;
+ state->prog->Parameters = _mesa_new_parameter_list();
+
+ /* Make a copy of the program string and force it to be NUL-terminated.
+ */
+ strz = (GLubyte *) malloc(len + 1);
+ if (strz == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return GL_FALSE;
+ }
+ memcpy (strz, str, len);
+ strz[len] = '\0';
+
+ state->prog->String = strz;
+
+ state->st = _mesa_symbol_table_ctor();
+
+ state->limits = (target == GL_VERTEX_PROGRAM_ARB)
+ ? & ctx->Const.Program[MESA_SHADER_VERTEX]
+ : & ctx->Const.Program[MESA_SHADER_FRAGMENT];
+
+ state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
+ state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
+ state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
+ state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
+ state->MaxLights = ctx->Const.MaxLights;
+ state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+ state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
+
+ state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
+ ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
+
+ _mesa_set_program_error(ctx, -1, NULL);
+
+ _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
+ yyparse(state);
+ _mesa_program_lexer_dtor(state->scanner);
+
+
+ if (ctx->Program.ErrorPos != -1) {
+ goto error;
+ }
+
+ if (! _mesa_layout_parameters(state)) {
+ struct YYLTYPE loc;
+
+ loc.first_line = 0;
+ loc.first_column = 0;
+ loc.position = len;
+
+ yyerror(& loc, state, "invalid PARAM usage");
+ goto error;
+ }
+
+
+
+ /* Add one instruction to store the "END" instruction.
+ */
+ state->prog->Instructions =
+ _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+
+ if (state->prog->Instructions == NULL) {
+ goto error;
+ }
+
+ inst = state->inst_head;
+ for (i = 0; i < state->prog->NumInstructions; i++) {
+ struct asm_instruction *const temp = inst->next;
+
+ state->prog->Instructions[i] = inst->Base;
+ inst = temp;
+ }
+
+ /* Finally, tag on an OPCODE_END instruction */
+ {
+ const GLuint numInst = state->prog->NumInstructions;
+ _mesa_init_instructions(state->prog->Instructions + numInst, 1);
+ state->prog->Instructions[numInst].Opcode = OPCODE_END;
+ }
+ state->prog->NumInstructions++;
+
+ state->prog->NumParameters = state->prog->Parameters->NumParameters;
+ state->prog->NumAttributes = _mesa_bitcount_64(state->prog->InputsRead);
+
+ /*
+ * Initialize native counts to logical counts. The device driver may
+ * change them if program is translated into a hardware program.
+ */
+ state->prog->NumNativeInstructions = state->prog->NumInstructions;
+ state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
+ state->prog->NumNativeParameters = state->prog->NumParameters;
+ state->prog->NumNativeAttributes = state->prog->NumAttributes;
+ state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+
+ result = GL_TRUE;
+
+error:
+ for (inst = state->inst_head; inst != NULL; inst = temp) {
+ temp = inst->next;
+ free(inst);
+ }
+
+ state->inst_head = NULL;
+ state->inst_tail = NULL;
+
+ for (sym = state->sym; sym != NULL; sym = temp) {
+ temp = sym->next;
+
+ free((void *) sym->name);
+ free(sym);
+ }
+ state->sym = NULL;
+
+ _mesa_symbol_table_dtor(state->st);
+ state->st = NULL;
+
+ return result;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.tab.h b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.tab.h
new file mode 100644
index 0000000..eab1c10
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.tab.h
@@ -0,0 +1,225 @@
+/* A Bison parser, made by GNU Bison 2.7.12-4996. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY__MESA_PROGRAM_PROGRAM_PROGRAM_PARSE_TAB_H_INCLUDED
+# define YY__MESA_PROGRAM_PROGRAM_PROGRAM_PARSE_TAB_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int _mesa_program_debug;
+#endif
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ARBvp_10 = 258,
+ ARBfp_10 = 259,
+ ADDRESS = 260,
+ ALIAS = 261,
+ ATTRIB = 262,
+ OPTION = 263,
+ OUTPUT = 264,
+ PARAM = 265,
+ TEMP = 266,
+ END = 267,
+ BIN_OP = 268,
+ BINSC_OP = 269,
+ SAMPLE_OP = 270,
+ SCALAR_OP = 271,
+ TRI_OP = 272,
+ VECTOR_OP = 273,
+ ARL = 274,
+ KIL = 275,
+ SWZ = 276,
+ TXD_OP = 277,
+ INTEGER = 278,
+ REAL = 279,
+ AMBIENT = 280,
+ ATTENUATION = 281,
+ BACK = 282,
+ CLIP = 283,
+ COLOR = 284,
+ DEPTH = 285,
+ DIFFUSE = 286,
+ DIRECTION = 287,
+ EMISSION = 288,
+ ENV = 289,
+ EYE = 290,
+ FOG = 291,
+ FOGCOORD = 292,
+ FRAGMENT = 293,
+ FRONT = 294,
+ HALF = 295,
+ INVERSE = 296,
+ INVTRANS = 297,
+ LIGHT = 298,
+ LIGHTMODEL = 299,
+ LIGHTPROD = 300,
+ LOCAL = 301,
+ MATERIAL = 302,
+ MAT_PROGRAM = 303,
+ MATRIX = 304,
+ MATRIXINDEX = 305,
+ MODELVIEW = 306,
+ MVP = 307,
+ NORMAL = 308,
+ OBJECT = 309,
+ PALETTE = 310,
+ PARAMS = 311,
+ PLANE = 312,
+ POINT_TOK = 313,
+ POINTSIZE = 314,
+ POSITION = 315,
+ PRIMARY = 316,
+ PROGRAM = 317,
+ PROJECTION = 318,
+ RANGE = 319,
+ RESULT = 320,
+ ROW = 321,
+ SCENECOLOR = 322,
+ SECONDARY = 323,
+ SHININESS = 324,
+ SIZE_TOK = 325,
+ SPECULAR = 326,
+ SPOT = 327,
+ STATE = 328,
+ TEXCOORD = 329,
+ TEXENV = 330,
+ TEXGEN = 331,
+ TEXGEN_Q = 332,
+ TEXGEN_R = 333,
+ TEXGEN_S = 334,
+ TEXGEN_T = 335,
+ TEXTURE = 336,
+ TRANSPOSE = 337,
+ TEXTURE_UNIT = 338,
+ TEX_1D = 339,
+ TEX_2D = 340,
+ TEX_3D = 341,
+ TEX_CUBE = 342,
+ TEX_RECT = 343,
+ TEX_SHADOW1D = 344,
+ TEX_SHADOW2D = 345,
+ TEX_SHADOWRECT = 346,
+ TEX_ARRAY1D = 347,
+ TEX_ARRAY2D = 348,
+ TEX_ARRAYSHADOW1D = 349,
+ TEX_ARRAYSHADOW2D = 350,
+ VERTEX = 351,
+ VTXATTRIB = 352,
+ WEIGHT = 353,
+ IDENTIFIER = 354,
+ USED_IDENTIFIER = 355,
+ MASK4 = 356,
+ MASK3 = 357,
+ MASK2 = 358,
+ MASK1 = 359,
+ SWIZZLE = 360,
+ DOT_DOT = 361,
+ DOT = 362
+ };
+#endif
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+/* Line 2053 of yacc.c */
+#line 124 "program/program_parse.y"
+
+ struct asm_instruction *inst;
+ struct asm_symbol *sym;
+ struct asm_symbol temp_sym;
+ struct asm_swizzle_mask swiz_mask;
+ struct asm_src_register src_reg;
+ struct prog_dst_register dst_reg;
+ struct prog_instruction temp_inst;
+ char *string;
+ unsigned result;
+ unsigned attrib;
+ int integer;
+ float real;
+ gl_state_index state[STATE_LENGTH];
+ int negate;
+ struct asm_vector vector;
+ gl_inst_opcode opcode;
+
+ struct {
+ unsigned swz;
+ unsigned rgba_valid:1;
+ unsigned xyzw_valid:1;
+ unsigned negate:1;
+ } ext_swizzle;
+
+
+/* Line 2053 of yacc.c */
+#line 191 "./program/program_parse.tab.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int _mesa_program_parse (void *YYPARSE_PARAM);
+#else
+int _mesa_program_parse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int _mesa_program_parse (struct asm_parser_state *state);
+#else
+int _mesa_program_parse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY__MESA_PROGRAM_PROGRAM_PROGRAM_PARSE_TAB_H_INCLUDED */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.y b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.y
new file mode 100644
index 0000000..1664740
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse.y
@@ -0,0 +1,2809 @@
+%{
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_parameter_layout.h"
+#include "program/prog_statevars.h"
+#include "program/prog_instruction.h"
+
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+
+extern void *yy_scan_string(char *);
+extern void yy_delete_buffer(void *);
+
+static struct asm_symbol *declare_variable(struct asm_parser_state *state,
+ char *name, enum asm_type t, struct YYLTYPE *locp);
+
+static int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var, const struct asm_vector *vec,
+ GLboolean allowSwizzle);
+
+static int yyparse(struct asm_parser_state *state);
+
+static char *make_error_string(const char *fmt, ...);
+
+static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
+ const char *s);
+
+static int validate_inputs(struct YYLTYPE *locp,
+ struct asm_parser_state *state);
+
+static void init_dst_reg(struct prog_dst_register *r);
+
+static void set_dst_reg(struct prog_dst_register *r,
+ gl_register_file file, GLint index);
+
+static void init_src_reg(struct asm_src_register *r);
+
+static void set_src_reg(struct asm_src_register *r,
+ gl_register_file file, GLint index);
+
+static void set_src_reg_swz(struct asm_src_register *r,
+ gl_register_file file, GLint index, GLuint swizzle);
+
+static void asm_instruction_set_operands(struct asm_instruction *inst,
+ const struct prog_dst_register *dst, const struct asm_src_register *src0,
+ const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst, const struct asm_src_register *src0,
+ const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_copy_ctor(
+ const struct prog_instruction *base, const struct prog_dst_register *dst,
+ const struct asm_src_register *src0, const struct asm_src_register *src1,
+ const struct asm_src_register *src2);
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (N) { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 1).position; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
+ } else { \
+ (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).last_line = (Current).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \
+ (Current).last_column = (Current).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 0).position \
+ + (Current).first_column; \
+ } \
+ } while(0)
+%}
+
+%pure-parser
+%locations
+%lex-param { struct asm_parser_state *state }
+%parse-param { struct asm_parser_state *state }
+%error-verbose
+
+%union {
+ struct asm_instruction *inst;
+ struct asm_symbol *sym;
+ struct asm_symbol temp_sym;
+ struct asm_swizzle_mask swiz_mask;
+ struct asm_src_register src_reg;
+ struct prog_dst_register dst_reg;
+ struct prog_instruction temp_inst;
+ char *string;
+ unsigned result;
+ unsigned attrib;
+ int integer;
+ float real;
+ gl_state_index state[STATE_LENGTH];
+ int negate;
+ struct asm_vector vector;
+ gl_inst_opcode opcode;
+
+ struct {
+ unsigned swz;
+ unsigned rgba_valid:1;
+ unsigned xyzw_valid:1;
+ unsigned negate:1;
+ } ext_swizzle;
+}
+
+%token ARBvp_10 ARBfp_10
+
+/* Tokens for assembler pseudo-ops */
+%token <integer> ADDRESS
+%token ALIAS ATTRIB
+%token OPTION OUTPUT
+%token PARAM
+%token <integer> TEMP
+%token END
+
+ /* Tokens for instructions */
+%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
+%token <temp_inst> ARL KIL SWZ TXD_OP
+
+%token <integer> INTEGER
+%token <real> REAL
+
+%token AMBIENT ATTENUATION
+%token BACK
+%token CLIP COLOR
+%token DEPTH DIFFUSE DIRECTION
+%token EMISSION ENV EYE
+%token FOG FOGCOORD FRAGMENT FRONT
+%token HALF
+%token INVERSE INVTRANS
+%token LIGHT LIGHTMODEL LIGHTPROD LOCAL
+%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
+%token NORMAL
+%token OBJECT
+%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
+%token RANGE RESULT ROW
+%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
+%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
+%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
+%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
+%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D
+%token VERTEX VTXATTRIB
+%token WEIGHT
+
+%token <string> IDENTIFIER USED_IDENTIFIER
+%type <string> string
+%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
+%token DOT_DOT
+%token DOT
+
+%type <inst> instruction ALU_instruction TexInstruction
+%type <inst> ARL_instruction VECTORop_instruction
+%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
+%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
+%type <inst> KIL_instruction
+
+%type <dst_reg> dstReg maskedDstReg maskedAddrReg
+%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
+%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
+%type <ext_swizzle> extSwizComp extSwizSel
+%type <swiz_mask> optionalMask
+
+%type <sym> progParamArray
+%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
+%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
+%type <sym> addrReg
+%type <swiz_mask> addrComponent addrWriteMask
+
+%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
+
+%type <result> resultBinding resultColBinding
+%type <integer> optFaceType optColorType
+%type <integer> optResultFaceType optResultColorType
+
+%type <integer> optTexImageUnitNum texImageUnitNum
+%type <integer> optTexCoordUnitNum texCoordUnitNum
+%type <integer> optLegacyTexUnitNum legacyTexUnitNum
+%type <integer> texImageUnit texTarget
+%type <integer> vtxAttribNum
+
+%type <attrib> attribBinding vtxAttribItem fragAttribItem
+
+%type <temp_sym> paramSingleInit paramSingleItemDecl
+%type <integer> optArraySize
+
+%type <state> stateSingleItem stateMultipleItem
+%type <state> stateMaterialItem
+%type <state> stateLightItem stateLightModelItem stateLightProdItem
+%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
+%type <state> stateMatrixItem stateMatrixRow stateMatrixRows
+%type <state> stateTexEnvItem stateDepthItem
+
+%type <state> stateLModProperty
+%type <state> stateMatrixName optMatrixRows
+
+%type <integer> stateMatProperty
+%type <integer> stateLightProperty stateSpotProperty
+%type <integer> stateLightNumber stateLProdProperty
+%type <integer> stateTexGenType stateTexGenCoord
+%type <integer> stateTexEnvProperty
+%type <integer> stateFogProperty
+%type <integer> stateClipPlaneNum
+%type <integer> statePointProperty
+
+%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
+%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
+%type <integer> stateProgramMatNum
+
+%type <integer> ambDiffSpecProperty
+
+%type <state> programSingleItem progEnvParam progLocalParam
+%type <state> programMultipleItem progEnvParams progLocalParams
+
+%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
+%type <temp_sym> paramSingleItemUse
+
+%type <integer> progEnvParamNum progLocalParamNum
+%type <state> progEnvParamNums progLocalParamNums
+
+%type <vector> paramConstDecl paramConstUse
+%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
+%type <real> signedFloatConstant
+%type <negate> optionalSign
+
+%{
+extern int
+_mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ void *yyscanner);
+
+static int
+yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ struct asm_parser_state *state)
+{
+ return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner);
+}
+%}
+
+%%
+
+program: language optionSequence statementSequence END
+ ;
+
+language: ARBvp_10
+ {
+ if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
+ yyerror(& @1, state, "invalid fragment program header");
+
+ }
+ state->mode = ARB_vertex;
+ }
+ | ARBfp_10
+ {
+ if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
+ yyerror(& @1, state, "invalid vertex program header");
+ }
+ state->mode = ARB_fragment;
+
+ state->option.TexRect =
+ (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
+ }
+ ;
+
+optionSequence: optionSequence option
+ |
+ ;
+
+option: OPTION string ';'
+ {
+ int valid = 0;
+
+ if (state->mode == ARB_vertex) {
+ valid = _mesa_ARBvp_parse_option(state, $2);
+ } else if (state->mode == ARB_fragment) {
+ valid = _mesa_ARBfp_parse_option(state, $2);
+ }
+
+
+ free($2);
+
+ if (!valid) {
+ const char *const err_str = (state->mode == ARB_vertex)
+ ? "invalid ARB vertex program option"
+ : "invalid ARB fragment program option";
+
+ yyerror(& @2, state, err_str);
+ YYERROR;
+ }
+ }
+ ;
+
+statementSequence: statementSequence statement
+ |
+ ;
+
+statement: instruction ';'
+ {
+ if ($1 != NULL) {
+ if (state->inst_tail == NULL) {
+ state->inst_head = $1;
+ } else {
+ state->inst_tail->next = $1;
+ }
+
+ state->inst_tail = $1;
+ $1->next = NULL;
+
+ state->prog->NumInstructions++;
+ }
+ }
+ | namingStatement ';'
+ ;
+
+instruction: ALU_instruction
+ {
+ $$ = $1;
+ state->prog->NumAluInstructions++;
+ }
+ | TexInstruction
+ {
+ $$ = $1;
+ state->prog->NumTexInstructions++;
+ }
+ ;
+
+ALU_instruction: ARL_instruction
+ | VECTORop_instruction
+ | SCALARop_instruction
+ | BINSCop_instruction
+ | BINop_instruction
+ | TRIop_instruction
+ | SWZ_instruction
+ ;
+
+TexInstruction: SAMPLE_instruction
+ | KIL_instruction
+ | TXD_instruction
+ ;
+
+ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
+ {
+ $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
+ }
+ ;
+
+VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
+ {
+ if ($1.Opcode == OPCODE_DDY)
+ state->fragment.UsesDFdy = 1;
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+ }
+ ;
+
+SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
+ {
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+ }
+ ;
+
+BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
+ {
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
+ }
+ ;
+
+
+BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
+ {
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
+ }
+ ;
+
+TRIop_instruction: TRI_OP maskedDstReg ','
+ swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
+ {
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
+ }
+ ;
+
+SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
+ {
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+ if ($$ != NULL) {
+ const GLbitfield tex_mask = (1U << $6);
+ GLbitfield shadow_tex = 0;
+ GLbitfield target_mask = 0;
+
+
+ $$->Base.TexSrcUnit = $6;
+
+ if ($8 < 0) {
+ shadow_tex = tex_mask;
+
+ $$->Base.TexSrcTarget = -$8;
+ $$->Base.TexShadow = 1;
+ } else {
+ $$->Base.TexSrcTarget = $8;
+ }
+
+ target_mask = (1U << $$->Base.TexSrcTarget);
+
+ /* If this texture unit was previously accessed and that access
+ * had a different texture target, generate an error.
+ *
+ * If this texture unit was previously accessed and that access
+ * had a different shadow mode, generate an error.
+ */
+ if ((state->prog->TexturesUsed[$6] != 0)
+ && ((state->prog->TexturesUsed[$6] != target_mask)
+ || ((state->prog->ShadowSamplers & tex_mask)
+ != shadow_tex))) {
+ yyerror(& @8, state,
+ "multiple targets used on one texture image unit");
+ YYERROR;
+ }
+
+
+ state->prog->TexturesUsed[$6] |= target_mask;
+ state->prog->ShadowSamplers |= shadow_tex;
+ }
+ }
+ ;
+
+KIL_instruction: KIL swizzleSrcReg
+ {
+ $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
+ state->fragment.UsesKill = 1;
+ }
+ | KIL ccTest
+ {
+ $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
+ $$->Base.DstReg.CondMask = $2.CondMask;
+ $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
+ state->fragment.UsesKill = 1;
+ }
+ ;
+
+TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
+ {
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
+ if ($$ != NULL) {
+ const GLbitfield tex_mask = (1U << $10);
+ GLbitfield shadow_tex = 0;
+ GLbitfield target_mask = 0;
+
+
+ $$->Base.TexSrcUnit = $10;
+
+ if ($12 < 0) {
+ shadow_tex = tex_mask;
+
+ $$->Base.TexSrcTarget = -$12;
+ $$->Base.TexShadow = 1;
+ } else {
+ $$->Base.TexSrcTarget = $12;
+ }
+
+ target_mask = (1U << $$->Base.TexSrcTarget);
+
+ /* If this texture unit was previously accessed and that access
+ * had a different texture target, generate an error.
+ *
+ * If this texture unit was previously accessed and that access
+ * had a different shadow mode, generate an error.
+ */
+ if ((state->prog->TexturesUsed[$10] != 0)
+ && ((state->prog->TexturesUsed[$10] != target_mask)
+ || ((state->prog->ShadowSamplers & tex_mask)
+ != shadow_tex))) {
+ yyerror(& @12, state,
+ "multiple targets used on one texture image unit");
+ YYERROR;
+ }
+
+
+ state->prog->TexturesUsed[$10] |= target_mask;
+ state->prog->ShadowSamplers |= shadow_tex;
+ }
+ }
+ ;
+
+texImageUnit: TEXTURE_UNIT optTexImageUnitNum
+ {
+ $$ = $2;
+ }
+ ;
+
+texTarget: TEX_1D { $$ = TEXTURE_1D_INDEX; }
+ | TEX_2D { $$ = TEXTURE_2D_INDEX; }
+ | TEX_3D { $$ = TEXTURE_3D_INDEX; }
+ | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
+ | TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
+ | TEX_SHADOW1D { $$ = -TEXTURE_1D_INDEX; }
+ | TEX_SHADOW2D { $$ = -TEXTURE_2D_INDEX; }
+ | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
+ | TEX_ARRAY1D { $$ = TEXTURE_1D_ARRAY_INDEX; }
+ | TEX_ARRAY2D { $$ = TEXTURE_2D_ARRAY_INDEX; }
+ | TEX_ARRAYSHADOW1D { $$ = -TEXTURE_1D_ARRAY_INDEX; }
+ | TEX_ARRAYSHADOW2D { $$ = -TEXTURE_2D_ARRAY_INDEX; }
+ ;
+
+SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
+ {
+ /* FIXME: Is this correct? Should the extenedSwizzle be applied
+ * FIXME: to the existing swizzle?
+ */
+ $4.Base.Swizzle = $6.swizzle;
+ $4.Base.Negate = $6.mask;
+
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+ }
+ ;
+
+scalarSrcReg: optionalSign scalarUse
+ {
+ $$ = $2;
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+ }
+ | optionalSign '|' scalarUse '|'
+ {
+ $$ = $3;
+
+ if (!state->option.NV_fragment) {
+ yyerror(& @2, state, "unexpected character '|'");
+ YYERROR;
+ }
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+
+ $$.Base.Abs = 1;
+ }
+ ;
+
+scalarUse: srcReg scalarSuffix
+ {
+ $$ = $1;
+
+ $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+ $2.swizzle);
+ }
+ | paramConstScalarUse
+ {
+ struct asm_symbol temp_sym;
+
+ if (!state->option.NV_fragment) {
+ yyerror(& @1, state, "expected scalar suffix");
+ YYERROR;
+ }
+
+ memset(& temp_sym, 0, sizeof(temp_sym));
+ temp_sym.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
+
+ set_src_reg_swz(& $$, PROGRAM_CONSTANT,
+ temp_sym.param_binding_begin,
+ temp_sym.param_binding_swizzle);
+ }
+ ;
+
+swizzleSrcReg: optionalSign srcReg swizzleSuffix
+ {
+ $$ = $2;
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+
+ $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+ $3.swizzle);
+ }
+ | optionalSign '|' srcReg swizzleSuffix '|'
+ {
+ $$ = $3;
+
+ if (!state->option.NV_fragment) {
+ yyerror(& @2, state, "unexpected character '|'");
+ YYERROR;
+ }
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+
+ $$.Base.Abs = 1;
+ $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+ $4.swizzle);
+ }
+
+ ;
+
+maskedDstReg: dstReg optionalMask optionalCcMask
+ {
+ $$ = $1;
+ $$.WriteMask = $2.mask;
+ $$.CondMask = $3.CondMask;
+ $$.CondSwizzle = $3.CondSwizzle;
+
+ if ($$.File == PROGRAM_OUTPUT) {
+ /* Technically speaking, this should check that it is in
+ * vertex program mode. However, PositionInvariant can never be
+ * set in fragment program mode, so it is somewhat irrelevant.
+ */
+ if (state->option.PositionInvariant
+ && ($$.Index == VARYING_SLOT_POS)) {
+ yyerror(& @1, state, "position-invariant programs cannot "
+ "write position");
+ YYERROR;
+ }
+
+ state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
+ }
+ }
+ ;
+
+maskedAddrReg: addrReg addrWriteMask
+ {
+ set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
+ $$.WriteMask = $2.mask;
+ }
+ ;
+
+extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
+ {
+ const unsigned xyzw_valid =
+ ($1.xyzw_valid << 0)
+ | ($3.xyzw_valid << 1)
+ | ($5.xyzw_valid << 2)
+ | ($7.xyzw_valid << 3);
+ const unsigned rgba_valid =
+ ($1.rgba_valid << 0)
+ | ($3.rgba_valid << 1)
+ | ($5.rgba_valid << 2)
+ | ($7.rgba_valid << 3);
+
+ /* All of the swizzle components have to be valid in either RGBA
+ * or XYZW. Note that 0 and 1 are valid in both, so both masks
+ * can have some bits set.
+ *
+ * We somewhat deviate from the spec here. It would be really hard
+ * to figure out which component is the error, and there probably
+ * isn't a lot of benefit.
+ */
+ if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
+ yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
+ "components");
+ YYERROR;
+ }
+
+ $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
+ $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
+ | ($7.negate << 3);
+ }
+ ;
+
+extSwizComp: optionalSign extSwizSel
+ {
+ $$ = $2;
+ $$.negate = ($1) ? 1 : 0;
+ }
+ ;
+
+extSwizSel: INTEGER
+ {
+ if (($1 != 0) && ($1 != 1)) {
+ yyerror(& @1, state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+ $$.negate = 0;
+
+ /* 0 and 1 are valid for both RGBA swizzle names and XYZW
+ * swizzle names.
+ */
+ $$.xyzw_valid = 1;
+ $$.rgba_valid = 1;
+ }
+ | string
+ {
+ char s;
+
+ if (strlen($1) > 1) {
+ yyerror(& @1, state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ s = $1[0];
+ free($1);
+
+ $$.rgba_valid = 0;
+ $$.xyzw_valid = 0;
+ $$.negate = 0;
+
+ switch (s) {
+ case 'x':
+ $$.swz = SWIZZLE_X;
+ $$.xyzw_valid = 1;
+ break;
+ case 'y':
+ $$.swz = SWIZZLE_Y;
+ $$.xyzw_valid = 1;
+ break;
+ case 'z':
+ $$.swz = SWIZZLE_Z;
+ $$.xyzw_valid = 1;
+ break;
+ case 'w':
+ $$.swz = SWIZZLE_W;
+ $$.xyzw_valid = 1;
+ break;
+
+ case 'r':
+ $$.swz = SWIZZLE_X;
+ $$.rgba_valid = 1;
+ break;
+ case 'g':
+ $$.swz = SWIZZLE_Y;
+ $$.rgba_valid = 1;
+ break;
+ case 'b':
+ $$.swz = SWIZZLE_Z;
+ $$.rgba_valid = 1;
+ break;
+ case 'a':
+ $$.swz = SWIZZLE_W;
+ $$.rgba_valid = 1;
+ break;
+
+ default:
+ yyerror(& @1, state, "invalid extended swizzle selector");
+ YYERROR;
+ break;
+ }
+ }
+ ;
+
+srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ free($1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) && (s->type != at_temp)
+ && (s->type != at_attrib)) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type == at_param) && s->param_is_array) {
+ yyerror(& @1, state, "non-array access to array PARAM");
+ YYERROR;
+ }
+
+ init_src_reg(& $$);
+ switch (s->type) {
+ case at_temp:
+ set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
+ break;
+ case at_param:
+ set_src_reg_swz(& $$, s->param_binding_type,
+ s->param_binding_begin,
+ s->param_binding_swizzle);
+ break;
+ case at_attrib:
+ set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
+ state->prog->InputsRead |= BITFIELD64_BIT($$.Base.Index);
+
+ if (!validate_inputs(& @1, state)) {
+ YYERROR;
+ }
+ break;
+
+ default:
+ YYERROR;
+ break;
+ }
+ }
+ | attribBinding
+ {
+ set_src_reg(& $$, PROGRAM_INPUT, $1);
+ state->prog->InputsRead |= BITFIELD64_BIT($$.Base.Index);
+
+ if (!validate_inputs(& @1, state)) {
+ YYERROR;
+ }
+ }
+ | progParamArray '[' progParamArrayMem ']'
+ {
+ if (! $3.Base.RelAddr
+ && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
+ yyerror(& @3, state, "out of bounds array access");
+ YYERROR;
+ }
+
+ init_src_reg(& $$);
+ $$.Base.File = $1->param_binding_type;
+
+ if ($3.Base.RelAddr) {
+ state->prog->IndirectRegisterFiles |= (1 << $$.Base.File);
+ $1->param_accessed_indirectly = 1;
+
+ $$.Base.RelAddr = 1;
+ $$.Base.Index = $3.Base.Index;
+ $$.Symbol = $1;
+ } else {
+ $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
+ }
+ }
+ | paramSingleItemUse
+ {
+ gl_register_file file = ($1.name != NULL)
+ ? $1.param_binding_type
+ : PROGRAM_CONSTANT;
+ set_src_reg_swz(& $$, file, $1.param_binding_begin,
+ $1.param_binding_swizzle);
+ }
+ ;
+
+dstReg: resultBinding
+ {
+ set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
+ }
+ | USED_IDENTIFIER /* temporaryReg | vertexResultReg */
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ free($1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_output) && (s->type != at_temp)) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ }
+
+ switch (s->type) {
+ case at_temp:
+ set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
+ break;
+ case at_output:
+ set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
+ break;
+ default:
+ set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
+ break;
+ }
+ }
+ ;
+
+progParamArray: USED_IDENTIFIER
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ free($1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) || !s->param_is_array) {
+ yyerror(& @1, state, "array access to non-PARAM variable");
+ YYERROR;
+ } else {
+ $$ = s;
+ }
+ }
+ ;
+
+progParamArrayMem: progParamArrayAbs | progParamArrayRel;
+
+progParamArrayAbs: INTEGER
+ {
+ init_src_reg(& $$);
+ $$.Base.Index = $1;
+ }
+ ;
+
+progParamArrayRel: addrReg addrComponent addrRegRelOffset
+ {
+ /* FINISHME: Add support for multiple address registers.
+ */
+ /* FINISHME: Add support for 4-component address registers.
+ */
+ init_src_reg(& $$);
+ $$.Base.RelAddr = 1;
+ $$.Base.Index = $3;
+ }
+ ;
+
+addrRegRelOffset: { $$ = 0; }
+ | '+' addrRegPosOffset { $$ = $2; }
+ | '-' addrRegNegOffset { $$ = -$2; }
+ ;
+
+addrRegPosOffset: INTEGER
+ {
+ if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+addrRegNegOffset: INTEGER
+ {
+ if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+addrReg: USED_IDENTIFIER
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ free($1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid array member");
+ YYERROR;
+ } else if (s->type != at_address) {
+ yyerror(& @1, state,
+ "invalid variable for indexed array access");
+ YYERROR;
+ } else {
+ $$ = s;
+ }
+ }
+ ;
+
+addrComponent: MASK1
+ {
+ if ($1.mask != WRITEMASK_X) {
+ yyerror(& @1, state, "invalid address component selector");
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+addrWriteMask: MASK1
+ {
+ if ($1.mask != WRITEMASK_X) {
+ yyerror(& @1, state,
+ "address register write mask must be \".x\"");
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+scalarSuffix: MASK1;
+
+swizzleSuffix: MASK1
+ | MASK4
+ | SWIZZLE
+ | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
+ ;
+
+optionalMask: MASK4 | MASK3 | MASK2 | MASK1
+ | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
+ ;
+
+optionalCcMask: '(' ccTest ')'
+ {
+ $$ = $2;
+ }
+ | '(' ccTest2 ')'
+ {
+ $$ = $2;
+ }
+ |
+ {
+ $$.CondMask = COND_TR;
+ $$.CondSwizzle = SWIZZLE_NOOP;
+ }
+ ;
+
+ccTest: ccMaskRule swizzleSuffix
+ {
+ $$ = $1;
+ $$.CondSwizzle = $2.swizzle;
+ }
+ ;
+
+ccTest2: ccMaskRule2 swizzleSuffix
+ {
+ $$ = $1;
+ $$.CondSwizzle = $2.swizzle;
+ }
+ ;
+
+ccMaskRule: IDENTIFIER
+ {
+ const int cond = _mesa_parse_cc($1);
+ if ((cond == 0) || ($1[2] != '\0')) {
+ char *const err_str =
+ make_error_string("invalid condition code \"%s\"", $1);
+
+ yyerror(& @1, state, (err_str != NULL)
+ ? err_str : "invalid condition code");
+
+ if (err_str != NULL) {
+ free(err_str);
+ }
+
+ YYERROR;
+ }
+
+ $$.CondMask = cond;
+ $$.CondSwizzle = SWIZZLE_NOOP;
+ }
+ ;
+
+ccMaskRule2: USED_IDENTIFIER
+ {
+ const int cond = _mesa_parse_cc($1);
+ if ((cond == 0) || ($1[2] != '\0')) {
+ char *const err_str =
+ make_error_string("invalid condition code \"%s\"", $1);
+
+ yyerror(& @1, state, (err_str != NULL)
+ ? err_str : "invalid condition code");
+
+ if (err_str != NULL) {
+ free(err_str);
+ }
+
+ YYERROR;
+ }
+
+ $$.CondMask = cond;
+ $$.CondSwizzle = SWIZZLE_NOOP;
+ }
+ ;
+
+namingStatement: ATTRIB_statement
+ | PARAM_statement
+ | TEMP_statement
+ | ADDRESS_statement
+ | OUTPUT_statement
+ | ALIAS_statement
+ ;
+
+ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, $2, at_attrib, & @2);
+
+ if (s == NULL) {
+ free($2);
+ YYERROR;
+ } else {
+ s->attrib_binding = $4;
+ state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
+
+ if (!validate_inputs(& @4, state)) {
+ YYERROR;
+ }
+ }
+ }
+ ;
+
+attribBinding: VERTEX vtxAttribItem
+ {
+ $$ = $2;
+ }
+ | FRAGMENT fragAttribItem
+ {
+ $$ = $2;
+ }
+ ;
+
+vtxAttribItem: POSITION
+ {
+ $$ = VERT_ATTRIB_POS;
+ }
+ | WEIGHT vtxOptWeightNum
+ {
+ $$ = VERT_ATTRIB_WEIGHT;
+ }
+ | NORMAL
+ {
+ $$ = VERT_ATTRIB_NORMAL;
+ }
+ | COLOR optColorType
+ {
+ $$ = VERT_ATTRIB_COLOR0 + $2;
+ }
+ | FOGCOORD
+ {
+ $$ = VERT_ATTRIB_FOG;
+ }
+ | TEXCOORD optTexCoordUnitNum
+ {
+ $$ = VERT_ATTRIB_TEX0 + $2;
+ }
+ | MATRIXINDEX '[' vtxWeightNum ']'
+ {
+ yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ }
+ | VTXATTRIB '[' vtxAttribNum ']'
+ {
+ $$ = VERT_ATTRIB_GENERIC0 + $3;
+ }
+ ;
+
+vtxAttribNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->limits->MaxAttribs) {
+ yyerror(& @1, state, "invalid vertex attribute reference");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+vtxOptWeightNum: | '[' vtxWeightNum ']';
+vtxWeightNum: INTEGER;
+
+fragAttribItem: POSITION
+ {
+ $$ = VARYING_SLOT_POS;
+ }
+ | COLOR optColorType
+ {
+ $$ = VARYING_SLOT_COL0 + $2;
+ }
+ | FOGCOORD
+ {
+ $$ = VARYING_SLOT_FOGC;
+ }
+ | TEXCOORD optTexCoordUnitNum
+ {
+ $$ = VARYING_SLOT_TEX0 + $2;
+ }
+ ;
+
+PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
+
+PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, $2, at_param, & @2);
+
+ if (s == NULL) {
+ free($2);
+ YYERROR;
+ } else {
+ s->param_binding_type = $3.param_binding_type;
+ s->param_binding_begin = $3.param_binding_begin;
+ s->param_binding_length = $3.param_binding_length;
+ s->param_binding_swizzle = $3.param_binding_swizzle;
+ s->param_is_array = 0;
+ }
+ }
+ ;
+
+PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
+ {
+ if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
+ free($2);
+ yyerror(& @4, state,
+ "parameter array size and number of bindings must match");
+ YYERROR;
+ } else {
+ struct asm_symbol *const s =
+ declare_variable(state, $2, $6.type, & @2);
+
+ if (s == NULL) {
+ free($2);
+ YYERROR;
+ } else {
+ s->param_binding_type = $6.param_binding_type;
+ s->param_binding_begin = $6.param_binding_begin;
+ s->param_binding_length = $6.param_binding_length;
+ s->param_binding_swizzle = SWIZZLE_XYZW;
+ s->param_is_array = 1;
+ }
+ }
+ }
+ ;
+
+optArraySize:
+ {
+ $$ = 0;
+ }
+ | INTEGER
+ {
+ if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
+ char msg[100];
+ _mesa_snprintf(msg, sizeof(msg),
+ "invalid parameter array size (size=%d max=%u)",
+ $1, state->limits->MaxParameters);
+ yyerror(& @1, state, msg);
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+paramSingleInit: '=' paramSingleItemDecl
+ {
+ $$ = $2;
+ }
+ ;
+
+paramMultipleInit: '=' '{' paramMultInitList '}'
+ {
+ $$ = $3;
+ }
+ ;
+
+paramMultInitList: paramMultipleItem
+ | paramMultInitList ',' paramMultipleItem
+ {
+ $1.param_binding_length += $3.param_binding_length;
+ $$ = $1;
+ }
+ ;
+
+paramSingleItemDecl: stateSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & $$, $1);
+ }
+ | programSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & $$, $1);
+ }
+ | paramConstDecl
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
+ }
+ ;
+
+paramSingleItemUse: stateSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & $$, $1);
+ }
+ | programSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & $$, $1);
+ }
+ | paramConstUse
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
+ }
+ ;
+
+paramMultipleItem: stateMultipleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & $$, $1);
+ }
+ | programMultipleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & $$, $1);
+ }
+ | paramConstDecl
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
+ }
+ ;
+
+stateMultipleItem: stateSingleItem { memcpy($$, $1, sizeof($$)); }
+ | STATE stateMatrixRows { memcpy($$, $2, sizeof($$)); }
+ ;
+
+stateSingleItem: STATE stateMaterialItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateLightItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateLightModelItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateLightProdItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateTexGenItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateTexEnvItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateFogItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateClipPlaneItem { memcpy($$, $2, sizeof($$)); }
+ | STATE statePointItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateMatrixRow { memcpy($$, $2, sizeof($$)); }
+ | STATE stateDepthItem { memcpy($$, $2, sizeof($$)); }
+ ;
+
+stateMaterialItem: MATERIAL optFaceType stateMatProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_MATERIAL;
+ $$[1] = $2;
+ $$[2] = $3;
+ }
+ ;
+
+stateMatProperty: ambDiffSpecProperty
+ {
+ $$ = $1;
+ }
+ | EMISSION
+ {
+ $$ = STATE_EMISSION;
+ }
+ | SHININESS
+ {
+ $$ = STATE_SHININESS;
+ }
+ ;
+
+stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHT;
+ $$[1] = $3;
+ $$[2] = $5;
+ }
+ ;
+
+stateLightProperty: ambDiffSpecProperty
+ {
+ $$ = $1;
+ }
+ | POSITION
+ {
+ $$ = STATE_POSITION;
+ }
+ | ATTENUATION
+ {
+ if (!state->ctx->Extensions.EXT_point_parameters) {
+ yyerror(& @1, state, "GL_ARB_point_parameters not supported");
+ YYERROR;
+ }
+
+ $$ = STATE_ATTENUATION;
+ }
+ | SPOT stateSpotProperty
+ {
+ $$ = $2;
+ }
+ | HALF
+ {
+ $$ = STATE_HALF_VECTOR;
+ }
+ ;
+
+stateSpotProperty: DIRECTION
+ {
+ $$ = STATE_SPOT_DIRECTION;
+ }
+ ;
+
+stateLightModelItem: LIGHTMODEL stateLModProperty
+ {
+ $$[0] = $2[0];
+ $$[1] = $2[1];
+ }
+ ;
+
+stateLModProperty: AMBIENT
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHTMODEL_AMBIENT;
+ }
+ | optFaceType SCENECOLOR
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
+ $$[1] = $1;
+ }
+ ;
+
+stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHTPROD;
+ $$[1] = $3;
+ $$[2] = $5;
+ $$[3] = $6;
+ }
+ ;
+
+stateLProdProperty: ambDiffSpecProperty;
+
+stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = $3;
+ $$[1] = $2;
+ }
+ ;
+
+stateTexEnvProperty: COLOR
+ {
+ $$ = STATE_TEXENV_COLOR;
+ }
+ ;
+
+ambDiffSpecProperty: AMBIENT
+ {
+ $$ = STATE_AMBIENT;
+ }
+ | DIFFUSE
+ {
+ $$ = STATE_DIFFUSE;
+ }
+ | SPECULAR
+ {
+ $$ = STATE_SPECULAR;
+ }
+ ;
+
+stateLightNumber: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxLights) {
+ yyerror(& @1, state, "invalid light selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_TEXGEN;
+ $$[1] = $2;
+ $$[2] = $3 + $4;
+ }
+ ;
+
+stateTexGenType: EYE
+ {
+ $$ = STATE_TEXGEN_EYE_S;
+ }
+ | OBJECT
+ {
+ $$ = STATE_TEXGEN_OBJECT_S;
+ }
+ ;
+stateTexGenCoord: TEXGEN_S
+ {
+ $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
+ }
+ | TEXGEN_T
+ {
+ $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
+ }
+ | TEXGEN_R
+ {
+ $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
+ }
+ | TEXGEN_Q
+ {
+ $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
+ }
+ ;
+
+stateFogItem: FOG stateFogProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = $2;
+ }
+ ;
+
+stateFogProperty: COLOR
+ {
+ $$ = STATE_FOG_COLOR;
+ }
+ | PARAMS
+ {
+ $$ = STATE_FOG_PARAMS;
+ }
+ ;
+
+stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_CLIPPLANE;
+ $$[1] = $3;
+ }
+ ;
+
+stateClipPlaneNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxClipPlanes) {
+ yyerror(& @1, state, "invalid clip plane selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+statePointItem: POINT_TOK statePointProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = $2;
+ }
+ ;
+
+statePointProperty: SIZE_TOK
+ {
+ $$ = STATE_POINT_SIZE;
+ }
+ | ATTENUATION
+ {
+ $$ = STATE_POINT_ATTENUATION;
+ }
+ ;
+
+stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
+ {
+ $$[0] = $1[0];
+ $$[1] = $1[1];
+ $$[2] = $4;
+ $$[3] = $4;
+ $$[4] = $1[2];
+ }
+ ;
+
+stateMatrixRows: stateMatrixItem optMatrixRows
+ {
+ $$[0] = $1[0];
+ $$[1] = $1[1];
+ $$[2] = $2[2];
+ $$[3] = $2[3];
+ $$[4] = $1[2];
+ }
+ ;
+
+optMatrixRows:
+ {
+ $$[2] = 0;
+ $$[3] = 3;
+ }
+ | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
+ {
+ /* It seems logical that the matrix row range specifier would have
+ * to specify a range or more than one row (i.e., $5 > $3).
+ * However, the ARB_vertex_program spec says "a program will fail
+ * to load if <a> is greater than <b>." This means that $3 == $5
+ * is valid.
+ */
+ if ($3 > $5) {
+ yyerror(& @3, state, "invalid matrix row range");
+ YYERROR;
+ }
+
+ $$[2] = $3;
+ $$[3] = $5;
+ }
+ ;
+
+stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
+ {
+ $$[0] = $2[0];
+ $$[1] = $2[1];
+ $$[2] = $3;
+ }
+ ;
+
+stateOptMatModifier:
+ {
+ $$ = 0;
+ }
+ | stateMatModifier
+ {
+ $$ = $1;
+ }
+ ;
+
+stateMatModifier: INVERSE
+ {
+ $$ = STATE_MATRIX_INVERSE;
+ }
+ | TRANSPOSE
+ {
+ $$ = STATE_MATRIX_TRANSPOSE;
+ }
+ | INVTRANS
+ {
+ $$ = STATE_MATRIX_INVTRANS;
+ }
+ ;
+
+stateMatrixRowNum: INTEGER
+ {
+ if ($1 > 3) {
+ yyerror(& @1, state, "invalid matrix row reference");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+stateMatrixName: MODELVIEW stateOptModMatNum
+ {
+ $$[0] = STATE_MODELVIEW_MATRIX;
+ $$[1] = $2;
+ }
+ | PROJECTION
+ {
+ $$[0] = STATE_PROJECTION_MATRIX;
+ $$[1] = 0;
+ }
+ | MVP
+ {
+ $$[0] = STATE_MVP_MATRIX;
+ $$[1] = 0;
+ }
+ | TEXTURE optTexCoordUnitNum
+ {
+ $$[0] = STATE_TEXTURE_MATRIX;
+ $$[1] = $2;
+ }
+ | PALETTE '[' statePaletteMatNum ']'
+ {
+ yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ }
+ | MAT_PROGRAM '[' stateProgramMatNum ']'
+ {
+ $$[0] = STATE_PROGRAM_MATRIX;
+ $$[1] = $3;
+ }
+ ;
+
+stateOptModMatNum:
+ {
+ $$ = 0;
+ }
+ | '[' stateModMatNum ']'
+ {
+ $$ = $2;
+ }
+ ;
+stateModMatNum: INTEGER
+ {
+ /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
+ * zero is valid.
+ */
+ if ($1 != 0) {
+ yyerror(& @1, state, "invalid modelview matrix index");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+statePaletteMatNum: INTEGER
+ {
+ /* Since GL_ARB_matrix_palette isn't supported, just let any value
+ * through here. The error will be generated later.
+ */
+ $$ = $1;
+ }
+ ;
+stateProgramMatNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxProgramMatrices) {
+ yyerror(& @1, state, "invalid program matrix selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+stateDepthItem: DEPTH RANGE
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_DEPTH_RANGE;
+ }
+ ;
+
+
+programSingleItem: progEnvParam | progLocalParam;
+
+programMultipleItem: progEnvParams | progLocalParams;
+
+progEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_ENV;
+ $$[2] = $4[0];
+ $$[3] = $4[1];
+ }
+ ;
+
+progEnvParamNums: progEnvParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $1;
+ }
+ | progEnvParamNum DOT_DOT progEnvParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $3;
+ }
+ ;
+
+progEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_ENV;
+ $$[2] = $4;
+ $$[3] = $4;
+ }
+ ;
+
+progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_LOCAL;
+ $$[2] = $4[0];
+ $$[3] = $4[1];
+ }
+
+progLocalParamNums: progLocalParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $1;
+ }
+ | progLocalParamNum DOT_DOT progLocalParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $3;
+ }
+ ;
+
+progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_LOCAL;
+ $$[2] = $4;
+ $$[3] = $4;
+ }
+ ;
+
+progEnvParamNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->limits->MaxEnvParams) {
+ yyerror(& @1, state, "invalid environment parameter reference");
+ YYERROR;
+ }
+ $$ = $1;
+ }
+ ;
+
+progLocalParamNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->limits->MaxLocalParams) {
+ yyerror(& @1, state, "invalid local parameter reference");
+ YYERROR;
+ }
+ $$ = $1;
+ }
+ ;
+
+
+
+paramConstDecl: paramConstScalarDecl | paramConstVector;
+paramConstUse: paramConstScalarUse | paramConstVector;
+
+paramConstScalarDecl: signedFloatConstant
+ {
+ $$.count = 4;
+ $$.data[0].f = $1;
+ $$.data[1].f = $1;
+ $$.data[2].f = $1;
+ $$.data[3].f = $1;
+ }
+ ;
+
+paramConstScalarUse: REAL
+ {
+ $$.count = 1;
+ $$.data[0].f = $1;
+ $$.data[1].f = $1;
+ $$.data[2].f = $1;
+ $$.data[3].f = $1;
+ }
+ | INTEGER
+ {
+ $$.count = 1;
+ $$.data[0].f = (float) $1;
+ $$.data[1].f = (float) $1;
+ $$.data[2].f = (float) $1;
+ $$.data[3].f = (float) $1;
+ }
+ ;
+
+paramConstVector: '{' signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0].f = $2;
+ $$.data[1].f = 0.0f;
+ $$.data[2].f = 0.0f;
+ $$.data[3].f = 1.0f;
+ }
+ | '{' signedFloatConstant ',' signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0].f = $2;
+ $$.data[1].f = $4;
+ $$.data[2].f = 0.0f;
+ $$.data[3].f = 1.0f;
+ }
+ | '{' signedFloatConstant ',' signedFloatConstant ','
+ signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0].f = $2;
+ $$.data[1].f = $4;
+ $$.data[2].f = $6;
+ $$.data[3].f = 1.0f;
+ }
+ | '{' signedFloatConstant ',' signedFloatConstant ','
+ signedFloatConstant ',' signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0].f = $2;
+ $$.data[1].f = $4;
+ $$.data[2].f = $6;
+ $$.data[3].f = $8;
+ }
+ ;
+
+signedFloatConstant: optionalSign REAL
+ {
+ $$ = ($1) ? -$2 : $2;
+ }
+ | optionalSign INTEGER
+ {
+ $$ = (float)(($1) ? -$2 : $2);
+ }
+ ;
+
+optionalSign: '+' { $$ = FALSE; }
+ | '-' { $$ = TRUE; }
+ | { $$ = FALSE; }
+ ;
+
+TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
+ ;
+
+optVarSize: string
+ {
+ /* NV_fragment_program_option defines the size qualifiers in a
+ * fairly broken way. "SHORT" or "LONG" can optionally be used
+ * before TEMP or OUTPUT. However, neither is a reserved word!
+ * This means that we have to parse it as an identifier, then check
+ * to make sure it's one of the valid values. *sigh*
+ *
+ * In addition, the grammar in the extension spec does *not* allow
+ * the size specifier to be optional, but all known implementations
+ * do.
+ */
+ if (!state->option.NV_fragment) {
+ yyerror(& @1, state, "unexpected IDENTIFIER");
+ YYERROR;
+ }
+
+ if (strcmp("SHORT", $1) == 0) {
+ } else if (strcmp("LONG", $1) == 0) {
+ } else {
+ char *const err_str =
+ make_error_string("invalid storage size specifier \"%s\"",
+ $1);
+
+ yyerror(& @1, state, (err_str != NULL)
+ ? err_str : "invalid storage size specifier");
+
+ if (err_str != NULL) {
+ free(err_str);
+ }
+
+ YYERROR;
+ }
+ }
+ |
+ {
+ }
+ ;
+
+ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
+ ;
+
+varNameList: varNameList ',' IDENTIFIER
+ {
+ if (!declare_variable(state, $3, $<integer>0, & @3)) {
+ free($3);
+ YYERROR;
+ }
+ }
+ | IDENTIFIER
+ {
+ if (!declare_variable(state, $1, $<integer>0, & @1)) {
+ free($1);
+ YYERROR;
+ }
+ }
+ ;
+
+OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, $3, at_output, & @3);
+
+ if (s == NULL) {
+ free($3);
+ YYERROR;
+ } else {
+ s->output_binding = $5;
+ }
+ }
+ ;
+
+resultBinding: RESULT POSITION
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_POS;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT FOGCOORD
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_FOGC;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT resultColBinding
+ {
+ $$ = $2;
+ }
+ | RESULT POINTSIZE
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_PSIZ;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT TEXCOORD optTexCoordUnitNum
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_TEX0 + $3;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT DEPTH
+ {
+ if (state->mode == ARB_fragment) {
+ $$ = FRAG_RESULT_DEPTH;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ ;
+
+resultColBinding: COLOR optResultFaceType optResultColorType
+ {
+ $$ = $2 + $3;
+ }
+ ;
+
+optResultFaceType:
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_COL0;
+ } else {
+ if (state->option.DrawBuffers)
+ $$ = FRAG_RESULT_DATA0;
+ else
+ $$ = FRAG_RESULT_COLOR;
+ }
+ }
+ | '[' INTEGER ']'
+ {
+ if (state->mode == ARB_vertex) {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ } else {
+ if (!state->option.DrawBuffers) {
+ /* From the ARB_draw_buffers spec (same text exists
+ * for ATI_draw_buffers):
+ *
+ * If this option is not specified, a fragment
+ * program that attempts to bind
+ * "result.color[n]" will fail to load, and only
+ * "result.color" will be allowed.
+ */
+ yyerror(& @1, state,
+ "result.color[] used without "
+ "`OPTION ARB_draw_buffers' or "
+ "`OPTION ATI_draw_buffers'");
+ YYERROR;
+ } else if ($2 >= state->MaxDrawBuffers) {
+ yyerror(& @1, state,
+ "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
+ YYERROR;
+ }
+ $$ = FRAG_RESULT_DATA0 + $2;
+ }
+ }
+ | FRONT
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_COL0;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | BACK
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_BFC0;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ ;
+
+optResultColorType:
+ {
+ $$ = 0;
+ }
+ | PRIMARY
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = 0;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | SECONDARY
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = 1;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ ;
+
+optFaceType: { $$ = 0; }
+ | FRONT { $$ = 0; }
+ | BACK { $$ = 1; }
+ ;
+
+optColorType: { $$ = 0; }
+ | PRIMARY { $$ = 0; }
+ | SECONDARY { $$ = 1; }
+ ;
+
+optTexCoordUnitNum: { $$ = 0; }
+ | '[' texCoordUnitNum ']' { $$ = $2; }
+ ;
+
+optTexImageUnitNum: { $$ = 0; }
+ | '[' texImageUnitNum ']' { $$ = $2; }
+ ;
+
+optLegacyTexUnitNum: { $$ = 0; }
+ | '[' legacyTexUnitNum ']' { $$ = $2; }
+ ;
+
+texCoordUnitNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
+ yyerror(& @1, state, "invalid texture coordinate unit selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+texImageUnitNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxTextureImageUnits) {
+ yyerror(& @1, state, "invalid texture image unit selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+legacyTexUnitNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxTextureUnits) {
+ yyerror(& @1, state, "invalid texture unit selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
+ {
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $2);
+ struct asm_symbol *target = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $4);
+
+ free($4);
+
+ if (exist != NULL) {
+ char m[1000];
+ _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
+ free($2);
+ yyerror(& @2, state, m);
+ YYERROR;
+ } else if (target == NULL) {
+ free($2);
+ yyerror(& @4, state,
+ "undefined variable binding in ALIAS statement");
+ YYERROR;
+ } else {
+ _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
+ }
+ }
+ ;
+
+string: IDENTIFIER
+ | USED_IDENTIFIER
+ ;
+
+%%
+
+void
+asm_instruction_set_operands(struct asm_instruction *inst,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ /* In the core ARB extensions only the KIL instruction doesn't have a
+ * destination register.
+ */
+ if (dst == NULL) {
+ init_dst_reg(& inst->Base.DstReg);
+ } else {
+ inst->Base.DstReg = *dst;
+ }
+
+ /* The only instruction that doesn't have any source registers is the
+ * condition-code based KIL instruction added by NV_fragment_program_option.
+ */
+ if (src0 != NULL) {
+ inst->Base.SrcReg[0] = src0->Base;
+ inst->SrcReg[0] = *src0;
+ } else {
+ init_src_reg(& inst->SrcReg[0]);
+ }
+
+ if (src1 != NULL) {
+ inst->Base.SrcReg[1] = src1->Base;
+ inst->SrcReg[1] = *src1;
+ } else {
+ init_src_reg(& inst->SrcReg[1]);
+ }
+
+ if (src2 != NULL) {
+ inst->Base.SrcReg[2] = src2->Base;
+ inst->SrcReg[2] = *src2;
+ } else {
+ init_src_reg(& inst->SrcReg[2]);
+ }
+}
+
+
+struct asm_instruction *
+asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+ if (inst) {
+ _mesa_init_instructions(& inst->Base, 1);
+ inst->Base.Opcode = op;
+
+ asm_instruction_set_operands(inst, dst, src0, src1, src2);
+ }
+
+ return inst;
+}
+
+
+struct asm_instruction *
+asm_instruction_copy_ctor(const struct prog_instruction *base,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+ if (inst) {
+ _mesa_init_instructions(& inst->Base, 1);
+ inst->Base.Opcode = base->Opcode;
+ inst->Base.CondUpdate = base->CondUpdate;
+ inst->Base.CondDst = base->CondDst;
+ inst->Base.SaturateMode = base->SaturateMode;
+ inst->Base.Precision = base->Precision;
+
+ asm_instruction_set_operands(inst, dst, src0, src1, src2);
+ }
+
+ return inst;
+}
+
+
+void
+init_dst_reg(struct prog_dst_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->File = PROGRAM_UNDEFINED;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+/** Like init_dst_reg() but set the File and Index fields. */
+void
+set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
+{
+ const GLint maxIndex = 1 << INST_INDEX_BITS;
+ const GLint minIndex = 0;
+ ASSERT(index >= minIndex);
+ (void) minIndex;
+ ASSERT(index <= maxIndex);
+ (void) maxIndex;
+ ASSERT(file == PROGRAM_TEMPORARY ||
+ file == PROGRAM_ADDRESS ||
+ file == PROGRAM_OUTPUT);
+ memset(r, 0, sizeof(*r));
+ r->File = file;
+ r->Index = index;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+void
+init_src_reg(struct asm_src_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->Base.File = PROGRAM_UNDEFINED;
+ r->Base.Swizzle = SWIZZLE_NOOP;
+ r->Symbol = NULL;
+}
+
+
+/** Like init_src_reg() but set the File and Index fields.
+ * \return GL_TRUE if a valid src register, GL_FALSE otherwise
+ */
+void
+set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
+{
+ set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
+}
+
+
+void
+set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
+ GLuint swizzle)
+{
+ const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
+ const GLint minIndex = -(1 << INST_INDEX_BITS);
+ ASSERT(file < PROGRAM_FILE_MAX);
+ ASSERT(index >= minIndex);
+ (void) minIndex;
+ ASSERT(index <= maxIndex);
+ (void) maxIndex;
+ memset(r, 0, sizeof(*r));
+ r->Base.File = file;
+ r->Base.Index = index;
+ r->Base.Swizzle = swizzle;
+ r->Symbol = NULL;
+}
+
+
+/**
+ * Validate the set of inputs used by a program
+ *
+ * Validates that legal sets of inputs are used by the program. In this case
+ * "used" included both reading the input or binding the input to a name using
+ * the \c ATTRIB command.
+ *
+ * \return
+ * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
+ */
+int
+validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
+{
+ const GLbitfield64 inputs = state->prog->InputsRead | state->InputsBound;
+
+ if (((inputs & VERT_BIT_FF_ALL) & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
+ yyerror(locp, state, "illegal use of generic attribute and name attribute");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+struct asm_symbol *
+declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
+ struct YYLTYPE *locp)
+{
+ struct asm_symbol *s = NULL;
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, name);
+
+
+ if (exist != NULL) {
+ yyerror(locp, state, "redeclared identifier");
+ } else {
+ s = calloc(1, sizeof(struct asm_symbol));
+ s->name = name;
+ s->type = t;
+
+ switch (t) {
+ case at_temp:
+ if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+ yyerror(locp, state, "too many temporaries declared");
+ free(s);
+ return NULL;
+ }
+
+ s->temp_binding = state->prog->NumTemporaries;
+ state->prog->NumTemporaries++;
+ break;
+
+ case at_address:
+ if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+ yyerror(locp, state, "too many address registers declared");
+ free(s);
+ return NULL;
+ }
+
+ /* FINISHME: Add support for multiple address registers.
+ */
+ state->prog->NumAddressRegs++;
+ break;
+
+ default:
+ break;
+ }
+
+ _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+ s->next = state->sym;
+ state->sym = s;
+ }
+
+ return s;
+}
+
+
+int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ const GLuint size = 4; /* XXX fix */
+ char *name;
+ GLint index;
+
+ name = _mesa_program_state_string(tokens);
+ index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
+ size, GL_NONE, NULL, tokens);
+ param_list->StateFlags |= _mesa_program_state_flags(tokens);
+
+ /* free name string here since we duplicated it in add_parameter() */
+ free(name);
+
+ return index;
+}
+
+
+int
+initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+ /* If we are adding a STATE_MATRIX that has multiple rows, we need to
+ * unroll it and call add_state_reference() for each row
+ */
+ if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
+ state_tokens[0] == STATE_PROJECTION_MATRIX ||
+ state_tokens[0] == STATE_MVP_MATRIX ||
+ state_tokens[0] == STATE_TEXTURE_MATRIX ||
+ state_tokens[0] == STATE_PROGRAM_MATRIX)
+ && (state_tokens[2] != state_tokens[3])) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+int
+initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
+ || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
+ assert((state_tokens[1] == STATE_ENV)
+ || (state_tokens[1] == STATE_LOCAL));
+
+ /*
+ * The param type is STATE_VAR. The program parameter entry will
+ * effectively be a pointer into the LOCAL or ENV parameter array.
+ */
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+ /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
+ * we need to unroll it and call add_state_reference() for each row
+ */
+ if (state_tokens[2] != state_tokens[3]) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+/**
+ * Put a float/vector constant/literal into the parameter list.
+ * \param param_var returns info about the parameter/constant's location,
+ * binding, type, etc.
+ * \param vec the vector/constant to add
+ * \param allowSwizzle if true, try to consolidate constants which only differ
+ * by a swizzle. We don't want to do this when building
+ * arrays of constants that may be indexed indirectly.
+ * \return index of the constant in the parameter list.
+ */
+int
+initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const struct asm_vector *vec,
+ GLboolean allowSwizzle)
+{
+ unsigned swizzle;
+ const int idx = _mesa_add_unnamed_constant(prog->Parameters,
+ vec->data, vec->count,
+ allowSwizzle ? &swizzle : NULL);
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_CONSTANT;
+
+ if (param_var->param_binding_begin == ~0U) {
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
+ }
+ param_var->param_binding_length++;
+
+ return idx;
+}
+
+
+char *
+make_error_string(const char *fmt, ...)
+{
+ int length;
+ char *str;
+ va_list args;
+
+
+ /* Call vsnprintf once to determine how large the final string is. Call it
+ * again to do the actual formatting. from the vsnprintf manual page:
+ *
+ * Upon successful return, these functions return the number of
+ * characters printed (not including the trailing '\0' used to end
+ * output to strings).
+ */
+ va_start(args, fmt);
+ length = 1 + vsnprintf(NULL, 0, fmt, args);
+ va_end(args);
+
+ str = malloc(length);
+ if (str) {
+ va_start(args, fmt);
+ vsnprintf(str, length, fmt, args);
+ va_end(args);
+ }
+
+ return str;
+}
+
+
+void
+yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
+{
+ char *err_str;
+
+
+ err_str = make_error_string("glProgramStringARB(%s)\n", s);
+ if (err_str) {
+ _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str);
+ free(err_str);
+ }
+
+ err_str = make_error_string("line %u, char %u: error: %s\n",
+ locp->first_line, locp->first_column, s);
+ _mesa_set_program_error(state->ctx, locp->position, err_str);
+
+ if (err_str) {
+ free(err_str);
+ }
+}
+
+
+GLboolean
+_mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str,
+ GLsizei len, struct asm_parser_state *state)
+{
+ struct asm_instruction *inst;
+ unsigned i;
+ GLubyte *strz;
+ GLboolean result = GL_FALSE;
+ void *temp;
+ struct asm_symbol *sym;
+
+ state->ctx = ctx;
+ state->prog->Target = target;
+ state->prog->Parameters = _mesa_new_parameter_list();
+
+ /* Make a copy of the program string and force it to be NUL-terminated.
+ */
+ strz = (GLubyte *) malloc(len + 1);
+ if (strz == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return GL_FALSE;
+ }
+ memcpy (strz, str, len);
+ strz[len] = '\0';
+
+ state->prog->String = strz;
+
+ state->st = _mesa_symbol_table_ctor();
+
+ state->limits = (target == GL_VERTEX_PROGRAM_ARB)
+ ? & ctx->Const.Program[MESA_SHADER_VERTEX]
+ : & ctx->Const.Program[MESA_SHADER_FRAGMENT];
+
+ state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
+ state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
+ state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
+ state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
+ state->MaxLights = ctx->Const.MaxLights;
+ state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+ state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
+
+ state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
+ ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
+
+ _mesa_set_program_error(ctx, -1, NULL);
+
+ _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
+ yyparse(state);
+ _mesa_program_lexer_dtor(state->scanner);
+
+
+ if (ctx->Program.ErrorPos != -1) {
+ goto error;
+ }
+
+ if (! _mesa_layout_parameters(state)) {
+ struct YYLTYPE loc;
+
+ loc.first_line = 0;
+ loc.first_column = 0;
+ loc.position = len;
+
+ yyerror(& loc, state, "invalid PARAM usage");
+ goto error;
+ }
+
+
+
+ /* Add one instruction to store the "END" instruction.
+ */
+ state->prog->Instructions =
+ _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+
+ if (state->prog->Instructions == NULL) {
+ goto error;
+ }
+
+ inst = state->inst_head;
+ for (i = 0; i < state->prog->NumInstructions; i++) {
+ struct asm_instruction *const temp = inst->next;
+
+ state->prog->Instructions[i] = inst->Base;
+ inst = temp;
+ }
+
+ /* Finally, tag on an OPCODE_END instruction */
+ {
+ const GLuint numInst = state->prog->NumInstructions;
+ _mesa_init_instructions(state->prog->Instructions + numInst, 1);
+ state->prog->Instructions[numInst].Opcode = OPCODE_END;
+ }
+ state->prog->NumInstructions++;
+
+ state->prog->NumParameters = state->prog->Parameters->NumParameters;
+ state->prog->NumAttributes = _mesa_bitcount_64(state->prog->InputsRead);
+
+ /*
+ * Initialize native counts to logical counts. The device driver may
+ * change them if program is translated into a hardware program.
+ */
+ state->prog->NumNativeInstructions = state->prog->NumInstructions;
+ state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
+ state->prog->NumNativeParameters = state->prog->NumParameters;
+ state->prog->NumNativeAttributes = state->prog->NumAttributes;
+ state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+
+ result = GL_TRUE;
+
+error:
+ for (inst = state->inst_head; inst != NULL; inst = temp) {
+ temp = inst->next;
+ free(inst);
+ }
+
+ state->inst_head = NULL;
+ state->inst_tail = NULL;
+
+ for (sym = state->sym; sym != NULL; sym = temp) {
+ temp = sym->next;
+
+ free((void *) sym->name);
+ free(sym);
+ }
+ state->sym = NULL;
+
+ _mesa_symbol_table_dtor(state->st);
+ state->st = NULL;
+
+ return result;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse_extra.c b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse_extra.c
new file mode 100644
index 0000000..a9e3640
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parse_extra.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include "main/mtypes.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+
+/**
+ * Extra assembly-level parser routines
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+int
+_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
+ const char *suffix,
+ struct prog_instruction *inst)
+{
+ inst->CondUpdate = 0;
+ inst->CondDst = 0;
+ inst->SaturateMode = SATURATE_OFF;
+ inst->Precision = FLOAT32;
+
+
+ /* The first possible suffix element is the precision specifier from
+ * NV_fragment_program_option.
+ */
+ if (state->option.NV_fragment) {
+ switch (suffix[0]) {
+ case 'H':
+ inst->Precision = FLOAT16;
+ suffix++;
+ break;
+ case 'R':
+ inst->Precision = FLOAT32;
+ suffix++;
+ break;
+ case 'X':
+ inst->Precision = FIXED12;
+ suffix++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* The next possible suffix element is the condition code modifier selection
+ * from NV_fragment_program_option.
+ */
+ if (state->option.NV_fragment) {
+ if (suffix[0] == 'C') {
+ inst->CondUpdate = 1;
+ suffix++;
+ }
+ }
+
+
+ /* The final possible suffix element is the saturation selector from
+ * ARB_fragment_program.
+ */
+ if (state->mode == ARB_fragment) {
+ if (strcmp(suffix, "_SAT") == 0) {
+ inst->SaturateMode = SATURATE_ZERO_ONE;
+ suffix += 4;
+ }
+ }
+
+
+ /* It is an error for all of the suffix string not to be consumed.
+ */
+ return suffix[0] == '\0';
+}
+
+
+int
+_mesa_parse_cc(const char *s)
+{
+ int cond = 0;
+
+ switch (s[0]) {
+ case 'E':
+ if (s[1] == 'Q') {
+ cond = COND_EQ;
+ }
+ break;
+
+ case 'F':
+ if (s[1] == 'L') {
+ cond = COND_FL;
+ }
+ break;
+
+ case 'G':
+ if (s[1] == 'E') {
+ cond = COND_GE;
+ } else if (s[1] == 'T') {
+ cond = COND_GT;
+ }
+ break;
+
+ case 'L':
+ if (s[1] == 'E') {
+ cond = COND_LE;
+ } else if (s[1] == 'T') {
+ cond = COND_LT;
+ }
+ break;
+
+ case 'N':
+ if (s[1] == 'E') {
+ cond = COND_NE;
+ }
+ break;
+
+ case 'T':
+ if (s[1] == 'R') {
+ cond = COND_TR;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return ((cond == 0) || (s[2] != '\0')) ? 0 : cond;
+}
+
+
+int
+_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
+{
+ if (strcmp(option, "ARB_position_invariant") == 0) {
+ state->option.PositionInvariant = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int
+_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
+{
+ /* All of the options currently supported start with "ARB_". The code is
+ * currently structured with nested if-statements because eventually options
+ * that start with "NV_" will be supported. This structure will result in
+ * less churn when those options are added.
+ */
+ if (strncmp(option, "ARB_", 4) == 0) {
+ /* Advance the pointer past the "ARB_" prefix.
+ */
+ option += 4;
+
+
+ if (strncmp(option, "fog_", 4) == 0) {
+ option += 4;
+
+ if (state->option.Fog == OPTION_NONE) {
+ if (strcmp(option, "exp") == 0) {
+ state->option.Fog = OPTION_FOG_EXP;
+ return 1;
+ } else if (strcmp(option, "exp2") == 0) {
+ state->option.Fog = OPTION_FOG_EXP2;
+ return 1;
+ } else if (strcmp(option, "linear") == 0) {
+ state->option.Fog = OPTION_FOG_LINEAR;
+ return 1;
+ }
+ }
+
+ return 0;
+ } else if (strncmp(option, "precision_hint_", 15) == 0) {
+ option += 15;
+
+ /* The ARB_fragment_program spec, 3.11.4.5.2 says:
+ *
+ * "Only one precision control option may be specified by any given
+ * fragment program. A fragment program that specifies both the
+ * "ARB_precision_hint_fastest" and "ARB_precision_hint_nicest"
+ * program options will fail to load.
+ */
+
+ if (strcmp(option, "nicest") == 0 && state->option.PrecisionHint != OPTION_FASTEST) {
+ state->option.PrecisionHint = OPTION_NICEST;
+ return 1;
+ } else if (strcmp(option, "fastest") == 0 && state->option.PrecisionHint != OPTION_NICEST) {
+ state->option.PrecisionHint = OPTION_FASTEST;
+ return 1;
+ }
+
+ return 0;
+ } else if (strcmp(option, "draw_buffers") == 0) {
+ /* Don't need to check extension availability because all Mesa-based
+ * drivers support GL_ARB_draw_buffers.
+ */
+ state->option.DrawBuffers = 1;
+ return 1;
+ } else if (strcmp(option, "fragment_program_shadow") == 0) {
+ if (state->ctx->Extensions.ARB_fragment_program_shadow) {
+ state->option.Shadow = 1;
+ return 1;
+ }
+ } else if (strncmp(option, "fragment_coord_", 15) == 0) {
+ option += 15;
+ if (state->ctx->Extensions.ARB_fragment_coord_conventions) {
+ if (strcmp(option, "origin_upper_left") == 0) {
+ state->option.OriginUpperLeft = 1;
+ return 1;
+ }
+ else if (strcmp(option, "pixel_center_integer") == 0) {
+ state->option.PixelCenterInteger = 1;
+ return 1;
+ }
+ }
+ }
+ } else if (strncmp(option, "ATI_", 4) == 0) {
+ option += 4;
+
+ if (strcmp(option, "draw_buffers") == 0) {
+ /* Don't need to check extension availability because all Mesa-based
+ * drivers support GL_ATI_draw_buffers.
+ */
+ state->option.DrawBuffers = 1;
+ return 1;
+ }
+ } else if (strncmp(option, "NV_fragment_program", 19) == 0) {
+ option += 19;
+
+ /* Other NV_fragment_program strings may be supported later.
+ */
+ if (option[0] == '\0') {
+ if (state->ctx->Extensions.NV_fragment_program_option) {
+ state->option.NV_fragment = 1;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/program_parser.h b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parser.h
new file mode 100644
index 0000000..04c64f4
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/program_parser.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#pragma once
+
+#include "main/config.h"
+#include "program/prog_parameter.h"
+
+struct gl_context;
+
+enum asm_type {
+ at_none,
+ at_address,
+ at_attrib,
+ at_param,
+ at_temp,
+ at_output
+};
+
+struct asm_symbol {
+ struct asm_symbol *next; /**< List linkage for freeing. */
+ const char *name;
+ enum asm_type type;
+ unsigned attrib_binding;
+ unsigned output_binding; /**< Output / result register number. */
+
+ /**
+ * One of PROGRAM_STATE_VAR or PROGRAM_CONSTANT.
+ */
+ unsigned param_binding_type;
+
+ /**
+ * Offset into the program_parameter_list where the tokens representing our
+ * bound state (or constants) start.
+ */
+ unsigned param_binding_begin;
+
+ /**
+ * Constants put into the parameter list may be swizzled. This
+ * field contain's the symbol's swizzle. (SWIZZLE_X/Y/Z/W)
+ */
+ unsigned param_binding_swizzle;
+
+ /* This is how many entries in the program_parameter_list we take up
+ * with our state tokens or constants. Note that this is _not_ the same as
+ * the number of param registers we eventually use.
+ */
+ unsigned param_binding_length;
+
+ /**
+ * Index of the temp register assigned to this variable.
+ */
+ unsigned temp_binding;
+
+ /**
+ * Flag whether or not a PARAM is an array
+ */
+ unsigned param_is_array:1;
+
+
+ /**
+ * Flag whether or not a PARAM array is accessed indirectly
+ */
+ unsigned param_accessed_indirectly:1;
+
+
+ /**
+ * \brief Is first pass of parameter layout done with this variable?
+ *
+ * The parameter layout routine operates in two passes. This flag tracks
+ * whether or not the first pass has handled this variable.
+ *
+ * \sa _mesa_layout_parameters
+ */
+ unsigned pass1_done:1;
+};
+
+
+struct asm_vector {
+ unsigned count;
+ gl_constant_value data[4];
+};
+
+
+struct asm_swizzle_mask {
+ unsigned swizzle:12;
+ unsigned mask:4;
+};
+
+
+struct asm_src_register {
+ struct prog_src_register Base;
+
+ /**
+ * Symbol associated with indirect access to parameter arrays.
+ *
+ * If \c Base::RelAddr is 1, this will point to the symbol for the parameter
+ * that is being dereferenced. Further, \c Base::Index will be the offset
+ * from the address register being used.
+ */
+ struct asm_symbol *Symbol;
+};
+
+
+struct asm_instruction {
+ struct prog_instruction Base;
+ struct asm_instruction *next;
+ struct asm_src_register SrcReg[3];
+};
+
+
+struct asm_parser_state {
+ struct gl_context *ctx;
+ struct gl_program *prog;
+
+ /**
+ * Per-program target limits
+ */
+ struct gl_program_constants *limits;
+
+ struct _mesa_symbol_table *st;
+
+ /**
+ * Linked list of symbols
+ *
+ * This list is \b only used when cleaning up compiler state and freeing
+ * memory.
+ */
+ struct asm_symbol *sym;
+
+ /**
+ * State for the lexer.
+ */
+ void *scanner;
+
+ /**
+ * Linked list of instructions generated during parsing.
+ */
+ /*@{*/
+ struct asm_instruction *inst_head;
+ struct asm_instruction *inst_tail;
+ /*@}*/
+
+
+ /**
+ * Selected limits copied from gl_constants
+ *
+ * These are limits from the GL context, but various bits in the program
+ * must be validated against these values.
+ */
+ /*@{*/
+ unsigned MaxTextureCoordUnits;
+ unsigned MaxTextureImageUnits;
+ unsigned MaxTextureUnits;
+ unsigned MaxClipPlanes;
+ unsigned MaxLights;
+ unsigned MaxProgramMatrices;
+ unsigned MaxDrawBuffers;
+ /*@}*/
+
+ /**
+ * Value to use in state vector accessors for environment and local
+ * parameters
+ */
+ unsigned state_param_enum;
+
+
+ /**
+ * Input attributes bound to specific names
+ *
+ * This is only needed so that errors can be properly produced when
+ * multiple ATTRIB statements bind illegal combinations of vertex
+ * attributes.
+ */
+ GLbitfield64 InputsBound;
+
+ enum {
+ invalid_mode = 0,
+ ARB_vertex,
+ ARB_fragment
+ } mode;
+
+ struct {
+ unsigned PositionInvariant:1;
+ unsigned Fog:2;
+ unsigned PrecisionHint:2;
+ unsigned DrawBuffers:1;
+ unsigned Shadow:1;
+ unsigned TexRect:1;
+ unsigned TexArray:1;
+ unsigned NV_fragment:1;
+ unsigned OriginUpperLeft:1;
+ unsigned PixelCenterInteger:1;
+ } option;
+
+ struct {
+ unsigned UsesKill:1;
+ unsigned UsesDFdy:1;
+ } fragment;
+};
+
+#define OPTION_NONE 0
+#define OPTION_FOG_EXP 1
+#define OPTION_FOG_EXP2 2
+#define OPTION_FOG_LINEAR 3
+#define OPTION_NICEST 1
+#define OPTION_FASTEST 2
+
+typedef struct YYLTYPE {
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ int position;
+} YYLTYPE;
+
+#define YYLTYPE_IS_DECLARED 1
+#define YYLTYPE_IS_TRIVIAL 1
+
+
+extern GLboolean _mesa_parse_arb_program(struct gl_context *ctx, GLenum target,
+ const GLubyte *str, GLsizei len, struct asm_parser_state *state);
+
+
+
+/* From program_lexer.l. */
+extern void _mesa_program_lexer_dtor(void *scanner);
+
+extern void _mesa_program_lexer_ctor(void **scanner,
+ struct asm_parser_state *state, const char *string, size_t len);
+
+
+/**
+ *\name From program_parse_extra.c
+ */
+/*@{*/
+
+/**
+ * Parses and processes an option string to an ARB vertex program
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state,
+ const char *option);
+
+/**
+ * Parses and processes an option string to an ARB fragment program
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
+ const char *option);
+
+/**
+ * Parses and processes instruction suffixes
+ *
+ * Instruction suffixes, such as \c _SAT, are processed. The relevant bits
+ * are set in \c inst. If suffixes are encountered that are either not known
+ * or not supported by the modes and options set in \c state, zero will be
+ * returned.
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
+ const char *suffix, struct prog_instruction *inst);
+
+/**
+ * Parses a condition code name
+ *
+ * The condition code names (e.g., \c LT, \c GT, \c NE) were added to assembly
+ * shaders with the \c GL_NV_fragment_program_option extension. This function
+ * converts a string representation into one of the \c COND_ macros.
+ *
+ * \return
+ * One of the \c COND_ macros defined in prog_instruction.h on success or zero
+ * on failure.
+ */
+extern int _mesa_parse_cc(const char *s);
+
+/*@}*/
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/programopt.c b/icd/intel/compiler/mesa-utils/src/mesa/program/programopt.c
new file mode 100644
index 0000000..92a8831
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/programopt.c
@@ -0,0 +1,682 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file programopt.c
+ * Vertex/Fragment program optimizations and transformations for program
+ * options, etc.
+ *
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "prog_parameter.h"
+#include "prog_statevars.h"
+#include "program.h"
+#include "programopt.h"
+#include "prog_instruction.h"
+
+
+/**
+ * This function inserts instructions for coordinate modelview * projection
+ * into a vertex program.
+ * May be used to implement the position_invariant option.
+ */
+static void
+_mesa_insert_mvp_dp4_code(struct gl_context *ctx, struct gl_vertex_program *vprog)
+{
+ struct prog_instruction *newInst;
+ const GLuint origLen = vprog->Base.NumInstructions;
+ const GLuint newLen = origLen + 4;
+ GLuint i;
+
+ /*
+ * Setup state references for the modelview/projection matrix.
+ * XXX we should check if these state vars are already declared.
+ */
+ static const gl_state_index mvpState[4][STATE_LENGTH] = {
+ { STATE_MVP_MATRIX, 0, 0, 0, 0 }, /* state.matrix.mvp.row[0] */
+ { STATE_MVP_MATRIX, 0, 1, 1, 0 }, /* state.matrix.mvp.row[1] */
+ { STATE_MVP_MATRIX, 0, 2, 2, 0 }, /* state.matrix.mvp.row[2] */
+ { STATE_MVP_MATRIX, 0, 3, 3, 0 }, /* state.matrix.mvp.row[3] */
+ };
+ GLint mvpRef[4];
+
+ for (i = 0; i < 4; i++) {
+ mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
+ mvpState[i]);
+ }
+
+ /* Alloc storage for new instructions */
+ newInst = _mesa_alloc_instructions(newLen);
+ if (!newInst) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glProgramString(inserting position_invariant code)");
+ return;
+ }
+
+ /*
+ * Generated instructions:
+ * newInst[0] = DP4 result.position.x, mvp.row[0], vertex.position;
+ * newInst[1] = DP4 result.position.y, mvp.row[1], vertex.position;
+ * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position;
+ * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position;
+ */
+ _mesa_init_instructions(newInst, 4);
+ for (i = 0; i < 4; i++) {
+ newInst[i].Opcode = OPCODE_DP4;
+ newInst[i].DstReg.File = PROGRAM_OUTPUT;
+ newInst[i].DstReg.Index = VARYING_SLOT_POS;
+ newInst[i].DstReg.WriteMask = (WRITEMASK_X << i);
+ newInst[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+ newInst[i].SrcReg[0].Index = mvpRef[i];
+ newInst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
+ newInst[i].SrcReg[1].File = PROGRAM_INPUT;
+ newInst[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+ newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ }
+
+ /* Append original instructions after new instructions */
+ _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);
+
+ /* free old instructions */
+ _mesa_free_instructions(vprog->Base.Instructions, origLen);
+
+ /* install new instructions */
+ vprog->Base.Instructions = newInst;
+ vprog->Base.NumInstructions = newLen;
+ vprog->Base.InputsRead |= VERT_BIT_POS;
+ vprog->Base.OutputsWritten |= BITFIELD64_BIT(VARYING_SLOT_POS);
+}
+
+
+static void
+_mesa_insert_mvp_mad_code(struct gl_context *ctx, struct gl_vertex_program *vprog)
+{
+ struct prog_instruction *newInst;
+ const GLuint origLen = vprog->Base.NumInstructions;
+ const GLuint newLen = origLen + 4;
+ GLuint hposTemp;
+ GLuint i;
+
+ /*
+ * Setup state references for the modelview/projection matrix.
+ * XXX we should check if these state vars are already declared.
+ */
+ static const gl_state_index mvpState[4][STATE_LENGTH] = {
+ { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE },
+ { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE },
+ { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE },
+ { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE },
+ };
+ GLint mvpRef[4];
+
+ for (i = 0; i < 4; i++) {
+ mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
+ mvpState[i]);
+ }
+
+ /* Alloc storage for new instructions */
+ newInst = _mesa_alloc_instructions(newLen);
+ if (!newInst) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glProgramString(inserting position_invariant code)");
+ return;
+ }
+
+ /* TEMP hposTemp; */
+ hposTemp = vprog->Base.NumTemporaries++;
+
+ /*
+ * Generated instructions:
+ * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]);
+ * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp);
+ * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp);
+ * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp);
+ */
+ _mesa_init_instructions(newInst, 4);
+
+ newInst[0].Opcode = OPCODE_MUL;
+ newInst[0].DstReg.File = PROGRAM_TEMPORARY;
+ newInst[0].DstReg.Index = hposTemp;
+ newInst[0].DstReg.WriteMask = WRITEMASK_XYZW;
+ newInst[0].SrcReg[0].File = PROGRAM_INPUT;
+ newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS;
+ newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX;
+ newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR;
+ newInst[0].SrcReg[1].Index = mvpRef[0];
+ newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+ for (i = 1; i <= 2; i++) {
+ newInst[i].Opcode = OPCODE_MAD;
+ newInst[i].DstReg.File = PROGRAM_TEMPORARY;
+ newInst[i].DstReg.Index = hposTemp;
+ newInst[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ newInst[i].SrcReg[0].File = PROGRAM_INPUT;
+ newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS;
+ newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i);
+ newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR;
+ newInst[i].SrcReg[1].Index = mvpRef[i];
+ newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY;
+ newInst[i].SrcReg[2].Index = hposTemp;
+ newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+ }
+
+ newInst[3].Opcode = OPCODE_MAD;
+ newInst[3].DstReg.File = PROGRAM_OUTPUT;
+ newInst[3].DstReg.Index = VARYING_SLOT_POS;
+ newInst[3].DstReg.WriteMask = WRITEMASK_XYZW;
+ newInst[3].SrcReg[0].File = PROGRAM_INPUT;
+ newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS;
+ newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW;
+ newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR;
+ newInst[3].SrcReg[1].Index = mvpRef[3];
+ newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY;
+ newInst[3].SrcReg[2].Index = hposTemp;
+ newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+
+
+ /* Append original instructions after new instructions */
+ _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);
+
+ /* free old instructions */
+ _mesa_free_instructions(vprog->Base.Instructions, origLen);
+
+ /* install new instructions */
+ vprog->Base.Instructions = newInst;
+ vprog->Base.NumInstructions = newLen;
+ vprog->Base.InputsRead |= VERT_BIT_POS;
+ vprog->Base.OutputsWritten |= BITFIELD64_BIT(VARYING_SLOT_POS);
+}
+
+
+void
+_mesa_insert_mvp_code(struct gl_context *ctx, struct gl_vertex_program *vprog)
+{
+ if (ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS)
+ _mesa_insert_mvp_dp4_code( ctx, vprog );
+ else
+ _mesa_insert_mvp_mad_code( ctx, vprog );
+}
+
+
+
+
+
+
+/**
+ * Append instructions to implement fog
+ *
+ * The \c fragment.fogcoord input is used to compute the fog blend factor.
+ *
+ * \param ctx The GL context
+ * \param fprog Fragment program that fog instructions will be appended to.
+ * \param fog_mode Fog mode. One of \c GL_EXP, \c GL_EXP2, or \c GL_LINEAR.
+ * \param saturate True if writes to color outputs should be clamped to [0, 1]
+ *
+ * \note
+ * This function sets \c VARYING_BIT_FOGC in \c fprog->Base.InputsRead.
+ *
+ * \todo With a little work, this function could be adapted to add fog code
+ * to vertex programs too.
+ */
+void
+_mesa_append_fog_code(struct gl_context *ctx,
+ struct gl_fragment_program *fprog, GLenum fog_mode,
+ GLboolean saturate)
+{
+ static const gl_state_index fogPStateOpt[STATE_LENGTH]
+ = { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 };
+ static const gl_state_index fogColorState[STATE_LENGTH]
+ = { STATE_FOG_COLOR, 0, 0, 0, 0};
+ struct prog_instruction *newInst, *inst;
+ const GLuint origLen = fprog->Base.NumInstructions;
+ const GLuint newLen = origLen + 5;
+ GLuint i;
+ GLint fogPRefOpt, fogColorRef; /* state references */
+ GLuint colorTemp, fogFactorTemp; /* temporary registerss */
+
+ if (fog_mode == GL_NONE) {
+ _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program"
+ " with fog_mode == GL_NONE");
+ return;
+ }
+
+ if (!(fprog->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR))) {
+ /* program doesn't output color, so nothing to do */
+ return;
+ }
+
+ /* Alloc storage for new instructions */
+ newInst = _mesa_alloc_instructions(newLen);
+ if (!newInst) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glProgramString(inserting fog_option code)");
+ return;
+ }
+
+ /* Copy orig instructions into new instruction buffer */
+ _mesa_copy_instructions(newInst, fprog->Base.Instructions, origLen);
+
+ /* PARAM fogParamsRefOpt = internal optimized fog params; */
+ fogPRefOpt
+ = _mesa_add_state_reference(fprog->Base.Parameters, fogPStateOpt);
+ /* PARAM fogColorRef = state.fog.color; */
+ fogColorRef
+ = _mesa_add_state_reference(fprog->Base.Parameters, fogColorState);
+
+ /* TEMP colorTemp; */
+ colorTemp = fprog->Base.NumTemporaries++;
+ /* TEMP fogFactorTemp; */
+ fogFactorTemp = fprog->Base.NumTemporaries++;
+
+ /* Scan program to find where result.color is written */
+ inst = newInst;
+ for (i = 0; i < fprog->Base.NumInstructions; i++) {
+ if (inst->Opcode == OPCODE_END)
+ break;
+ if (inst->DstReg.File == PROGRAM_OUTPUT &&
+ inst->DstReg.Index == FRAG_RESULT_COLOR) {
+ /* change the instruction to write to colorTemp w/ clamping */
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = colorTemp;
+ inst->SaturateMode = saturate;
+ /* don't break (may be several writes to result.color) */
+ }
+ inst++;
+ }
+ assert(inst->Opcode == OPCODE_END); /* we'll overwrite this inst */
+
+ _mesa_init_instructions(inst, 5);
+
+ /* emit instructions to compute fog blending factor */
+ /* this is always clamped to [0, 1] regardless of fragment clamping */
+ if (fog_mode == GL_LINEAR) {
+ /* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */
+ inst->Opcode = OPCODE_MAD;
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = fogFactorTemp;
+ inst->DstReg.WriteMask = WRITEMASK_X;
+ inst->SrcReg[0].File = PROGRAM_INPUT;
+ inst->SrcReg[0].Index = VARYING_SLOT_FOGC;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+ inst->SrcReg[1].File = PROGRAM_STATE_VAR;
+ inst->SrcReg[1].Index = fogPRefOpt;
+ inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
+ inst->SrcReg[2].File = PROGRAM_STATE_VAR;
+ inst->SrcReg[2].Index = fogPRefOpt;
+ inst->SrcReg[2].Swizzle = SWIZZLE_YYYY;
+ inst->SaturateMode = SATURATE_ZERO_ONE;
+ inst++;
+ }
+ else {
+ ASSERT(fog_mode == GL_EXP || fog_mode == GL_EXP2);
+ /* fogPRefOpt.z = d/ln(2), fogPRefOpt.w = d/sqrt(ln(2) */
+ /* EXP: MUL fogFactorTemp.x, fogPRefOpt.z, fragment.fogcoord.x; */
+ /* EXP2: MUL fogFactorTemp.x, fogPRefOpt.w, fragment.fogcoord.x; */
+ inst->Opcode = OPCODE_MUL;
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = fogFactorTemp;
+ inst->DstReg.WriteMask = WRITEMASK_X;
+ inst->SrcReg[0].File = PROGRAM_STATE_VAR;
+ inst->SrcReg[0].Index = fogPRefOpt;
+ inst->SrcReg[0].Swizzle
+ = (fog_mode == GL_EXP) ? SWIZZLE_ZZZZ : SWIZZLE_WWWW;
+ inst->SrcReg[1].File = PROGRAM_INPUT;
+ inst->SrcReg[1].Index = VARYING_SLOT_FOGC;
+ inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
+ inst++;
+ if (fog_mode == GL_EXP2) {
+ /* MUL fogFactorTemp.x, fogFactorTemp.x, fogFactorTemp.x; */
+ inst->Opcode = OPCODE_MUL;
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = fogFactorTemp;
+ inst->DstReg.WriteMask = WRITEMASK_X;
+ inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[0].Index = fogFactorTemp;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+ inst->SrcReg[1].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[1].Index = fogFactorTemp;
+ inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
+ inst++;
+ }
+ /* EX2_SAT fogFactorTemp.x, -fogFactorTemp.x; */
+ inst->Opcode = OPCODE_EX2;
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = fogFactorTemp;
+ inst->DstReg.WriteMask = WRITEMASK_X;
+ inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[0].Index = fogFactorTemp;
+ inst->SrcReg[0].Negate = NEGATE_XYZW;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+ inst->SaturateMode = SATURATE_ZERO_ONE;
+ inst++;
+ }
+ /* LRP result.color.xyz, fogFactorTemp.xxxx, colorTemp, fogColorRef; */
+ inst->Opcode = OPCODE_LRP;
+ inst->DstReg.File = PROGRAM_OUTPUT;
+ inst->DstReg.Index = FRAG_RESULT_COLOR;
+ inst->DstReg.WriteMask = WRITEMASK_XYZ;
+ inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[0].Index = fogFactorTemp;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+ inst->SrcReg[1].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[1].Index = colorTemp;
+ inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ inst->SrcReg[2].File = PROGRAM_STATE_VAR;
+ inst->SrcReg[2].Index = fogColorRef;
+ inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
+ inst++;
+ /* MOV result.color.w, colorTemp.x; # copy alpha */
+ inst->Opcode = OPCODE_MOV;
+ inst->DstReg.File = PROGRAM_OUTPUT;
+ inst->DstReg.Index = FRAG_RESULT_COLOR;
+ inst->DstReg.WriteMask = WRITEMASK_W;
+ inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[0].Index = colorTemp;
+ inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
+ inst++;
+ /* END; */
+ inst->Opcode = OPCODE_END;
+ inst++;
+
+ /* free old instructions */
+ _mesa_free_instructions(fprog->Base.Instructions, origLen);
+
+ /* install new instructions */
+ fprog->Base.Instructions = newInst;
+ fprog->Base.NumInstructions = inst - newInst;
+ fprog->Base.InputsRead |= VARYING_BIT_FOGC;
+ assert(fprog->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR));
+}
+
+
+
+static GLboolean
+is_texture_instruction(const struct prog_instruction *inst)
+{
+ switch (inst->Opcode) {
+ case OPCODE_TEX:
+ case OPCODE_TXB:
+ case OPCODE_TXD:
+ case OPCODE_TXL:
+ case OPCODE_TXP:
+ case OPCODE_TXP_NV:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Count the number of texure indirections in the given program.
+ * The program's NumTexIndirections field will be updated.
+ * See the GL_ARB_fragment_program spec (issue 24) for details.
+ * XXX we count texture indirections in texenvprogram.c (maybe use this code
+ * instead and elsewhere).
+ */
+void
+_mesa_count_texture_indirections(struct gl_program *prog)
+{
+ GLuint indirections = 1;
+ GLbitfield tempsOutput = 0x0;
+ GLbitfield aluTemps = 0x0;
+ GLuint i;
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *inst = prog->Instructions + i;
+
+ if (is_texture_instruction(inst)) {
+ if (((inst->SrcReg[0].File == PROGRAM_TEMPORARY) &&
+ (tempsOutput & (1 << inst->SrcReg[0].Index))) ||
+ ((inst->Opcode != OPCODE_KIL) &&
+ (inst->DstReg.File == PROGRAM_TEMPORARY) &&
+ (aluTemps & (1 << inst->DstReg.Index))))
+ {
+ indirections++;
+ tempsOutput = 0x0;
+ aluTemps = 0x0;
+ }
+ }
+ else {
+ GLuint j;
+ for (j = 0; j < 3; j++) {
+ if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)
+ aluTemps |= (1 << inst->SrcReg[j].Index);
+ }
+ if (inst->DstReg.File == PROGRAM_TEMPORARY)
+ aluTemps |= (1 << inst->DstReg.Index);
+ }
+
+ if ((inst->Opcode != OPCODE_KIL) && (inst->DstReg.File == PROGRAM_TEMPORARY))
+ tempsOutput |= (1 << inst->DstReg.Index);
+ }
+
+ prog->NumTexIndirections = indirections;
+}
+
+
+/**
+ * Count number of texture instructions in given program and update the
+ * program's NumTexInstructions field.
+ */
+void
+_mesa_count_texture_instructions(struct gl_program *prog)
+{
+ GLuint i;
+ prog->NumTexInstructions = 0;
+ for (i = 0; i < prog->NumInstructions; i++) {
+ prog->NumTexInstructions += is_texture_instruction(prog->Instructions + i);
+ }
+}
+
+
+/**
+ * Scan/rewrite program to remove reads of custom (output) registers.
+ * The passed type has to be PROGRAM_OUTPUT.
+ * On some hardware, trying to read an output register causes trouble.
+ * So, rewrite the program to use a temporary register in this case.
+ */
+void
+_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type)
+{
+ GLuint i;
+ GLint outputMap[VARYING_SLOT_MAX];
+ GLuint numVaryingReads = 0;
+ GLboolean usedTemps[MAX_PROGRAM_TEMPS];
+ GLuint firstTemp = 0;
+
+ _mesa_find_used_registers(prog, PROGRAM_TEMPORARY,
+ usedTemps, MAX_PROGRAM_TEMPS);
+
+ assert(type == PROGRAM_OUTPUT);
+
+ for (i = 0; i < VARYING_SLOT_MAX; i++)
+ outputMap[i] = -1;
+
+ /* look for instructions which read from varying vars */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+ GLuint j;
+ for (j = 0; j < numSrc; j++) {
+ if (inst->SrcReg[j].File == type) {
+ /* replace the read with a temp reg */
+ const GLuint var = inst->SrcReg[j].Index;
+ if (outputMap[var] == -1) {
+ numVaryingReads++;
+ outputMap[var] = _mesa_find_free_register(usedTemps,
+ MAX_PROGRAM_TEMPS,
+ firstTemp);
+ firstTemp = outputMap[var] + 1;
+ }
+ inst->SrcReg[j].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[j].Index = outputMap[var];
+ }
+ }
+ }
+
+ if (numVaryingReads == 0)
+ return; /* nothing to be done */
+
+ /* look for instructions which write to the varying vars identified above */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ if (inst->DstReg.File == type &&
+ outputMap[inst->DstReg.Index] >= 0) {
+ /* change inst to write to the temp reg, instead of the varying */
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = outputMap[inst->DstReg.Index];
+ }
+ }
+
+ /* insert new instructions to copy the temp vars to the varying vars */
+ {
+ struct prog_instruction *inst;
+ GLint endPos, var;
+
+ /* Look for END instruction and insert the new varying writes */
+ endPos = -1;
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ if (inst->Opcode == OPCODE_END) {
+ endPos = i;
+ _mesa_insert_instructions(prog, i, numVaryingReads);
+ break;
+ }
+ }
+
+ assert(endPos >= 0);
+
+ /* insert new MOV instructions here */
+ inst = prog->Instructions + endPos;
+ for (var = 0; var < VARYING_SLOT_MAX; var++) {
+ if (outputMap[var] >= 0) {
+ /* MOV VAR[var], TEMP[tmp]; */
+ inst->Opcode = OPCODE_MOV;
+ inst->DstReg.File = type;
+ inst->DstReg.Index = var;
+ inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[0].Index = outputMap[var];
+ inst++;
+ }
+ }
+ }
+}
+
+
+/**
+ * Make the given fragment program into a "no-op" shader.
+ * Actually, just copy the incoming fragment color (or texcoord)
+ * to the output color.
+ * This is for debug/test purposes.
+ */
+void
+_mesa_nop_fragment_program(struct gl_context *ctx, struct gl_fragment_program *prog)
+{
+ struct prog_instruction *inst;
+ GLuint inputAttr;
+
+ inst = _mesa_alloc_instructions(2);
+ if (!inst) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_fragment_program");
+ return;
+ }
+
+ _mesa_init_instructions(inst, 2);
+
+ inst[0].Opcode = OPCODE_MOV;
+ inst[0].DstReg.File = PROGRAM_OUTPUT;
+ inst[0].DstReg.Index = FRAG_RESULT_COLOR;
+ inst[0].SrcReg[0].File = PROGRAM_INPUT;
+ if (prog->Base.InputsRead & VARYING_BIT_COL0)
+ inputAttr = VARYING_SLOT_COL0;
+ else
+ inputAttr = VARYING_SLOT_TEX0;
+ inst[0].SrcReg[0].Index = inputAttr;
+
+ inst[1].Opcode = OPCODE_END;
+
+ _mesa_free_instructions(prog->Base.Instructions,
+ prog->Base.NumInstructions);
+
+ prog->Base.Instructions = inst;
+ prog->Base.NumInstructions = 2;
+ prog->Base.InputsRead = BITFIELD64_BIT(inputAttr);
+ prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
+}
+
+
+/**
+ * \sa _mesa_nop_fragment_program
+ * Replace the given vertex program with a "no-op" program that just
+ * transforms vertex position and emits color.
+ */
+void
+_mesa_nop_vertex_program(struct gl_context *ctx, struct gl_vertex_program *prog)
+{
+ struct prog_instruction *inst;
+ GLuint inputAttr;
+
+ /*
+ * Start with a simple vertex program that emits color.
+ */
+ inst = _mesa_alloc_instructions(2);
+ if (!inst) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_vertex_program");
+ return;
+ }
+
+ _mesa_init_instructions(inst, 2);
+
+ inst[0].Opcode = OPCODE_MOV;
+ inst[0].DstReg.File = PROGRAM_OUTPUT;
+ inst[0].DstReg.Index = VARYING_SLOT_COL0;
+ inst[0].SrcReg[0].File = PROGRAM_INPUT;
+ if (prog->Base.InputsRead & VERT_BIT_COLOR0)
+ inputAttr = VERT_ATTRIB_COLOR0;
+ else
+ inputAttr = VERT_ATTRIB_TEX0;
+ inst[0].SrcReg[0].Index = inputAttr;
+
+ inst[1].Opcode = OPCODE_END;
+
+ _mesa_free_instructions(prog->Base.Instructions,
+ prog->Base.NumInstructions);
+
+ prog->Base.Instructions = inst;
+ prog->Base.NumInstructions = 2;
+ prog->Base.InputsRead = BITFIELD64_BIT(inputAttr);
+ prog->Base.OutputsWritten = BITFIELD64_BIT(VARYING_SLOT_COL0);
+
+ /*
+ * Now insert code to do standard modelview/projection transformation.
+ */
+ _mesa_insert_mvp_code(ctx, prog);
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/programopt.h b/icd/intel/compiler/mesa-utils/src/mesa/program/programopt.h
new file mode 100644
index 0000000..f22109f
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/programopt.h
@@ -0,0 +1,55 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef PROGRAMOPT_H
+#define PROGRAMOPT_H 1
+
+#include "main/mtypes.h"
+
+extern void
+_mesa_insert_mvp_code(struct gl_context *ctx, struct gl_vertex_program *vprog);
+
+extern void
+_mesa_append_fog_code(struct gl_context *ctx,
+ struct gl_fragment_program *fprog, GLenum fog_mode,
+ GLboolean saturate);
+
+extern void
+_mesa_count_texture_indirections(struct gl_program *prog);
+
+extern void
+_mesa_count_texture_instructions(struct gl_program *prog);
+
+extern void
+_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type);
+
+extern void
+_mesa_nop_fragment_program(struct gl_context *ctx, struct gl_fragment_program *prog);
+
+extern void
+_mesa_nop_vertex_program(struct gl_context *ctx, struct gl_vertex_program *prog);
+
+
+#endif /* PROGRAMOPT_H */
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/register_allocate.c b/icd/intel/compiler/mesa-utils/src/mesa/program/register_allocate.c
new file mode 100644
index 0000000..6fac690
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/register_allocate.c
@@ -0,0 +1,676 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file register_allocate.c
+ *
+ * Graph-coloring register allocator.
+ *
+ * The basic idea of graph coloring is to make a node in a graph for
+ * every thing that needs a register (color) number assigned, and make
+ * edges in the graph between nodes that interfere (can't be allocated
+ * to the same register at the same time).
+ *
+ * During the "simplify" process, any any node with fewer edges than
+ * there are registers means that that edge can get assigned a
+ * register regardless of what its neighbors choose, so that node is
+ * pushed on a stack and removed (with its edges) from the graph.
+ * That likely causes other nodes to become trivially colorable as well.
+ *
+ * Then during the "select" process, nodes are popped off of that
+ * stack, their edges restored, and assigned a color different from
+ * their neighbors. Because they were pushed on the stack only when
+ * they were trivially colorable, any color chosen won't interfere
+ * with the registers to be popped later.
+ *
+ * The downside to most graph coloring is that real hardware often has
+ * limitations, like registers that need to be allocated to a node in
+ * pairs, or aligned on some boundary. This implementation follows
+ * the paper "Retargetable Graph-Coloring Register Allocation for
+ * Irregular Architectures" by Johan Runeson and Sven-Olof Nyström.
+ *
+ * In this system, there are register classes each containing various
+ * registers, and registers may interfere with other registers. For
+ * example, one might have a class of base registers, and a class of
+ * aligned register pairs that would each interfere with their pair of
+ * the base registers. Each node has a register class it needs to be
+ * assigned to. Define p(B) to be the size of register class B, and
+ * q(B,C) to be the number of registers in B that the worst choice
+ * register in C could conflict with. Then, this system replaces the
+ * basic graph coloring test of "fewer edges from this node than there
+ * are registers" with "For this node of class B, the sum of q(B,C)
+ * for each neighbor node of class C is less than pB".
+ *
+ * A nice feature of the pq test is that q(B,C) can be computed once
+ * up front and stored in a 2-dimensional array, so that the cost of
+ * coloring a node is constant with the number of registers. We do
+ * this during ra_set_finalize().
+ */
+
+#include <stdbool.h>
+#include <ralloc.h>
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/bitset.h"
+#include "register_allocate.h"
+
+#define NO_REG ~0
+
+struct ra_reg {
+ BITSET_WORD *conflicts;
+ unsigned int *conflict_list;
+ unsigned int conflict_list_size;
+ unsigned int num_conflicts;
+};
+
+struct ra_regs {
+ struct ra_reg *regs;
+ unsigned int count;
+
+ struct ra_class **classes;
+ unsigned int class_count;
+
+ bool round_robin;
+};
+
+struct ra_class {
+ /**
+ * Bitset indicating which registers belong to this class.
+ *
+ * (If bit N is set, then register N belongs to this class.)
+ */
+ BITSET_WORD *regs;
+
+ /**
+ * p(B) in Runeson/Nyström paper.
+ *
+ * This is "how many regs are in the set."
+ */
+ unsigned int p;
+
+ /**
+ * q(B,C) (indexed by C, B is this register class) in
+ * Runeson/Nyström paper. This is "how many registers of B could
+ * the worst choice register from C conflict with".
+ */
+ unsigned int *q;
+};
+
+struct ra_node {
+ /** @{
+ *
+ * List of which nodes this node interferes with. This should be
+ * symmetric with the other node.
+ */
+ BITSET_WORD *adjacency;
+ unsigned int *adjacency_list;
+ unsigned int adjacency_list_size;
+ unsigned int adjacency_count;
+ /** @} */
+
+ unsigned int class;
+
+ /* Register, if assigned, or NO_REG. */
+ unsigned int reg;
+
+ /**
+ * Set when the node is in the trivially colorable stack. When
+ * set, the adjacency to this node is ignored, to implement the
+ * "remove the edge from the graph" in simplification without
+ * having to actually modify the adjacency_list.
+ */
+ bool in_stack;
+
+ /* For an implementation that needs register spilling, this is the
+ * approximate cost of spilling this node.
+ */
+ float spill_cost;
+};
+
+struct ra_graph {
+ struct ra_regs *regs;
+ /**
+ * the variables that need register allocation.
+ */
+ struct ra_node *nodes;
+ unsigned int count; /**< count of nodes. */
+
+ unsigned int *stack;
+ unsigned int stack_count;
+
+ /**
+ * Tracks the start of the set of optimistically-colored registers in the
+ * stack.
+ *
+ * Along with any registers not in the stack (if one called ra_simplify()
+ * and didn't do optimistic coloring), these need to be considered for
+ * spilling.
+ */
+ unsigned int stack_optimistic_start;
+};
+
+/**
+ * Creates a set of registers for the allocator.
+ *
+ * mem_ctx is a ralloc context for the allocator. The reg set may be freed
+ * using ralloc_free().
+ */
+struct ra_regs *
+ra_alloc_reg_set(void *mem_ctx, unsigned int count)
+{
+ unsigned int i;
+ struct ra_regs *regs;
+
+ regs = rzalloc(mem_ctx, struct ra_regs);
+ regs->count = count;
+ regs->regs = rzalloc_array(regs, struct ra_reg, count);
+
+ for (i = 0; i < count; i++) {
+ regs->regs[i].conflicts = rzalloc_array(regs->regs, BITSET_WORD,
+ BITSET_WORDS(count));
+ BITSET_SET(regs->regs[i].conflicts, i);
+
+ regs->regs[i].conflict_list = ralloc_array(regs->regs, unsigned int, 4);
+ regs->regs[i].conflict_list_size = 4;
+ regs->regs[i].conflict_list[0] = i;
+ regs->regs[i].num_conflicts = 1;
+ }
+
+ return regs;
+}
+
+/**
+ * The register allocator by default prefers to allocate low register numbers,
+ * since it was written for hardware (gen4/5 Intel) that is limited in its
+ * multithreadedness by the number of registers used in a given shader.
+ *
+ * However, for hardware without that restriction, densely packed register
+ * allocation can put serious constraints on instruction scheduling. This
+ * function tells the allocator to rotate around the registers if possible as
+ * it allocates the nodes.
+ */
+void
+ra_set_allocate_round_robin(struct ra_regs *regs)
+{
+ regs->round_robin = true;
+}
+
+static void
+ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2)
+{
+ struct ra_reg *reg1 = ®s->regs[r1];
+
+ if (reg1->conflict_list_size == reg1->num_conflicts) {
+ reg1->conflict_list_size *= 2;
+ reg1->conflict_list = reralloc(regs->regs, reg1->conflict_list,
+ unsigned int, reg1->conflict_list_size);
+ }
+ reg1->conflict_list[reg1->num_conflicts++] = r2;
+ BITSET_SET(reg1->conflicts, r2);
+}
+
+void
+ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2)
+{
+ if (!BITSET_TEST(regs->regs[r1].conflicts, r2)) {
+ ra_add_conflict_list(regs, r1, r2);
+ ra_add_conflict_list(regs, r2, r1);
+ }
+}
+
+/**
+ * Adds a conflict between base_reg and reg, and also between reg and
+ * anything that base_reg conflicts with.
+ *
+ * This can simplify code for setting up multiple register classes
+ * which are aggregates of some base hardware registers, compared to
+ * explicitly using ra_add_reg_conflict.
+ */
+void
+ra_add_transitive_reg_conflict(struct ra_regs *regs,
+ unsigned int base_reg, unsigned int reg)
+{
+ int i;
+
+ ra_add_reg_conflict(regs, reg, base_reg);
+
+ for (i = 0; i < regs->regs[base_reg].num_conflicts; i++) {
+ ra_add_reg_conflict(regs, reg, regs->regs[base_reg].conflict_list[i]);
+ }
+}
+
+unsigned int
+ra_alloc_reg_class(struct ra_regs *regs)
+{
+ struct ra_class *class;
+
+ regs->classes = reralloc(regs->regs, regs->classes, struct ra_class *,
+ regs->class_count + 1);
+
+ class = rzalloc(regs, struct ra_class);
+ regs->classes[regs->class_count] = class;
+
+ class->regs = rzalloc_array(class, BITSET_WORD, BITSET_WORDS(regs->count));
+
+ return regs->class_count++;
+}
+
+void
+ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r)
+{
+ struct ra_class *class = regs->classes[c];
+
+ BITSET_SET(class->regs, r);
+ class->p++;
+}
+
+/**
+ * Returns true if the register belongs to the given class.
+ */
+static bool
+reg_belongs_to_class(unsigned int r, struct ra_class *c)
+{
+ return BITSET_TEST(c->regs, r);
+}
+
+/**
+ * Must be called after all conflicts and register classes have been
+ * set up and before the register set is used for allocation.
+ * To avoid costly q value computation, use the q_values paramater
+ * to pass precomputed q values to this function.
+ */
+void
+ra_set_finalize(struct ra_regs *regs, unsigned int **q_values)
+{
+ unsigned int b, c;
+
+ for (b = 0; b < regs->class_count; b++) {
+ regs->classes[b]->q = ralloc_array(regs, unsigned int, regs->class_count);
+ }
+
+ if (q_values) {
+ for (b = 0; b < regs->class_count; b++) {
+ for (c = 0; c < regs->class_count; c++) {
+ regs->classes[b]->q[c] = q_values[b][c];
+ }
+ }
+ return;
+ }
+
+ /* Compute, for each class B and C, how many regs of B an
+ * allocation to C could conflict with.
+ */
+ for (b = 0; b < regs->class_count; b++) {
+ for (c = 0; c < regs->class_count; c++) {
+ unsigned int rc;
+ int max_conflicts = 0;
+
+ for (rc = 0; rc < regs->count; rc++) {
+ int conflicts = 0;
+ int i;
+
+ if (!reg_belongs_to_class(rc, regs->classes[c]))
+ continue;
+
+ for (i = 0; i < regs->regs[rc].num_conflicts; i++) {
+ unsigned int rb = regs->regs[rc].conflict_list[i];
+ if (BITSET_TEST(regs->classes[b]->regs, rb))
+ conflicts++;
+ }
+ max_conflicts = MAX2(max_conflicts, conflicts);
+ }
+ regs->classes[b]->q[c] = max_conflicts;
+ }
+ }
+}
+
+static void
+ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2)
+{
+ BITSET_SET(g->nodes[n1].adjacency, n2);
+
+ if (g->nodes[n1].adjacency_count >=
+ g->nodes[n1].adjacency_list_size) {
+ g->nodes[n1].adjacency_list_size *= 2;
+ g->nodes[n1].adjacency_list = reralloc(g, g->nodes[n1].adjacency_list,
+ unsigned int,
+ g->nodes[n1].adjacency_list_size);
+ }
+
+ g->nodes[n1].adjacency_list[g->nodes[n1].adjacency_count] = n2;
+ g->nodes[n1].adjacency_count++;
+}
+
+struct ra_graph *
+ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
+{
+ struct ra_graph *g;
+ unsigned int i;
+
+ g = rzalloc(regs, struct ra_graph);
+ g->regs = regs;
+ g->nodes = rzalloc_array(g, struct ra_node, count);
+ g->count = count;
+
+ g->stack = rzalloc_array(g, unsigned int, count);
+
+ for (i = 0; i < count; i++) {
+ int bitset_count = BITSET_WORDS(count);
+ g->nodes[i].adjacency = rzalloc_array(g, BITSET_WORD, bitset_count);
+
+ g->nodes[i].adjacency_list_size = 4;
+ g->nodes[i].adjacency_list =
+ ralloc_array(g, unsigned int, g->nodes[i].adjacency_list_size);
+ g->nodes[i].adjacency_count = 0;
+
+ ra_add_node_adjacency(g, i, i);
+ g->nodes[i].reg = NO_REG;
+ }
+
+ return g;
+}
+
+void
+ra_set_node_class(struct ra_graph *g,
+ unsigned int n, unsigned int class)
+{
+ g->nodes[n].class = class;
+}
+
+void
+ra_add_node_interference(struct ra_graph *g,
+ unsigned int n1, unsigned int n2)
+{
+ if (!BITSET_TEST(g->nodes[n1].adjacency, n2)) {
+ ra_add_node_adjacency(g, n1, n2);
+ ra_add_node_adjacency(g, n2, n1);
+ }
+}
+
+static bool
+pq_test(struct ra_graph *g, unsigned int n)
+{
+ unsigned int j;
+ unsigned int q = 0;
+ int n_class = g->nodes[n].class;
+
+ for (j = 0; j < g->nodes[n].adjacency_count; j++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[j];
+ unsigned int n2_class = g->nodes[n2].class;
+
+ if (n != n2 && !g->nodes[n2].in_stack) {
+ q += g->regs->classes[n_class]->q[n2_class];
+ }
+ }
+
+ return q < g->regs->classes[n_class]->p;
+}
+
+/**
+ * Simplifies the interference graph by pushing all
+ * trivially-colorable nodes into a stack of nodes to be colored,
+ * removing them from the graph, and rinsing and repeating.
+ *
+ * Returns true if all nodes were removed from the graph. false
+ * means that either spilling will be required, or optimistic coloring
+ * should be applied.
+ */
+bool
+ra_simplify(struct ra_graph *g)
+{
+ bool progress = true;
+ int i;
+
+ while (progress) {
+ progress = false;
+
+ for (i = g->count - 1; i >= 0; i--) {
+ if (g->nodes[i].in_stack || g->nodes[i].reg != NO_REG)
+ continue;
+
+ if (pq_test(g, i)) {
+ g->stack[g->stack_count] = i;
+ g->stack_count++;
+ g->nodes[i].in_stack = true;
+ progress = true;
+ }
+ }
+ }
+
+ for (i = 0; i < g->count; i++) {
+ if (!g->nodes[i].in_stack && g->nodes[i].reg == -1)
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Pops nodes from the stack back into the graph, coloring them with
+ * registers as they go.
+ *
+ * If all nodes were trivially colorable, then this must succeed. If
+ * not (optimistic coloring), then it may return false;
+ */
+bool
+ra_select(struct ra_graph *g)
+{
+ int i;
+ int start_search_reg = 0;
+
+ while (g->stack_count != 0) {
+ unsigned int ri;
+ unsigned int r = -1;
+ int n = g->stack[g->stack_count - 1];
+ struct ra_class *c = g->regs->classes[g->nodes[n].class];
+
+ /* Find the lowest-numbered reg which is not used by a member
+ * of the graph adjacent to us.
+ */
+ for (ri = 0; ri < g->regs->count; ri++) {
+ r = (start_search_reg + ri) % g->regs->count;
+ if (!reg_belongs_to_class(r, c))
+ continue;
+
+ /* Check if any of our neighbors conflict with this register choice. */
+ for (i = 0; i < g->nodes[n].adjacency_count; i++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[i];
+
+ if (!g->nodes[n2].in_stack &&
+ BITSET_TEST(g->regs->regs[r].conflicts, g->nodes[n2].reg)) {
+ break;
+ }
+ }
+ if (i == g->nodes[n].adjacency_count)
+ break;
+ }
+ if (ri == g->regs->count)
+ return false;
+
+ g->nodes[n].reg = r;
+ g->nodes[n].in_stack = false;
+ g->stack_count--;
+
+ if (g->regs->round_robin)
+ start_search_reg = r + 1;
+ }
+
+ return true;
+}
+
+/**
+ * Optimistic register coloring: Just push the remaining nodes
+ * on the stack. They'll be colored first in ra_select(), and
+ * if they succeed then the locally-colorable nodes are still
+ * locally-colorable and the rest of the register allocation
+ * will succeed.
+ */
+void
+ra_optimistic_color(struct ra_graph *g)
+{
+ unsigned int i;
+
+ g->stack_optimistic_start = g->stack_count;
+ for (i = 0; i < g->count; i++) {
+ if (g->nodes[i].in_stack || g->nodes[i].reg != NO_REG)
+ continue;
+
+ g->stack[g->stack_count] = i;
+ g->stack_count++;
+ g->nodes[i].in_stack = true;
+ }
+}
+
+bool
+ra_allocate_no_spills(struct ra_graph *g)
+{
+ if (!ra_simplify(g)) {
+ ra_optimistic_color(g);
+ }
+ return ra_select(g);
+}
+
+unsigned int
+ra_get_node_reg(struct ra_graph *g, unsigned int n)
+{
+ return g->nodes[n].reg;
+}
+
+/**
+ * Forces a node to a specific register. This can be used to avoid
+ * creating a register class containing one node when handling data
+ * that must live in a fixed location and is known to not conflict
+ * with other forced register assignment (as is common with shader
+ * input data). These nodes do not end up in the stack during
+ * ra_simplify(), and thus at ra_select() time it is as if they were
+ * the first popped off the stack and assigned their fixed locations.
+ * Nodes that use this function do not need to be assigned a register
+ * class.
+ *
+ * Must be called before ra_simplify().
+ */
+void
+ra_set_node_reg(struct ra_graph *g, unsigned int n, unsigned int reg)
+{
+ g->nodes[n].reg = reg;
+ g->nodes[n].in_stack = false;
+}
+
+static float
+ra_get_spill_benefit(struct ra_graph *g, unsigned int n)
+{
+ int j;
+ float benefit = 0;
+ int n_class = g->nodes[n].class;
+
+ /* Define the benefit of eliminating an interference between n, n2
+ * through spilling as q(C, B) / p(C). This is similar to the
+ * "count number of edges" approach of traditional graph coloring,
+ * but takes classes into account.
+ */
+ for (j = 0; j < g->nodes[n].adjacency_count; j++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[j];
+ if (n != n2) {
+ unsigned int n2_class = g->nodes[n2].class;
+ benefit += ((float)g->regs->classes[n_class]->q[n2_class] /
+ g->regs->classes[n_class]->p);
+ }
+ }
+
+ return benefit;
+}
+
+/**
+ * Returns a node number to be spilled according to the cost/benefit using
+ * the pq test, or -1 if there are no spillable nodes.
+ */
+int
+ra_get_best_spill_node(struct ra_graph *g)
+{
+ unsigned int best_node = -1;
+ float best_benefit = 0.0;
+ unsigned int n, i;
+
+ /* For any registers not in the stack to be colored, consider them for
+ * spilling. This will mostly collect nodes that were being optimistally
+ * colored as part of ra_allocate_no_spills() if we didn't successfully
+ * optimistically color.
+ *
+ * It also includes nodes not trivially colorable by ra_simplify() if it
+ * was used directly instead of as part of ra_allocate_no_spills().
+ */
+ for (n = 0; n < g->count; n++) {
+ float cost = g->nodes[n].spill_cost;
+ float benefit;
+
+ if (cost <= 0.0)
+ continue;
+
+ if (g->nodes[n].in_stack)
+ continue;
+
+ benefit = ra_get_spill_benefit(g, n);
+
+ if (benefit / cost > best_benefit) {
+ best_benefit = benefit / cost;
+ best_node = n;
+ }
+ }
+
+ /* Also consider spilling any nodes that were set up to be optimistically
+ * colored that we couldn't manage to color in ra_select().
+ */
+ for (i = g->stack_optimistic_start; i < g->stack_count; i++) {
+ float cost, benefit;
+
+ n = g->stack[i];
+ cost = g->nodes[n].spill_cost;
+
+ if (cost <= 0.0)
+ continue;
+
+ benefit = ra_get_spill_benefit(g, n);
+
+ if (benefit / cost > best_benefit) {
+ best_benefit = benefit / cost;
+ best_node = n;
+ }
+ }
+
+ return best_node;
+}
+
+/**
+ * Only nodes with a spill cost set (cost != 0.0) will be considered
+ * for register spilling.
+ */
+void
+ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost)
+{
+ g->nodes[n].spill_cost = cost;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/register_allocate.h b/icd/intel/compiler/mesa-utils/src/mesa/program/register_allocate.h
new file mode 100644
index 0000000..337dcf7
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/register_allocate.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <stdbool.h>
+
+struct ra_class;
+struct ra_regs;
+
+/* @{
+ * Register set setup.
+ *
+ * This should be done once at backend initializaion, as
+ * ra_set_finalize is O(r^2*c^2). The registers may be virtual
+ * registers, such as aligned register pairs that conflict with the
+ * two real registers from which they are composed.
+ */
+struct ra_regs *ra_alloc_reg_set(void *mem_ctx, unsigned int count);
+void ra_set_allocate_round_robin(struct ra_regs *regs);
+unsigned int ra_alloc_reg_class(struct ra_regs *regs);
+void ra_add_reg_conflict(struct ra_regs *regs,
+ unsigned int r1, unsigned int r2);
+void ra_add_transitive_reg_conflict(struct ra_regs *regs,
+ unsigned int base_reg, unsigned int reg);
+void ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int reg);
+void ra_set_num_conflicts(struct ra_regs *regs, unsigned int class_a,
+ unsigned int class_b, unsigned int num_conflicts);
+void ra_set_finalize(struct ra_regs *regs, unsigned int **conflicts);
+/** @} */
+
+/** @{ Interference graph setup.
+ *
+ * Each interference graph node is a virtual variable in the IL. It
+ * is up to the user to ra_set_node_class() for the virtual variable,
+ * and compute live ranges and ra_node_interfere() between conflicting
+ * live ranges.
+ */
+struct ra_graph *ra_alloc_interference_graph(struct ra_regs *regs,
+ unsigned int count);
+void ra_set_node_class(struct ra_graph *g, unsigned int n, unsigned int c);
+void ra_add_node_interference(struct ra_graph *g,
+ unsigned int n1, unsigned int n2);
+/** @} */
+
+/** @{ Graph-coloring register allocation */
+bool ra_simplify(struct ra_graph *g);
+void ra_optimistic_color(struct ra_graph *g);
+bool ra_select(struct ra_graph *g);
+bool ra_allocate_no_spills(struct ra_graph *g);
+
+unsigned int ra_get_node_reg(struct ra_graph *g, unsigned int n);
+void ra_set_node_reg(struct ra_graph * g, unsigned int n, unsigned int reg);
+void ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost);
+int ra_get_best_spill_node(struct ra_graph *g);
+/** @} */
+
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/sampler.cpp b/icd/intel/compiler/mesa-utils/src/mesa/program/sampler.cpp
new file mode 100644
index 0000000..e6532be
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/sampler.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ir.h"
+#include "glsl_types.h"
+#include "ir_visitor.h"
+#include "../glsl/program.h"
+#include "program/hash_table.h"
+#include "ir_uniform.h"
+
+extern "C" {
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "program/prog_parameter.h"
+#include "program/program.h"
+}
+
+class get_sampler_name : public ir_hierarchical_visitor
+{
+public:
+ get_sampler_name(ir_dereference *last,
+ struct gl_shader_program *shader_program)
+ {
+ this->mem_ctx = ralloc_context(NULL);
+ this->shader_program = shader_program;
+ this->name = NULL;
+ this->offset = 0;
+ this->last = last;
+ }
+
+ ~get_sampler_name()
+ {
+ ralloc_free(this->mem_ctx);
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ this->name = ir->var->name;
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
+ {
+ this->name = ralloc_asprintf(mem_ctx, "%s.%s", name, ir->field);
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
+ {
+ ir_constant *index = ir->array_index->as_constant();
+ int i;
+
+ if (index) {
+ i = index->value.i[0];
+ } else {
+ /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
+ * while GLSL 1.30 requires that the array indices be
+ * constant integer expressions. We don't expect any driver
+ * to actually work with a really variable array index, so
+ * all that would work would be an unrolled loop counter that ends
+ * up being constant above.
+ */
+ ralloc_strcat(&shader_program->InfoLog,
+ "warning: Variable sampler array index unsupported.\n"
+ "This feature of the language was removed in GLSL 1.20 "
+ "and is unlikely to be supported for 1.10 in Mesa.\n");
+ i = 0;
+ }
+ if (ir != last) {
+ this->name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i);
+ } else {
+ offset = i;
+ }
+ return visit_continue;
+ }
+
+ struct gl_shader_program *shader_program;
+ const char *name;
+ void *mem_ctx;
+ int offset;
+ ir_dereference *last;
+};
+
+
+extern "C" int
+_mesa_get_sampler_uniform_value(class ir_dereference *sampler,
+ struct gl_shader_program *shader_program,
+ const struct gl_program *prog)
+{
+ get_sampler_name getname(sampler, shader_program);
+
+ GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target);
+
+ sampler->accept(&getname);
+
+ unsigned location;
+ if (!shader_program->UniformHash->get(location, getname.name)) {
+ linker_error(shader_program,
+ "failed to find sampler named %s.\n", getname.name);
+ return 0;
+ }
+
+ if (!shader_program->UniformStorage[location].sampler[shader].active) {
+ assert(0 && "cannot return a sampler");
+ linker_error(shader_program,
+ "cannot return a sampler named %s, because it is not "
+ "used in this shader stage. This is a driver bug.\n",
+ getname.name);
+ return 0;
+ }
+
+ return shader_program->UniformStorage[location].sampler[shader].index +
+ getname.offset;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/sampler.h b/icd/intel/compiler/mesa-utils/src/mesa/program/sampler.h
new file mode 100644
index 0000000..22467e9
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/sampler.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+int
+_mesa_get_sampler_uniform_value(class ir_dereference *sampler,
+ struct gl_shader_program *shader_program,
+ const struct gl_program *prog);
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/string_to_uint_map.cpp b/icd/intel/compiler/mesa-utils/src/mesa/program/string_to_uint_map.cpp
new file mode 100644
index 0000000..cfa73ab
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/string_to_uint_map.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file string_to_uint_map.cpp
+ * \brief Dumb wrapprs so that C code can create and destroy maps.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+#include "hash_table.h"
+
+extern "C" struct string_to_uint_map *
+string_to_uint_map_ctor()
+{
+ return new string_to_uint_map;
+}
+
+extern "C" void
+string_to_uint_map_dtor(struct string_to_uint_map *map)
+{
+ delete map;
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/symbol_table.c b/icd/intel/compiler/mesa-utils/src/mesa/program/symbol_table.c
new file mode 100644
index 0000000..9462978
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/symbol_table.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "main/imports.h"
+#include "symbol_table.h"
+#include "hash_table.h"
+
+struct symbol {
+ /**
+ * Link to the next symbol in the table with the same name
+ *
+ * The linked list of symbols with the same name is ordered by scope
+ * from inner-most to outer-most.
+ */
+ struct symbol *next_with_same_name;
+
+
+ /**
+ * Link to the next symbol in the table with the same scope
+ *
+ * The linked list of symbols with the same scope is unordered. Symbols
+ * in this list my have unique names.
+ */
+ struct symbol *next_with_same_scope;
+
+
+ /**
+ * Header information for the list of symbols with the same name.
+ */
+ struct symbol_header *hdr;
+
+
+ /**
+ * Name space of the symbol
+ *
+ * Name space are arbitrary user assigned integers. No two symbols can
+ * exist in the same name space at the same scope level.
+ */
+ int name_space;
+
+ /** Scope depth where this symbol was defined. */
+ unsigned depth;
+
+ /**
+ * Arbitrary user supplied data.
+ */
+ void *data;
+};
+
+
+/**
+ */
+struct symbol_header {
+ /** Linkage in list of all headers in a given symbol table. */
+ struct symbol_header *next;
+
+ /** Symbol name. */
+ char *name;
+
+ /** Linked list of symbols with the same name. */
+ struct symbol *symbols;
+};
+
+
+/**
+ * Element of the scope stack.
+ */
+struct scope_level {
+ /** Link to next (inner) scope level. */
+ struct scope_level *next;
+
+ /** Linked list of symbols with the same scope. */
+ struct symbol *symbols;
+};
+
+
+/**
+ *
+ */
+struct _mesa_symbol_table {
+ /** Hash table containing all symbols in the symbol table. */
+ struct hash_table *ht;
+
+ /** Top of scope stack. */
+ struct scope_level *current_scope;
+
+ /** List of all symbol headers in the table. */
+ struct symbol_header *hdr;
+
+ /** Current scope depth. */
+ unsigned depth;
+};
+
+
+static void
+check_symbol_table(struct _mesa_symbol_table *table)
+{
+#if !defined(NDEBUG)
+ struct scope_level *scope;
+
+ for (scope = table->current_scope; scope != NULL; scope = scope->next) {
+ struct symbol *sym;
+
+ for (sym = scope->symbols
+ ; sym != NULL
+ ; sym = sym->next_with_same_name) {
+ const struct symbol_header *const hdr = sym->hdr;
+ struct symbol *sym2;
+
+ for (sym2 = hdr->symbols
+ ; sym2 != NULL
+ ; sym2 = sym2->next_with_same_name) {
+ assert(sym2->hdr == hdr);
+ }
+ }
+ }
+#else
+ (void) table;
+#endif /* !defined(NDEBUG) */
+}
+
+void
+_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = table->current_scope;
+ struct symbol *sym = scope->symbols;
+
+ table->current_scope = scope->next;
+ table->depth--;
+
+ free(scope);
+
+ while (sym != NULL) {
+ struct symbol *const next = sym->next_with_same_scope;
+ struct symbol_header *const hdr = sym->hdr;
+
+ assert(hdr->symbols == sym);
+
+ hdr->symbols = sym->next_with_same_name;
+
+ free(sym);
+
+ sym = next;
+ }
+
+ check_symbol_table(table);
+}
+
+
+void
+_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = calloc(1, sizeof(*scope));
+
+ scope->next = table->current_scope;
+ table->current_scope = scope;
+ table->depth++;
+}
+
+
+static struct symbol_header *
+find_symbol(struct _mesa_symbol_table *table, const char *name)
+{
+ return (struct symbol_header *) hash_table_find(table->ht, name);
+}
+
+
+/**
+ * Determine the scope "distance" of a symbol from the current scope
+ *
+ * \return
+ * A non-negative number for the number of scopes between the current scope
+ * and the scope where a symbol was defined. A value of zero means the current
+ * scope. A negative number if the symbol does not exist.
+ */
+int
+_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+ struct symbol *sym;
+
+ if (hdr != NULL) {
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ assert(sym->depth <= table->depth);
+ return sym->depth - table->depth;
+ }
+ }
+ }
+
+ return -1;
+}
+
+
+void *
+_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+
+ if (hdr != NULL) {
+ struct symbol *sym;
+
+
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ return sym->data;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+int
+_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name,
+ void *declaration)
+{
+ struct symbol_header *hdr;
+ struct symbol *sym;
+
+ check_symbol_table(table);
+
+ hdr = find_symbol(table, name);
+
+ check_symbol_table(table);
+
+ if (hdr == NULL) {
+ hdr = calloc(1, sizeof(*hdr));
+ hdr->name = strdup(name);
+
+ hash_table_insert(table->ht, hdr, hdr->name);
+ hdr->next = table->hdr;
+ table->hdr = hdr;
+ }
+
+ check_symbol_table(table);
+
+ /* If the symbol already exists in this namespace at this scope, it cannot
+ * be added to the table.
+ */
+ for (sym = hdr->symbols
+ ; (sym != NULL) && (sym->name_space != name_space)
+ ; sym = sym->next_with_same_name) {
+ /* empty */
+ }
+
+ if (sym && (sym->depth == table->depth))
+ return -1;
+
+ sym = calloc(1, sizeof(*sym));
+ sym->next_with_same_name = hdr->symbols;
+ sym->next_with_same_scope = table->current_scope->symbols;
+ sym->hdr = hdr;
+ sym->name_space = name_space;
+ sym->data = declaration;
+ sym->depth = table->depth;
+
+ assert(sym->hdr == hdr);
+
+ hdr->symbols = sym;
+ table->current_scope->symbols = sym;
+
+ check_symbol_table(table);
+ return 0;
+}
+
+
+int
+_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name,
+ void *declaration)
+{
+ struct symbol_header *hdr;
+ struct symbol *sym;
+ struct symbol *curr;
+ struct scope_level *top_scope;
+
+ check_symbol_table(table);
+
+ hdr = find_symbol(table, name);
+
+ check_symbol_table(table);
+
+ if (hdr == NULL) {
+ hdr = calloc(1, sizeof(*hdr));
+ hdr->name = strdup(name);
+
+ hash_table_insert(table->ht, hdr, hdr->name);
+ hdr->next = table->hdr;
+ table->hdr = hdr;
+ }
+
+ check_symbol_table(table);
+
+ /* If the symbol already exists in this namespace at this scope, it cannot
+ * be added to the table.
+ */
+ for (sym = hdr->symbols
+ ; (sym != NULL) && (sym->name_space != name_space)
+ ; sym = sym->next_with_same_name) {
+ /* empty */
+ }
+
+ if (sym && sym->depth == 0)
+ return -1;
+
+ /* Find the top-level scope */
+ for (top_scope = table->current_scope
+ ; top_scope->next != NULL
+ ; top_scope = top_scope->next) {
+ /* empty */
+ }
+
+ sym = calloc(1, sizeof(*sym));
+ sym->next_with_same_scope = top_scope->symbols;
+ sym->hdr = hdr;
+ sym->name_space = name_space;
+ sym->data = declaration;
+
+ assert(sym->hdr == hdr);
+
+ /* Since next_with_same_name is ordered by scope, we need to append the
+ * new symbol to the _end_ of the list.
+ */
+ if (hdr->symbols == NULL) {
+ hdr->symbols = sym;
+ } else {
+ for (curr = hdr->symbols
+ ; curr->next_with_same_name != NULL
+ ; curr = curr->next_with_same_name) {
+ /* empty */
+ }
+ curr->next_with_same_name = sym;
+ }
+ top_scope->symbols = sym;
+
+ check_symbol_table(table);
+ return 0;
+}
+
+
+
+struct _mesa_symbol_table *
+_mesa_symbol_table_ctor(void)
+{
+ struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
+
+ if (table != NULL) {
+ table->ht = hash_table_ctor(32, hash_table_string_hash,
+ hash_table_string_compare);
+
+ _mesa_symbol_table_push_scope(table);
+ }
+
+ return table;
+}
+
+
+void
+_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
+{
+ struct symbol_header *hdr;
+ struct symbol_header *next;
+
+ while (table->current_scope != NULL) {
+ _mesa_symbol_table_pop_scope(table);
+ }
+
+ for (hdr = table->hdr; hdr != NULL; hdr = next) {
+ next = hdr->next;
+ free(hdr->name);
+ free(hdr);
+ }
+
+ hash_table_dtor(table->ht);
+ free(table);
+}
diff --git a/icd/intel/compiler/mesa-utils/src/mesa/program/symbol_table.h b/icd/intel/compiler/mesa-utils/src/mesa/program/symbol_table.h
new file mode 100644
index 0000000..1027f47
--- /dev/null
+++ b/icd/intel/compiler/mesa-utils/src/mesa/program/symbol_table.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef MESA_SYMBOL_TABLE_H
+#define MESA_SYMBOL_TABLE_H
+
+struct _mesa_symbol_table;
+
+extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
+
+extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
+
+extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
+ int name_space, const char *name, void *declaration);
+
+extern int _mesa_symbol_table_add_global_symbol(
+ struct _mesa_symbol_table *symtab, int name_space, const char *name,
+ void *declaration);
+
+extern int _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+ int name_space, const char *name);
+
+extern void *_mesa_symbol_table_find_symbol(
+ struct _mesa_symbol_table *symtab, int name_space, const char *name);
+
+extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
+
+extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
+
+#endif /* MESA_SYMBOL_TABLE_H */
diff --git a/icd/intel/compiler/shader/ast_function.cpp b/icd/intel/compiler/shader/ast_function.cpp
index 0cfaf4c..80c8032 100644
--- a/icd/intel/compiler/shader/ast_function.cpp
+++ b/icd/intel/compiler/shader/ast_function.cpp
@@ -25,7 +25,7 @@
#include "ast.h"
#include "glsl_types.h"
#include "ir.h"
-#include "main/core.h" /* for MIN2 */
+#include "libfns.h" // LunarG ADD:
static ir_rvalue *
convert_component(ir_rvalue *src, const glsl_type *desired_type);
diff --git a/icd/intel/compiler/shader/ast_to_hir.cpp b/icd/intel/compiler/shader/ast_to_hir.cpp
index 332f934..009c823 100644
--- a/icd/intel/compiler/shader/ast_to_hir.cpp
+++ b/icd/intel/compiler/shader/ast_to_hir.cpp
@@ -49,7 +49,7 @@
* parser (and lexer) sources.
*/
-#include "main/core.h" /* for struct gl_extensions */
+#include "libfns.h" // LunarG ADD:
#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "ast.h"
diff --git a/icd/intel/compiler/shader/builtin_functions.cpp b/icd/intel/compiler/shader/builtin_functions.cpp
index f9f0686..28b241e 100644
--- a/icd/intel/compiler/shader/builtin_functions.cpp
+++ b/icd/intel/compiler/shader/builtin_functions.cpp
@@ -55,7 +55,7 @@
#include <stdarg.h>
#include <stdio.h>
-#include "main/core.h" /* for struct gl_shader */
+#include "libfns.h" /* for struct gl_shader */
#include "main/shaderobj.h"
#include "ir_builder.h"
#include "glsl_parser_extras.h"
diff --git a/icd/intel/compiler/shader/builtin_variables.cpp b/icd/intel/compiler/shader/builtin_variables.cpp
index 60b0e38..1b4a39e 100644
--- a/icd/intel/compiler/shader/builtin_variables.cpp
+++ b/icd/intel/compiler/shader/builtin_variables.cpp
@@ -24,7 +24,7 @@
#include "ir.h"
#include "glsl_parser_extras.h"
#include "glsl_symbol_table.h"
-#include "main/core.h"
+#include "libfns.h"
#include "main/uniforms.h"
#include "program/prog_parameter.h"
#include "program/prog_statevars.h"
diff --git a/icd/intel/compiler/shader/glsl_parser_extras.cpp b/icd/intel/compiler/shader/glsl_parser_extras.cpp
index 2dbec8b..6cdbd25 100644
--- a/icd/intel/compiler/shader/glsl_parser_extras.cpp
+++ b/icd/intel/compiler/shader/glsl_parser_extras.cpp
@@ -35,7 +35,7 @@
#endif // USE_LUNARGLASS
extern "C" {
-#include "main/core.h" /* for struct gl_context */
+#include "libfns.h" // LunarG ADD:
#include "main/context.h"
#include "main/shaderobj.h"
#include "program/prog_diskcache.h"
@@ -44,7 +44,7 @@
#include "ralloc.h"
#include "ast.h"
#include "glsl_parser_extras.h"
-#include "glsl_parser.h"
+//#include "glsl_parser.h"
#include "ir_optimization.h"
#include "loop_analysis.h"
#include "threadpool.h"
@@ -1738,8 +1738,8 @@
bool dump_ast, bool dump_hir)
{
/* Search program disk cache if active. */
- if (ctx->BinaryShaderCacheActive && mesa_shader_diskcache_find(ctx, shader) == 0)
- return;
+// if (ctx->BinaryShaderCacheActive && mesa_shader_diskcache_find(ctx, shader) == 0)
+// return;
struct _mesa_glsl_parse_state *state =
new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
@@ -1807,8 +1807,8 @@
/* Retain any live IR, but trash the rest. */
reparent_ir(shader->ir, shader->ir);
- if (ctx->BinaryShaderCacheActive && shader->CompileStatus)
- mesa_shader_diskcache_cache(ctx, shader);
+// if (ctx->BinaryShaderCacheActive && shader->CompileStatus)
+// mesa_shader_diskcache_cache(ctx, shader);
ralloc_free(state);
}
@@ -1818,8 +1818,8 @@
bool dump_ast, bool dump_hir)
{
/* Search program disk cache if active. */
- if (ctx->BinaryShaderCacheActive && mesa_shader_diskcache_find(ctx, shader) == 0)
- return;
+// if (ctx->BinaryShaderCacheActive && mesa_shader_diskcache_find(ctx, shader) == 0)
+// return;
#ifdef USE_LUNARGLASS
// Temporary shader source blacklist, until a source of falling back into SIMD8 can be fixed.
@@ -1837,8 +1837,8 @@
}
#endif // USE_LUNARGLASS
- if (ctx->BinaryShaderCacheActive && shader->CompileStatus)
- mesa_shader_diskcache_cache(ctx, shader);
+// if (ctx->BinaryShaderCacheActive && shader->CompileStatus)
+// mesa_shader_diskcache_cache(ctx, shader);
}
} /* extern "C" */
diff --git a/icd/intel/compiler/shader/glsl_types.cpp b/icd/intel/compiler/shader/glsl_types.cpp
index cc14177..ca96940 100644
--- a/icd/intel/compiler/shader/glsl_types.cpp
+++ b/icd/intel/compiler/shader/glsl_types.cpp
@@ -23,7 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "main/core.h" /* for Elements */
+#include "libfns.h" // LunarG ADD:
#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "glsl_types.h"
diff --git a/icd/intel/compiler/shader/ir.cpp b/icd/intel/compiler/shader/ir.cpp
index ba8a839..2a3a5c6 100644
--- a/icd/intel/compiler/shader/ir.cpp
+++ b/icd/intel/compiler/shader/ir.cpp
@@ -21,10 +21,10 @@
* DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
-#include "main/core.h" /* for MAX2 */
#include "ir.h"
#include "ir_visitor.h"
#include "glsl_types.h"
+#include "libfns.h"
ir_rvalue::ir_rvalue()
{
diff --git a/icd/intel/compiler/shader/ir_constant_expression.cpp b/icd/intel/compiler/shader/ir_constant_expression.cpp
index 8afe8f7..4df343f 100644
--- a/icd/intel/compiler/shader/ir_constant_expression.cpp
+++ b/icd/intel/compiler/shader/ir_constant_expression.cpp
@@ -34,7 +34,7 @@
*/
#include <math.h>
-#include "main/core.h" /* for MAX2, MIN2, CLAMP */
+#include "libfns.h"
#include "ir.h"
#include "ir_visitor.h"
#include "glsl_types.h"
diff --git a/icd/intel/compiler/shader/ir_function_detect_recursion.cpp b/icd/intel/compiler/shader/ir_function_detect_recursion.cpp
index 5813315..af985cd 100644
--- a/icd/intel/compiler/shader/ir_function_detect_recursion.cpp
+++ b/icd/intel/compiler/shader/ir_function_detect_recursion.cpp
@@ -120,7 +120,7 @@
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
-#include "main/core.h"
+#include "libfns.h" // LunarG ADD:
#include "ir.h"
#include "glsl_parser_extras.h"
#include "linker.h"
diff --git a/icd/intel/compiler/shader/ir_set_program_inouts.cpp b/icd/intel/compiler/shader/ir_set_program_inouts.cpp
index 5163eb2..e2ec9b6 100644
--- a/icd/intel/compiler/shader/ir_set_program_inouts.cpp
+++ b/icd/intel/compiler/shader/ir_set_program_inouts.cpp
@@ -37,7 +37,7 @@
* from the GLSL IR.
*/
-#include "main/core.h" /* for struct gl_program */
+#include "libfns.h" // LunarG ADD:
#include "ir.h"
#include "ir_visitor.h"
#include "glsl_types.h"
diff --git a/icd/intel/compiler/shader/libfns.h b/icd/intel/compiler/shader/libfns.h
new file mode 100644
index 0000000..d2760db
--- /dev/null
+++ b/icd/intel/compiler/shader/libfns.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2010 LunarG Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+// LunarG ADD:
+
+#ifndef LIBFNS_H
+#define LIBFNS_H
+
+#include "main/macros.h"
+
+#endif // LIBFNS_H
diff --git a/icd/intel/compiler/shader/libfns.h~ b/icd/intel/compiler/shader/libfns.h~
new file mode 100644
index 0000000..f42c3cb
--- /dev/null
+++ b/icd/intel/compiler/shader/libfns.h~
@@ -0,0 +1,6 @@
+// LunarG ADD:
+template<typename T>
+T MAX2(const T& a, const T& b) { return a > b ? a : b; }
+template<typename T>
+T MIN2(const T& a, const T& b) { return a < b ? a : b; }
+
diff --git a/icd/intel/compiler/shader/link_functions.cpp b/icd/intel/compiler/shader/link_functions.cpp
index 56f3f20..e16567e 100644
--- a/icd/intel/compiler/shader/link_functions.cpp
+++ b/icd/intel/compiler/shader/link_functions.cpp
@@ -21,7 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "main/core.h"
+#include "libfns.h" // LunarG ADD:
#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "ir.h"
diff --git a/icd/intel/compiler/shader/link_uniform_blocks.cpp b/icd/intel/compiler/shader/link_uniform_blocks.cpp
index 1a0e643..6430c34 100644
--- a/icd/intel/compiler/shader/link_uniform_blocks.cpp
+++ b/icd/intel/compiler/shader/link_uniform_blocks.cpp
@@ -21,7 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "main/core.h"
+#include "libfns.h" // LunarG ADD:
#include "ir.h"
#include "linker.h"
#include "ir_uniform.h"
diff --git a/icd/intel/compiler/shader/link_uniform_initializers.cpp b/icd/intel/compiler/shader/link_uniform_initializers.cpp
index 2100e05..ae4cd71 100644
--- a/icd/intel/compiler/shader/link_uniform_initializers.cpp
+++ b/icd/intel/compiler/shader/link_uniform_initializers.cpp
@@ -21,7 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "main/core.h"
+#include "libfns.h" // LunarG ADD:
#include "ir.h"
#include "linker.h"
#include "ir_uniform.h"
diff --git a/icd/intel/compiler/shader/link_uniforms.cpp b/icd/intel/compiler/shader/link_uniforms.cpp
index 29dc0b1..3d98f75 100644
--- a/icd/intel/compiler/shader/link_uniforms.cpp
+++ b/icd/intel/compiler/shader/link_uniforms.cpp
@@ -21,7 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "main/core.h"
+#include "libfns.h" // LunarG ADD:
#include "ir.h"
#include "linker.h"
#include "ir_uniform.h"
diff --git a/icd/intel/compiler/shader/linker.cpp b/icd/intel/compiler/shader/linker.cpp
index c448847..6f3b876 100644
--- a/icd/intel/compiler/shader/linker.cpp
+++ b/icd/intel/compiler/shader/linker.cpp
@@ -64,7 +64,7 @@
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
-#include "main/core.h"
+#include "libfns.h" // LunarG ADD:
#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "ir.h"
diff --git a/icd/intel/compiler/shader/lower_instructions.cpp b/icd/intel/compiler/shader/lower_instructions.cpp
index 176070c..8d6d630 100644
--- a/icd/intel/compiler/shader/lower_instructions.cpp
+++ b/icd/intel/compiler/shader/lower_instructions.cpp
@@ -106,7 +106,7 @@
*
*/
-#include "main/core.h" /* for M_LOG2E */
+#include "libfns.h" // LunarG ADD:
#include "glsl_types.h"
#include "ir.h"
#include "ir_builder.h"
diff --git a/icd/intel/compiler/shader/main.cpp b/icd/intel/compiler/shader/main.cpp
index a9faad6..58f1140 100644
--- a/icd/intel/compiler/shader/main.cpp
+++ b/icd/intel/compiler/shader/main.cpp
@@ -40,11 +40,11 @@
static int glsl_version = 330;
-extern "C" void
-_mesa_error_no_memory(const char *caller)
-{
- fprintf(stderr, "Mesa error: out of memory in %s", caller);
-}
+//extern "C" void
+//_mesa_error_no_memory(const char *caller)
+//{
+// fprintf(stderr, "Mesa error: out of memory in %s", caller);
+//}
static void
initialize_context(struct gl_context *ctx, gl_api api)
diff --git a/icd/intel/compiler/shader/opt_dead_builtin_varyings.cpp b/icd/intel/compiler/shader/opt_dead_builtin_varyings.cpp
index 6612592..7e29b9b 100644
--- a/icd/intel/compiler/shader/opt_dead_builtin_varyings.cpp
+++ b/icd/intel/compiler/shader/opt_dead_builtin_varyings.cpp
@@ -46,7 +46,7 @@
* The same is done for the gl_FragData fragment shader output.
*/
-#include "main/core.h" /* for snprintf and ARRAY_SIZE */
+#include "libfns.h" // LunarG ADD:
#include "ir.h"
#include "ir_rvalue_visitor.h"
#include "ir_optimization.h"
diff --git a/icd/intel/compiler/shader/program.h b/icd/intel/compiler/shader/program.h
index f15113a..d44294d 100644
--- a/icd/intel/compiler/shader/program.h
+++ b/icd/intel/compiler/shader/program.h
@@ -22,7 +22,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "main/core.h"
+#include "libfns.h" // LunarG ADD:
#ifdef __cplusplus
extern "C" {
diff --git a/icd/intel/compiler/shader/s_expression.h b/icd/intel/compiler/shader/s_expression.h
index 642af19..b3751e4 100644
--- a/icd/intel/compiler/shader/s_expression.h
+++ b/icd/intel/compiler/shader/s_expression.h
@@ -26,7 +26,7 @@
#ifndef S_EXPRESSION_H
#define S_EXPRESSION_H
-#include "main/core.h" /* for Elements */
+#include "libfns.h" // LunarG ADD:
#include "strtod.h"
#include "list.h"
diff --git a/icd/intel/compiler/shader/standalone_scaffolding.cpp b/icd/intel/compiler/shader/standalone_scaffolding.cpp
index 6c25010..7d34e90 100644
--- a/icd/intel/compiler/shader/standalone_scaffolding.cpp
+++ b/icd/intel/compiler/shader/standalone_scaffolding.cpp
@@ -33,23 +33,23 @@
#include <string.h>
#include "ralloc.h"
-void
-_mesa_warning(struct gl_context *ctx, const char *fmt, ...)
-{
- va_list vargs;
- (void) ctx;
+//void
+//_mesa_warning(struct gl_context *ctx, const char *fmt, ...)
+//{
+// va_list vargs;
+// (void) ctx;
- va_start(vargs, fmt);
+// va_start(vargs, fmt);
- /* This output is not thread-safe, but that's good enough for the
- * standalone compiler.
- */
- fprintf(stderr, "Mesa warning: ");
- vfprintf(stderr, fmt, vargs);
- fprintf(stderr, "\n");
+// /* This output is not thread-safe, but that's good enough for the
+// * standalone compiler.
+// */
+// fprintf(stderr, "Mesa warning: ");
+// vfprintf(stderr, fmt, vargs);
+// fprintf(stderr, "\n");
- va_end(vargs);
-}
+// va_end(vargs);
+//}
void
_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
@@ -59,11 +59,11 @@
*ptr = sh;
}
-void
-_mesa_shader_debug(struct gl_context *, GLenum, GLuint *id,
- const char *, int)
-{
-}
+//void
+//_mesa_shader_debug(struct gl_context *, GLenum, GLuint *id,
+// const char *, int)
+//{
+//}
struct gl_shader *
_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)