[Mesa-dev] [PATCH 1/9] mesa: Fix bugs in ff fragment shader fog handling

Ian Romanick idr at freedesktop.org
Fri Apr 15 23:10:44 PDT 2011


From: Ian Romanick <ian.d.romanick at intel.com>

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.
---
 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) {
-- 
1.7.4



More information about the mesa-dev mailing list