Mesa (master): mesa: Fix bugs in ff fragment shader fog handling

Ian Romanick idr at kemper.freedesktop.org
Thu Apr 21 17:34:35 PDT 2011


Module: Mesa
Branch: master
Commit: 3aa21f93dc1329c6f956277f2746c2a0bdae5446
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3aa21f93dc1329c6f956277f2746c2a0bdae5446

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Apr 15 18:38:54 2011 -0700

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 <eric at anholt.net>
Acked-by: Corbin Simpson <MostAwesomeDude at gmail.com>
Acked-by: Alex Deucher <alexdeucher at gmail.com>

---

 src/mesa/main/ff_fragment_shader.cpp |   39 +++++++++++++++++----------------
 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 43930a4..b799b29 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) {



More information about the mesa-commit mailing list