r300: Workaround problem on R500 with very large fragment programs
authorNicolai Hähnle <nhaehnle@gmail.com>
Fri, 2 Oct 2009 23:26:38 +0000 (01:26 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Fri, 2 Oct 2009 23:39:13 +0000 (01:39 +0200)
The non-KMS interface is to blame here. In theory, a proper fix
could be produced that works for the KMS interface only, but it
require cleaning a lot of mess. Easier to just do it right in r300g.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
docs/relnotes-7.6.1.html
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_fragprog_common.c

index a475845c02e3a3e050eb769babea8cdcedd3387e..d69af7aec26f8524348cfdb6f65513f4f5c66f31 100644 (file)
@@ -41,6 +41,7 @@ tbd
 <li>glXQueryContext(GLX_RENDER_TYPE) returned wrong values (bug 24211)
 <li>GLSL sqrt(0) returned unpredictable results
 <li>Fixed default texture binding bug when a bound texture was deleted.
+<li>r300: Work around an issue with very large fragment programs on R500.
 </ul>
 
 </body>
index 2ea1b826de972f6ce3ebe56f2ff70371c2a112d8..9df3897e65c4d169d8a6d21444e9db246b9bb7bd 100644 (file)
@@ -374,11 +374,21 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
        if (screen->chip_family >= CHIP_FAMILY_RV515) {
                ctx->Const.FragmentProgram.MaxNativeTemps = R500_PFS_NUM_TEMP_REGS;
                ctx->Const.FragmentProgram.MaxNativeAttribs = 11;       /* copy i915... */
-               ctx->Const.FragmentProgram.MaxNativeParameters = R500_PFS_NUM_CONST_REGS;
-               ctx->Const.FragmentProgram.MaxNativeAluInstructions = R500_PFS_MAX_INST;
-               ctx->Const.FragmentProgram.MaxNativeTexInstructions = R500_PFS_MAX_INST;
-               ctx->Const.FragmentProgram.MaxNativeInstructions = R500_PFS_MAX_INST;
-               ctx->Const.FragmentProgram.MaxNativeTexIndirections = R500_PFS_MAX_INST;
+
+               /* The hardware limits are higher than this,
+                * but the non-KMS DRM interface artificially limits us
+                * to this many instructions.
+                *
+                * We could of course work around it in the KMS path,
+                * but it would be a mess, so it seems wiser
+                * to leave it as is. Going forward, the Gallium driver
+                * will not be subject to these limitations.
+                */
+               ctx->Const.FragmentProgram.MaxNativeParameters = 255;
+               ctx->Const.FragmentProgram.MaxNativeAluInstructions = 255;
+               ctx->Const.FragmentProgram.MaxNativeTexInstructions = 255;
+               ctx->Const.FragmentProgram.MaxNativeInstructions = 255;
+               ctx->Const.FragmentProgram.MaxNativeTexIndirections = 255;
                ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
        } else {
                ctx->Const.FragmentProgram.MaxNativeTemps = R300_PFS_NUM_TEMP_REGS;
index 0bdc90b4a84ead9cf9a5259c835cf33b0d2992d4..70c92528943719436fc2343e889c1c34e8214a02 100644 (file)
@@ -239,6 +239,19 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog
        rewriteFog(&compiler, fp);
 
        r3xx_compile_fragment_program(&compiler);
+
+       if (compiler.is_r500) {
+               /* We need to support the non-KMS DRM interface, which
+                * artificially limits the number of instructions and
+                * constants which are available to us.
+                *
+                * See also the comment in r300_context.c where we
+                * set the MAX_NATIVE_xxx values.
+                */
+               if (fp->code.code.r500.inst_end >= 255 || fp->code.constants.Count > 255)
+                       rc_error(&compiler.Base, "Program is too big (upgrade to r300g to avoid this limitation).\n");
+       }
+
        fp->error = compiler.Base.Error;
 
        fp->InputsRead = compiler.Base.Program.InputsRead;