1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci/** 26bf215546Sopenharmony_ci * \file prog_statevars.c 27bf215546Sopenharmony_ci * Program state variable management. 28bf215546Sopenharmony_ci * \author Brian Paul 29bf215546Sopenharmony_ci */ 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include <stdio.h> 33bf215546Sopenharmony_ci#include <stddef.h> 34bf215546Sopenharmony_ci#include "main/glheader.h" 35bf215546Sopenharmony_ci#include "main/context.h" 36bf215546Sopenharmony_ci#include "main/blend.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include "main/macros.h" 39bf215546Sopenharmony_ci#include "main/fbobject.h" 40bf215546Sopenharmony_ci#include "prog_statevars.h" 41bf215546Sopenharmony_ci#include "prog_parameter.h" 42bf215546Sopenharmony_ci#include "main/samplerobj.h" 43bf215546Sopenharmony_ci#include "main/framebuffer.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#define ONE_DIV_SQRT_LN2 (1.201122408786449815) 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_cistatic ALWAYS_INLINE void 49bf215546Sopenharmony_cicopy_matrix(float *value, const float *m, unsigned firstRow, unsigned lastRow) 50bf215546Sopenharmony_ci{ 51bf215546Sopenharmony_ci unsigned i, row; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci assert(firstRow < 4); 54bf215546Sopenharmony_ci assert(lastRow < 4); 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci for (i = 0, row = firstRow; row <= lastRow; row++) { 57bf215546Sopenharmony_ci value[i++] = m[row + 0]; 58bf215546Sopenharmony_ci value[i++] = m[row + 4]; 59bf215546Sopenharmony_ci value[i++] = m[row + 8]; 60bf215546Sopenharmony_ci value[i++] = m[row + 12]; 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci} 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_cistatic ALWAYS_INLINE void 65bf215546Sopenharmony_cicopy_matrix_transposed(float *value, const float *m, unsigned firstRow, unsigned lastRow) 66bf215546Sopenharmony_ci{ 67bf215546Sopenharmony_ci assert(firstRow < 4); 68bf215546Sopenharmony_ci assert(lastRow < 4); 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci memcpy(value, &m[firstRow * 4], 71bf215546Sopenharmony_ci (lastRow - firstRow + 1) * 4 * sizeof(GLfloat)); 72bf215546Sopenharmony_ci} 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci/** 75bf215546Sopenharmony_ci * Use the list of tokens in the state[] array to find global GL state 76bf215546Sopenharmony_ci * and return it in <value>. Usually, four values are returned in <value> 77bf215546Sopenharmony_ci * but matrix queries may return as many as 16 values. 78bf215546Sopenharmony_ci * This function is used for ARB vertex/fragment programs. 79bf215546Sopenharmony_ci * The program parser will produce the state[] values. 80bf215546Sopenharmony_ci */ 81bf215546Sopenharmony_cistatic void 82bf215546Sopenharmony_cifetch_state(struct gl_context *ctx, const gl_state_index16 state[], 83bf215546Sopenharmony_ci gl_constant_value *val) 84bf215546Sopenharmony_ci{ 85bf215546Sopenharmony_ci GLfloat *value = &val->f; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci switch (state[0]) { 88bf215546Sopenharmony_ci case STATE_MATERIAL: 89bf215546Sopenharmony_ci { 90bf215546Sopenharmony_ci /* state[1] is MAT_ATTRIB_FRONT_* */ 91bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 92bf215546Sopenharmony_ci const struct gl_material *mat = &ctx->Light.Material; 93bf215546Sopenharmony_ci assert(index >= MAT_ATTRIB_FRONT_AMBIENT && 94bf215546Sopenharmony_ci index <= MAT_ATTRIB_BACK_SHININESS); 95bf215546Sopenharmony_ci if (index >= MAT_ATTRIB_FRONT_SHININESS) { 96bf215546Sopenharmony_ci value[0] = mat->Attrib[index][0]; 97bf215546Sopenharmony_ci value[1] = 0.0F; 98bf215546Sopenharmony_ci value[2] = 0.0F; 99bf215546Sopenharmony_ci value[3] = 1.0F; 100bf215546Sopenharmony_ci } else { 101bf215546Sopenharmony_ci COPY_4V(value, mat->Attrib[index]); 102bf215546Sopenharmony_ci } 103bf215546Sopenharmony_ci return; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci case STATE_LIGHT: 106bf215546Sopenharmony_ci { 107bf215546Sopenharmony_ci /* state[1] is the light number */ 108bf215546Sopenharmony_ci const GLuint ln = (GLuint) state[1]; 109bf215546Sopenharmony_ci /* state[2] is the light attribute */ 110bf215546Sopenharmony_ci const unsigned index = state[2] - STATE_AMBIENT; 111bf215546Sopenharmony_ci assert(index < 8); 112bf215546Sopenharmony_ci if (index != STATE_SPOT_CUTOFF) 113bf215546Sopenharmony_ci COPY_4V(value, (float*)&ctx->Light.LightSource[ln] + index * 4); 114bf215546Sopenharmony_ci else 115bf215546Sopenharmony_ci value[0] = ctx->Light.LightSource[ln].SpotCutoff; 116bf215546Sopenharmony_ci return; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci case STATE_LIGHT_ARRAY: { 119bf215546Sopenharmony_ci /* This must be exact because it must match the gl_LightSource layout 120bf215546Sopenharmony_ci * in GLSL. 121bf215546Sopenharmony_ci */ 122bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(struct gl_light_uniforms) == 29 * 4); 123bf215546Sopenharmony_ci STATIC_ASSERT(ARRAY_SIZE(ctx->Light.LightSourceData) == 29 * MAX_LIGHTS); 124bf215546Sopenharmony_ci /* state[1] is the index of the first value */ 125bf215546Sopenharmony_ci /* state[2] is the number of values */ 126bf215546Sopenharmony_ci assert(state[1] + state[2] <= ARRAY_SIZE(ctx->Light.LightSourceData)); 127bf215546Sopenharmony_ci memcpy(value, &ctx->Light.LightSourceData[state[1]], 128bf215546Sopenharmony_ci state[2] * sizeof(float)); 129bf215546Sopenharmony_ci return; 130bf215546Sopenharmony_ci } 131bf215546Sopenharmony_ci case STATE_LIGHT_ATTENUATION_ARRAY: { 132bf215546Sopenharmony_ci const unsigned first = state[1]; 133bf215546Sopenharmony_ci const unsigned num_lights = state[2]; 134bf215546Sopenharmony_ci for (unsigned i = 0; i < num_lights; i++) { 135bf215546Sopenharmony_ci COPY_4V(value, 136bf215546Sopenharmony_ci &ctx->Light.LightSource[first + i].ConstantAttenuation); 137bf215546Sopenharmony_ci value += 4; 138bf215546Sopenharmony_ci } 139bf215546Sopenharmony_ci return; 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci case STATE_LIGHTMODEL_AMBIENT: 142bf215546Sopenharmony_ci COPY_4V(value, ctx->Light.Model.Ambient); 143bf215546Sopenharmony_ci return; 144bf215546Sopenharmony_ci case STATE_LIGHTMODEL_SCENECOLOR: 145bf215546Sopenharmony_ci if (state[1] == 0) { 146bf215546Sopenharmony_ci /* front */ 147bf215546Sopenharmony_ci GLint i; 148bf215546Sopenharmony_ci for (i = 0; i < 3; i++) { 149bf215546Sopenharmony_ci value[i] = ctx->Light.Model.Ambient[i] 150bf215546Sopenharmony_ci * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] 151bf215546Sopenharmony_ci + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci else { 156bf215546Sopenharmony_ci /* back */ 157bf215546Sopenharmony_ci GLint i; 158bf215546Sopenharmony_ci for (i = 0; i < 3; i++) { 159bf215546Sopenharmony_ci value[i] = ctx->Light.Model.Ambient[i] 160bf215546Sopenharmony_ci * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] 161bf215546Sopenharmony_ci + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; 162bf215546Sopenharmony_ci } 163bf215546Sopenharmony_ci value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 164bf215546Sopenharmony_ci } 165bf215546Sopenharmony_ci return; 166bf215546Sopenharmony_ci case STATE_LIGHTPROD: 167bf215546Sopenharmony_ci { 168bf215546Sopenharmony_ci const GLuint ln = (GLuint) state[1]; 169bf215546Sopenharmony_ci const GLuint index = (GLuint) state[2]; 170bf215546Sopenharmony_ci const GLuint attr = (index / 2) * 4; 171bf215546Sopenharmony_ci assert(index >= MAT_ATTRIB_FRONT_AMBIENT && 172bf215546Sopenharmony_ci index <= MAT_ATTRIB_BACK_SPECULAR); 173bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 174bf215546Sopenharmony_ci /* We want attr to access out of bounds into the following Diffuse 175bf215546Sopenharmony_ci * and Specular fields. This is guaranteed to work because 176bf215546Sopenharmony_ci * STATE_LIGHT and STATE_LIGHT_ARRAY also rely on this memory 177bf215546Sopenharmony_ci * layout. 178bf215546Sopenharmony_ci */ 179bf215546Sopenharmony_ci STATIC_ASSERT(offsetof(struct gl_light_uniforms, Ambient) + 16 == 180bf215546Sopenharmony_ci offsetof(struct gl_light_uniforms, Diffuse)); 181bf215546Sopenharmony_ci STATIC_ASSERT(offsetof(struct gl_light_uniforms, Diffuse) + 16 == 182bf215546Sopenharmony_ci offsetof(struct gl_light_uniforms, Specular)); 183bf215546Sopenharmony_ci value[i] = ctx->Light.LightSource[ln].Ambient[attr + i] * 184bf215546Sopenharmony_ci ctx->Light.Material.Attrib[index][i]; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci /* [3] = material alpha */ 187bf215546Sopenharmony_ci value[3] = ctx->Light.Material.Attrib[index][3]; 188bf215546Sopenharmony_ci return; 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_FRONT: { 191bf215546Sopenharmony_ci const unsigned first_light = state[1]; 192bf215546Sopenharmony_ci const unsigned num_lights = state[2]; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci for (unsigned i = 0; i < num_lights; i++) { 195bf215546Sopenharmony_ci unsigned light = first_light + i; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci for (unsigned attrib = MAT_ATTRIB_FRONT_AMBIENT; 198bf215546Sopenharmony_ci attrib <= MAT_ATTRIB_FRONT_SPECULAR; attrib += 2) { 199bf215546Sopenharmony_ci for (int chan = 0; chan < 3; chan++) { 200bf215546Sopenharmony_ci /* We want offset to access out of bounds into the following 201bf215546Sopenharmony_ci * Diffuse and Specular fields. This is guaranteed to work 202bf215546Sopenharmony_ci * because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely 203bf215546Sopenharmony_ci * on this memory layout. 204bf215546Sopenharmony_ci */ 205bf215546Sopenharmony_ci unsigned offset = (attrib / 2) * 4 + chan; 206bf215546Sopenharmony_ci *value++ = 207bf215546Sopenharmony_ci (&ctx->Light.LightSource[light].Ambient[0])[offset] * 208bf215546Sopenharmony_ci ctx->Light.Material.Attrib[attrib][chan]; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci /* [3] = material alpha */ 211bf215546Sopenharmony_ci *value++ = ctx->Light.Material.Attrib[attrib][3]; 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci } 214bf215546Sopenharmony_ci return; 215bf215546Sopenharmony_ci } 216bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_BACK: { 217bf215546Sopenharmony_ci const unsigned first_light = state[1]; 218bf215546Sopenharmony_ci const unsigned num_lights = state[2]; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci for (unsigned i = 0; i < num_lights; i++) { 221bf215546Sopenharmony_ci unsigned light = first_light + i; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci for (unsigned attrib = MAT_ATTRIB_BACK_AMBIENT; 224bf215546Sopenharmony_ci attrib <= MAT_ATTRIB_BACK_SPECULAR; attrib += 2) { 225bf215546Sopenharmony_ci for (int chan = 0; chan < 3; chan++) { 226bf215546Sopenharmony_ci /* We want offset to access out of bounds into the following 227bf215546Sopenharmony_ci * Diffuse and Specular fields. This is guaranteed to work 228bf215546Sopenharmony_ci * because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely 229bf215546Sopenharmony_ci * on this memory layout. 230bf215546Sopenharmony_ci */ 231bf215546Sopenharmony_ci unsigned offset = (attrib / 2) * 4 + chan; 232bf215546Sopenharmony_ci *value++ = 233bf215546Sopenharmony_ci (&ctx->Light.LightSource[light].Ambient[0])[offset] * 234bf215546Sopenharmony_ci ctx->Light.Material.Attrib[attrib][chan]; 235bf215546Sopenharmony_ci } 236bf215546Sopenharmony_ci /* [3] = material alpha */ 237bf215546Sopenharmony_ci *value++ = ctx->Light.Material.Attrib[attrib][3]; 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci } 240bf215546Sopenharmony_ci return; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_TWOSIDE: { 243bf215546Sopenharmony_ci const unsigned first_light = state[1]; 244bf215546Sopenharmony_ci const unsigned num_lights = state[2]; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci for (unsigned i = 0; i < num_lights; i++) { 247bf215546Sopenharmony_ci unsigned light = first_light + i; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci for (unsigned attrib = MAT_ATTRIB_FRONT_AMBIENT; 250bf215546Sopenharmony_ci attrib <= MAT_ATTRIB_BACK_SPECULAR; attrib++) { 251bf215546Sopenharmony_ci for (int chan = 0; chan < 3; chan++) { 252bf215546Sopenharmony_ci /* We want offset to access out of bounds into the following 253bf215546Sopenharmony_ci * Diffuse and Specular fields. This is guaranteed to work 254bf215546Sopenharmony_ci * because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely 255bf215546Sopenharmony_ci * on this memory layout. 256bf215546Sopenharmony_ci */ 257bf215546Sopenharmony_ci unsigned offset = (attrib / 2) * 4 + chan; 258bf215546Sopenharmony_ci *value++ = 259bf215546Sopenharmony_ci (&ctx->Light.LightSource[light].Ambient[0])[offset] * 260bf215546Sopenharmony_ci ctx->Light.Material.Attrib[attrib][chan]; 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci /* [3] = material alpha */ 263bf215546Sopenharmony_ci *value++ = ctx->Light.Material.Attrib[attrib][3]; 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci } 266bf215546Sopenharmony_ci return; 267bf215546Sopenharmony_ci } 268bf215546Sopenharmony_ci case STATE_TEXGEN: 269bf215546Sopenharmony_ci { 270bf215546Sopenharmony_ci /* state[1] is the texture unit */ 271bf215546Sopenharmony_ci const GLuint unit = (GLuint) state[1]; 272bf215546Sopenharmony_ci /* state[2] is the texgen attribute */ 273bf215546Sopenharmony_ci /* Assertions for the expected memory layout. */ 274bf215546Sopenharmony_ci#define MEMBER_SIZEOF(type, member) sizeof(((type *)0)->member) 275bf215546Sopenharmony_ci STATIC_ASSERT(MEMBER_SIZEOF(struct gl_fixedfunc_texture_unit, 276bf215546Sopenharmony_ci EyePlane[0]) == 4 * sizeof(float)); 277bf215546Sopenharmony_ci STATIC_ASSERT(MEMBER_SIZEOF(struct gl_fixedfunc_texture_unit, 278bf215546Sopenharmony_ci ObjectPlane[0]) == 4 * sizeof(float)); 279bf215546Sopenharmony_ci#undef MEMBER_SIZEOF 280bf215546Sopenharmony_ci STATIC_ASSERT(STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S == GEN_T - GEN_S); 281bf215546Sopenharmony_ci STATIC_ASSERT(STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S == GEN_R - GEN_S); 282bf215546Sopenharmony_ci STATIC_ASSERT(STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S == GEN_Q - GEN_S); 283bf215546Sopenharmony_ci STATIC_ASSERT(offsetof(struct gl_fixedfunc_texture_unit, ObjectPlane) - 284bf215546Sopenharmony_ci offsetof(struct gl_fixedfunc_texture_unit, EyePlane) == 285bf215546Sopenharmony_ci (STATE_TEXGEN_OBJECT_S - STATE_TEXGEN_EYE_S) * 4 * sizeof(float)); 286bf215546Sopenharmony_ci STATIC_ASSERT(STATE_TEXGEN_OBJECT_T - STATE_TEXGEN_OBJECT_S == GEN_T - GEN_S); 287bf215546Sopenharmony_ci STATIC_ASSERT(STATE_TEXGEN_OBJECT_R - STATE_TEXGEN_OBJECT_S == GEN_R - GEN_S); 288bf215546Sopenharmony_ci STATIC_ASSERT(STATE_TEXGEN_OBJECT_Q - STATE_TEXGEN_OBJECT_S == GEN_Q - GEN_S); 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci const float *attr = (float*)ctx->Texture.FixedFuncUnit[unit].EyePlane + 291bf215546Sopenharmony_ci (state[2] - STATE_TEXGEN_EYE_S) * 4; 292bf215546Sopenharmony_ci COPY_4V(value, attr); 293bf215546Sopenharmony_ci return; 294bf215546Sopenharmony_ci } 295bf215546Sopenharmony_ci case STATE_TEXENV_COLOR: 296bf215546Sopenharmony_ci { 297bf215546Sopenharmony_ci /* state[1] is the texture unit */ 298bf215546Sopenharmony_ci const GLuint unit = (GLuint) state[1]; 299bf215546Sopenharmony_ci if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) 300bf215546Sopenharmony_ci COPY_4V(value, ctx->Texture.FixedFuncUnit[unit].EnvColor); 301bf215546Sopenharmony_ci else 302bf215546Sopenharmony_ci COPY_4V(value, ctx->Texture.FixedFuncUnit[unit].EnvColorUnclamped); 303bf215546Sopenharmony_ci } 304bf215546Sopenharmony_ci return; 305bf215546Sopenharmony_ci case STATE_FOG_COLOR: 306bf215546Sopenharmony_ci if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) 307bf215546Sopenharmony_ci COPY_4V(value, ctx->Fog.Color); 308bf215546Sopenharmony_ci else 309bf215546Sopenharmony_ci COPY_4V(value, ctx->Fog.ColorUnclamped); 310bf215546Sopenharmony_ci return; 311bf215546Sopenharmony_ci case STATE_FOG_PARAMS: 312bf215546Sopenharmony_ci value[0] = ctx->Fog.Density; 313bf215546Sopenharmony_ci value[1] = ctx->Fog.Start; 314bf215546Sopenharmony_ci value[2] = ctx->Fog.End; 315bf215546Sopenharmony_ci value[3] = 1.0f / (ctx->Fog.End - ctx->Fog.Start); 316bf215546Sopenharmony_ci return; 317bf215546Sopenharmony_ci case STATE_CLIPPLANE: 318bf215546Sopenharmony_ci { 319bf215546Sopenharmony_ci const GLuint plane = (GLuint) state[1]; 320bf215546Sopenharmony_ci COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); 321bf215546Sopenharmony_ci } 322bf215546Sopenharmony_ci return; 323bf215546Sopenharmony_ci case STATE_POINT_SIZE: 324bf215546Sopenharmony_ci value[0] = ctx->Point.Size; 325bf215546Sopenharmony_ci value[1] = ctx->Point.MinSize; 326bf215546Sopenharmony_ci value[2] = ctx->Point.MaxSize; 327bf215546Sopenharmony_ci value[3] = ctx->Point.Threshold; 328bf215546Sopenharmony_ci return; 329bf215546Sopenharmony_ci case STATE_POINT_ATTENUATION: 330bf215546Sopenharmony_ci value[0] = ctx->Point.Params[0]; 331bf215546Sopenharmony_ci value[1] = ctx->Point.Params[1]; 332bf215546Sopenharmony_ci value[2] = ctx->Point.Params[2]; 333bf215546Sopenharmony_ci value[3] = 1.0F; 334bf215546Sopenharmony_ci return; 335bf215546Sopenharmony_ci /* state[0] = modelview, projection, texture, etc. */ 336bf215546Sopenharmony_ci /* state[1] = which texture matrix or program matrix */ 337bf215546Sopenharmony_ci /* state[2] = first row to fetch */ 338bf215546Sopenharmony_ci /* state[3] = last row to fetch */ 339bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX: { 340bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top; 341bf215546Sopenharmony_ci copy_matrix(value, matrix->m, state[2], state[3]); 342bf215546Sopenharmony_ci return; 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVERSE: { 345bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top; 346bf215546Sopenharmony_ci copy_matrix(value, matrix->inv, state[2], state[3]); 347bf215546Sopenharmony_ci return; 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_TRANSPOSE: { 350bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top; 351bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->m, state[2], state[3]); 352bf215546Sopenharmony_ci return; 353bf215546Sopenharmony_ci } 354bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVTRANS: { 355bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top; 356bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->inv, state[2], state[3]); 357bf215546Sopenharmony_ci return; 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX: { 360bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ProjectionMatrixStack.Top; 361bf215546Sopenharmony_ci copy_matrix(value, matrix->m, state[2], state[3]); 362bf215546Sopenharmony_ci return; 363bf215546Sopenharmony_ci } 364bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVERSE: { 365bf215546Sopenharmony_ci GLmatrix *matrix = ctx->ProjectionMatrixStack.Top; 366bf215546Sopenharmony_ci _math_matrix_analyse(matrix); /* make sure the inverse is up to date */ 367bf215546Sopenharmony_ci copy_matrix(value, matrix->inv, state[2], state[3]); 368bf215546Sopenharmony_ci return; 369bf215546Sopenharmony_ci } 370bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_TRANSPOSE: { 371bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ProjectionMatrixStack.Top; 372bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->m, state[2], state[3]); 373bf215546Sopenharmony_ci return; 374bf215546Sopenharmony_ci } 375bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVTRANS: { 376bf215546Sopenharmony_ci GLmatrix *matrix = ctx->ProjectionMatrixStack.Top; 377bf215546Sopenharmony_ci _math_matrix_analyse(matrix); /* make sure the inverse is up to date */ 378bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->inv, state[2], state[3]); 379bf215546Sopenharmony_ci return; 380bf215546Sopenharmony_ci } 381bf215546Sopenharmony_ci case STATE_MVP_MATRIX: { 382bf215546Sopenharmony_ci const GLmatrix *matrix = &ctx->_ModelProjectMatrix; 383bf215546Sopenharmony_ci copy_matrix(value, matrix->m, state[2], state[3]); 384bf215546Sopenharmony_ci return; 385bf215546Sopenharmony_ci } 386bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVERSE: { 387bf215546Sopenharmony_ci GLmatrix *matrix = &ctx->_ModelProjectMatrix; 388bf215546Sopenharmony_ci _math_matrix_analyse(matrix); /* make sure the inverse is up to date */ 389bf215546Sopenharmony_ci copy_matrix(value, matrix->inv, state[2], state[3]); 390bf215546Sopenharmony_ci return; 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci case STATE_MVP_MATRIX_TRANSPOSE: { 393bf215546Sopenharmony_ci const GLmatrix *matrix = &ctx->_ModelProjectMatrix; 394bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->m, state[2], state[3]); 395bf215546Sopenharmony_ci return; 396bf215546Sopenharmony_ci } 397bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVTRANS: { 398bf215546Sopenharmony_ci GLmatrix *matrix = &ctx->_ModelProjectMatrix; 399bf215546Sopenharmony_ci _math_matrix_analyse(matrix); /* make sure the inverse is up to date */ 400bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->inv, state[2], state[3]); 401bf215546Sopenharmony_ci return; 402bf215546Sopenharmony_ci } 403bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX: { 404bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 405bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->TextureMatrixStack)); 406bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top; 407bf215546Sopenharmony_ci copy_matrix(value, matrix->m, state[2], state[3]); 408bf215546Sopenharmony_ci return; 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVERSE: { 411bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 412bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->TextureMatrixStack)); 413bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top; 414bf215546Sopenharmony_ci copy_matrix(value, matrix->inv, state[2], state[3]); 415bf215546Sopenharmony_ci return; 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_TRANSPOSE: { 418bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 419bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->TextureMatrixStack)); 420bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top; 421bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->m, state[2], state[3]); 422bf215546Sopenharmony_ci return; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVTRANS: { 425bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 426bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->TextureMatrixStack)); 427bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top; 428bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->inv, state[2], state[3]); 429bf215546Sopenharmony_ci return; 430bf215546Sopenharmony_ci } 431bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX: { 432bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 433bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack)); 434bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top; 435bf215546Sopenharmony_ci copy_matrix(value, matrix->m, state[2], state[3]); 436bf215546Sopenharmony_ci return; 437bf215546Sopenharmony_ci } 438bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVERSE: { 439bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 440bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack)); 441bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top; 442bf215546Sopenharmony_ci _math_matrix_analyse((GLmatrix*)matrix); /* Be sure inverse is up to date: */ 443bf215546Sopenharmony_ci copy_matrix(value, matrix->inv, state[2], state[3]); 444bf215546Sopenharmony_ci return; 445bf215546Sopenharmony_ci } 446bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_TRANSPOSE: { 447bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 448bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack)); 449bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top; 450bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->m, state[2], state[3]); 451bf215546Sopenharmony_ci return; 452bf215546Sopenharmony_ci } 453bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVTRANS: { 454bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 455bf215546Sopenharmony_ci assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack)); 456bf215546Sopenharmony_ci const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top; 457bf215546Sopenharmony_ci _math_matrix_analyse((GLmatrix*)matrix); /* Be sure inverse is up to date: */ 458bf215546Sopenharmony_ci copy_matrix_transposed(value, matrix->inv, state[2], state[3]); 459bf215546Sopenharmony_ci return; 460bf215546Sopenharmony_ci } 461bf215546Sopenharmony_ci case STATE_NUM_SAMPLES: 462bf215546Sopenharmony_ci val[0].i = MAX2(1, _mesa_geometric_samples(ctx->DrawBuffer)); 463bf215546Sopenharmony_ci return; 464bf215546Sopenharmony_ci case STATE_DEPTH_RANGE: 465bf215546Sopenharmony_ci value[0] = ctx->ViewportArray[0].Near; /* near */ 466bf215546Sopenharmony_ci value[1] = ctx->ViewportArray[0].Far; /* far */ 467bf215546Sopenharmony_ci value[2] = ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near; /* far - near */ 468bf215546Sopenharmony_ci value[3] = 1.0; 469bf215546Sopenharmony_ci return; 470bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV: { 471bf215546Sopenharmony_ci const int idx = (int) state[1]; 472bf215546Sopenharmony_ci COPY_4V(value, ctx->FragmentProgram.Parameters[idx]); 473bf215546Sopenharmony_ci return; 474bf215546Sopenharmony_ci } 475bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV_ARRAY: { 476bf215546Sopenharmony_ci const unsigned idx = state[1]; 477bf215546Sopenharmony_ci const unsigned bytes = state[2] * 16; 478bf215546Sopenharmony_ci memcpy(value, ctx->FragmentProgram.Parameters[idx], bytes); 479bf215546Sopenharmony_ci return; 480bf215546Sopenharmony_ci } 481bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL: { 482bf215546Sopenharmony_ci float (*params)[4] = ctx->FragmentProgram.Current->arb.LocalParams; 483bf215546Sopenharmony_ci if (unlikely(!params)) { 484bf215546Sopenharmony_ci /* Local parameters haven't been allocated yet. 485bf215546Sopenharmony_ci * ARB_fragment_program says that local parameters are 486bf215546Sopenharmony_ci * "initially set to (0,0,0,0)." Return that. 487bf215546Sopenharmony_ci */ 488bf215546Sopenharmony_ci memset(value, 0, sizeof(float) * 4); 489bf215546Sopenharmony_ci return; 490bf215546Sopenharmony_ci } 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci const int idx = (int) state[1]; 493bf215546Sopenharmony_ci COPY_4V(value, params[idx]); 494bf215546Sopenharmony_ci return; 495bf215546Sopenharmony_ci } 496bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY: { 497bf215546Sopenharmony_ci const unsigned idx = state[1]; 498bf215546Sopenharmony_ci const unsigned bytes = state[2] * 16; 499bf215546Sopenharmony_ci float (*params)[4] = ctx->FragmentProgram.Current->arb.LocalParams; 500bf215546Sopenharmony_ci if (!params) { 501bf215546Sopenharmony_ci /* Local parameters haven't been allocated yet. 502bf215546Sopenharmony_ci * ARB_fragment_program says that local parameters are 503bf215546Sopenharmony_ci * "initially set to (0,0,0,0)." Return that. 504bf215546Sopenharmony_ci */ 505bf215546Sopenharmony_ci memset(value, 0, bytes); 506bf215546Sopenharmony_ci return; 507bf215546Sopenharmony_ci } 508bf215546Sopenharmony_ci memcpy(value, params[idx], bytes); 509bf215546Sopenharmony_ci return; 510bf215546Sopenharmony_ci } 511bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV: { 512bf215546Sopenharmony_ci const int idx = (int) state[1]; 513bf215546Sopenharmony_ci COPY_4V(value, ctx->VertexProgram.Parameters[idx]); 514bf215546Sopenharmony_ci return; 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV_ARRAY: { 517bf215546Sopenharmony_ci const unsigned idx = state[1]; 518bf215546Sopenharmony_ci const unsigned bytes = state[2] * 16; 519bf215546Sopenharmony_ci memcpy(value, ctx->VertexProgram.Parameters[idx], bytes); 520bf215546Sopenharmony_ci return; 521bf215546Sopenharmony_ci } 522bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL: { 523bf215546Sopenharmony_ci float (*params)[4] = ctx->VertexProgram.Current->arb.LocalParams; 524bf215546Sopenharmony_ci if (unlikely(!params)) { 525bf215546Sopenharmony_ci /* Local parameters haven't been allocated yet. 526bf215546Sopenharmony_ci * ARB_vertex_program says that local parameters are 527bf215546Sopenharmony_ci * "initially set to (0,0,0,0)." Return that. 528bf215546Sopenharmony_ci */ 529bf215546Sopenharmony_ci memset(value, 0, sizeof(float) * 4); 530bf215546Sopenharmony_ci return; 531bf215546Sopenharmony_ci } 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci const int idx = (int) state[1]; 534bf215546Sopenharmony_ci COPY_4V(value, params[idx]); 535bf215546Sopenharmony_ci return; 536bf215546Sopenharmony_ci } 537bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL_ARRAY: { 538bf215546Sopenharmony_ci const unsigned idx = state[1]; 539bf215546Sopenharmony_ci const unsigned bytes = state[2] * 16; 540bf215546Sopenharmony_ci float (*params)[4] = ctx->VertexProgram.Current->arb.LocalParams; 541bf215546Sopenharmony_ci if (!params) { 542bf215546Sopenharmony_ci /* Local parameters haven't been allocated yet. 543bf215546Sopenharmony_ci * ARB_vertex_program says that local parameters are 544bf215546Sopenharmony_ci * "initially set to (0,0,0,0)." Return that. 545bf215546Sopenharmony_ci */ 546bf215546Sopenharmony_ci memset(value, 0, bytes); 547bf215546Sopenharmony_ci return; 548bf215546Sopenharmony_ci } 549bf215546Sopenharmony_ci memcpy(value, params[idx], bytes); 550bf215546Sopenharmony_ci return; 551bf215546Sopenharmony_ci } 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci case STATE_NORMAL_SCALE_EYESPACE: 554bf215546Sopenharmony_ci ASSIGN_4V(value, ctx->_ModelViewInvScaleEyespace, 0, 0, 1); 555bf215546Sopenharmony_ci return; 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB: 558bf215546Sopenharmony_ci { 559bf215546Sopenharmony_ci const GLuint idx = (GLuint) state[1]; 560bf215546Sopenharmony_ci COPY_4V(value, ctx->Current.Attrib[idx]); 561bf215546Sopenharmony_ci } 562bf215546Sopenharmony_ci return; 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 565bf215546Sopenharmony_ci { 566bf215546Sopenharmony_ci const GLuint idx = (GLuint) state[1]; 567bf215546Sopenharmony_ci if(ctx->Light._ClampVertexColor && 568bf215546Sopenharmony_ci (idx == VERT_ATTRIB_COLOR0 || 569bf215546Sopenharmony_ci idx == VERT_ATTRIB_COLOR1)) { 570bf215546Sopenharmony_ci value[0] = SATURATE(ctx->Current.Attrib[idx][0]); 571bf215546Sopenharmony_ci value[1] = SATURATE(ctx->Current.Attrib[idx][1]); 572bf215546Sopenharmony_ci value[2] = SATURATE(ctx->Current.Attrib[idx][2]); 573bf215546Sopenharmony_ci value[3] = SATURATE(ctx->Current.Attrib[idx][3]); 574bf215546Sopenharmony_ci } 575bf215546Sopenharmony_ci else 576bf215546Sopenharmony_ci COPY_4V(value, ctx->Current.Attrib[idx]); 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci return; 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci case STATE_NORMAL_SCALE: 581bf215546Sopenharmony_ci ASSIGN_4V(value, 582bf215546Sopenharmony_ci ctx->_ModelViewInvScale, 583bf215546Sopenharmony_ci ctx->_ModelViewInvScale, 584bf215546Sopenharmony_ci ctx->_ModelViewInvScale, 585bf215546Sopenharmony_ci 1); 586bf215546Sopenharmony_ci return; 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci case STATE_FOG_PARAMS_OPTIMIZED: { 589bf215546Sopenharmony_ci /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog) 590bf215546Sopenharmony_ci * might be more expensive than EX2 on some hw, plus it needs 591bf215546Sopenharmony_ci * another constant (e) anyway. Linear fog can now be done with a 592bf215546Sopenharmony_ci * single MAD. 593bf215546Sopenharmony_ci * linear: fogcoord * -1/(end-start) + end/(end-start) 594bf215546Sopenharmony_ci * exp: 2^-(density/ln(2) * fogcoord) 595bf215546Sopenharmony_ci * exp2: 2^-((density/(sqrt(ln(2))) * fogcoord)^2) 596bf215546Sopenharmony_ci */ 597bf215546Sopenharmony_ci float val = (ctx->Fog.End == ctx->Fog.Start) 598bf215546Sopenharmony_ci ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start)); 599bf215546Sopenharmony_ci value[0] = val; 600bf215546Sopenharmony_ci value[1] = ctx->Fog.End * -val; 601bf215546Sopenharmony_ci value[2] = (GLfloat)(ctx->Fog.Density * M_LOG2E); /* M_LOG2E == 1/ln(2) */ 602bf215546Sopenharmony_ci value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2); 603bf215546Sopenharmony_ci return; 604bf215546Sopenharmony_ci } 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci case STATE_POINT_SIZE_CLAMPED: 607bf215546Sopenharmony_ci { 608bf215546Sopenharmony_ci /* this includes implementation dependent limits, to avoid 609bf215546Sopenharmony_ci * another potentially necessary clamp. 610bf215546Sopenharmony_ci * Note: for sprites, point smooth (point AA) is ignored 611bf215546Sopenharmony_ci * and we'll clamp to MinPointSizeAA and MaxPointSize, because we 612bf215546Sopenharmony_ci * expect drivers will want to say their minimum for AA size is 0.0 613bf215546Sopenharmony_ci * but for non-AA it's 1.0 (because normal points with size below 1.0 614bf215546Sopenharmony_ci * need to get rounded up to 1.0, hence never disappear). GL does 615bf215546Sopenharmony_ci * not specify max clamp size for sprites, other than it needs to be 616bf215546Sopenharmony_ci * at least as large as max AA size, hence use non-AA size there. 617bf215546Sopenharmony_ci */ 618bf215546Sopenharmony_ci GLfloat minImplSize; 619bf215546Sopenharmony_ci GLfloat maxImplSize; 620bf215546Sopenharmony_ci if (ctx->Point.PointSprite) { 621bf215546Sopenharmony_ci minImplSize = ctx->Const.MinPointSizeAA; 622bf215546Sopenharmony_ci maxImplSize = ctx->Const.MaxPointSize; 623bf215546Sopenharmony_ci } 624bf215546Sopenharmony_ci else if (ctx->Point.SmoothFlag || _mesa_is_multisample_enabled(ctx)) { 625bf215546Sopenharmony_ci minImplSize = ctx->Const.MinPointSizeAA; 626bf215546Sopenharmony_ci maxImplSize = ctx->Const.MaxPointSizeAA; 627bf215546Sopenharmony_ci } 628bf215546Sopenharmony_ci else { 629bf215546Sopenharmony_ci minImplSize = ctx->Const.MinPointSize; 630bf215546Sopenharmony_ci maxImplSize = ctx->Const.MaxPointSize; 631bf215546Sopenharmony_ci } 632bf215546Sopenharmony_ci value[0] = ctx->Point.Size; 633bf215546Sopenharmony_ci value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize; 634bf215546Sopenharmony_ci value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize; 635bf215546Sopenharmony_ci value[3] = ctx->Point.Threshold; 636bf215546Sopenharmony_ci } 637bf215546Sopenharmony_ci return; 638bf215546Sopenharmony_ci case STATE_LIGHT_SPOT_DIR_NORMALIZED: 639bf215546Sopenharmony_ci { 640bf215546Sopenharmony_ci /* here, state[1] is the light number */ 641bf215546Sopenharmony_ci /* pre-normalize spot dir */ 642bf215546Sopenharmony_ci const GLuint ln = (GLuint) state[1]; 643bf215546Sopenharmony_ci COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection); 644bf215546Sopenharmony_ci value[3] = ctx->Light.LightSource[ln]._CosCutoff; 645bf215546Sopenharmony_ci } 646bf215546Sopenharmony_ci return; 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci case STATE_LIGHT_POSITION: 649bf215546Sopenharmony_ci { 650bf215546Sopenharmony_ci const GLuint ln = (GLuint) state[1]; 651bf215546Sopenharmony_ci COPY_4V(value, ctx->Light.Light[ln]._Position); 652bf215546Sopenharmony_ci } 653bf215546Sopenharmony_ci return; 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_ARRAY: { 656bf215546Sopenharmony_ci const unsigned first = state[1]; 657bf215546Sopenharmony_ci const unsigned num_lights = state[2]; 658bf215546Sopenharmony_ci for (unsigned i = 0; i < num_lights; i++) { 659bf215546Sopenharmony_ci COPY_4V(value, ctx->Light.Light[first + i]._Position); 660bf215546Sopenharmony_ci value += 4; 661bf215546Sopenharmony_ci } 662bf215546Sopenharmony_ci return; 663bf215546Sopenharmony_ci } 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED: 666bf215546Sopenharmony_ci { 667bf215546Sopenharmony_ci const GLuint ln = (GLuint) state[1]; 668bf215546Sopenharmony_ci float p[4]; 669bf215546Sopenharmony_ci COPY_4V(p, ctx->Light.Light[ln]._Position); 670bf215546Sopenharmony_ci NORMALIZE_3FV(p); 671bf215546Sopenharmony_ci COPY_4V(value, p); 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci return; 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED_ARRAY: { 676bf215546Sopenharmony_ci const unsigned first = state[1]; 677bf215546Sopenharmony_ci const unsigned num_lights = state[2]; 678bf215546Sopenharmony_ci for (unsigned i = 0; i < num_lights; i++) { 679bf215546Sopenharmony_ci float p[4]; 680bf215546Sopenharmony_ci COPY_4V(p, ctx->Light.Light[first + i]._Position); 681bf215546Sopenharmony_ci NORMALIZE_3FV(p); 682bf215546Sopenharmony_ci COPY_4V(value, p); 683bf215546Sopenharmony_ci value += 4; 684bf215546Sopenharmony_ci } 685bf215546Sopenharmony_ci return; 686bf215546Sopenharmony_ci } 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci case STATE_LIGHT_HALF_VECTOR: 689bf215546Sopenharmony_ci { 690bf215546Sopenharmony_ci const GLuint ln = (GLuint) state[1]; 691bf215546Sopenharmony_ci GLfloat p[3]; 692bf215546Sopenharmony_ci /* Compute infinite half angle vector: 693bf215546Sopenharmony_ci * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) 694bf215546Sopenharmony_ci * light.EyePosition.w should be 0 for infinite lights. 695bf215546Sopenharmony_ci */ 696bf215546Sopenharmony_ci COPY_3V(p, ctx->Light.Light[ln]._Position); 697bf215546Sopenharmony_ci NORMALIZE_3FV(p); 698bf215546Sopenharmony_ci ADD_3V(p, p, ctx->_EyeZDir); 699bf215546Sopenharmony_ci NORMALIZE_3FV(p); 700bf215546Sopenharmony_ci COPY_3V(value, p); 701bf215546Sopenharmony_ci value[3] = 1.0; 702bf215546Sopenharmony_ci } 703bf215546Sopenharmony_ci return; 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci case STATE_PT_SCALE: 706bf215546Sopenharmony_ci value[0] = ctx->Pixel.RedScale; 707bf215546Sopenharmony_ci value[1] = ctx->Pixel.GreenScale; 708bf215546Sopenharmony_ci value[2] = ctx->Pixel.BlueScale; 709bf215546Sopenharmony_ci value[3] = ctx->Pixel.AlphaScale; 710bf215546Sopenharmony_ci return; 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci case STATE_PT_BIAS: 713bf215546Sopenharmony_ci value[0] = ctx->Pixel.RedBias; 714bf215546Sopenharmony_ci value[1] = ctx->Pixel.GreenBias; 715bf215546Sopenharmony_ci value[2] = ctx->Pixel.BlueBias; 716bf215546Sopenharmony_ci value[3] = ctx->Pixel.AlphaBias; 717bf215546Sopenharmony_ci return; 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci case STATE_FB_SIZE: 720bf215546Sopenharmony_ci value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1); 721bf215546Sopenharmony_ci value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1); 722bf215546Sopenharmony_ci value[2] = 0.0F; 723bf215546Sopenharmony_ci value[3] = 0.0F; 724bf215546Sopenharmony_ci return; 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci case STATE_FB_WPOS_Y_TRANSFORM: 727bf215546Sopenharmony_ci /* A driver may negate this conditional by using ZW swizzle 728bf215546Sopenharmony_ci * instead of XY (based on e.g. some other state). */ 729bf215546Sopenharmony_ci if (!ctx->DrawBuffer->FlipY) { 730bf215546Sopenharmony_ci /* Identity (XY) followed by flipping Y upside down (ZW). */ 731bf215546Sopenharmony_ci value[0] = 1.0F; 732bf215546Sopenharmony_ci value[1] = 0.0F; 733bf215546Sopenharmony_ci value[2] = -1.0F; 734bf215546Sopenharmony_ci value[3] = _mesa_geometric_height(ctx->DrawBuffer); 735bf215546Sopenharmony_ci } else { 736bf215546Sopenharmony_ci /* Flipping Y upside down (XY) followed by identity (ZW). */ 737bf215546Sopenharmony_ci value[0] = -1.0F; 738bf215546Sopenharmony_ci value[1] = _mesa_geometric_height(ctx->DrawBuffer); 739bf215546Sopenharmony_ci value[2] = 1.0F; 740bf215546Sopenharmony_ci value[3] = 0.0F; 741bf215546Sopenharmony_ci } 742bf215546Sopenharmony_ci return; 743bf215546Sopenharmony_ci 744bf215546Sopenharmony_ci case STATE_FB_PNTC_Y_TRANSFORM: 745bf215546Sopenharmony_ci { 746bf215546Sopenharmony_ci bool flip_y = (ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^ 747bf215546Sopenharmony_ci (ctx->Const.PointCoordOriginUpperLeft) ^ 748bf215546Sopenharmony_ci (ctx->DrawBuffer->FlipY); 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci value[0] = flip_y ? -1.0F : 1.0F; 751bf215546Sopenharmony_ci value[1] = flip_y ? 1.0F : 0.0F; 752bf215546Sopenharmony_ci value[2] = 0.0F; 753bf215546Sopenharmony_ci value[3] = 0.0F; 754bf215546Sopenharmony_ci } 755bf215546Sopenharmony_ci return; 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ci case STATE_TCS_PATCH_VERTICES_IN: 758bf215546Sopenharmony_ci val[0].i = ctx->TessCtrlProgram.patch_vertices; 759bf215546Sopenharmony_ci return; 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci case STATE_TES_PATCH_VERTICES_IN: 762bf215546Sopenharmony_ci if (ctx->TessCtrlProgram._Current) 763bf215546Sopenharmony_ci val[0].i = ctx->TessCtrlProgram._Current->info.tess.tcs_vertices_out; 764bf215546Sopenharmony_ci else 765bf215546Sopenharmony_ci val[0].i = ctx->TessCtrlProgram.patch_vertices; 766bf215546Sopenharmony_ci return; 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci case STATE_ADVANCED_BLENDING_MODE: 769bf215546Sopenharmony_ci val[0].i = _mesa_get_advanced_blend_sh_constant( 770bf215546Sopenharmony_ci ctx->Color.BlendEnabled, ctx->Color._AdvancedBlendMode); 771bf215546Sopenharmony_ci return; 772bf215546Sopenharmony_ci 773bf215546Sopenharmony_ci case STATE_ALPHA_REF: 774bf215546Sopenharmony_ci value[0] = ctx->Color.AlphaRefUnclamped; 775bf215546Sopenharmony_ci return; 776bf215546Sopenharmony_ci 777bf215546Sopenharmony_ci case STATE_CLIP_INTERNAL: 778bf215546Sopenharmony_ci { 779bf215546Sopenharmony_ci const GLuint plane = (GLuint) state[1]; 780bf215546Sopenharmony_ci COPY_4V(value, ctx->Transform._ClipUserPlane[plane]); 781bf215546Sopenharmony_ci } 782bf215546Sopenharmony_ci return; 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci case STATE_ATOMIC_COUNTER_OFFSET: 785bf215546Sopenharmony_ci { 786bf215546Sopenharmony_ci const GLuint counter = (GLuint) state[1]; 787bf215546Sopenharmony_ci val[0].i = ctx->AtomicBufferBindings[counter].Offset % ctx->Const.ShaderStorageBufferOffsetAlignment; 788bf215546Sopenharmony_ci } 789bf215546Sopenharmony_ci return; 790bf215546Sopenharmony_ci } 791bf215546Sopenharmony_ci} 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ciunsigned 794bf215546Sopenharmony_ci_mesa_program_state_value_size(const gl_state_index16 state[STATE_LENGTH]) 795bf215546Sopenharmony_ci{ 796bf215546Sopenharmony_ci if (state[0] == STATE_LIGHT && state[2] == STATE_SPOT_CUTOFF) 797bf215546Sopenharmony_ci return 1; 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci /* Everything else is packed into vec4s */ 800bf215546Sopenharmony_ci return 4; 801bf215546Sopenharmony_ci} 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci/** 804bf215546Sopenharmony_ci * Return a bitmask of the Mesa state flags (_NEW_* values) which would 805bf215546Sopenharmony_ci * indicate that the given context state may have changed. 806bf215546Sopenharmony_ci * The bitmask is used during validation to determine if we need to update 807bf215546Sopenharmony_ci * vertex/fragment program parameters (like "state.material.color") when 808bf215546Sopenharmony_ci * some GL state has changed. 809bf215546Sopenharmony_ci */ 810bf215546Sopenharmony_ciGLbitfield 811bf215546Sopenharmony_ci_mesa_program_state_flags(const gl_state_index16 state[STATE_LENGTH]) 812bf215546Sopenharmony_ci{ 813bf215546Sopenharmony_ci switch (state[0]) { 814bf215546Sopenharmony_ci case STATE_MATERIAL: 815bf215546Sopenharmony_ci return _NEW_MATERIAL; 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci case STATE_LIGHTPROD: 818bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_FRONT: 819bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_BACK: 820bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_TWOSIDE: 821bf215546Sopenharmony_ci case STATE_LIGHTMODEL_SCENECOLOR: 822bf215546Sopenharmony_ci return _NEW_LIGHT_CONSTANTS | _NEW_MATERIAL; 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci case STATE_LIGHT: 825bf215546Sopenharmony_ci case STATE_LIGHT_ARRAY: 826bf215546Sopenharmony_ci case STATE_LIGHT_ATTENUATION_ARRAY: 827bf215546Sopenharmony_ci case STATE_LIGHTMODEL_AMBIENT: 828bf215546Sopenharmony_ci case STATE_LIGHT_SPOT_DIR_NORMALIZED: 829bf215546Sopenharmony_ci case STATE_LIGHT_POSITION: 830bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_ARRAY: 831bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED: 832bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED_ARRAY: 833bf215546Sopenharmony_ci case STATE_LIGHT_HALF_VECTOR: 834bf215546Sopenharmony_ci return _NEW_LIGHT_CONSTANTS; 835bf215546Sopenharmony_ci 836bf215546Sopenharmony_ci case STATE_TEXGEN: 837bf215546Sopenharmony_ci return _NEW_TEXTURE_STATE; 838bf215546Sopenharmony_ci case STATE_TEXENV_COLOR: 839bf215546Sopenharmony_ci return _NEW_TEXTURE_STATE | _NEW_BUFFERS | _NEW_FRAG_CLAMP; 840bf215546Sopenharmony_ci 841bf215546Sopenharmony_ci case STATE_FOG_COLOR: 842bf215546Sopenharmony_ci return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP; 843bf215546Sopenharmony_ci case STATE_FOG_PARAMS: 844bf215546Sopenharmony_ci case STATE_FOG_PARAMS_OPTIMIZED: 845bf215546Sopenharmony_ci return _NEW_FOG; 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci case STATE_CLIPPLANE: 848bf215546Sopenharmony_ci return _NEW_TRANSFORM; 849bf215546Sopenharmony_ci 850bf215546Sopenharmony_ci case STATE_POINT_SIZE: 851bf215546Sopenharmony_ci case STATE_POINT_ATTENUATION: 852bf215546Sopenharmony_ci return _NEW_POINT; 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX: 855bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVERSE: 856bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_TRANSPOSE: 857bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVTRANS: 858bf215546Sopenharmony_ci case STATE_NORMAL_SCALE_EYESPACE: 859bf215546Sopenharmony_ci case STATE_NORMAL_SCALE: 860bf215546Sopenharmony_ci return _NEW_MODELVIEW; 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX: 863bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVERSE: 864bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_TRANSPOSE: 865bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVTRANS: 866bf215546Sopenharmony_ci return _NEW_PROJECTION; 867bf215546Sopenharmony_ci case STATE_MVP_MATRIX: 868bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVERSE: 869bf215546Sopenharmony_ci case STATE_MVP_MATRIX_TRANSPOSE: 870bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVTRANS: 871bf215546Sopenharmony_ci return _NEW_MODELVIEW | _NEW_PROJECTION; 872bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX: 873bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVERSE: 874bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_TRANSPOSE: 875bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVTRANS: 876bf215546Sopenharmony_ci return _NEW_TEXTURE_MATRIX; 877bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX: 878bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVERSE: 879bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_TRANSPOSE: 880bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVTRANS: 881bf215546Sopenharmony_ci return _NEW_TRACK_MATRIX; 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci case STATE_NUM_SAMPLES: 884bf215546Sopenharmony_ci case STATE_FB_SIZE: 885bf215546Sopenharmony_ci case STATE_FB_WPOS_Y_TRANSFORM: 886bf215546Sopenharmony_ci return _NEW_BUFFERS; 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ci case STATE_FB_PNTC_Y_TRANSFORM: 889bf215546Sopenharmony_ci return _NEW_BUFFERS | _NEW_POINT; 890bf215546Sopenharmony_ci 891bf215546Sopenharmony_ci case STATE_DEPTH_RANGE: 892bf215546Sopenharmony_ci return _NEW_VIEWPORT; 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV: 895bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV_ARRAY: 896bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL: 897bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY: 898bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV: 899bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV_ARRAY: 900bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL: 901bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL_ARRAY: 902bf215546Sopenharmony_ci return _NEW_PROGRAM; 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB: 905bf215546Sopenharmony_ci return _NEW_CURRENT_ATTRIB; 906bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 907bf215546Sopenharmony_ci return _NEW_CURRENT_ATTRIB | _NEW_LIGHT_STATE | _NEW_BUFFERS; 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci case STATE_POINT_SIZE_CLAMPED: 910bf215546Sopenharmony_ci return _NEW_POINT | _NEW_MULTISAMPLE; 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci case STATE_PT_SCALE: 913bf215546Sopenharmony_ci case STATE_PT_BIAS: 914bf215546Sopenharmony_ci return _NEW_PIXEL; 915bf215546Sopenharmony_ci 916bf215546Sopenharmony_ci case STATE_ADVANCED_BLENDING_MODE: 917bf215546Sopenharmony_ci case STATE_ALPHA_REF: 918bf215546Sopenharmony_ci return _NEW_COLOR; 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_ci case STATE_CLIP_INTERNAL: 921bf215546Sopenharmony_ci return _NEW_TRANSFORM | _NEW_PROJECTION; 922bf215546Sopenharmony_ci 923bf215546Sopenharmony_ci /* Needs to return any nonzero value to trigger constant updating */ 924bf215546Sopenharmony_ci case STATE_ATOMIC_COUNTER_OFFSET: 925bf215546Sopenharmony_ci return _NEW_PROGRAM_CONSTANTS; 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci case STATE_TCS_PATCH_VERTICES_IN: 928bf215546Sopenharmony_ci case STATE_TES_PATCH_VERTICES_IN: 929bf215546Sopenharmony_ci case STATE_INTERNAL_DRIVER: 930bf215546Sopenharmony_ci return 0; /* internal driver state */ 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci case STATE_NOT_STATE_VAR: 933bf215546Sopenharmony_ci return 0; 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci default: 936bf215546Sopenharmony_ci _mesa_problem(NULL, "unexpected state[0] in make_state_flags()"); 937bf215546Sopenharmony_ci return 0; 938bf215546Sopenharmony_ci } 939bf215546Sopenharmony_ci} 940bf215546Sopenharmony_ci 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_cistatic void 943bf215546Sopenharmony_ciappend(char *dst, const char *src) 944bf215546Sopenharmony_ci{ 945bf215546Sopenharmony_ci while (*dst) 946bf215546Sopenharmony_ci dst++; 947bf215546Sopenharmony_ci while (*src) 948bf215546Sopenharmony_ci *dst++ = *src++; 949bf215546Sopenharmony_ci *dst = 0; 950bf215546Sopenharmony_ci} 951bf215546Sopenharmony_ci 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_ci/** 954bf215546Sopenharmony_ci * Convert token 'k' to a string, append it onto 'dst' string. 955bf215546Sopenharmony_ci */ 956bf215546Sopenharmony_cistatic void 957bf215546Sopenharmony_ciappend_token(char *dst, gl_state_index k) 958bf215546Sopenharmony_ci{ 959bf215546Sopenharmony_ci switch (k) { 960bf215546Sopenharmony_ci case STATE_MATERIAL: 961bf215546Sopenharmony_ci append(dst, "material"); 962bf215546Sopenharmony_ci break; 963bf215546Sopenharmony_ci case STATE_LIGHT: 964bf215546Sopenharmony_ci append(dst, "light"); 965bf215546Sopenharmony_ci break; 966bf215546Sopenharmony_ci case STATE_LIGHT_ARRAY: 967bf215546Sopenharmony_ci append(dst, "light.array"); 968bf215546Sopenharmony_ci break; 969bf215546Sopenharmony_ci case STATE_LIGHT_ATTENUATION_ARRAY: 970bf215546Sopenharmony_ci append(dst, "light.attenuation"); 971bf215546Sopenharmony_ci break; 972bf215546Sopenharmony_ci case STATE_LIGHTMODEL_AMBIENT: 973bf215546Sopenharmony_ci append(dst, "lightmodel.ambient"); 974bf215546Sopenharmony_ci break; 975bf215546Sopenharmony_ci case STATE_LIGHTMODEL_SCENECOLOR: 976bf215546Sopenharmony_ci break; 977bf215546Sopenharmony_ci case STATE_LIGHTPROD: 978bf215546Sopenharmony_ci append(dst, "lightprod"); 979bf215546Sopenharmony_ci break; 980bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_FRONT: 981bf215546Sopenharmony_ci append(dst, "lightprod.array.front"); 982bf215546Sopenharmony_ci break; 983bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_BACK: 984bf215546Sopenharmony_ci append(dst, "lightprod.array.back"); 985bf215546Sopenharmony_ci break; 986bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_TWOSIDE: 987bf215546Sopenharmony_ci append(dst, "lightprod.array.twoside"); 988bf215546Sopenharmony_ci break; 989bf215546Sopenharmony_ci case STATE_TEXGEN: 990bf215546Sopenharmony_ci append(dst, "texgen"); 991bf215546Sopenharmony_ci break; 992bf215546Sopenharmony_ci case STATE_FOG_COLOR: 993bf215546Sopenharmony_ci append(dst, "fog.color"); 994bf215546Sopenharmony_ci break; 995bf215546Sopenharmony_ci case STATE_FOG_PARAMS: 996bf215546Sopenharmony_ci append(dst, "fog.params"); 997bf215546Sopenharmony_ci break; 998bf215546Sopenharmony_ci case STATE_CLIPPLANE: 999bf215546Sopenharmony_ci append(dst, "clip"); 1000bf215546Sopenharmony_ci break; 1001bf215546Sopenharmony_ci case STATE_POINT_SIZE: 1002bf215546Sopenharmony_ci append(dst, "point.size"); 1003bf215546Sopenharmony_ci break; 1004bf215546Sopenharmony_ci case STATE_POINT_ATTENUATION: 1005bf215546Sopenharmony_ci append(dst, "point.attenuation"); 1006bf215546Sopenharmony_ci break; 1007bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX: 1008bf215546Sopenharmony_ci append(dst, "matrix.modelview."); 1009bf215546Sopenharmony_ci break; 1010bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVERSE: 1011bf215546Sopenharmony_ci append(dst, "matrix.modelview.inverse."); 1012bf215546Sopenharmony_ci break; 1013bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_TRANSPOSE: 1014bf215546Sopenharmony_ci append(dst, "matrix.modelview.transpose."); 1015bf215546Sopenharmony_ci break; 1016bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVTRANS: 1017bf215546Sopenharmony_ci append(dst, "matrix.modelview.invtrans."); 1018bf215546Sopenharmony_ci break; 1019bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX: 1020bf215546Sopenharmony_ci append(dst, "matrix.projection."); 1021bf215546Sopenharmony_ci break; 1022bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVERSE: 1023bf215546Sopenharmony_ci append(dst, "matrix.projection.inverse."); 1024bf215546Sopenharmony_ci break; 1025bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_TRANSPOSE: 1026bf215546Sopenharmony_ci append(dst, "matrix.projection.transpose."); 1027bf215546Sopenharmony_ci break; 1028bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVTRANS: 1029bf215546Sopenharmony_ci append(dst, "matrix.projection.invtrans."); 1030bf215546Sopenharmony_ci break; 1031bf215546Sopenharmony_ci case STATE_MVP_MATRIX: 1032bf215546Sopenharmony_ci append(dst, "matrix.mvp."); 1033bf215546Sopenharmony_ci break; 1034bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVERSE: 1035bf215546Sopenharmony_ci append(dst, "matrix.mvp.inverse."); 1036bf215546Sopenharmony_ci break; 1037bf215546Sopenharmony_ci case STATE_MVP_MATRIX_TRANSPOSE: 1038bf215546Sopenharmony_ci append(dst, "matrix.mvp.transpose."); 1039bf215546Sopenharmony_ci break; 1040bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVTRANS: 1041bf215546Sopenharmony_ci append(dst, "matrix.mvp.invtrans."); 1042bf215546Sopenharmony_ci break; 1043bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX: 1044bf215546Sopenharmony_ci append(dst, "matrix.texture"); 1045bf215546Sopenharmony_ci break; 1046bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVERSE: 1047bf215546Sopenharmony_ci append(dst, "matrix.texture.inverse"); 1048bf215546Sopenharmony_ci break; 1049bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_TRANSPOSE: 1050bf215546Sopenharmony_ci append(dst, "matrix.texture.transpose"); 1051bf215546Sopenharmony_ci break; 1052bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVTRANS: 1053bf215546Sopenharmony_ci append(dst, "matrix.texture.invtrans"); 1054bf215546Sopenharmony_ci break; 1055bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX: 1056bf215546Sopenharmony_ci append(dst, "matrix.program"); 1057bf215546Sopenharmony_ci break; 1058bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVERSE: 1059bf215546Sopenharmony_ci append(dst, "matrix.program.inverse"); 1060bf215546Sopenharmony_ci break; 1061bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_TRANSPOSE: 1062bf215546Sopenharmony_ci append(dst, "matrix.program.transpose"); 1063bf215546Sopenharmony_ci break; 1064bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVTRANS: 1065bf215546Sopenharmony_ci append(dst, "matrix.program.invtrans"); 1066bf215546Sopenharmony_ci break; 1067bf215546Sopenharmony_ci break; 1068bf215546Sopenharmony_ci case STATE_AMBIENT: 1069bf215546Sopenharmony_ci append(dst, "ambient"); 1070bf215546Sopenharmony_ci break; 1071bf215546Sopenharmony_ci case STATE_DIFFUSE: 1072bf215546Sopenharmony_ci append(dst, "diffuse"); 1073bf215546Sopenharmony_ci break; 1074bf215546Sopenharmony_ci case STATE_SPECULAR: 1075bf215546Sopenharmony_ci append(dst, "specular"); 1076bf215546Sopenharmony_ci break; 1077bf215546Sopenharmony_ci case STATE_EMISSION: 1078bf215546Sopenharmony_ci append(dst, "emission"); 1079bf215546Sopenharmony_ci break; 1080bf215546Sopenharmony_ci case STATE_SHININESS: 1081bf215546Sopenharmony_ci append(dst, "shininess"); 1082bf215546Sopenharmony_ci break; 1083bf215546Sopenharmony_ci case STATE_HALF_VECTOR: 1084bf215546Sopenharmony_ci append(dst, "half"); 1085bf215546Sopenharmony_ci break; 1086bf215546Sopenharmony_ci case STATE_POSITION: 1087bf215546Sopenharmony_ci append(dst, "position"); 1088bf215546Sopenharmony_ci break; 1089bf215546Sopenharmony_ci case STATE_ATTENUATION: 1090bf215546Sopenharmony_ci append(dst, "attenuation"); 1091bf215546Sopenharmony_ci break; 1092bf215546Sopenharmony_ci case STATE_SPOT_DIRECTION: 1093bf215546Sopenharmony_ci append(dst, "spot.direction"); 1094bf215546Sopenharmony_ci break; 1095bf215546Sopenharmony_ci case STATE_SPOT_CUTOFF: 1096bf215546Sopenharmony_ci append(dst, "spot.cutoff"); 1097bf215546Sopenharmony_ci break; 1098bf215546Sopenharmony_ci case STATE_TEXGEN_EYE_S: 1099bf215546Sopenharmony_ci append(dst, "eye.s"); 1100bf215546Sopenharmony_ci break; 1101bf215546Sopenharmony_ci case STATE_TEXGEN_EYE_T: 1102bf215546Sopenharmony_ci append(dst, "eye.t"); 1103bf215546Sopenharmony_ci break; 1104bf215546Sopenharmony_ci case STATE_TEXGEN_EYE_R: 1105bf215546Sopenharmony_ci append(dst, "eye.r"); 1106bf215546Sopenharmony_ci break; 1107bf215546Sopenharmony_ci case STATE_TEXGEN_EYE_Q: 1108bf215546Sopenharmony_ci append(dst, "eye.q"); 1109bf215546Sopenharmony_ci break; 1110bf215546Sopenharmony_ci case STATE_TEXGEN_OBJECT_S: 1111bf215546Sopenharmony_ci append(dst, "object.s"); 1112bf215546Sopenharmony_ci break; 1113bf215546Sopenharmony_ci case STATE_TEXGEN_OBJECT_T: 1114bf215546Sopenharmony_ci append(dst, "object.t"); 1115bf215546Sopenharmony_ci break; 1116bf215546Sopenharmony_ci case STATE_TEXGEN_OBJECT_R: 1117bf215546Sopenharmony_ci append(dst, "object.r"); 1118bf215546Sopenharmony_ci break; 1119bf215546Sopenharmony_ci case STATE_TEXGEN_OBJECT_Q: 1120bf215546Sopenharmony_ci append(dst, "object.q"); 1121bf215546Sopenharmony_ci break; 1122bf215546Sopenharmony_ci case STATE_TEXENV_COLOR: 1123bf215546Sopenharmony_ci append(dst, "texenv"); 1124bf215546Sopenharmony_ci break; 1125bf215546Sopenharmony_ci case STATE_NUM_SAMPLES: 1126bf215546Sopenharmony_ci append(dst, "numsamples"); 1127bf215546Sopenharmony_ci break; 1128bf215546Sopenharmony_ci case STATE_DEPTH_RANGE: 1129bf215546Sopenharmony_ci append(dst, "depth.range"); 1130bf215546Sopenharmony_ci break; 1131bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV: 1132bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV: 1133bf215546Sopenharmony_ci append(dst, "env"); 1134bf215546Sopenharmony_ci break; 1135bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV_ARRAY: 1136bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV_ARRAY: 1137bf215546Sopenharmony_ci append(dst, "env.range"); 1138bf215546Sopenharmony_ci break; 1139bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL: 1140bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL: 1141bf215546Sopenharmony_ci append(dst, "local"); 1142bf215546Sopenharmony_ci break; 1143bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL_ARRAY: 1144bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY: 1145bf215546Sopenharmony_ci append(dst, "local.range"); 1146bf215546Sopenharmony_ci break; 1147bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB: 1148bf215546Sopenharmony_ci append(dst, "current"); 1149bf215546Sopenharmony_ci break; 1150bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 1151bf215546Sopenharmony_ci append(dst, "currentAttribMaybeVPClamped"); 1152bf215546Sopenharmony_ci break; 1153bf215546Sopenharmony_ci case STATE_NORMAL_SCALE_EYESPACE: 1154bf215546Sopenharmony_ci append(dst, "normalScaleEyeSpace"); 1155bf215546Sopenharmony_ci break; 1156bf215546Sopenharmony_ci case STATE_NORMAL_SCALE: 1157bf215546Sopenharmony_ci append(dst, "normalScale"); 1158bf215546Sopenharmony_ci break; 1159bf215546Sopenharmony_ci case STATE_FOG_PARAMS_OPTIMIZED: 1160bf215546Sopenharmony_ci append(dst, "fogParamsOptimized"); 1161bf215546Sopenharmony_ci break; 1162bf215546Sopenharmony_ci case STATE_POINT_SIZE_CLAMPED: 1163bf215546Sopenharmony_ci append(dst, "pointSizeClamped"); 1164bf215546Sopenharmony_ci break; 1165bf215546Sopenharmony_ci case STATE_LIGHT_SPOT_DIR_NORMALIZED: 1166bf215546Sopenharmony_ci append(dst, "lightSpotDirNormalized"); 1167bf215546Sopenharmony_ci break; 1168bf215546Sopenharmony_ci case STATE_LIGHT_POSITION: 1169bf215546Sopenharmony_ci append(dst, "light.position"); 1170bf215546Sopenharmony_ci break; 1171bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_ARRAY: 1172bf215546Sopenharmony_ci append(dst, "light.position.array"); 1173bf215546Sopenharmony_ci break; 1174bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED: 1175bf215546Sopenharmony_ci append(dst, "light.position.normalized"); 1176bf215546Sopenharmony_ci break; 1177bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED_ARRAY: 1178bf215546Sopenharmony_ci append(dst, "light.position.normalized.array"); 1179bf215546Sopenharmony_ci break; 1180bf215546Sopenharmony_ci case STATE_LIGHT_HALF_VECTOR: 1181bf215546Sopenharmony_ci append(dst, "lightHalfVector"); 1182bf215546Sopenharmony_ci break; 1183bf215546Sopenharmony_ci case STATE_PT_SCALE: 1184bf215546Sopenharmony_ci append(dst, "PTscale"); 1185bf215546Sopenharmony_ci break; 1186bf215546Sopenharmony_ci case STATE_PT_BIAS: 1187bf215546Sopenharmony_ci append(dst, "PTbias"); 1188bf215546Sopenharmony_ci break; 1189bf215546Sopenharmony_ci case STATE_FB_SIZE: 1190bf215546Sopenharmony_ci append(dst, "FbSize"); 1191bf215546Sopenharmony_ci break; 1192bf215546Sopenharmony_ci case STATE_FB_WPOS_Y_TRANSFORM: 1193bf215546Sopenharmony_ci append(dst, "FbWposYTransform"); 1194bf215546Sopenharmony_ci break; 1195bf215546Sopenharmony_ci case STATE_FB_PNTC_Y_TRANSFORM: 1196bf215546Sopenharmony_ci append(dst, "PntcYTransform"); 1197bf215546Sopenharmony_ci break; 1198bf215546Sopenharmony_ci case STATE_ADVANCED_BLENDING_MODE: 1199bf215546Sopenharmony_ci append(dst, "AdvancedBlendingMode"); 1200bf215546Sopenharmony_ci break; 1201bf215546Sopenharmony_ci case STATE_ALPHA_REF: 1202bf215546Sopenharmony_ci append(dst, "alphaRef"); 1203bf215546Sopenharmony_ci break; 1204bf215546Sopenharmony_ci case STATE_CLIP_INTERNAL: 1205bf215546Sopenharmony_ci append(dst, "clipInternal"); 1206bf215546Sopenharmony_ci break; 1207bf215546Sopenharmony_ci case STATE_ATOMIC_COUNTER_OFFSET: 1208bf215546Sopenharmony_ci append(dst, "counterOffset"); 1209bf215546Sopenharmony_ci break; 1210bf215546Sopenharmony_ci default: 1211bf215546Sopenharmony_ci /* probably STATE_INTERNAL_DRIVER+i (driver private state) */ 1212bf215546Sopenharmony_ci append(dst, "driverState"); 1213bf215546Sopenharmony_ci } 1214bf215546Sopenharmony_ci} 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_cistatic void 1217bf215546Sopenharmony_ciappend_index(char *dst, GLint index, bool structure) 1218bf215546Sopenharmony_ci{ 1219bf215546Sopenharmony_ci char s[20]; 1220bf215546Sopenharmony_ci sprintf(s, "[%d]%s", index, structure ? "." : ""); 1221bf215546Sopenharmony_ci append(dst, s); 1222bf215546Sopenharmony_ci} 1223bf215546Sopenharmony_ci 1224bf215546Sopenharmony_ci/** 1225bf215546Sopenharmony_ci * Make a string from the given state vector. 1226bf215546Sopenharmony_ci * For example, return "state.matrix.texture[2].inverse". 1227bf215546Sopenharmony_ci * Use free() to deallocate the string. 1228bf215546Sopenharmony_ci */ 1229bf215546Sopenharmony_cichar * 1230bf215546Sopenharmony_ci_mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH]) 1231bf215546Sopenharmony_ci{ 1232bf215546Sopenharmony_ci char str[1000] = ""; 1233bf215546Sopenharmony_ci char tmp[30]; 1234bf215546Sopenharmony_ci 1235bf215546Sopenharmony_ci append(str, "state."); 1236bf215546Sopenharmony_ci append_token(str, state[0]); 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci switch (state[0]) { 1239bf215546Sopenharmony_ci case STATE_LIGHT: 1240bf215546Sopenharmony_ci append_index(str, state[1], true); /* light number [i]. */ 1241bf215546Sopenharmony_ci append_token(str, state[2]); /* coefficients */ 1242bf215546Sopenharmony_ci break; 1243bf215546Sopenharmony_ci case STATE_LIGHTMODEL_AMBIENT: 1244bf215546Sopenharmony_ci break; 1245bf215546Sopenharmony_ci case STATE_LIGHTMODEL_SCENECOLOR: 1246bf215546Sopenharmony_ci if (state[1] == 0) { 1247bf215546Sopenharmony_ci append(str, "lightmodel.front.scenecolor"); 1248bf215546Sopenharmony_ci } 1249bf215546Sopenharmony_ci else { 1250bf215546Sopenharmony_ci append(str, "lightmodel.back.scenecolor"); 1251bf215546Sopenharmony_ci } 1252bf215546Sopenharmony_ci break; 1253bf215546Sopenharmony_ci case STATE_LIGHTPROD: 1254bf215546Sopenharmony_ci append_index(str, state[1], false); /* light number [i] */ 1255bf215546Sopenharmony_ci append_index(str, state[2], false); 1256bf215546Sopenharmony_ci break; 1257bf215546Sopenharmony_ci case STATE_TEXGEN: 1258bf215546Sopenharmony_ci append_index(str, state[1], true); /* tex unit [i] */ 1259bf215546Sopenharmony_ci append_token(str, state[2]); /* plane coef */ 1260bf215546Sopenharmony_ci break; 1261bf215546Sopenharmony_ci case STATE_TEXENV_COLOR: 1262bf215546Sopenharmony_ci append_index(str, state[1], true); /* tex unit [i] */ 1263bf215546Sopenharmony_ci append(str, "color"); 1264bf215546Sopenharmony_ci break; 1265bf215546Sopenharmony_ci case STATE_CLIPPLANE: 1266bf215546Sopenharmony_ci append_index(str, state[1], true); /* plane [i] */ 1267bf215546Sopenharmony_ci append(str, "plane"); 1268bf215546Sopenharmony_ci break; 1269bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX: 1270bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVERSE: 1271bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_TRANSPOSE: 1272bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVTRANS: 1273bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX: 1274bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVERSE: 1275bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_TRANSPOSE: 1276bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVTRANS: 1277bf215546Sopenharmony_ci case STATE_MVP_MATRIX: 1278bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVERSE: 1279bf215546Sopenharmony_ci case STATE_MVP_MATRIX_TRANSPOSE: 1280bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVTRANS: 1281bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX: 1282bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVERSE: 1283bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_TRANSPOSE: 1284bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVTRANS: 1285bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX: 1286bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVERSE: 1287bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_TRANSPOSE: 1288bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVTRANS: 1289bf215546Sopenharmony_ci { 1290bf215546Sopenharmony_ci /* state[0] = modelview, projection, texture, etc. */ 1291bf215546Sopenharmony_ci /* state[1] = which texture matrix or program matrix */ 1292bf215546Sopenharmony_ci /* state[2] = first row to fetch */ 1293bf215546Sopenharmony_ci /* state[3] = last row to fetch */ 1294bf215546Sopenharmony_ci const gl_state_index mat = state[0]; 1295bf215546Sopenharmony_ci const GLuint index = (GLuint) state[1]; 1296bf215546Sopenharmony_ci const GLuint firstRow = (GLuint) state[2]; 1297bf215546Sopenharmony_ci const GLuint lastRow = (GLuint) state[3]; 1298bf215546Sopenharmony_ci if (index || 1299bf215546Sopenharmony_ci (mat >= STATE_TEXTURE_MATRIX && 1300bf215546Sopenharmony_ci mat <= STATE_PROGRAM_MATRIX_INVTRANS)) 1301bf215546Sopenharmony_ci append_index(str, index, true); 1302bf215546Sopenharmony_ci if (firstRow == lastRow) 1303bf215546Sopenharmony_ci sprintf(tmp, "row[%d]", firstRow); 1304bf215546Sopenharmony_ci else 1305bf215546Sopenharmony_ci sprintf(tmp, "row[%d..%d]", firstRow, lastRow); 1306bf215546Sopenharmony_ci append(str, tmp); 1307bf215546Sopenharmony_ci } 1308bf215546Sopenharmony_ci break; 1309bf215546Sopenharmony_ci case STATE_LIGHT_ARRAY: 1310bf215546Sopenharmony_ci case STATE_LIGHT_ATTENUATION_ARRAY: 1311bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV_ARRAY: 1312bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY: 1313bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV_ARRAY: 1314bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL_ARRAY: 1315bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_FRONT: 1316bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_BACK: 1317bf215546Sopenharmony_ci case STATE_LIGHTPROD_ARRAY_TWOSIDE: 1318bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_ARRAY: 1319bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED_ARRAY: 1320bf215546Sopenharmony_ci sprintf(tmp, "[%d..%d]", state[1], state[1] + state[2] - 1); 1321bf215546Sopenharmony_ci append(str, tmp); 1322bf215546Sopenharmony_ci break; 1323bf215546Sopenharmony_ci case STATE_MATERIAL: 1324bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV: 1325bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL: 1326bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV: 1327bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL: 1328bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB: 1329bf215546Sopenharmony_ci case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 1330bf215546Sopenharmony_ci case STATE_LIGHT_SPOT_DIR_NORMALIZED: 1331bf215546Sopenharmony_ci case STATE_LIGHT_POSITION: 1332bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED: 1333bf215546Sopenharmony_ci case STATE_LIGHT_HALF_VECTOR: 1334bf215546Sopenharmony_ci case STATE_CLIP_INTERNAL: 1335bf215546Sopenharmony_ci case STATE_ATOMIC_COUNTER_OFFSET: 1336bf215546Sopenharmony_ci append_index(str, state[1], false); 1337bf215546Sopenharmony_ci break; 1338bf215546Sopenharmony_ci case STATE_POINT_SIZE: 1339bf215546Sopenharmony_ci case STATE_POINT_ATTENUATION: 1340bf215546Sopenharmony_ci case STATE_FOG_PARAMS: 1341bf215546Sopenharmony_ci case STATE_FOG_COLOR: 1342bf215546Sopenharmony_ci case STATE_NUM_SAMPLES: 1343bf215546Sopenharmony_ci case STATE_DEPTH_RANGE: 1344bf215546Sopenharmony_ci case STATE_NORMAL_SCALE_EYESPACE: 1345bf215546Sopenharmony_ci case STATE_NORMAL_SCALE: 1346bf215546Sopenharmony_ci case STATE_FOG_PARAMS_OPTIMIZED: 1347bf215546Sopenharmony_ci case STATE_POINT_SIZE_CLAMPED: 1348bf215546Sopenharmony_ci case STATE_PT_SCALE: 1349bf215546Sopenharmony_ci case STATE_PT_BIAS: 1350bf215546Sopenharmony_ci case STATE_FB_SIZE: 1351bf215546Sopenharmony_ci case STATE_FB_WPOS_Y_TRANSFORM: 1352bf215546Sopenharmony_ci case STATE_FB_PNTC_Y_TRANSFORM: 1353bf215546Sopenharmony_ci case STATE_TCS_PATCH_VERTICES_IN: 1354bf215546Sopenharmony_ci case STATE_TES_PATCH_VERTICES_IN: 1355bf215546Sopenharmony_ci case STATE_ADVANCED_BLENDING_MODE: 1356bf215546Sopenharmony_ci case STATE_ALPHA_REF: 1357bf215546Sopenharmony_ci break; 1358bf215546Sopenharmony_ci case STATE_NOT_STATE_VAR: 1359bf215546Sopenharmony_ci append(str, "not_state"); 1360bf215546Sopenharmony_ci break; 1361bf215546Sopenharmony_ci default: 1362bf215546Sopenharmony_ci _mesa_problem(NULL, "Invalid state in _mesa_program_state_string: %d", state[0]); 1363bf215546Sopenharmony_ci break; 1364bf215546Sopenharmony_ci } 1365bf215546Sopenharmony_ci 1366bf215546Sopenharmony_ci return strdup(str); 1367bf215546Sopenharmony_ci} 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ci 1370bf215546Sopenharmony_ci/** 1371bf215546Sopenharmony_ci * Loop over all the parameters in a parameter list. If the parameter 1372bf215546Sopenharmony_ci * is a GL state reference, look up the current value of that state 1373bf215546Sopenharmony_ci * variable and put it into the parameter's Value[4] array. 1374bf215546Sopenharmony_ci * Other parameter types never change or are explicitly set by the user 1375bf215546Sopenharmony_ci * with glUniform() or glProgramParameter(), etc. 1376bf215546Sopenharmony_ci * This would be called at glBegin time. 1377bf215546Sopenharmony_ci */ 1378bf215546Sopenharmony_civoid 1379bf215546Sopenharmony_ci_mesa_load_state_parameters(struct gl_context *ctx, 1380bf215546Sopenharmony_ci struct gl_program_parameter_list *paramList) 1381bf215546Sopenharmony_ci{ 1382bf215546Sopenharmony_ci if (!paramList) 1383bf215546Sopenharmony_ci return; 1384bf215546Sopenharmony_ci 1385bf215546Sopenharmony_ci int last = paramList->LastStateVarIndex; 1386bf215546Sopenharmony_ci 1387bf215546Sopenharmony_ci for (int i = paramList->FirstStateVarIndex; i <= last; i++) { 1388bf215546Sopenharmony_ci unsigned pvo = paramList->Parameters[i].ValueOffset; 1389bf215546Sopenharmony_ci fetch_state(ctx, paramList->Parameters[i].StateIndexes, 1390bf215546Sopenharmony_ci paramList->ParameterValues + pvo); 1391bf215546Sopenharmony_ci } 1392bf215546Sopenharmony_ci} 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_civoid 1395bf215546Sopenharmony_ci_mesa_upload_state_parameters(struct gl_context *ctx, 1396bf215546Sopenharmony_ci struct gl_program_parameter_list *paramList, 1397bf215546Sopenharmony_ci uint32_t *dst) 1398bf215546Sopenharmony_ci{ 1399bf215546Sopenharmony_ci int last = paramList->LastStateVarIndex; 1400bf215546Sopenharmony_ci 1401bf215546Sopenharmony_ci for (int i = paramList->FirstStateVarIndex; i <= last; i++) { 1402bf215546Sopenharmony_ci unsigned pvo = paramList->Parameters[i].ValueOffset; 1403bf215546Sopenharmony_ci fetch_state(ctx, paramList->Parameters[i].StateIndexes, 1404bf215546Sopenharmony_ci (gl_constant_value*)(dst + pvo)); 1405bf215546Sopenharmony_ci } 1406bf215546Sopenharmony_ci} 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci/* Merge consecutive state vars into one for the state vars that allow 1409bf215546Sopenharmony_ci * multiple vec4s. 1410bf215546Sopenharmony_ci * 1411bf215546Sopenharmony_ci * This should be done after shader compilation, so that drivers don't 1412bf215546Sopenharmony_ci * have to deal with multi-slot state parameters in their backends. 1413bf215546Sopenharmony_ci * It's only meant to optimize _mesa_load/upload_state_parameters. 1414bf215546Sopenharmony_ci */ 1415bf215546Sopenharmony_civoid 1416bf215546Sopenharmony_ci_mesa_optimize_state_parameters(struct gl_constants *consts, 1417bf215546Sopenharmony_ci struct gl_program_parameter_list *list) 1418bf215546Sopenharmony_ci{ 1419bf215546Sopenharmony_ci for (int first_param = list->FirstStateVarIndex; 1420bf215546Sopenharmony_ci first_param < (int)list->NumParameters; first_param++) { 1421bf215546Sopenharmony_ci int last_param = first_param; 1422bf215546Sopenharmony_ci int param_diff = 0; 1423bf215546Sopenharmony_ci 1424bf215546Sopenharmony_ci switch (list->Parameters[first_param].StateIndexes[0]) { 1425bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX: 1426bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVERSE: 1427bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_TRANSPOSE: 1428bf215546Sopenharmony_ci case STATE_MODELVIEW_MATRIX_INVTRANS: 1429bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX: 1430bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVERSE: 1431bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_TRANSPOSE: 1432bf215546Sopenharmony_ci case STATE_PROJECTION_MATRIX_INVTRANS: 1433bf215546Sopenharmony_ci case STATE_MVP_MATRIX: 1434bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVERSE: 1435bf215546Sopenharmony_ci case STATE_MVP_MATRIX_TRANSPOSE: 1436bf215546Sopenharmony_ci case STATE_MVP_MATRIX_INVTRANS: 1437bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX: 1438bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVERSE: 1439bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_TRANSPOSE: 1440bf215546Sopenharmony_ci case STATE_TEXTURE_MATRIX_INVTRANS: 1441bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX: 1442bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVERSE: 1443bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_TRANSPOSE: 1444bf215546Sopenharmony_ci case STATE_PROGRAM_MATRIX_INVTRANS: 1445bf215546Sopenharmony_ci /* Skip unaligned state vars. */ 1446bf215546Sopenharmony_ci if (list->Parameters[first_param].Size % 4) 1447bf215546Sopenharmony_ci break; 1448bf215546Sopenharmony_ci 1449bf215546Sopenharmony_ci /* Search for adjacent state vars that refer to adjacent rows. */ 1450bf215546Sopenharmony_ci for (int i = first_param + 1; i < (int)list->NumParameters; i++) { 1451bf215546Sopenharmony_ci if (list->Parameters[i].StateIndexes[0] == 1452bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[0] && 1453bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[1] == 1454bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[1] && 1455bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[2] == /* FirstRow */ 1456bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[3] + 1 && /* LastRow + 1 */ 1457bf215546Sopenharmony_ci list->Parameters[i].Size == 4) { 1458bf215546Sopenharmony_ci last_param = i; 1459bf215546Sopenharmony_ci continue; 1460bf215546Sopenharmony_ci } 1461bf215546Sopenharmony_ci break; /* The adjacent state var is incompatible. */ 1462bf215546Sopenharmony_ci } 1463bf215546Sopenharmony_ci if (last_param > first_param) { 1464bf215546Sopenharmony_ci int first_vec = list->Parameters[first_param].StateIndexes[2]; 1465bf215546Sopenharmony_ci int last_vec = list->Parameters[last_param].StateIndexes[3]; 1466bf215546Sopenharmony_ci 1467bf215546Sopenharmony_ci assert(first_vec < last_vec); 1468bf215546Sopenharmony_ci assert(last_vec - first_vec == last_param - first_param); 1469bf215546Sopenharmony_ci 1470bf215546Sopenharmony_ci /* Update LastRow. */ 1471bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[3] = last_vec; 1472bf215546Sopenharmony_ci list->Parameters[first_param].Size = (last_vec - first_vec + 1) * 4; 1473bf215546Sopenharmony_ci 1474bf215546Sopenharmony_ci param_diff = last_param - first_param; 1475bf215546Sopenharmony_ci } 1476bf215546Sopenharmony_ci break; 1477bf215546Sopenharmony_ci 1478bf215546Sopenharmony_ci case STATE_LIGHT: 1479bf215546Sopenharmony_ci /* Skip trimmed state vars. (this shouldn't occur though) */ 1480bf215546Sopenharmony_ci if (list->Parameters[first_param].Size != 1481bf215546Sopenharmony_ci _mesa_program_state_value_size(list->Parameters[first_param].StateIndexes)) 1482bf215546Sopenharmony_ci break; 1483bf215546Sopenharmony_ci 1484bf215546Sopenharmony_ci /* Search for light attributes that are adjacent in memory. */ 1485bf215546Sopenharmony_ci for (int i = first_param + 1; i < (int)list->NumParameters; i++) { 1486bf215546Sopenharmony_ci if (list->Parameters[i].StateIndexes[0] == STATE_LIGHT && 1487bf215546Sopenharmony_ci /* Consecutive attributes of the same light: */ 1488bf215546Sopenharmony_ci ((list->Parameters[i].StateIndexes[1] == 1489bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[1] && 1490bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[2] == 1491bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[2] + 1) || 1492bf215546Sopenharmony_ci /* Consecutive attributes between 2 lights: */ 1493bf215546Sopenharmony_ci /* SPOT_CUTOFF should have only 1 component, which isn't true 1494bf215546Sopenharmony_ci * with unpacked uniform storage. */ 1495bf215546Sopenharmony_ci (consts->PackedDriverUniformStorage && 1496bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[1] == 1497bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[1] + 1 && 1498bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[2] == STATE_AMBIENT && 1499bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[2] == STATE_SPOT_CUTOFF))) { 1500bf215546Sopenharmony_ci last_param = i; 1501bf215546Sopenharmony_ci continue; 1502bf215546Sopenharmony_ci } 1503bf215546Sopenharmony_ci break; /* The adjacent state var is incompatible. */ 1504bf215546Sopenharmony_ci } 1505bf215546Sopenharmony_ci if (last_param > first_param) { 1506bf215546Sopenharmony_ci /* Convert the state var to STATE_LIGHT_ARRAY. */ 1507bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[0] = STATE_LIGHT_ARRAY; 1508bf215546Sopenharmony_ci /* Set the offset in floats. */ 1509bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[1] = 1510bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[1] * /* light index */ 1511bf215546Sopenharmony_ci sizeof(struct gl_light_uniforms) / 4 + 1512bf215546Sopenharmony_ci (list->Parameters[first_param].StateIndexes[2] - STATE_AMBIENT) * 4; 1513bf215546Sopenharmony_ci 1514bf215546Sopenharmony_ci /* Set the real size in floats that we will upload (memcpy). */ 1515bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[2] = 1516bf215546Sopenharmony_ci _mesa_program_state_value_size(list->Parameters[last_param].StateIndexes) + 1517bf215546Sopenharmony_ci list->Parameters[last_param].ValueOffset - 1518bf215546Sopenharmony_ci list->Parameters[first_param].ValueOffset; 1519bf215546Sopenharmony_ci 1520bf215546Sopenharmony_ci /* Set the allocated size, which can be aligned to 4 components. */ 1521bf215546Sopenharmony_ci list->Parameters[first_param].Size = 1522bf215546Sopenharmony_ci list->Parameters[last_param].Size + 1523bf215546Sopenharmony_ci list->Parameters[last_param].ValueOffset - 1524bf215546Sopenharmony_ci list->Parameters[first_param].ValueOffset; 1525bf215546Sopenharmony_ci 1526bf215546Sopenharmony_ci param_diff = last_param - first_param; 1527bf215546Sopenharmony_ci break; /* all done */ 1528bf215546Sopenharmony_ci } 1529bf215546Sopenharmony_ci 1530bf215546Sopenharmony_ci /* We were not able to convert light attributes to STATE_LIGHT_ARRAY. 1531bf215546Sopenharmony_ci * Another occuring pattern is light attentuation vectors placed back 1532bf215546Sopenharmony_ci * to back. Find them. 1533bf215546Sopenharmony_ci */ 1534bf215546Sopenharmony_ci if (list->Parameters[first_param].StateIndexes[2] == STATE_ATTENUATION) { 1535bf215546Sopenharmony_ci for (int i = first_param + 1; i < (int)list->NumParameters; i++) { 1536bf215546Sopenharmony_ci if (list->Parameters[i].StateIndexes[0] == STATE_LIGHT && 1537bf215546Sopenharmony_ci /* Consecutive light: */ 1538bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[1] == 1539bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[1] + 1 && 1540bf215546Sopenharmony_ci /* Same attribute: */ 1541bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[2] == 1542bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[2]) { 1543bf215546Sopenharmony_ci last_param = i; 1544bf215546Sopenharmony_ci continue; 1545bf215546Sopenharmony_ci } 1546bf215546Sopenharmony_ci break; /* The adjacent state var is incompatible. */ 1547bf215546Sopenharmony_ci } 1548bf215546Sopenharmony_ci if (last_param > first_param) { 1549bf215546Sopenharmony_ci param_diff = last_param - first_param; 1550bf215546Sopenharmony_ci 1551bf215546Sopenharmony_ci /* Convert the state var to STATE_LIGHT_ATTENUATION_ARRAY. */ 1552bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[0] = 1553bf215546Sopenharmony_ci STATE_LIGHT_ATTENUATION_ARRAY; 1554bf215546Sopenharmony_ci /* Keep the light index the same. */ 1555bf215546Sopenharmony_ci /* Set the number of lights. */ 1556bf215546Sopenharmony_ci unsigned size = param_diff + 1; 1557bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[2] = size; 1558bf215546Sopenharmony_ci list->Parameters[first_param].Size = size * 4; 1559bf215546Sopenharmony_ci break; /* all done */ 1560bf215546Sopenharmony_ci } 1561bf215546Sopenharmony_ci } 1562bf215546Sopenharmony_ci break; 1563bf215546Sopenharmony_ci 1564bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_ENV: 1565bf215546Sopenharmony_ci case STATE_VERTEX_PROGRAM_LOCAL: 1566bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_ENV: 1567bf215546Sopenharmony_ci case STATE_FRAGMENT_PROGRAM_LOCAL: 1568bf215546Sopenharmony_ci if (list->Parameters[first_param].Size != 4) 1569bf215546Sopenharmony_ci break; 1570bf215546Sopenharmony_ci 1571bf215546Sopenharmony_ci /* Search for adjacent mergeable state vars. */ 1572bf215546Sopenharmony_ci for (int i = first_param + 1; i < (int)list->NumParameters; i++) { 1573bf215546Sopenharmony_ci if (list->Parameters[i].StateIndexes[0] == 1574bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[0] && 1575bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[1] == 1576bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[1] + 1 && 1577bf215546Sopenharmony_ci list->Parameters[i].Size == 4) { 1578bf215546Sopenharmony_ci last_param = i; 1579bf215546Sopenharmony_ci continue; 1580bf215546Sopenharmony_ci } 1581bf215546Sopenharmony_ci break; /* The adjacent state var is incompatible. */ 1582bf215546Sopenharmony_ci } 1583bf215546Sopenharmony_ci if (last_param > first_param) { 1584bf215546Sopenharmony_ci /* Set STATE_xxx_RANGE. */ 1585bf215546Sopenharmony_ci STATIC_ASSERT(STATE_VERTEX_PROGRAM_ENV + 1 == 1586bf215546Sopenharmony_ci STATE_VERTEX_PROGRAM_ENV_ARRAY); 1587bf215546Sopenharmony_ci STATIC_ASSERT(STATE_VERTEX_PROGRAM_LOCAL + 1 == 1588bf215546Sopenharmony_ci STATE_VERTEX_PROGRAM_LOCAL_ARRAY); 1589bf215546Sopenharmony_ci STATIC_ASSERT(STATE_FRAGMENT_PROGRAM_ENV + 1 == 1590bf215546Sopenharmony_ci STATE_FRAGMENT_PROGRAM_ENV_ARRAY); 1591bf215546Sopenharmony_ci STATIC_ASSERT(STATE_FRAGMENT_PROGRAM_LOCAL + 1 == 1592bf215546Sopenharmony_ci STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY); 1593bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[0]++; 1594bf215546Sopenharmony_ci 1595bf215546Sopenharmony_ci param_diff = last_param - first_param; 1596bf215546Sopenharmony_ci 1597bf215546Sopenharmony_ci /* Set the size. */ 1598bf215546Sopenharmony_ci unsigned size = param_diff + 1; 1599bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[2] = size; 1600bf215546Sopenharmony_ci list->Parameters[first_param].Size = size * 4; 1601bf215546Sopenharmony_ci } 1602bf215546Sopenharmony_ci break; 1603bf215546Sopenharmony_ci 1604bf215546Sopenharmony_ci case STATE_LIGHTPROD: { 1605bf215546Sopenharmony_ci if (list->Parameters[first_param].Size != 4) 1606bf215546Sopenharmony_ci break; 1607bf215546Sopenharmony_ci 1608bf215546Sopenharmony_ci gl_state_index16 state = STATE_NOT_STATE_VAR; 1609bf215546Sopenharmony_ci unsigned num_lights = 0; 1610bf215546Sopenharmony_ci 1611bf215546Sopenharmony_ci for (unsigned state_iter = STATE_LIGHTPROD_ARRAY_FRONT; 1612bf215546Sopenharmony_ci state_iter <= STATE_LIGHTPROD_ARRAY_TWOSIDE; state_iter++) { 1613bf215546Sopenharmony_ci unsigned num_attribs, base_attrib, attrib_incr; 1614bf215546Sopenharmony_ci 1615bf215546Sopenharmony_ci if (state_iter == STATE_LIGHTPROD_ARRAY_FRONT) { 1616bf215546Sopenharmony_ci num_attribs = 3; 1617bf215546Sopenharmony_ci base_attrib = MAT_ATTRIB_FRONT_AMBIENT; 1618bf215546Sopenharmony_ci attrib_incr = 2; 1619bf215546Sopenharmony_ci } else if (state_iter == STATE_LIGHTPROD_ARRAY_BACK) { 1620bf215546Sopenharmony_ci num_attribs = 3; 1621bf215546Sopenharmony_ci base_attrib = MAT_ATTRIB_BACK_AMBIENT; 1622bf215546Sopenharmony_ci attrib_incr = 2; 1623bf215546Sopenharmony_ci } else if (state_iter == STATE_LIGHTPROD_ARRAY_TWOSIDE) { 1624bf215546Sopenharmony_ci num_attribs = 6; 1625bf215546Sopenharmony_ci base_attrib = MAT_ATTRIB_FRONT_AMBIENT; 1626bf215546Sopenharmony_ci attrib_incr = 1; 1627bf215546Sopenharmony_ci } 1628bf215546Sopenharmony_ci 1629bf215546Sopenharmony_ci /* Find all attributes for one light. */ 1630bf215546Sopenharmony_ci while (first_param + (num_lights + 1) * num_attribs <= 1631bf215546Sopenharmony_ci list->NumParameters && 1632bf215546Sopenharmony_ci (state == STATE_NOT_STATE_VAR || state == state_iter)) { 1633bf215546Sopenharmony_ci unsigned i = 0, base = first_param + num_lights * num_attribs; 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ci /* Consecutive light indices: */ 1636bf215546Sopenharmony_ci if (list->Parameters[first_param].StateIndexes[1] + num_lights == 1637bf215546Sopenharmony_ci list->Parameters[base].StateIndexes[1]) { 1638bf215546Sopenharmony_ci for (i = 0; i < num_attribs; i++) { 1639bf215546Sopenharmony_ci if (list->Parameters[base + i].StateIndexes[0] == 1640bf215546Sopenharmony_ci STATE_LIGHTPROD && 1641bf215546Sopenharmony_ci list->Parameters[base + i].Size == 4 && 1642bf215546Sopenharmony_ci /* Equal light indices: */ 1643bf215546Sopenharmony_ci list->Parameters[base + i].StateIndexes[1] == 1644bf215546Sopenharmony_ci list->Parameters[base + 0].StateIndexes[1] && 1645bf215546Sopenharmony_ci /* Consecutive attributes: */ 1646bf215546Sopenharmony_ci list->Parameters[base + i].StateIndexes[2] == 1647bf215546Sopenharmony_ci base_attrib + i * attrib_incr) 1648bf215546Sopenharmony_ci continue; 1649bf215546Sopenharmony_ci break; 1650bf215546Sopenharmony_ci } 1651bf215546Sopenharmony_ci } 1652bf215546Sopenharmony_ci if (i == num_attribs) { 1653bf215546Sopenharmony_ci /* Accept all parameters for merging. */ 1654bf215546Sopenharmony_ci state = state_iter; 1655bf215546Sopenharmony_ci last_param = base + num_attribs - 1; 1656bf215546Sopenharmony_ci num_lights++; 1657bf215546Sopenharmony_ci } else { 1658bf215546Sopenharmony_ci break; 1659bf215546Sopenharmony_ci } 1660bf215546Sopenharmony_ci } 1661bf215546Sopenharmony_ci } 1662bf215546Sopenharmony_ci 1663bf215546Sopenharmony_ci if (last_param > first_param) { 1664bf215546Sopenharmony_ci param_diff = last_param - first_param; 1665bf215546Sopenharmony_ci 1666bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[0] = state; 1667bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[2] = num_lights; 1668bf215546Sopenharmony_ci list->Parameters[first_param].Size = (param_diff + 1) * 4; 1669bf215546Sopenharmony_ci } 1670bf215546Sopenharmony_ci break; 1671bf215546Sopenharmony_ci } 1672bf215546Sopenharmony_ci 1673bf215546Sopenharmony_ci case STATE_LIGHT_POSITION: 1674bf215546Sopenharmony_ci case STATE_LIGHT_POSITION_NORMALIZED: 1675bf215546Sopenharmony_ci if (list->Parameters[first_param].Size != 4) 1676bf215546Sopenharmony_ci break; 1677bf215546Sopenharmony_ci 1678bf215546Sopenharmony_ci for (int i = first_param + 1; i < (int)list->NumParameters; i++) { 1679bf215546Sopenharmony_ci if (list->Parameters[i].StateIndexes[0] == 1680bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[0] && 1681bf215546Sopenharmony_ci /* Consecutive light: */ 1682bf215546Sopenharmony_ci list->Parameters[i].StateIndexes[1] == 1683bf215546Sopenharmony_ci list->Parameters[i - 1].StateIndexes[1] + 1) { 1684bf215546Sopenharmony_ci last_param = i; 1685bf215546Sopenharmony_ci continue; 1686bf215546Sopenharmony_ci } 1687bf215546Sopenharmony_ci break; /* The adjacent state var is incompatible. */ 1688bf215546Sopenharmony_ci } 1689bf215546Sopenharmony_ci if (last_param > first_param) { 1690bf215546Sopenharmony_ci param_diff = last_param - first_param; 1691bf215546Sopenharmony_ci 1692bf215546Sopenharmony_ci /* Convert the state var to STATE_LIGHT_POSITION_*ARRAY. */ 1693bf215546Sopenharmony_ci STATIC_ASSERT(STATE_LIGHT_POSITION + 1 == 1694bf215546Sopenharmony_ci STATE_LIGHT_POSITION_ARRAY); 1695bf215546Sopenharmony_ci STATIC_ASSERT(STATE_LIGHT_POSITION_NORMALIZED + 1 == 1696bf215546Sopenharmony_ci STATE_LIGHT_POSITION_NORMALIZED_ARRAY); 1697bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[0]++; 1698bf215546Sopenharmony_ci /* Keep the light index the same. */ 1699bf215546Sopenharmony_ci unsigned size = param_diff + 1; 1700bf215546Sopenharmony_ci /* Set the number of lights. */ 1701bf215546Sopenharmony_ci list->Parameters[first_param].StateIndexes[2] = size; 1702bf215546Sopenharmony_ci list->Parameters[first_param].Size = size * 4; 1703bf215546Sopenharmony_ci } 1704bf215546Sopenharmony_ci } 1705bf215546Sopenharmony_ci 1706bf215546Sopenharmony_ci if (param_diff) { 1707bf215546Sopenharmony_ci /* Update the name. */ 1708bf215546Sopenharmony_ci free((void*)list->Parameters[first_param].Name); 1709bf215546Sopenharmony_ci list->Parameters[first_param].Name = 1710bf215546Sopenharmony_ci _mesa_program_state_string(list->Parameters[first_param].StateIndexes); 1711bf215546Sopenharmony_ci 1712bf215546Sopenharmony_ci /* Free names that we are going to overwrite. */ 1713bf215546Sopenharmony_ci for (int i = first_param + 1; i <= last_param; i++) 1714bf215546Sopenharmony_ci free((char*)list->Parameters[i].Name); 1715bf215546Sopenharmony_ci 1716bf215546Sopenharmony_ci /* Remove the merged state vars. */ 1717bf215546Sopenharmony_ci if (last_param + 1 < list->NumParameters) { 1718bf215546Sopenharmony_ci memmove(&list->Parameters[first_param + 1], 1719bf215546Sopenharmony_ci &list->Parameters[last_param + 1], 1720bf215546Sopenharmony_ci sizeof(list->Parameters[0]) * 1721bf215546Sopenharmony_ci (list->NumParameters - last_param - 1)); 1722bf215546Sopenharmony_ci } 1723bf215546Sopenharmony_ci list->NumParameters -= param_diff; 1724bf215546Sopenharmony_ci } 1725bf215546Sopenharmony_ci } 1726bf215546Sopenharmony_ci 1727bf215546Sopenharmony_ci _mesa_recompute_parameter_bounds(list); 1728bf215546Sopenharmony_ci} 1729