r300: cleanup frag prog setup a little
authorMaciej Cencora <m.cencora@gmail.com>
Thu, 16 Apr 2009 15:50:13 +0000 (17:50 +0200)
committerDave Airlie <airlied@redhat.com>
Fri, 17 Apr 2009 01:27:31 +0000 (11:27 +1000)
Use proper fields for marking if fp is translated, and if is translated succesfully.
Now if fp gets translated (even unsuccesfully) fp->translated is true. If the translation failed (i.e. because we exceeded limit of
maximum texture indirections) the fp->error is set. With a little updated fallback function it prevents non native fragment programs
from beeing translated with every frame (the translation would fail anyway so there's no point to try again).

Also implement IsProgramNative function for GL_FRAGMENT_PROGRAM_ARB (it should give some performance boost in apps that checks if
program is native and falls back to simpler shader to meet hw limits if necessary) and cleanup indentation (remove whitespaces on empty
lines).

src/mesa/drivers/dri/r300/r300_fragprog.c
src/mesa/drivers/dri/r300/r300_render.c
src/mesa/drivers/dri/r300/r300_shader.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r500_fragprog.c

index 32182bb66744ea18ca219eca4749e8ce75c1d2ee..f2d7cec5d3688de0f9a9cb9f48974a06a6e2a34a 100644 (file)
@@ -175,7 +175,7 @@ static GLboolean transform_TEX(
                inst.SrcReg[0].File = PROGRAM_TEMPORARY;
                inst.SrcReg[0].Index = tmpreg;
        }
-       
+
        tgt = radeonAppendInstructions(t->Program, 1);
        _mesa_copy_instructions(tgt, &inst, 1);
 
@@ -466,8 +466,8 @@ void r300TranslateFragmentShader(r300ContextPtr r300,
 
                _mesa_reference_program(r300->radeon.glCtx, &compiler.program, NULL);
 
-               if (!fp->error)
-                       fp->translated = GL_TRUE;
+               fp->translated = GL_TRUE;
+
                if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
                        r300FragmentProgramDump(fp, &fp->code);
                r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM);
index 924305dd128cfa43bbbc16d632eb2866d01caf9e..d33396e150a7b9f2b8c615b46afbb8099cc48020 100644 (file)
@@ -194,7 +194,7 @@ static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type)
                          ((vertex_count + 0) << 16) |
                          type |
                          R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
-               
+
                if (!rmesa->radeon.radeonScreen->kernel_mm) {
                        OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2);
                        OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) |
@@ -224,12 +224,12 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
        uint32_t voffset;
        int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
        int i;
-       
+
        if (RADEON_DEBUG & DEBUG_VERTS)
                fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
                        offset);
 
-    
+
        if (!rmesa->radeon.radeonScreen->kernel_mm) {
                BEGIN_BATCH(sz+2+(nr * 2));
                OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1);
@@ -240,7 +240,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
                                  (rmesa->radeon.tcl.aos[i].stride << 8) |
                                  (rmesa->radeon.tcl.aos[i + 1].components << 16) |
                                  (rmesa->radeon.tcl.aos[i + 1].stride << 24));
-                       
+
                        voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
                                offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
                        OUT_BATCH_RELOC(voffset,
@@ -256,7 +256,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
                                        RADEON_GEM_DOMAIN_GTT,
                                        0, 0);
                }
-               
+
                if (nr & 1) {
                        OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
                                  (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
@@ -280,7 +280,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
                                  (rmesa->radeon.tcl.aos[i].stride << 8) |
                                  (rmesa->radeon.tcl.aos[i + 1].components << 16) |
                                  (rmesa->radeon.tcl.aos[i + 1].stride << 24));
-                       
+
                        voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
                                offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
                        OUT_BATCH(voffset);
@@ -288,7 +288,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
                                offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
                        OUT_BATCH(voffset);
                }
-               
+
                if (nr & 1) {
                        OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
                          (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
@@ -427,7 +427,7 @@ static int r300Fallback(GLcontext * ctx)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
        const unsigned back = ctx->Stencil._BackFace;
-       
+
        FALLBACK_IF(r300->radeon.Fallback);
        /* Do we need to use new-style shaders?
         * Also is there a better way to do this? */
@@ -435,19 +435,19 @@ static int r300Fallback(GLcontext * ctx)
                struct r500_fragment_program *fp = (struct r500_fragment_program *)
            (char *)ctx->FragmentProgram._Current;
                if (fp) {
-                       if (!fp->translated) {
+                       if (!fp->translated)
                                r500TranslateFragmentShader(r300, fp);
-                               FALLBACK_IF(!fp->translated);
-                       }
+
+                       FALLBACK_IF(fp->error);
                }
        } else {
                struct r300_fragment_program *fp = (struct r300_fragment_program *)
            (char *)ctx->FragmentProgram._Current;
                if (fp) {
-                       if (!fp->translated) {
+                       if (!fp->translated)
                                r300TranslateFragmentShader(r300, fp);
-                               FALLBACK_IF(!fp->translated);
-                       }
+
+                       FALLBACK_IF(fp->error);
                }
        }
 
@@ -492,7 +492,7 @@ static GLboolean r300RunNonTCLRender(GLcontext * ctx,
 
        if (!r300ValidateBuffers(ctx))
            return GL_TRUE;
-       
+
        return r300RunRender(ctx, stage);
 }
 
@@ -517,7 +517,7 @@ static GLboolean r300RunTCLRender(GLcontext * ctx,
 
        if (!r300ValidateBuffers(ctx))
            return GL_TRUE;
-       
+
        r300UpdateShaders(rmesa);
 
        vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
index f30fd986e0f0c1029b60eb9cd7158be259433704..d90658ba478237fabf5cfb065a4e60f16301f5e8 100644 (file)
@@ -81,7 +81,26 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
 static GLboolean
 r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
 {
-       return GL_TRUE;
+       if (target == GL_FRAGMENT_PROGRAM_ARB) {
+               r300ContextPtr rmesa = R300_CONTEXT(ctx);
+
+               if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+                       struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)prog;
+
+                       if (!r500_fp->translated)
+                               r500TranslateFragmentShader(rmesa, r500_fp);
+
+                       return !r500_fp->error;
+               } else {
+                       struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog;
+
+                       if (!r300_fp->translated)
+                               r300TranslateFragmentShader(rmesa, r300_fp);
+
+                       return !r300_fp->error;
+               }
+       } else
+               return GL_TRUE;
 }
 
 void r300InitShaderFuncs(struct dd_function_table *functions)
index f464335422f6b0914d03487529e3cb466946b03e..64ec87097606de0a3bc7d953c63bf514d55955b0 100644 (file)
@@ -2301,7 +2301,7 @@ static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx,
 }
 
 
-static void r300SetupPixelShader(r300ContextPtr rmesa)
+static GLboolean r300SetupPixelShader(r300ContextPtr rmesa)
 {
        GLcontext *ctx = rmesa->radeon.glCtx;
        struct r300_fragment_program *fp = (struct r300_fragment_program *)
@@ -2309,15 +2309,12 @@ static void r300SetupPixelShader(r300ContextPtr rmesa)
        struct r300_fragment_program_code *code;
        int i, k;
 
-       if (!fp)                /* should only happenen once, just after context is created */
-               return;
-
        r300TranslateFragmentShader(rmesa, fp);
-       if (!fp->translated) {
-               fprintf(stderr, "%s: No valid fragment shader, exiting\n",
-                       __FUNCTION__);
-               return;
-       }
+
+       /* Program is not native, fallback to software */
+       if (fp->error)
+               return GL_FALSE;
+
        code = &fp->code;
 
        r300SetupTextures(ctx);
@@ -2369,6 +2366,8 @@ static void r300SetupPixelShader(r300ContextPtr rmesa)
                rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(constant[2]);
                rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat24(constant[3]);
        }
+
+       return GL_TRUE;
 }
 
 #define bump_r500fp_count(ptr, new_count)   do{\
@@ -2385,7 +2384,7 @@ static void r300SetupPixelShader(r300ContextPtr rmesa)
        if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
 } while(0)
 
-static void r500SetupPixelShader(r300ContextPtr rmesa)
+static GLboolean r500SetupPixelShader(r300ContextPtr rmesa)
 {
        GLcontext *ctx = rmesa->radeon.glCtx;
        struct r500_fragment_program *fp = (struct r500_fragment_program *)
@@ -2393,18 +2392,15 @@ static void r500SetupPixelShader(r300ContextPtr rmesa)
        int i;
        struct r500_fragment_program_code *code;
 
-       if (!fp)                /* should only happenen once, just after context is created */
-               return;
-
        ((drm_r300_cmd_header_t *) rmesa->hw.r500fp.cmd)->r500fp.count = 0;
        ((drm_r300_cmd_header_t *) rmesa->hw.r500fp_const.cmd)->r500fp.count = 0;
 
        r500TranslateFragmentShader(rmesa, fp);
-       if (!fp->translated) {
-               fprintf(stderr, "%s: No valid fragment shader, exiting\n",
-                       __FUNCTION__);
-               return;
-       }
+
+       /* Program is not native, fallback to software */
+       if (fp->error)
+               return GL_FALSE;
+
        code = &fp->code;
 
        r300SetupTextures(ctx);
@@ -2445,6 +2441,7 @@ static void r500SetupPixelShader(r300ContextPtr rmesa)
        }
        bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, code->const_nr * 4);
 
+       return GL_TRUE;
 }
 
 void r300UpdateShaderStates(r300ContextPtr rmesa)
@@ -2452,6 +2449,10 @@ void r300UpdateShaderStates(r300ContextPtr rmesa)
        GLcontext *ctx;
        ctx = rmesa->radeon.glCtx;
 
+       /* should only happenen once, just after context is created */
+       if (!ctx->FragmentProgram._Current)
+               return;
+
        r300SetEarlyZState(ctx);
 
        /* w_fmt value is set to get best performance
@@ -2475,19 +2476,18 @@ void r300UpdateShaderStates(r300ContextPtr rmesa)
                rmesa->hw.fg_depth_src.cmd[1] = fgdepthsrc;
        }
 
-       if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
-               r500SetupPixelShader(rmesa);
-       else
-               r300SetupPixelShader(rmesa);
-
-       if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
+       if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+               if (!r500SetupPixelShader(rmesa))
+                       return;
                r500SetupRSUnit(ctx);
-       else
+       } else {
+               if (!r300SetupPixelShader(rmesa))
+                       return;
                r300SetupRSUnit(ctx);
+       }
 
        if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
                r300SetupVertexProgram(rmesa);
-
 }
 
 /**
index 07a2a7b17ce5ca3b102460e2d5989ef0131e6d94..1b8343ab215df8fca0ea70c4ac67c613563cfc1c 100644 (file)
@@ -493,7 +493,10 @@ void r500TranslateFragmentShader(r300ContextPtr r300,
                        _mesa_print_program(compiler.program);
                }
 
-               fp->translated = r500FragmentProgramEmit(&compiler);
+               if (!r500FragmentProgramEmit(&compiler))
+                       fp->error = GL_TRUE;
+
+               fp->translated = GL_TRUE;
 
                /* Subtle: Rescue any parameters that have been added during transformations */
                _mesa_free_parameter_list(fp->mesa_program.Base.Parameters);
@@ -505,7 +508,7 @@ void r500TranslateFragmentShader(r300ContextPtr r300,
                r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM);
 
                if (RADEON_DEBUG & DEBUG_PIXEL) {
-                       if (fp->translated) {
+                       if (!fp->error) {
                                _mesa_printf("Machine-readable code:\n");
                                dump_program(&fp->code);
                        }