From 3aa21f93dc1329c6f956277f2746c2a0bdae5446 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 15 Apr 2011 18:38:54 -0700 Subject: [PATCH] mesa: Fix bugs in ff fragment shader fog handling This patch fixes two bugs related to fog in the fixed-function fragment shader generation code. Fog was only lowered to instructions if MRTs were used. The fragment shader assembler always lowers "fog option" code to instructions, and many drivers (e.g., r300) expect this. When fog lowering did happen, it was after the instruction count was checked against implementation limits. Since fog lowering may add up to 5 instructions, a program that was below the limits before lowering may exceed the limits after lowering. NOTE: This is a candidate for the stable branches. Reviewed-by: Eric Anholt Acked-by: Corbin Simpson Acked-by: Alex Deucher --- src/mesa/main/ff_fragment_shader.cpp | 39 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp index 43930a4b30e..b799b292664 100644 --- a/src/mesa/main/ff_fragment_shader.cpp +++ b/src/mesa/main/ff_fragment_shader.cpp @@ -1530,14 +1530,32 @@ create_new_program(struct gl_context *ctx, struct state_key *key, */ emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef); + /* Allocate final instruction array. This has to be done before calling + * _mesa_append_fog_code because that function frees the Base.Instructions. + * At this point, Base.Instructions points to stack data, so it's a really + * bad idea to free it. + */ + p.program->Base.Instructions + = _mesa_alloc_instructions(p.program->Base.NumInstructions); + if (!p.program->Base.Instructions) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "generating tex env program"); + return; + } + _mesa_copy_instructions(p.program->Base.Instructions, instBuffer, + p.program->Base.NumInstructions); + + /* Append fog code. This must be done before checking the program against + * the limits becuase it will potentially add some instructions. + */ if (key->fog_enabled) { /* 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; p.program->Base.InputsRead |= FRAG_BIT_FOGC; - } - else { + + _mesa_append_fog_code(ctx, p.program, GL_FALSE); p.program->FogOption = GL_NONE; } @@ -1552,23 +1570,6 @@ create_new_program(struct gl_context *ctx, struct state_key *key, ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); - /* Allocate final instruction array */ - p.program->Base.Instructions - = _mesa_alloc_instructions(p.program->Base.NumInstructions); - if (!p.program->Base.Instructions) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "generating tex env program"); - return; - } - _mesa_copy_instructions(p.program->Base.Instructions, instBuffer, - p.program->Base.NumInstructions); - - if (key->num_draw_buffers && p.program->FogOption) { - _mesa_append_fog_code(ctx, p.program, GL_FALSE); - p.program->FogOption = GL_NONE; - } - - /* Notify driver the fragment program has (actually) changed. */ if (ctx->Driver.ProgramStringNotify) { -- 2.30.2