summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2011-04-15 18:38:54 -0700
committerIan Romanick <[email protected]>2011-04-21 17:33:18 -0700
commit3aa21f93dc1329c6f956277f2746c2a0bdae5446 (patch)
treebb08ebb6350c487bb69e8366ffcbeeb957273ba8
parenta22aba4eae9b29db731487bce90e8292f7e82c72 (diff)
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 <[email protected]> Acked-by: Corbin Simpson <[email protected]> Acked-by: Alex Deucher <[email protected]>
-rw-r--r--src/mesa/main/ff_fragment_shader.cpp39
1 files 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) {