X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexenvprogram.c;h=4647a9c440549c2a9cc20215cabda87fcd3ab5df;hb=cd6a31cd4a9ea6deef4778c2eaef2d47240c3a6e;hp=499b7330d0a35ffcfe0a67b834a7f843f09c151d;hpb=b46bcd8e7b37aa2e9159e126c1cc88234a3c2790;p=mesa.git diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 499b7330d0a..4647a9c4405 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -28,13 +28,13 @@ #include "glheader.h" #include "imports.h" -#include "shader/program.h" -#include "shader/prog_parameter.h" -#include "shader/prog_cache.h" -#include "shader/prog_instruction.h" -#include "shader/prog_print.h" -#include "shader/prog_statevars.h" -#include "shader/programopt.h" +#include "program/program.h" +#include "program/prog_parameter.h" +#include "program/prog_cache.h" +#include "program/prog_instruction.h" +#include "program/prog_print.h" +#include "program/prog_statevars.h" +#include "program/programopt.h" #include "texenvprogram.h" @@ -62,7 +62,7 @@ struct texenvprog_cache_item }; static GLboolean -texenv_doing_secondary_color(GLcontext *ctx) +texenv_doing_secondary_color(struct gl_context *ctx) { if (ctx->Light.Enabled && (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) @@ -98,6 +98,7 @@ struct state_key { GLuint fog_enabled:1; GLuint fog_mode:2; /**< FOG_x */ GLuint inputs_available:12; + GLuint num_draw_buffers:4; /* NOTE: This array of structs must be last! (see "keySize" below) */ struct { @@ -113,6 +114,8 @@ struct state_key { GLuint NumArgsA:3; /**< up to MAX_COMBINER_TERMS */ GLuint ModeA:5; /**< MODE_x */ + GLuint texture_cyl_wrap:1; /**< For gallium test/debug only */ + struct mode_opt OptRGB[MAX_COMBINER_TERMS]; struct mode_opt OptA[MAX_COMBINER_TERMS]; } unit[MAX_TEXTURE_UNITS]; @@ -304,7 +307,7 @@ static GLuint translate_tex_src_bit( GLbitfield bit ) * has access to. The bitmask is later reduced to just those which * are actually referenced. */ -static GLbitfield get_fp_input_mask( GLcontext *ctx ) +static GLbitfield get_fp_input_mask( struct gl_context *ctx ) { /* _NEW_PROGRAM */ const GLboolean vertexShader = (ctx->Shader.CurrentProgram && @@ -404,7 +407,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx ) * Examine current texture environment state and generate a unique * key to identify it. */ -static GLuint make_state_key( GLcontext *ctx, struct state_key *key ) +static GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) { GLuint i, j; GLbitfield inputs_referenced = FRAG_BIT_COL0; @@ -464,6 +467,10 @@ static GLuint make_state_key( GLcontext *ctx, struct state_key *key ) key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR; key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0; } + + /* this is a back-door for enabling cylindrical texture wrap mode */ + if (texObj->Priority == 0.125) + key->unit[i].texture_cyl_wrap = 1; } /* _NEW_LIGHT | _NEW_FOG */ @@ -479,6 +486,9 @@ static GLuint make_state_key( GLcontext *ctx, struct state_key *key ) inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ } + /* _NEW_BUFFERS */ + key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; + key->inputs_available = (inputs_available & inputs_referenced); /* compute size of state key, ignoring unused texture units */ @@ -653,7 +663,7 @@ static void reserve_temp( struct texenv_fragment_program *p, struct ureg r ) } -static void release_temps(GLcontext *ctx, struct texenv_fragment_program *p ) +static void release_temps(struct gl_context *ctx, struct texenv_fragment_program *p ) { GLuint max_temp = ctx->Const.FragmentProgram.MaxTemps; @@ -897,7 +907,7 @@ static struct ureg get_zero( struct texenv_fragment_program *p ) static void program_error( struct texenv_fragment_program *p, const char *msg ) { - _mesa_problem(NULL, msg); + _mesa_problem(NULL, "%s", msg); p->error = 1; } @@ -1089,7 +1099,7 @@ static struct ureg emit_combine( struct texenv_fragment_program *p, emit_arith( p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0, two, src[0], neg1); - if (_mesa_memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) + if (memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) tmp1 = tmp0; else emit_arith( p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0, @@ -1193,11 +1203,14 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) else alpha_saturate = GL_FALSE; - /* If this is the very last calculation, emit direct to output reg: + /* If this is the very last calculation (and various other conditions + * are met), emit directly to the color output register. Otherwise, + * emit to a temporary register. */ if (key->separate_specular || unit != p->last_tex_stage || alpha_shift || + key->num_draw_buffers != 1 || rgb_shift) dest = get_temp( p ); else @@ -1302,6 +1315,12 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) } else p->src_texture[unit] = get_zero(p); + + if (p->state->unit[unit].texture_cyl_wrap) { + /* set flag which is checked by Mesa->Gallium program translation */ + p->program->Base.InputFlags[0] |= PROG_PARAM_BIT_CYL_WRAP; + } + } } @@ -1396,15 +1415,16 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit ) * current texture env/combine mode. */ static void -create_new_program(GLcontext *ctx, struct state_key *key, +create_new_program(struct gl_context *ctx, struct state_key *key, struct gl_fragment_program *program) { struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; struct texenv_fragment_program p; GLuint unit; struct ureg cf, out; + int i; - _mesa_memset(&p, 0, sizeof(p)); + memset(&p, 0, sizeof(p)); p.state = key; p.program = program; @@ -1424,7 +1444,13 @@ create_new_program(GLcontext *ctx, struct state_key *key, p.program->Base.NumAddressRegs = 0; p.program->Base.Parameters = _mesa_new_parameter_list(); p.program->Base.InputsRead = 0x0; - p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR; + + if (key->num_draw_buffers == 1) + p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR; + else { + for (i = 0; i < key->num_draw_buffers; i++) + p.program->Base.OutputsWritten |= (1 << (FRAG_RESULT_DATA0 + i)); + } for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { p.src_texture[unit] = undef; @@ -1473,28 +1499,34 @@ create_new_program(GLcontext *ctx, struct state_key *key, } cf = get_source( &p, SRC_PREVIOUS, 0 ); - out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLOR ); - if (key->separate_specular) { - /* Emit specular add. - */ - struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); - emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); - emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); - } - else if (_mesa_memcmp(&cf, &out, sizeof(cf)) != 0) { - /* Will wind up in here if no texture enabled or a couple of - * other scenarios (GL_REPLACE for instance). - */ - emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); - } + for (i = 0; i < key->num_draw_buffers; i++) { + if (key->num_draw_buffers == 1) + out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLOR ); + else { + out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i ); + } + if (key->separate_specular) { + /* Emit specular add. + */ + struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); + emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); + emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); + } + else if (memcmp(&cf, &out, sizeof(cf)) != 0) { + /* Will wind up in here if no texture enabled or a couple of + * other scenarios (GL_REPLACE for instance). + */ + emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); + } + } /* Finish up: */ emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef); if (key->fog_enabled) { - /* Pull fog mode from GLcontext, the value in the state key is + /* Pull fog mode from struct gl_context, the value in the state key is * a reduced value and not what is expected in FogOption */ p.program->FogOption = ctx->Fog.Mode; @@ -1535,13 +1567,20 @@ create_new_program(GLcontext *ctx, struct state_key *key, /* Notify driver the fragment program has (actually) changed. */ if (ctx->Driver.ProgramStringNotify) { - ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, - &p.program->Base ); + GLboolean ok = ctx->Driver.ProgramStringNotify(ctx, + GL_FRAGMENT_PROGRAM_ARB, + &p.program->Base); + /* Driver should be able to handle any texenv programs as long as + * the driver correctly reported max number of texture units correctly, + * etc. + */ + ASSERT(ok); + (void) ok; /* silence unused var warning */ } if (DISASSEM) { _mesa_print_program(&p.program->Base); - _mesa_printf("\n"); + printf("\n"); } } @@ -1551,7 +1590,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, * fixed-function texture, fog and color-sum operations. */ struct gl_fragment_program * -_mesa_get_fixed_func_fragment_program(GLcontext *ctx) +_mesa_get_fixed_func_fragment_program(struct gl_context *ctx) { struct gl_fragment_program *prog; struct state_key key;