mesa/main/ff_frag: Use compressed TexEnv Combine state.

Along the way, add missing GL_ONE source support and drop non-existing
GL_ZERO and GL_ONE operand support.

Signed-off-by: Gustaw Smolarczyk <wielkiegie@gmail.com>
Signed-off-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Gustaw Smolarczyk 2017-03-30 20:09:32 +02:00 committed by Marek Olšák
parent f7c9bf0c6b
commit 8a4b93b1d9

View file

@ -81,16 +81,6 @@ texenv_doing_secondary_color(struct gl_context *ctx)
return GL_FALSE;
}
struct mode_opt {
#ifdef __GNUC__
__extension__ GLubyte Source:4; /**< SRC_x */
__extension__ GLubyte Operand:3; /**< OPR_x */
#else
GLubyte Source; /**< SRC_x */
GLubyte Operand; /**< OPR_x */
#endif
};
struct state_key {
GLuint nr_enabled_units:4;
GLuint separate_specular:1;
@ -103,131 +93,23 @@ struct state_key {
GLuint enabled:1;
GLuint source_index:4; /**< TEXTURE_x_INDEX */
GLuint shadow:1;
/***
* These are taken from struct gl_tex_env_combine_packed
* @{
*/
GLuint ModeRGB:4;
GLuint ModeA:4;
GLuint ScaleShiftRGB:2;
GLuint ScaleShiftA:2;
GLuint NumArgsRGB:3; /**< up to MAX_COMBINER_TERMS */
GLuint ModeRGB:5; /**< MODE_x */
GLuint NumArgsA:3; /**< up to MAX_COMBINER_TERMS */
GLuint ModeA:5; /**< MODE_x */
struct mode_opt OptRGB[MAX_COMBINER_TERMS];
struct mode_opt OptA[MAX_COMBINER_TERMS];
GLuint NumArgsRGB:3;
GLuint NumArgsA:3;
struct gl_tex_env_argument ArgsRGB[MAX_COMBINER_TERMS];
struct gl_tex_env_argument ArgsA[MAX_COMBINER_TERMS];
/** @} */
} unit[MAX_TEXTURE_COORD_UNITS];
};
#define OPR_SRC_COLOR 0
#define OPR_ONE_MINUS_SRC_COLOR 1
#define OPR_SRC_ALPHA 2
#define OPR_ONE_MINUS_SRC_ALPHA 3
#define OPR_ZERO 4
#define OPR_ONE 5
#define OPR_UNKNOWN 7
static GLuint translate_operand( GLenum operand )
{
switch (operand) {
case GL_SRC_COLOR: return OPR_SRC_COLOR;
case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR;
case GL_SRC_ALPHA: return OPR_SRC_ALPHA;
case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA;
case GL_ZERO: return OPR_ZERO;
case GL_ONE: return OPR_ONE;
default:
assert(0);
return OPR_UNKNOWN;
}
}
#define SRC_TEXTURE 0
#define SRC_TEXTURE0 1
#define SRC_TEXTURE1 2
#define SRC_TEXTURE2 3
#define SRC_TEXTURE3 4
#define SRC_TEXTURE4 5
#define SRC_TEXTURE5 6
#define SRC_TEXTURE6 7
#define SRC_TEXTURE7 8
#define SRC_CONSTANT 9
#define SRC_PRIMARY_COLOR 10
#define SRC_PREVIOUS 11
#define SRC_ZERO 12
#define SRC_UNKNOWN 15
static GLuint translate_source( GLenum src )
{
switch (src) {
case GL_TEXTURE: return SRC_TEXTURE;
case GL_TEXTURE0:
case GL_TEXTURE1:
case GL_TEXTURE2:
case GL_TEXTURE3:
case GL_TEXTURE4:
case GL_TEXTURE5:
case GL_TEXTURE6:
case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0);
case GL_CONSTANT: return SRC_CONSTANT;
case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR;
case GL_PREVIOUS: return SRC_PREVIOUS;
case GL_ZERO:
return SRC_ZERO;
default:
assert(0);
return SRC_UNKNOWN;
}
}
#define MODE_REPLACE 0 /* r = a0 */
#define MODE_MODULATE 1 /* r = a0 * a1 */
#define MODE_ADD 2 /* r = a0 + a1 */
#define MODE_ADD_SIGNED 3 /* r = a0 + a1 - 0.5 */
#define MODE_INTERPOLATE 4 /* r = a0 * a2 + a1 * (1 - a2) */
#define MODE_SUBTRACT 5 /* r = a0 - a1 */
#define MODE_DOT3_RGB 6 /* r = a0 . a1 */
#define MODE_DOT3_RGB_EXT 7 /* r = a0 . a1 */
#define MODE_DOT3_RGBA 8 /* r = a0 . a1 */
#define MODE_DOT3_RGBA_EXT 9 /* r = a0 . a1 */
#define MODE_MODULATE_ADD_ATI 10 /* r = a0 * a2 + a1 */
#define MODE_MODULATE_SIGNED_ADD_ATI 11 /* r = a0 * a2 + a1 - 0.5 */
#define MODE_MODULATE_SUBTRACT_ATI 12 /* r = a0 * a2 - a1 */
#define MODE_ADD_PRODUCTS 13 /* r = a0 * a1 + a2 * a3 */
#define MODE_ADD_PRODUCTS_SIGNED 14 /* r = a0 * a1 + a2 * a3 - 0.5 */
#define MODE_UNKNOWN 16
/**
* Translate GL combiner state into a MODE_x value
*/
static GLuint translate_mode( GLenum envMode, GLenum mode )
{
switch (mode) {
case GL_REPLACE: return MODE_REPLACE;
case GL_MODULATE: return MODE_MODULATE;
case GL_ADD:
if (envMode == GL_COMBINE4_NV)
return MODE_ADD_PRODUCTS;
else
return MODE_ADD;
case GL_ADD_SIGNED:
if (envMode == GL_COMBINE4_NV)
return MODE_ADD_PRODUCTS_SIGNED;
else
return MODE_ADD_SIGNED;
case GL_INTERPOLATE: return MODE_INTERPOLATE;
case GL_SUBTRACT: return MODE_SUBTRACT;
case GL_DOT3_RGB: return MODE_DOT3_RGB;
case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT;
case GL_DOT3_RGBA: return MODE_DOT3_RGBA;
case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT;
case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI;
case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI;
case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI;
default:
assert(0);
return MODE_UNKNOWN;
}
}
/**
* Do we need to clamp the results of the given texture env/combine mode?
@ -238,22 +120,22 @@ static GLboolean
need_saturate( GLuint mode )
{
switch (mode) {
case MODE_REPLACE:
case MODE_MODULATE:
case MODE_INTERPOLATE:
case TEXENV_MODE_REPLACE:
case TEXENV_MODE_MODULATE:
case TEXENV_MODE_INTERPOLATE:
return GL_FALSE;
case MODE_ADD:
case MODE_ADD_SIGNED:
case MODE_SUBTRACT:
case MODE_DOT3_RGB:
case MODE_DOT3_RGB_EXT:
case MODE_DOT3_RGBA:
case MODE_DOT3_RGBA_EXT:
case MODE_MODULATE_ADD_ATI:
case MODE_MODULATE_SIGNED_ADD_ATI:
case MODE_MODULATE_SUBTRACT_ATI:
case MODE_ADD_PRODUCTS:
case MODE_ADD_PRODUCTS_SIGNED:
case TEXENV_MODE_ADD:
case TEXENV_MODE_ADD_SIGNED:
case TEXENV_MODE_SUBTRACT:
case TEXENV_MODE_DOT3_RGB:
case TEXENV_MODE_DOT3_RGB_EXT:
case TEXENV_MODE_DOT3_RGBA:
case TEXENV_MODE_DOT3_RGBA_EXT:
case TEXENV_MODE_MODULATE_ADD_ATI:
case TEXENV_MODE_MODULATE_SIGNED_ADD_ATI:
case TEXENV_MODE_MODULATE_SUBTRACT_ATI:
case TEXENV_MODE_ADD_PRODUCTS_NV:
case TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV:
return GL_TRUE;
default:
assert(0);
@ -372,7 +254,6 @@ static GLbitfield filter_fp_input_mask( GLbitfield fp_inputs,
*/
static GLuint make_state_key( struct gl_context *ctx, struct state_key *key )
{
GLuint j;
GLbitfield inputs_referenced = VARYING_BIT_COL0;
GLbitfield mask;
GLuint keySize;
@ -386,7 +267,7 @@ static GLuint make_state_key( struct gl_context *ctx, struct state_key *key )
i = u_bit_scan(&mask);
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
const struct gl_texture_object *texObj = texUnit->_Current;
const struct gl_tex_env_combine_state *comb = texUnit->_CurrentCombine;
const struct gl_tex_env_combine_packed *comb = &texUnit->_CurrentCombinePacked;
if (!texObj)
continue;
@ -403,23 +284,15 @@ static GLuint make_state_key( struct gl_context *ctx, struct state_key *key )
format == GL_DEPTH_STENCIL_EXT);
}
key->unit[i].NumArgsRGB = comb->_NumArgsRGB;
key->unit[i].NumArgsA = comb->_NumArgsA;
key->unit[i].ModeRGB =
translate_mode(texUnit->EnvMode, comb->ModeRGB);
key->unit[i].ModeA =
translate_mode(texUnit->EnvMode, comb->ModeA);
key->unit[i].ModeRGB = comb->ModeRGB;
key->unit[i].ModeA = comb->ModeA;
key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB;
key->unit[i].ScaleShiftA = comb->ScaleShiftA;
key->unit[i].NumArgsRGB = comb->NumArgsRGB;
key->unit[i].NumArgsA = comb->NumArgsA;
for (j = 0; j < MAX_COMBINER_TERMS; j++) {
key->unit[i].OptRGB[j].Operand = translate_operand(comb->OperandRGB[j]);
key->unit[i].OptA[j].Operand = translate_operand(comb->OperandA[j]);
key->unit[i].OptRGB[j].Source = translate_source(comb->SourceRGB[j]);
key->unit[i].OptA[j].Source = translate_source(comb->SourceA[j]);
}
memcpy(key->unit[i].ArgsRGB, comb->ArgsRGB, sizeof comb->ArgsRGB);
memcpy(key->unit[i].ArgsA, comb->ArgsA, sizeof comb->ArgsA);
}
key->nr_enabled_units = i + 1;
@ -512,21 +385,21 @@ get_source(texenv_fragment_program *p,
ir_dereference *deref;
switch (src) {
case SRC_TEXTURE:
case TEXENV_SRC_TEXTURE:
return new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]);
case SRC_TEXTURE0:
case SRC_TEXTURE1:
case SRC_TEXTURE2:
case SRC_TEXTURE3:
case SRC_TEXTURE4:
case SRC_TEXTURE5:
case SRC_TEXTURE6:
case SRC_TEXTURE7:
case TEXENV_SRC_TEXTURE0:
case TEXENV_SRC_TEXTURE1:
case TEXENV_SRC_TEXTURE2:
case TEXENV_SRC_TEXTURE3:
case TEXENV_SRC_TEXTURE4:
case TEXENV_SRC_TEXTURE5:
case TEXENV_SRC_TEXTURE6:
case TEXENV_SRC_TEXTURE7:
return new(p->mem_ctx)
ir_dereference_variable(p->src_texture[src - SRC_TEXTURE0]);
ir_dereference_variable(p->src_texture[src - TEXENV_SRC_TEXTURE0]);
case SRC_CONSTANT:
case TEXENV_SRC_CONSTANT:
var = p->shader->symbols->get_variable("gl_TextureEnvColor");
assert(var);
deref = new(p->mem_ctx) ir_dereference_variable(var);
@ -534,15 +407,18 @@ get_source(texenv_fragment_program *p,
return new(p->mem_ctx) ir_dereference_array(deref,
new(p->mem_ctx) ir_constant(unit));
case SRC_PRIMARY_COLOR:
case TEXENV_SRC_PRIMARY_COLOR:
var = p->shader->symbols->get_variable("gl_Color");
assert(var);
return new(p->mem_ctx) ir_dereference_variable(var);
case SRC_ZERO:
case TEXENV_SRC_ZERO:
return new(p->mem_ctx) ir_constant(0.0f);
case SRC_PREVIOUS:
case TEXENV_SRC_ONE:
return new(p->mem_ctx) ir_constant(1.0f);
case TEXENV_SRC_PREVIOUS:
if (!p->src_previous) {
return get_gl_Color(p);
} else {
@ -566,24 +442,21 @@ emit_combine_source(texenv_fragment_program *p,
src = get_source(p, source, unit);
switch (operand) {
case OPR_ONE_MINUS_SRC_COLOR:
case TEXENV_OPR_ONE_MINUS_COLOR:
return sub(new(p->mem_ctx) ir_constant(1.0f), src);
case OPR_SRC_ALPHA:
case TEXENV_OPR_ALPHA:
return src->type->is_scalar() ? src : swizzle_w(src);
case OPR_ONE_MINUS_SRC_ALPHA: {
case TEXENV_OPR_ONE_MINUS_ALPHA: {
ir_rvalue *const scalar = src->type->is_scalar() ? src : swizzle_w(src);
return sub(new(p->mem_ctx) ir_constant(1.0f), scalar);
}
case OPR_ZERO:
return new(p->mem_ctx) ir_constant(0.0f);
case OPR_ONE:
return new(p->mem_ctx) ir_constant(1.0f);
case OPR_SRC_COLOR:
case TEXENV_OPR_COLOR:
return src;
default:
assert(0);
return src;
@ -600,23 +473,23 @@ static GLboolean args_match( const struct state_key *key, GLuint unit )
GLuint i, numArgs = key->unit[unit].NumArgsRGB;
for (i = 0; i < numArgs; i++) {
if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source)
if (key->unit[unit].ArgsA[i].Source != key->unit[unit].ArgsRGB[i].Source)
return GL_FALSE;
switch (key->unit[unit].OptA[i].Operand) {
case OPR_SRC_ALPHA:
switch (key->unit[unit].OptRGB[i].Operand) {
case OPR_SRC_COLOR:
case OPR_SRC_ALPHA:
switch (key->unit[unit].ArgsA[i].Operand) {
case TEXENV_OPR_ALPHA:
switch (key->unit[unit].ArgsRGB[i].Operand) {
case TEXENV_OPR_COLOR:
case TEXENV_OPR_ALPHA:
break;
default:
return GL_FALSE;
}
break;
case OPR_ONE_MINUS_SRC_ALPHA:
switch (key->unit[unit].OptRGB[i].Operand) {
case OPR_ONE_MINUS_SRC_COLOR:
case OPR_ONE_MINUS_SRC_ALPHA:
case TEXENV_OPR_ONE_MINUS_ALPHA:
switch (key->unit[unit].ArgsRGB[i].Operand) {
case TEXENV_OPR_ONE_MINUS_COLOR:
case TEXENV_OPR_ONE_MINUS_ALPHA:
break;
default:
return GL_FALSE;
@ -644,7 +517,7 @@ emit_combine(texenv_fragment_program *p,
GLuint unit,
GLuint nr,
GLuint mode,
const struct mode_opt *opt)
const struct gl_tex_env_argument *opt)
{
ir_rvalue *src[MAX_COMBINER_TERMS];
ir_rvalue *tmp0, *tmp1;
@ -656,32 +529,32 @@ emit_combine(texenv_fragment_program *p,
src[i] = emit_combine_source( p, unit, opt[i].Source, opt[i].Operand );
switch (mode) {
case MODE_REPLACE:
case TEXENV_MODE_REPLACE:
return src[0];
case MODE_MODULATE:
case TEXENV_MODE_MODULATE:
return mul(src[0], src[1]);
case MODE_ADD:
case TEXENV_MODE_ADD:
return add(src[0], src[1]);
case MODE_ADD_SIGNED:
case TEXENV_MODE_ADD_SIGNED:
return add(add(src[0], src[1]), new(p->mem_ctx) ir_constant(-0.5f));
case MODE_INTERPOLATE:
case TEXENV_MODE_INTERPOLATE:
/* Arg0 * (Arg2) + Arg1 * (1-Arg2) */
tmp0 = mul(src[0], src[2]);
tmp1 = mul(src[1], sub(new(p->mem_ctx) ir_constant(1.0f),
src[2]->clone(p->mem_ctx, NULL)));
return add(tmp0, tmp1);
case MODE_SUBTRACT:
case TEXENV_MODE_SUBTRACT:
return sub(src[0], src[1]);
case MODE_DOT3_RGBA:
case MODE_DOT3_RGBA_EXT:
case MODE_DOT3_RGB_EXT:
case MODE_DOT3_RGB: {
case TEXENV_MODE_DOT3_RGBA:
case TEXENV_MODE_DOT3_RGBA_EXT:
case TEXENV_MODE_DOT3_RGB_EXT:
case TEXENV_MODE_DOT3_RGB: {
tmp0 = mul(src[0], new(p->mem_ctx) ir_constant(2.0f));
tmp0 = add(tmp0, new(p->mem_ctx) ir_constant(-1.0f));
@ -690,20 +563,20 @@ emit_combine(texenv_fragment_program *p,
return dot(swizzle_xyz(smear(tmp0)), swizzle_xyz(smear(tmp1)));
}
case MODE_MODULATE_ADD_ATI:
case TEXENV_MODE_MODULATE_ADD_ATI:
return add(mul(src[0], src[2]), src[1]);
case MODE_MODULATE_SIGNED_ADD_ATI:
case TEXENV_MODE_MODULATE_SIGNED_ADD_ATI:
return add(add(mul(src[0], src[2]), src[1]),
new(p->mem_ctx) ir_constant(-0.5f));
case MODE_MODULATE_SUBTRACT_ATI:
case TEXENV_MODE_MODULATE_SUBTRACT_ATI:
return sub(mul(src[0], src[2]), src[1]);
case MODE_ADD_PRODUCTS:
case TEXENV_MODE_ADD_PRODUCTS_NV:
return add(mul(src[0], src[1]), mul(src[2], src[3]));
case MODE_ADD_PRODUCTS_SIGNED:
case TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV:
return add(add(mul(src[0], src[1]), mul(src[2], src[3])),
new(p->mem_ctx) ir_constant(-0.5f));
default:
@ -723,15 +596,15 @@ emit_texenv(texenv_fragment_program *p, GLuint unit)
GLuint rgb_shift, alpha_shift;
if (!key->unit[unit].enabled) {
return get_source(p, SRC_PREVIOUS, 0);
return get_source(p, TEXENV_SRC_PREVIOUS, 0);
}
switch (key->unit[unit].ModeRGB) {
case MODE_DOT3_RGB_EXT:
case TEXENV_MODE_DOT3_RGB_EXT:
alpha_shift = key->unit[unit].ScaleShiftA;
rgb_shift = 0;
break;
case MODE_DOT3_RGBA_EXT:
case TEXENV_MODE_DOT3_RGBA_EXT:
alpha_shift = 0;
rgb_shift = 0;
break;
@ -769,19 +642,19 @@ emit_texenv(texenv_fragment_program *p, GLuint unit)
val = emit_combine(p, unit,
key->unit[unit].NumArgsRGB,
key->unit[unit].ModeRGB,
key->unit[unit].OptRGB);
key->unit[unit].ArgsRGB);
val = smear(val);
if (rgb_saturate)
val = saturate(val);
p->emit(assign(temp_var, val));
}
else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT ||
key->unit[unit].ModeRGB == MODE_DOT3_RGBA) {
else if (key->unit[unit].ModeRGB == TEXENV_MODE_DOT3_RGBA_EXT ||
key->unit[unit].ModeRGB == TEXENV_MODE_DOT3_RGBA) {
ir_rvalue *val = emit_combine(p, unit,
key->unit[unit].NumArgsRGB,
key->unit[unit].ModeRGB,
key->unit[unit].OptRGB);
key->unit[unit].ArgsRGB);
val = smear(val);
if (rgb_saturate)
val = saturate(val);
@ -794,7 +667,7 @@ emit_texenv(texenv_fragment_program *p, GLuint unit)
val = emit_combine(p, unit,
key->unit[unit].NumArgsRGB,
key->unit[unit].ModeRGB,
key->unit[unit].OptRGB);
key->unit[unit].ArgsRGB);
val = swizzle_xyz(smear(val));
if (rgb_saturate)
val = saturate(val);
@ -803,7 +676,7 @@ emit_texenv(texenv_fragment_program *p, GLuint unit)
val = emit_combine(p, unit,
key->unit[unit].NumArgsA,
key->unit[unit].ModeA,
key->unit[unit].OptA);
key->unit[unit].ArgsA);
val = swizzle_w(smear(val));
if (alpha_saturate)
val = saturate(val);
@ -974,19 +847,19 @@ load_texenv_source(texenv_fragment_program *p,
GLuint src, GLuint unit)
{
switch (src) {
case SRC_TEXTURE:
case TEXENV_SRC_TEXTURE:
load_texture(p, unit);
break;
case SRC_TEXTURE0:
case SRC_TEXTURE1:
case SRC_TEXTURE2:
case SRC_TEXTURE3:
case SRC_TEXTURE4:
case SRC_TEXTURE5:
case SRC_TEXTURE6:
case SRC_TEXTURE7:
load_texture(p, src - SRC_TEXTURE0);
case TEXENV_SRC_TEXTURE0:
case TEXENV_SRC_TEXTURE1:
case TEXENV_SRC_TEXTURE2:
case TEXENV_SRC_TEXTURE3:
case TEXENV_SRC_TEXTURE4:
case TEXENV_SRC_TEXTURE5:
case TEXENV_SRC_TEXTURE6:
case TEXENV_SRC_TEXTURE7:
load_texture(p, src - TEXENV_SRC_TEXTURE0);
break;
default:
@ -1006,11 +879,11 @@ load_texunit_sources( texenv_fragment_program *p, GLuint unit )
GLuint i;
for (i = 0; i < key->unit[unit].NumArgsRGB; i++) {
load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit );
load_texenv_source( p, key->unit[unit].ArgsRGB[i].Source, unit );
}
for (i = 0; i < key->unit[unit].NumArgsA; i++) {
load_texenv_source( p, key->unit[unit].OptA[i].Source, unit );
load_texenv_source( p, key->unit[unit].ArgsA[i].Source, unit );
}
return GL_TRUE;
@ -1124,7 +997,7 @@ emit_instructions(texenv_fragment_program *p)
}
}
ir_rvalue *cf = get_source(p, SRC_PREVIOUS, 0);
ir_rvalue *cf = get_source(p, TEXENV_SRC_PREVIOUS, 0);
if (key->separate_specular) {
ir_variable *spec_result = p->make_temp(glsl_type::vec4_type,