diff options
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r-- | mesalib/src/mesa/main/blend.c | 11 | ||||
-rw-r--r-- | mesalib/src/mesa/main/context.c | 36 | ||||
-rw-r--r-- | mesalib/src/mesa/main/extensions.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/ff_fragment_shader.cpp | 321 | ||||
-rw-r--r-- | mesalib/src/mesa/main/format_pack.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/get.c | 3 | ||||
-rw-r--r-- | mesalib/src/mesa/main/mtypes.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shader_query.cpp | 85 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shaderapi.c | 3 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shaderapi.h | 7 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shaderobj.c | 6 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_blend.c | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_extensions.c | 7 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 2 |
14 files changed, 250 insertions, 247 deletions
diff --git a/mesalib/src/mesa/main/blend.c b/mesalib/src/mesa/main/blend.c index 09acdf5c5..bc446edca 100644 --- a/mesalib/src/mesa/main/blend.c +++ b/mesalib/src/mesa/main/blend.c @@ -63,6 +63,11 @@ legal_src_factor(const struct gl_context *ctx, GLenum factor) case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: return GL_TRUE; + case GL_SRC1_COLOR: + case GL_SRC1_ALPHA: + case GL_ONE_MINUS_SRC1_COLOR: + case GL_ONE_MINUS_SRC1_ALPHA: + return ctx->Extensions.ARB_blend_func_extended; default: return GL_FALSE; } @@ -93,6 +98,12 @@ legal_dst_factor(const struct gl_context *ctx, GLenum factor) case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: return GL_TRUE; + case GL_SRC_ALPHA_SATURATE: + case GL_SRC1_COLOR: + case GL_SRC1_ALPHA: + case GL_ONE_MINUS_SRC1_COLOR: + case GL_ONE_MINUS_SRC1_ALPHA: + return ctx->Extensions.ARB_blend_func_extended; default: return GL_FALSE; } diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 83e5de47a..51b024143 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1695,7 +1695,39 @@ _mesa_set_mvp_with_dp4( struct gl_context *ctx, ctx->mvp_with_dp4 = flag; } +static GLboolean +blend_factor_is_dual_src(GLenum factor) +{ + return factor == GL_SRC1_COLOR || factor == GL_SRC1_ALPHA || + factor == GL_ONE_MINUS_SRC1_COLOR || factor == GL_ONE_MINUS_SRC1_ALPHA; +} +/* + * ARB_blend_func_extended - ERRORS section + * "The error INVALID_OPERATION is generated by Begin or any procedure that + * implicitly calls Begin if any draw buffer has a blend function requiring the + * second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, SRC1_ALPHA or + * ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that has more than + * the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active color attachements." + */ +static GLboolean +_mesa_check_blend_func_error(struct gl_context *ctx) +{ + GLuint i; + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + if (blend_factor_is_dual_src(ctx->Color.Blend[i].SrcRGB) || + blend_factor_is_dual_src(ctx->Color.Blend[i].DstRGB) || + blend_factor_is_dual_src(ctx->Color.Blend[i].SrcA) || + blend_factor_is_dual_src(ctx->Color.Blend[i].DstA)) { + if (i >= ctx->Const.MaxDualSourceDrawBuffers) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "dual source blend on illegal attachment"); + return GL_FALSE; + } + } + } + return GL_TRUE; +} /** * Prior to drawing anything with glBegin, glDrawArrays, etc. this function @@ -1816,6 +1848,10 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where) return GL_FALSE; } + if (_mesa_check_blend_func_error(ctx) == GL_FALSE) { + return GL_FALSE; + } + #ifdef DEBUG if (ctx->Shader.Flags & GLSL_LOG) { struct gl_shader_program *shProg[MESA_SHADER_TYPES]; diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 3ce4cd559..5f2c74a75 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -940,7 +940,7 @@ _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index) n = 0; for (i = extension_table; i->name != 0; ++i) { if (n == index && base[i->offset]) { - return (GLubyte*) i->name; + return (const GLubyte*) i->name; } else if (base[i->offset]) { ++n; } diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 7b830439d..3c91b1a42 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -45,12 +45,15 @@ extern "C" { #include "main/uniforms.h" #include "../glsl/glsl_types.h" #include "../glsl/ir.h" +#include "../glsl/ir_builder.h" #include "../glsl/glsl_symbol_table.h" #include "../glsl/glsl_parser_extras.h" #include "../glsl/ir_optimization.h" #include "../glsl/ir_print_visitor.h" #include "../program/ir_to_mesa.h" +using namespace ir_builder; + /* * Note on texture units: * @@ -508,12 +511,11 @@ static GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) /** State used to build the fragment program: */ -struct texenv_fragment_program { +class texenv_fragment_program : public ir_factory { +public: struct gl_shader_program *shader_program; struct gl_shader *shader; - exec_list *instructions; exec_list *top_instructions; - void *mem_ctx; struct state_key *state; ir_variable *src_texture[MAX_TEXTURE_COORD_UNITS]; @@ -621,21 +623,15 @@ emit_combine_source(struct texenv_fragment_program *p, switch (operand) { case OPR_ONE_MINUS_SRC_COLOR: - return new(p->mem_ctx) ir_expression(ir_binop_sub, - new(p->mem_ctx) ir_constant(1.0f), - src); + return sub(new(p->mem_ctx) ir_constant(1.0f), src); case OPR_SRC_ALPHA: - return src->type->is_scalar() - ? src : (ir_rvalue *) new(p->mem_ctx) ir_swizzle(src, 3, 3, 3, 3, 1); + return src->type->is_scalar() ? src : swizzle_w(src); case OPR_ONE_MINUS_SRC_ALPHA: { - ir_rvalue *const scalar = (src->type->is_scalar()) - ? src : (ir_rvalue *) new(p->mem_ctx) ir_swizzle(src, 3, 3, 3, 3, 1); + ir_rvalue *const scalar = src->type->is_scalar() ? src : swizzle_w(src); - return new(p->mem_ctx) ir_expression(ir_binop_sub, - new(p->mem_ctx) ir_constant(1.0f), - scalar); + return sub(new(p->mem_ctx) ir_constant(1.0f), scalar); } case OPR_ZERO: @@ -696,7 +692,7 @@ smear(struct texenv_fragment_program *p, ir_rvalue *val) if (!val->type->is_scalar()) return val; - return new(p->mem_ctx) ir_swizzle(val, 0, 0, 0, 0, 4); + return swizzle_xxxx(val); } static ir_rvalue * @@ -720,73 +716,52 @@ emit_combine(struct texenv_fragment_program *p, return src[0]; case MODE_MODULATE: - return new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], src[1]); + return mul(src[0], src[1]); case MODE_ADD: - return new(p->mem_ctx) ir_expression(ir_binop_add, src[0], src[1]); + return add(src[0], src[1]); case MODE_ADD_SIGNED: - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_add, src[0], src[1]); - return new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, - new(p->mem_ctx) ir_constant(-0.5f)); + return add(add(src[0], src[1]), new(p->mem_ctx) ir_constant(-0.5f)); case MODE_INTERPOLATE: /* Arg0 * (Arg2) + Arg1 * (1-Arg2) */ - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], src[2]); - - tmp1 = new(p->mem_ctx) ir_expression(ir_binop_sub, - new(p->mem_ctx) ir_constant(1.0f), - src[2]->clone(p->mem_ctx, NULL)); - tmp1 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[1], tmp1); - - return new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, tmp1); + 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: - return new(p->mem_ctx) ir_expression(ir_binop_sub, src[0], src[1]); + return sub(src[0], src[1]); case MODE_DOT3_RGBA: case MODE_DOT3_RGBA_EXT: case MODE_DOT3_RGB_EXT: case MODE_DOT3_RGB: { - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], - new(p->mem_ctx) ir_constant(2.0f)); - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, - new(p->mem_ctx) ir_constant(-1.0f)); - tmp0 = new(p->mem_ctx) ir_swizzle(smear(p, tmp0), 0, 1, 2, 3, 3); - - tmp1 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[1], - new(p->mem_ctx) ir_constant(2.0f)); - tmp1 = new(p->mem_ctx) ir_expression(ir_binop_add, tmp1, - new(p->mem_ctx) ir_constant(-1.0f)); - tmp1 = new(p->mem_ctx) ir_swizzle(smear(p, tmp1), 0, 1, 2, 3, 3); - - return new(p->mem_ctx) ir_expression(ir_binop_dot, tmp0, tmp1); + tmp0 = mul(src[0], new(p->mem_ctx) ir_constant(2.0f)); + tmp0 = add(tmp0, new(p->mem_ctx) ir_constant(-1.0f)); + + tmp1 = mul(src[1], new(p->mem_ctx) ir_constant(2.0f)); + tmp1 = add(tmp1, new(p->mem_ctx) ir_constant(-1.0f)); + + return dot(swizzle_xyz(smear(p, tmp0)), swizzle_xyz(smear(p, tmp1))); } case MODE_MODULATE_ADD_ATI: - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], src[2]); - return new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, src[1]); + return add(mul(src[0], src[2]), src[1]); case MODE_MODULATE_SIGNED_ADD_ATI: - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], src[2]); - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, src[1]); - return new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, - new(p->mem_ctx) ir_constant(-0.5f)); + return add(add(mul(src[0], src[2]), src[1]), + new(p->mem_ctx) ir_constant(-0.5f)); case MODE_MODULATE_SUBTRACT_ATI: - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], src[2]); - return new(p->mem_ctx) ir_expression(ir_binop_sub, tmp0, src[1]); + return sub(mul(src[0], src[2]), src[1]); case MODE_ADD_PRODUCTS: - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], src[1]); - tmp1 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[2], src[3]); - return new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, tmp1); + return add(mul(src[0], src[1]), mul(src[2], src[3])); case MODE_ADD_PRODUCTS_SIGNED: - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[0], src[1]); - tmp1 = new(p->mem_ctx) ir_expression(ir_binop_mul, src[2], src[3]); - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, tmp1); - return new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, - new(p->mem_ctx) ir_constant(-0.5f)); + return add(add(mul(src[0], src[1]), mul(src[2], src[3])), + new(p->mem_ctx) ir_constant(-0.5f)); case MODE_BUMP_ENVMAP_ATI: /* special - not handled here */ @@ -798,15 +773,6 @@ emit_combine(struct texenv_fragment_program *p, } } -static ir_rvalue * -saturate(struct texenv_fragment_program *p, ir_rvalue *val) -{ - val = new(p->mem_ctx) ir_expression(ir_binop_min, val, - new(p->mem_ctx) ir_constant(1.0f)); - return new(p->mem_ctx) ir_expression(ir_binop_max, val, - new(p->mem_ctx) ir_constant(0.0f)); -} - /** * Generate instructions for one texture unit's env/combiner mode. */ @@ -857,13 +823,8 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) else alpha_saturate = GL_FALSE; - ir_variable *temp_var = new(p->mem_ctx) ir_variable(glsl_type::vec4_type, - "texenv_combine", - ir_var_temporary); - p->instructions->push_tail(temp_var); - + ir_variable *temp_var = p->make_temp(glsl_type::vec4_type, "texenv_combine"); ir_dereference *deref; - ir_assignment *assign; ir_rvalue *val; /* Emit the RGB and A combine ops @@ -876,11 +837,9 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) key->unit[unit].OptRGB); val = smear(p, val); if (rgb_saturate) - val = saturate(p, val); + val = saturate(val); - deref = new(p->mem_ctx) ir_dereference_variable(temp_var); - assign = new(p->mem_ctx) ir_assignment(deref, val); - p->instructions->push_tail(assign); + p->emit(assign(temp_var, val)); } else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { @@ -890,10 +849,8 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) key->unit[unit].OptRGB); val = smear(p, val); if (rgb_saturate) - val = saturate(p, val); - deref = new(p->mem_ctx) ir_dereference_variable(temp_var); - assign = new(p->mem_ctx) ir_assignment(deref, val); - p->instructions->push_tail(assign); + val = saturate(val); + p->emit(assign(temp_var, val)); } else { /* Need to do something to stop from re-emitting identical @@ -903,25 +860,19 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) key->unit[unit].NumArgsRGB, key->unit[unit].ModeRGB, key->unit[unit].OptRGB); - val = smear(p, val); - val = new(p->mem_ctx) ir_swizzle(val, 0, 1, 2, 3, 3); + val = swizzle_xyz(smear(p, val)); if (rgb_saturate) - val = saturate(p, val); - deref = new(p->mem_ctx) ir_dereference_variable(temp_var); - assign = new(p->mem_ctx) ir_assignment(deref, val, NULL, WRITEMASK_XYZ); - p->instructions->push_tail(assign); + val = saturate(val); + p->emit(assign(temp_var, val, WRITEMASK_XYZ)); val = emit_combine(p, unit, key->unit[unit].NumArgsA, key->unit[unit].ModeA, key->unit[unit].OptA); - val = smear(p, val); - val = new(p->mem_ctx) ir_swizzle(val, 3, 3, 3, 3, 1); + val = swizzle_w(smear(p, val)); if (alpha_saturate) - val = saturate(p, val); - deref = new(p->mem_ctx) ir_dereference_variable(temp_var); - assign = new(p->mem_ctx) ir_assignment(deref, val, NULL, WRITEMASK_W); - p->instructions->push_tail(assign); + val = saturate(val); + p->emit(assign(temp_var, val, WRITEMASK_W)); } deref = new(p->mem_ctx) ir_dereference_variable(temp_var); @@ -945,8 +896,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) (ir_constant_data *)const_data); } - return saturate(p, new(p->mem_ctx) ir_expression(ir_binop_mul, - deref, shift)); + return saturate(mul(deref, shift)); } else return deref; @@ -959,7 +909,6 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) static void load_texture( struct texenv_fragment_program *p, GLuint unit ) { ir_dereference *deref; - ir_assignment *assign; if (p->src_texture[unit]) return; @@ -981,15 +930,11 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) } if (!p->state->unit[unit].enabled) { - p->src_texture[unit] = new(p->mem_ctx) ir_variable(glsl_type::vec4_type, - "dummy_tex", - ir_var_temporary); - p->instructions->push_tail(p->src_texture[unit]); - - deref = new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]); - assign = new(p->mem_ctx) ir_assignment(deref, - new(p->mem_ctx) ir_constant(0.0f)); - p->instructions->push_tail(assign); + p->src_texture[unit] = p->make_temp(glsl_type::vec4_type, + "dummy_tex"); + p->emit(p->src_texture[unit]); + + p->emit(assign(p->src_texture[unit], new(p->mem_ctx) ir_constant(0.0f))); return ; } @@ -1051,10 +996,8 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) break; } - p->src_texture[unit] = new(p->mem_ctx) ir_variable(glsl_type::vec4_type, - "tex", - ir_var_temporary); - p->instructions->push_tail(p->src_texture[unit]); + p->src_texture[unit] = p->make_temp(glsl_type::vec4_type, + "tex"); ir_texture *tex = new(p->mem_ctx) ir_texture(ir_tex); @@ -1078,11 +1021,9 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) } texcoord = texcoord->clone(p->mem_ctx, NULL); - tex->projector = new(p->mem_ctx) ir_swizzle(texcoord, 3, 0, 0, 0, 1); + tex->projector = swizzle_w(texcoord); - deref = new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]); - assign = new(p->mem_ctx) ir_assignment(deref, tex); - p->instructions->push_tail(assign); + p->emit(assign(p->src_texture[unit], tex)); } static void @@ -1142,13 +1083,10 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit ) GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0; ir_rvalue *bump; ir_rvalue *texcoord; - ir_variable *rot_mat_0_var, *rot_mat_1_var; - ir_dereference_variable *rot_mat_0, *rot_mat_1; + ir_variable *rot_mat_0, *rot_mat_1; - rot_mat_0_var = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA"); - rot_mat_1_var = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA"); - rot_mat_0 = new(p->mem_ctx) ir_dereference_variable(rot_mat_0_var); - rot_mat_1 = new(p->mem_ctx) ir_dereference_variable(rot_mat_1_var); + rot_mat_0 = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA"); + rot_mat_1 = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA"); ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord"); assert(tc_array); @@ -1163,44 +1101,22 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit ) * dest = Arg1 + (Arg0.xx * rotMat0) + (Arg0.yy * rotMat1) * note only 2 coords are affected the rest are left unchanged (mul by 0) */ - ir_dereference *deref; - ir_assignment *assign; ir_rvalue *bump_x, *bump_y; texcoord = smear(p, texcoord); /* bump_texcoord = texcoord */ - ir_variable *bumped = new(p->mem_ctx) ir_variable(texcoord->type, - "bump_texcoord", - ir_var_temporary); - p->instructions->push_tail(bumped); - - deref = new(p->mem_ctx) ir_dereference_variable(bumped); - assign = new(p->mem_ctx) ir_assignment(deref, texcoord); - p->instructions->push_tail(assign); + ir_variable *bumped = p->make_temp(texcoord->type, "bump_texcoord"); + p->emit(bumped); + p->emit(assign(bumped, texcoord)); /* bump_texcoord.xy += arg0.x * rotmat0 + arg0.y * rotmat1 */ bump = get_source(p, key->unit[unit].OptRGB[0].Source, unit); - bump_x = new(p->mem_ctx) ir_swizzle(bump, 0, 0, 0, 0, 1); - bump = bump->clone(p->mem_ctx, NULL); - bump_y = new(p->mem_ctx) ir_swizzle(bump, 1, 0, 0, 0, 1); - - bump_x = new(p->mem_ctx) ir_expression(ir_binop_mul, bump_x, rot_mat_0); - bump_y = new(p->mem_ctx) ir_expression(ir_binop_mul, bump_y, rot_mat_1); - - ir_expression *expr; - expr = new(p->mem_ctx) ir_expression(ir_binop_add, bump_x, bump_y); + bump_x = mul(swizzle_x(bump), rot_mat_0); + bump_y = mul(swizzle_y(bump->clone(p->mem_ctx, NULL)), rot_mat_1); - deref = new(p->mem_ctx) ir_dereference_variable(bumped); - expr = new(p->mem_ctx) ir_expression(ir_binop_add, - new(p->mem_ctx) ir_swizzle(deref, - 0, 1, 1, 1, - 2), - expr); - - deref = new(p->mem_ctx) ir_dereference_variable(bumped); - assign = new(p->mem_ctx) ir_assignment(deref, expr, NULL, WRITEMASK_XY); - p->instructions->push_tail(assign); + p->emit(assign(bumped, add(swizzle_xy(bumped), add(bump_x, bump_y)), + WRITEMASK_XY)); p->texcoord_tex[bumpedUnitNr] = bumped; } @@ -1220,31 +1136,22 @@ emit_fog_instructions(struct texenv_fragment_program *p, ir_rvalue *f, *temp; ir_variable *params, *oparams; ir_variable *fogcoord; - ir_assignment *assign; /* Temporary storage for the whole fog result. Fog calculations * only affect rgb so we're hanging on to the .a value of fragcolor * this way. */ - ir_variable *fog_result = new(p->mem_ctx) ir_variable(glsl_type::vec4_type, - "fog_result", - ir_var_auto); - p->instructions->push_tail(fog_result); - temp = new(p->mem_ctx) ir_dereference_variable(fog_result); - assign = new(p->mem_ctx) ir_assignment(temp, fragcolor); - p->instructions->push_tail(assign); + ir_variable *fog_result = p->make_temp(glsl_type::vec4_type, "fog_result"); + p->emit(assign(fog_result, fragcolor)); - temp = new(p->mem_ctx) ir_dereference_variable(fog_result); - fragcolor = new(p->mem_ctx) ir_swizzle(temp, 0, 1, 2, 3, 3); + fragcolor = swizzle_xyz(fog_result); oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA"); fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord"); params = p->shader->symbols->get_variable("gl_Fog"); f = new(p->mem_ctx) ir_dereference_variable(fogcoord); - ir_variable *f_var = new(p->mem_ctx) ir_variable(glsl_type::float_type, - "fog_factor", ir_var_auto); - p->instructions->push_tail(f_var); + ir_variable *f_var = p->make_temp(glsl_type::float_type, "fog_factor"); switch (key->fog_mode) { case FOG_LINEAR: @@ -1253,13 +1160,7 @@ emit_fog_instructions(struct texenv_fragment_program *p, * gl_MesaFogParamsOptimized gives us (-1 / (end - start)) and * (end / (end - start)) so we can generate a single MAD. */ - temp = new(p->mem_ctx) ir_dereference_variable(oparams); - temp = new(p->mem_ctx) ir_swizzle(temp, 0, 0, 0, 0, 1); - f = new(p->mem_ctx) ir_expression(ir_binop_mul, f, temp); - - temp = new(p->mem_ctx) ir_dereference_variable(oparams); - temp = new(p->mem_ctx) ir_swizzle(temp, 1, 0, 0, 0, 1); - f = new(p->mem_ctx) ir_expression(ir_binop_add, f, temp); + f = add(mul(f, swizzle_x(oparams)), swizzle_y(oparams)); break; case FOG_EXP: /* f = e^(-(density * fogcoord)) @@ -1268,9 +1169,7 @@ emit_fog_instructions(struct texenv_fragment_program *p, * use EXP2 which is generally the native instruction without * having to do any further math on the fog density uniform. */ - temp = new(p->mem_ctx) ir_dereference_variable(oparams); - temp = new(p->mem_ctx) ir_swizzle(temp, 2, 0, 0, 0, 1); - f = new(p->mem_ctx) ir_expression(ir_binop_mul, f, temp); + f = mul(f, swizzle_z(oparams)); f = new(p->mem_ctx) ir_expression(ir_unop_neg, f); f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f); break; @@ -1281,50 +1180,23 @@ emit_fog_instructions(struct texenv_fragment_program *p, * can do this like FOG_EXP but with a squaring after the * multiply by density. */ - ir_variable *temp_var = new(p->mem_ctx) ir_variable(glsl_type::float_type, - "fog_temp", - ir_var_auto); - p->instructions->push_tail(temp_var); - - temp = new(p->mem_ctx) ir_dereference_variable(oparams); - temp = new(p->mem_ctx) ir_swizzle(temp, 3, 0, 0, 0, 1); - f = new(p->mem_ctx) ir_expression(ir_binop_mul, - f, temp); - - temp = new(p->mem_ctx) ir_dereference_variable(temp_var); - ir_assignment *assign = new(p->mem_ctx) ir_assignment(temp, f); - p->instructions->push_tail(assign); - - f = new(p->mem_ctx) ir_dereference_variable(temp_var); - temp = new(p->mem_ctx) ir_dereference_variable(temp_var); - f = new(p->mem_ctx) ir_expression(ir_binop_mul, f, temp); + ir_variable *temp_var = p->make_temp(glsl_type::float_type, "fog_temp"); + p->emit(assign(temp_var, mul(f, swizzle_w(oparams)))); + + f = mul(temp_var, temp_var); f = new(p->mem_ctx) ir_expression(ir_unop_neg, f); f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f); break; } - f = saturate(p, f); + p->emit(assign(f_var, saturate(f))); - temp = new(p->mem_ctx) ir_dereference_variable(f_var); - assign = new(p->mem_ctx) ir_assignment(temp, f); - p->instructions->push_tail(assign); - - f = new(p->mem_ctx) ir_dereference_variable(f_var); - f = new(p->mem_ctx) ir_expression(ir_binop_sub, - new(p->mem_ctx) ir_constant(1.0f), - f); + f = sub(new(p->mem_ctx) ir_constant(1.0f), f_var); temp = new(p->mem_ctx) ir_dereference_variable(params); temp = new(p->mem_ctx) ir_dereference_record(temp, "color"); - temp = new(p->mem_ctx) ir_swizzle(temp, 0, 1, 2, 3, 3); - temp = new(p->mem_ctx) ir_expression(ir_binop_mul, temp, f); - - f = new(p->mem_ctx) ir_dereference_variable(f_var); - f = new(p->mem_ctx) ir_expression(ir_binop_mul, fragcolor, f); - f = new(p->mem_ctx) ir_expression(ir_binop_add, temp, f); + temp = mul(swizzle_xyz(temp), f); - ir_dereference *deref = new(p->mem_ctx) ir_dereference_variable(fog_result); - assign = new(p->mem_ctx) ir_assignment(deref, f, NULL, WRITEMASK_XYZ); - p->instructions->push_tail(assign); + p->emit(assign(fog_result, add(temp, mul(fragcolor, f_var)), WRITEMASK_XYZ)); return new(p->mem_ctx) ir_dereference_variable(fog_result); } @@ -1363,40 +1235,24 @@ emit_instructions(struct texenv_fragment_program *p) } ir_rvalue *cf = get_source(p, SRC_PREVIOUS, 0); - ir_dereference_variable *deref; - ir_assignment *assign; if (key->separate_specular) { - ir_rvalue *tmp0; - ir_variable *spec_result = new(p->mem_ctx) ir_variable(glsl_type::vec4_type, - "specular_add", - ir_var_temporary); - - p->instructions->push_tail(spec_result); - - deref = new(p->mem_ctx) ir_dereference_variable(spec_result); - assign = new(p->mem_ctx) ir_assignment(deref, cf); - p->instructions->push_tail(assign); - - deref = new(p->mem_ctx) ir_dereference_variable(spec_result); - tmp0 = new(p->mem_ctx) ir_swizzle(deref, 0, 1, 2, 3, 3); + ir_variable *spec_result = p->make_temp(glsl_type::vec4_type, + "specular_add"); + p->emit(assign(spec_result, cf)); ir_rvalue *secondary; if (p->state->inputs_available & FRAG_BIT_COL1) { ir_variable *var = p->shader->symbols->get_variable("gl_SecondaryColor"); assert(var); - secondary = new(p->mem_ctx) ir_dereference_variable(var); + secondary = swizzle_xyz(var); } else { - secondary = get_current_attrib(p, VERT_ATTRIB_COLOR1); + secondary = swizzle_xyz(get_current_attrib(p, VERT_ATTRIB_COLOR1)); } - secondary = new(p->mem_ctx) ir_swizzle(secondary, 0, 1, 2, 3, 3); - - tmp0 = new(p->mem_ctx) ir_expression(ir_binop_add, tmp0, secondary); - deref = new(p->mem_ctx) ir_dereference_variable(spec_result); - assign = new(p->mem_ctx) ir_assignment(deref, tmp0, NULL, WRITEMASK_XYZ); - p->instructions->push_tail(assign); + p->emit(assign(spec_result, add(swizzle_xyz(spec_result), secondary), + WRITEMASK_XYZ)); cf = new(p->mem_ctx) ir_dereference_variable(spec_result); } @@ -1407,9 +1263,7 @@ emit_instructions(struct texenv_fragment_program *p) ir_variable *frag_color = p->shader->symbols->get_variable("gl_FragColor"); assert(frag_color); - deref = new(p->mem_ctx) ir_dereference_variable(frag_color); - assign = new(p->mem_ctx) ir_assignment(deref, cf); - p->instructions->push_tail(assign); + p->emit(assign(frag_color, cf)); } /** @@ -1419,11 +1273,10 @@ emit_instructions(struct texenv_fragment_program *p) static struct gl_shader_program * create_new_program(struct gl_context *ctx, struct state_key *key) { - struct texenv_fragment_program p; + texenv_fragment_program p; unsigned int unit; _mesa_glsl_parse_state *state; - memset(&p, 0, sizeof(p)); p.mem_ctx = ralloc_context(NULL); p.shader = ctx->Driver.NewShader(ctx, 0, GL_FRAGMENT_SHADER); p.shader->ir = new(p.shader) exec_list; @@ -1457,7 +1310,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key) p.src_previous = NULL; ir_function *main_f = new(p.mem_ctx) ir_function("main"); - p.instructions->push_tail(main_f); + p.emit(main_f); state->symbols->add_function(main_f); ir_function_signature *main_sig = diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c index ff08ac561..7f0bda127 100644 --- a/mesalib/src/mesa/main/format_pack.c +++ b/mesalib/src/mesa/main/format_pack.c @@ -2605,7 +2605,7 @@ _mesa_pack_colormask(gl_format format, const GLubyte colorMask[4], void *dst) if (bits == 8) { GLubyte *d = (GLubyte *) dst; for (i = 0; i < bytes; i++) { - d[i] = d[i] ? 0xffff : 0x0; + d[i] = d[i] ? 0xff : 0x0; } } else if (bits == 16) { diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 9a5ca5334..55dc20550 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -333,6 +333,7 @@ EXTRA_EXT(ARB_copy_buffer); EXTRA_EXT(EXT_framebuffer_sRGB); EXTRA_EXT(ARB_texture_buffer_object); EXTRA_EXT(OES_EGL_image_external); +EXTRA_EXT(ARB_blend_func_extended); static const int extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = { @@ -1304,6 +1305,8 @@ static const struct value_desc values[] = { { GL_MAX_DEBUG_LOGGED_MESSAGES_ARB, CONST(MAX_DEBUG_LOGGED_MESSAGES), NO_EXTRA }, { GL_MAX_DEBUG_MESSAGE_LENGTH_ARB, CONST(MAX_DEBUG_MESSAGE_LENGTH), NO_EXTRA }, + { GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, CONTEXT_INT(Const.MaxDualSourceDrawBuffers), extra_ARB_blend_func_extended }, + #endif /* FEATURE_GL */ }; diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 8e441c232..bfa320a52 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2263,6 +2263,7 @@ struct gl_shader_program * and they are \b not the values returned by \c glGetFragDataLocation. */ struct string_to_uint_map *FragDataBindings; + struct string_to_uint_map *FragDataIndexBindings; /** * Transform feedback varyings last specified by @@ -2814,6 +2815,9 @@ struct gl_constants /* GL_ARB_robustness */ GLenum ResetStrategy; + /* GL_ARB_blend_func_extended */ + GLuint MaxDualSourceDrawBuffers; + /** * Whether the implementation strips out and ignores texture borders. * diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp index 8ab18126c..02a48ba60 100644 --- a/mesalib/src/mesa/main/shader_query.cpp +++ b/mesalib/src/mesa/main/shader_query.cpp @@ -239,10 +239,17 @@ void GLAPIENTRY _mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, const GLchar *name) { + _mesa_BindFragDataLocationIndexed(program, colorNumber, 0, name); +} + +void GLAPIENTRY +_mesa_BindFragDataLocationIndexed(GLuint program, GLuint colorNumber, + GLuint index, const GLchar *name) +{ GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *const shProg = - _mesa_lookup_shader_program_err(ctx, program, "glBindFragDataLocation"); + _mesa_lookup_shader_program_err(ctx, program, "glBindFragDataLocationIndexed"); if (!shProg) return; @@ -250,13 +257,22 @@ _mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, return; if (strncmp(name, "gl_", 3) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindFragDataLocation(illegal name)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragDataLocationIndexed(illegal name)"); + return; + } + + if (index > 1) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(index)"); return; } - if (colorNumber >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocation(index)"); + if (index == 0 && colorNumber >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)"); + return; + } + + if (index == 1 && colorNumber >= ctx->Const.MaxDualSourceDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)"); return; } @@ -265,11 +281,68 @@ _mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, * between built-in attributes and user-defined attributes. */ shProg->FragDataBindings->put(colorNumber + FRAG_RESULT_DATA0, name); - + shProg->FragDataIndexBindings->put(index, name); /* * Note that this binding won't go into effect until * glLinkProgram is called again. */ + +} + +GLint GLAPIENTRY +_mesa_GetFragDataIndex(GLuint program, const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *const shProg = + _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataIndex"); + + if (!shProg) { + return -1; + } + + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetFragDataIndex(program not linked)"); + return -1; + } + + if (!name) + return -1; + + if (strncmp(name, "gl_", 3) == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetFragDataIndex(illegal name)"); + return -1; + } + + /* Not having a fragment shader is not an error. + */ + if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) + return -1; + + exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir; + foreach_list(node, ir) { + const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + /* The extra check against FRAG_RESULT_DATA0 is because + * glGetFragDataLocation cannot be used on "conventional" attributes. + * + * From page 95 of the OpenGL 3.0 spec: + * + * "If name is not an active attribute, if name is a conventional + * attribute, or if an error occurs, -1 will be returned." + */ + if (var == NULL + || var->mode != ir_var_out + || var->location == -1 + || var->location < FRAG_RESULT_DATA0) + continue; + + if (strcmp(var->name, name) == 0) + return var->index; + } + + return -1; } GLint GLAPIENTRY diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 0e655a0d8..e0f20b638 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -1748,6 +1748,9 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec) SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler); SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat); + /* GL_ARB_blend_func_extended */ + SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed); + SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex); #endif /* FEATURE_GL */ } diff --git a/mesalib/src/mesa/main/shaderapi.h b/mesalib/src/mesa/main/shaderapi.h index 0ffebdb07..4886959d5 100644 --- a/mesalib/src/mesa/main/shaderapi.h +++ b/mesalib/src/mesa/main/shaderapi.h @@ -86,6 +86,9 @@ _mesa_GetAttachedObjectsARB(GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); extern GLint GLAPIENTRY _mesa_GetFragDataLocation(GLuint program, const GLchar *name); +extern GLint GLAPIENTRY +_mesa_GetFragDataIndex(GLuint program, const GLchar *name); + extern GLhandleARB GLAPIENTRY _mesa_GetHandleARB(GLenum pname); @@ -128,6 +131,10 @@ _mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, const GLchar *name); extern void GLAPIENTRY +_mesa_BindFragDataLocationIndexed(GLuint program, GLuint colorNumber, + GLuint index, const GLchar *name); + +extern void GLAPIENTRY _mesa_GetActiveAttribARB(GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 36f208d6c..7eb6f0bda 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -242,6 +242,7 @@ _mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog prog->AttributeBindings = string_to_uint_map_ctor(); prog->FragDataBindings = string_to_uint_map_ctor(); + prog->FragDataIndexBindings = string_to_uint_map_ctor(); #if FEATURE_ARB_geometry_shader4 prog->Geom.VerticesOut = 0; @@ -319,6 +320,11 @@ _mesa_free_shader_program_data(struct gl_context *ctx, shProg->FragDataBindings = NULL; } + if (shProg->FragDataIndexBindings) { + string_to_uint_map_dtor(shProg->FragDataIndexBindings); + shProg->FragDataIndexBindings = NULL; + } + /* detach shaders */ for (i = 0; i < shProg->NumShaders; i++) { _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); diff --git a/mesalib/src/mesa/state_tracker/st_atom_blend.c b/mesalib/src/mesa/state_tracker/st_atom_blend.c index 1ffc2f1b7..dea50af67 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_blend.c +++ b/mesalib/src/mesa/state_tracker/st_atom_blend.c @@ -78,10 +78,10 @@ translate_blend(GLenum blend) return PIPE_BLENDFACTOR_CONST_COLOR; case GL_CONSTANT_ALPHA: return PIPE_BLENDFACTOR_CONST_ALPHA; - /* + case GL_SRC1_COLOR: return PIPE_BLENDFACTOR_SRC1_COLOR; + case GL_SRC1_ALPHA: return PIPE_BLENDFACTOR_SRC1_ALPHA; - */ case GL_ZERO: return PIPE_BLENDFACTOR_ZERO; case GL_ONE_MINUS_SRC_COLOR: @@ -96,10 +96,10 @@ translate_blend(GLenum blend) return PIPE_BLENDFACTOR_INV_CONST_COLOR; case GL_ONE_MINUS_CONSTANT_ALPHA: return PIPE_BLENDFACTOR_INV_CONST_ALPHA; - /* + case GL_ONE_MINUS_SRC1_COLOR: return PIPE_BLENDFACTOR_INV_SRC1_COLOR; + case GL_ONE_MINUS_SRC1_ALPHA: return PIPE_BLENDFACTOR_INV_SRC1_ALPHA; - */ default: assert("invalid GL token in translate_blend()" == NULL); return 0; diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index afea0ea4f..34e0329be 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -120,6 +120,10 @@ void st_init_limits(struct st_context *st) = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); + c->MaxDualSourceDrawBuffers + = _clamp(screen->get_param(screen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS), + 0, MAX_DRAW_BUFFERS); + c->MaxLineWidth = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_LINE_WIDTH)); @@ -629,4 +633,7 @@ void st_init_extensions(struct st_context *st) break; } } + + if (ctx->Const.MaxDualSourceDrawBuffers > 0) + ctx->Extensions.ARB_blend_func_extended = GL_TRUE; } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index ae8533e18..9e68deb34 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -1925,7 +1925,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) assert(var->location != -1); entry = new(mem_ctx) variable_storage(var, PROGRAM_OUTPUT, - var->location); + var->location + var->index); break; case ir_var_system_value: entry = new(mem_ctx) variable_storage(var, |