mesa: flatten STATE_MATERIAL and STATE_LIGHTPROD tokens
Flattening continue to get optimal code in fetch_state. This merges the "face" field with the "attrib" field using the combined MAT_ATTRIB_* enums. The outcome is that the inner switch statements can be flatten because we can use MAT_ATTRIB_* to index into the attrib array directly. With LightSource attributes that don't have two sides, more math is involved to get the correct index but it works out nicely too. Reviewed-by: Eric Anholt <eric@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8183>
This commit is contained in:
@@ -74,19 +74,19 @@ static const struct gl_builtin_uniform_element gl_Point_elements[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
|
static const struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
|
||||||
{"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
|
{"emission", {STATE_MATERIAL, MAT_ATTRIB_FRONT_EMISSION}, SWIZZLE_XYZW},
|
||||||
{"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
|
{"ambient", {STATE_MATERIAL, MAT_ATTRIB_FRONT_AMBIENT}, SWIZZLE_XYZW},
|
||||||
{"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
{"diffuse", {STATE_MATERIAL, MAT_ATTRIB_FRONT_DIFFUSE}, SWIZZLE_XYZW},
|
||||||
{"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
|
{"specular", {STATE_MATERIAL, MAT_ATTRIB_FRONT_SPECULAR}, SWIZZLE_XYZW},
|
||||||
{"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
|
{"shininess", {STATE_MATERIAL, MAT_ATTRIB_FRONT_SHININESS}, SWIZZLE_XXXX},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
|
static const struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
|
||||||
{"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
|
{"emission", {STATE_MATERIAL, MAT_ATTRIB_BACK_EMISSION}, SWIZZLE_XYZW},
|
||||||
{"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
|
{"ambient", {STATE_MATERIAL, MAT_ATTRIB_BACK_AMBIENT}, SWIZZLE_XYZW},
|
||||||
{"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
{"diffuse", {STATE_MATERIAL, MAT_ATTRIB_BACK_DIFFUSE}, SWIZZLE_XYZW},
|
||||||
{"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
|
{"specular", {STATE_MATERIAL, MAT_ATTRIB_BACK_SPECULAR}, SWIZZLE_XYZW},
|
||||||
{"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
|
{"shininess", {STATE_MATERIAL, MAT_ATTRIB_BACK_SHININESS}, SWIZZLE_XXXX},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct gl_builtin_uniform_element gl_LightSource_elements[] = {
|
static const struct gl_builtin_uniform_element gl_LightSource_elements[] = {
|
||||||
@@ -121,15 +121,15 @@ static const struct gl_builtin_uniform_element gl_BackLightModelProduct_elements
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
|
static const struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
|
||||||
{"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
|
{"ambient", {STATE_LIGHTPROD, 0, MAT_ATTRIB_FRONT_AMBIENT}, SWIZZLE_XYZW},
|
||||||
{"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
{"diffuse", {STATE_LIGHTPROD, 0, MAT_ATTRIB_FRONT_DIFFUSE}, SWIZZLE_XYZW},
|
||||||
{"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
|
{"specular", {STATE_LIGHTPROD, 0, MAT_ATTRIB_FRONT_SPECULAR}, SWIZZLE_XYZW},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
|
static const struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
|
||||||
{"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
|
{"ambient", {STATE_LIGHTPROD, 0, MAT_ATTRIB_BACK_AMBIENT}, SWIZZLE_XYZW},
|
||||||
{"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
{"diffuse", {STATE_LIGHTPROD, 0, MAT_ATTRIB_BACK_DIFFUSE}, SWIZZLE_XYZW},
|
||||||
{"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
|
{"specular", {STATE_LIGHTPROD, 0, MAT_ATTRIB_BACK_SPECULAR}, SWIZZLE_XYZW},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
|
static const struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
|
||||||
|
@@ -881,7 +881,7 @@ static struct ureg get_material( struct tnl_program *p, GLuint side,
|
|||||||
return register_input( p, VERT_ATTRIB_MAT(attrib) );
|
return register_input( p, VERT_ATTRIB_MAT(attrib) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return register_param3( p, STATE_MATERIAL, side, property );
|
return register_param2(p, STATE_MATERIAL, attrib);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SCENE_COLOR_BITS(side) (( MAT_BIT_FRONT_EMISSION | \
|
#define SCENE_COLOR_BITS(side) (( MAT_BIT_FRONT_EMISSION | \
|
||||||
@@ -930,7 +930,7 @@ static struct ureg get_lightprod( struct tnl_program *p, GLuint light,
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return register_param4(p, STATE_LIGHTPROD, light, side, property);
|
return register_param3(p, STATE_LIGHTPROD, light, attrib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "main/glheader.h"
|
#include "main/glheader.h"
|
||||||
#include "main/context.h"
|
#include "main/context.h"
|
||||||
#include "main/blend.h"
|
#include "main/blend.h"
|
||||||
@@ -87,39 +88,20 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
|
|||||||
switch (state[0]) {
|
switch (state[0]) {
|
||||||
case STATE_MATERIAL:
|
case STATE_MATERIAL:
|
||||||
{
|
{
|
||||||
/* state[1] is either 0=front or 1=back side */
|
/* state[1] is MAT_ATTRIB_FRONT_* */
|
||||||
const GLuint face = (GLuint) state[1];
|
const GLuint index = (GLuint) state[1];
|
||||||
const struct gl_material *mat = &ctx->Light.Material;
|
const struct gl_material *mat = &ctx->Light.Material;
|
||||||
assert(face == 0 || face == 1);
|
assert(index >= MAT_ATTRIB_FRONT_AMBIENT &&
|
||||||
/* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
|
index <= MAT_ATTRIB_BACK_SHININESS);
|
||||||
assert(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
|
if (index >= MAT_ATTRIB_FRONT_SHININESS) {
|
||||||
/* XXX we could get rid of this switch entirely with a little
|
value[0] = mat->Attrib[index][0];
|
||||||
* work in arbprogparse.c's parse_state_single_item().
|
|
||||||
*/
|
|
||||||
/* state[2] is the material attribute */
|
|
||||||
switch (state[2]) {
|
|
||||||
case STATE_AMBIENT:
|
|
||||||
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
|
|
||||||
return;
|
|
||||||
case STATE_DIFFUSE:
|
|
||||||
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
|
|
||||||
return;
|
|
||||||
case STATE_SPECULAR:
|
|
||||||
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
|
|
||||||
return;
|
|
||||||
case STATE_EMISSION:
|
|
||||||
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
|
|
||||||
return;
|
|
||||||
case STATE_SHININESS:
|
|
||||||
value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
|
|
||||||
value[1] = 0.0F;
|
value[1] = 0.0F;
|
||||||
value[2] = 0.0F;
|
value[2] = 0.0F;
|
||||||
value[3] = 1.0F;
|
value[3] = 1.0F;
|
||||||
return;
|
} else {
|
||||||
default:
|
COPY_4V(value, mat->Attrib[index]);
|
||||||
unreachable("Invalid material state in fetch_state");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case STATE_LIGHT:
|
case STATE_LIGHT:
|
||||||
{
|
{
|
||||||
@@ -175,38 +157,26 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
|
|||||||
case STATE_LIGHTPROD:
|
case STATE_LIGHTPROD:
|
||||||
{
|
{
|
||||||
const GLuint ln = (GLuint) state[1];
|
const GLuint ln = (GLuint) state[1];
|
||||||
const GLuint face = (GLuint) state[2];
|
const GLuint index = (GLuint) state[2];
|
||||||
GLint i;
|
const GLuint attr = (index / 2) * 4;
|
||||||
assert(face == 0 || face == 1);
|
assert(index >= MAT_ATTRIB_FRONT_AMBIENT &&
|
||||||
switch (state[3]) {
|
index <= MAT_ATTRIB_BACK_SPECULAR);
|
||||||
case STATE_AMBIENT:
|
for (int i = 0; i < 3; i++) {
|
||||||
for (i = 0; i < 3; i++) {
|
/* We want attr to access out of bounds into the following Diffuse
|
||||||
value[i] = ctx->Light.LightSource[ln].Ambient[i] *
|
* and Specular fields. This is guaranteed to work because
|
||||||
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
|
* STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely on this memory
|
||||||
}
|
* layout.
|
||||||
/* [3] = material alpha */
|
*/
|
||||||
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];
|
STATIC_ASSERT(offsetof(struct gl_light_uniforms, Ambient) + 16 ==
|
||||||
return;
|
offsetof(struct gl_light_uniforms, Diffuse));
|
||||||
case STATE_DIFFUSE:
|
STATIC_ASSERT(offsetof(struct gl_light_uniforms, Diffuse) + 16 ==
|
||||||
for (i = 0; i < 3; i++) {
|
offsetof(struct gl_light_uniforms, Specular));
|
||||||
value[i] = ctx->Light.LightSource[ln].Diffuse[i] *
|
value[i] = ctx->Light.LightSource[ln].Ambient[attr + i] *
|
||||||
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
|
ctx->Light.Material.Attrib[index][i];
|
||||||
}
|
|
||||||
/* [3] = material alpha */
|
|
||||||
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
|
|
||||||
return;
|
|
||||||
case STATE_SPECULAR:
|
|
||||||
for (i = 0; i < 3; i++) {
|
|
||||||
value[i] = ctx->Light.LightSource[ln].Specular[i] *
|
|
||||||
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
|
|
||||||
}
|
|
||||||
/* [3] = material alpha */
|
|
||||||
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
unreachable("Invalid lightprod state in fetch_state");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
/* [3] = material alpha */
|
||||||
|
value[3] = ctx->Light.Material.Attrib[index][3];
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case STATE_TEXGEN:
|
case STATE_TEXGEN:
|
||||||
{
|
{
|
||||||
@@ -835,7 +805,7 @@ append_token(char *dst, gl_state_index k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case STATE_MATERIAL:
|
case STATE_MATERIAL:
|
||||||
append(dst, "material.");
|
append(dst, "material");
|
||||||
break;
|
break;
|
||||||
case STATE_LIGHT:
|
case STATE_LIGHT:
|
||||||
append(dst, "light");
|
append(dst, "light");
|
||||||
@@ -1061,15 +1031,6 @@ append_token(char *dst, gl_state_index k)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
append_face(char *dst, GLint face)
|
|
||||||
{
|
|
||||||
if (face == 0)
|
|
||||||
append(dst, "front.");
|
|
||||||
else
|
|
||||||
append(dst, "back.");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_index(char *dst, GLint index, bool structure)
|
append_index(char *dst, GLint index, bool structure)
|
||||||
{
|
{
|
||||||
@@ -1094,8 +1055,7 @@ _mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH])
|
|||||||
|
|
||||||
switch (state[0]) {
|
switch (state[0]) {
|
||||||
case STATE_MATERIAL:
|
case STATE_MATERIAL:
|
||||||
append_face(str, state[1]);
|
append_index(str, state[1], false);
|
||||||
append_token(str, state[2]);
|
|
||||||
break;
|
break;
|
||||||
case STATE_LIGHT:
|
case STATE_LIGHT:
|
||||||
append_index(str, state[1], true); /* light number [i]. */
|
append_index(str, state[1], true); /* light number [i]. */
|
||||||
@@ -1116,9 +1076,8 @@ _mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_LIGHTPROD:
|
case STATE_LIGHTPROD:
|
||||||
append_index(str, state[1], true); /* light number [i]. */
|
append_index(str, state[1], false); /* light number [i] */
|
||||||
append_face(str, state[2]);
|
append_index(str, state[2], false);
|
||||||
append_token(str, state[3]);
|
|
||||||
break;
|
break;
|
||||||
case STATE_TEXGEN:
|
case STATE_TEXGEN:
|
||||||
append_index(str, state[1], true); /* tex unit [i] */
|
append_index(str, state[1], true); /* tex unit [i] */
|
||||||
|
@@ -260,7 +260,8 @@ static struct asm_instruction *asm_instruction_copy_ctor(
|
|||||||
%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
|
%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
|
||||||
%type <integer> stateProgramMatNum
|
%type <integer> stateProgramMatNum
|
||||||
|
|
||||||
%type <integer> ambDiffSpecProperty
|
%type <integer> ambDiffSpecPropertyMaterial
|
||||||
|
%type <integer> ambDiffSpecPropertyLight
|
||||||
|
|
||||||
%type <state> programSingleItem progEnvParam progLocalParam
|
%type <state> programSingleItem progEnvParam progLocalParam
|
||||||
%type <state> programMultipleItem progEnvParams progLocalParams
|
%type <state> programMultipleItem progEnvParams progLocalParams
|
||||||
@@ -1240,22 +1241,22 @@ stateMaterialItem: MATERIAL optFaceType stateMatProperty
|
|||||||
{
|
{
|
||||||
memset($$, 0, sizeof($$));
|
memset($$, 0, sizeof($$));
|
||||||
$$[0] = STATE_MATERIAL;
|
$$[0] = STATE_MATERIAL;
|
||||||
$$[1] = $2;
|
$$[1] = $3 + $2;
|
||||||
$$[2] = $3;
|
$$[2] = 0;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
stateMatProperty: ambDiffSpecProperty
|
stateMatProperty: ambDiffSpecPropertyMaterial
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| EMISSION
|
| EMISSION
|
||||||
{
|
{
|
||||||
$$ = STATE_EMISSION;
|
$$ = MAT_ATTRIB_FRONT_EMISSION;
|
||||||
}
|
}
|
||||||
| SHININESS
|
| SHININESS
|
||||||
{
|
{
|
||||||
$$ = STATE_SHININESS;
|
$$ = MAT_ATTRIB_FRONT_SHININESS;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -1268,7 +1269,7 @@ stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
stateLightProperty: ambDiffSpecProperty
|
stateLightProperty: ambDiffSpecPropertyLight
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
@@ -1326,12 +1327,12 @@ stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdPro
|
|||||||
memset($$, 0, sizeof($$));
|
memset($$, 0, sizeof($$));
|
||||||
$$[0] = STATE_LIGHTPROD;
|
$$[0] = STATE_LIGHTPROD;
|
||||||
$$[1] = $3;
|
$$[1] = $3;
|
||||||
$$[2] = $5;
|
$$[2] = $6 + $5;
|
||||||
$$[3] = $6;
|
$$[3] = 0;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
stateLProdProperty: ambDiffSpecProperty;
|
stateLProdProperty: ambDiffSpecPropertyMaterial;
|
||||||
|
|
||||||
stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
|
stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
|
||||||
{
|
{
|
||||||
@@ -1347,20 +1348,34 @@ stateTexEnvProperty: COLOR
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
ambDiffSpecProperty: AMBIENT
|
ambDiffSpecPropertyMaterial: AMBIENT
|
||||||
{
|
{
|
||||||
$$ = STATE_AMBIENT;
|
$$ = MAT_ATTRIB_FRONT_AMBIENT;
|
||||||
}
|
}
|
||||||
| DIFFUSE
|
| DIFFUSE
|
||||||
{
|
{
|
||||||
$$ = STATE_DIFFUSE;
|
$$ = MAT_ATTRIB_FRONT_DIFFUSE;
|
||||||
}
|
}
|
||||||
| SPECULAR
|
| SPECULAR
|
||||||
{
|
{
|
||||||
$$ = STATE_SPECULAR;
|
$$ = MAT_ATTRIB_FRONT_SPECULAR;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
ambDiffSpecPropertyLight: AMBIENT
|
||||||
|
{
|
||||||
|
$$ = STATE_AMBIENT;
|
||||||
|
}
|
||||||
|
| DIFFUSE
|
||||||
|
{
|
||||||
|
$$ = STATE_DIFFUSE;
|
||||||
|
}
|
||||||
|
| SPECULAR
|
||||||
|
{
|
||||||
|
$$ = STATE_SPECULAR;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
stateLightNumber: INTEGER
|
stateLightNumber: INTEGER
|
||||||
{
|
{
|
||||||
if ((unsigned) $1 >= state->MaxLights) {
|
if ((unsigned) $1 >= state->MaxLights) {
|
||||||
|
Reference in New Issue
Block a user