From 8a4b93b1d9aa72c00a29d3a1f26b42e3eca03768 Mon Sep 17 00:00:00 2001 From: Gustaw Smolarczyk Date: Thu, 30 Mar 2017 20:09:32 +0200 Subject: [PATCH] mesa/main/ff_frag: Use compressed TexEnv Combine state. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Marek Olšák --- src/mesa/main/ff_fragment_shader.cpp | 335 +++++++++------------------ 1 file changed, 104 insertions(+), 231 deletions(-) diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp index bdbefc7880b..aac9de78ca6 100644 --- a/src/mesa/main/ff_fragment_shader.cpp +++ b/src/mesa/main/ff_fragment_shader.cpp @@ -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, -- 2.30.2