X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexenvprogram.c;h=4647a9c440549c2a9cc20215cabda87fcd3ab5df;hb=cd6a31cd4a9ea6deef4778c2eaef2d47240c3a6e;hp=5cc5fdaebd1bba60cda3fe01cafce23b836d5dc3;hpb=4a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21e;p=mesa.git diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 5cc5fdaebd1..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 { @@ -306,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 && @@ -406,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; @@ -485,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 */ @@ -659,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; @@ -903,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; } @@ -1095,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, @@ -1199,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 @@ -1408,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; @@ -1436,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; @@ -1485,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; @@ -1560,7 +1580,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, if (DISASSEM) { _mesa_print_program(&p.program->Base); - _mesa_printf("\n"); + printf("\n"); } } @@ -1570,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;