r300/compiler: fail to compile if we hit hw limits or an unimplemented feature
authorMarek Olšák <maraeo@gmail.com>
Sun, 22 Aug 2010 18:45:50 +0000 (20:45 +0200)
committerMarek Olšák <maraeo@gmail.com>
Wed, 25 Aug 2010 00:44:28 +0000 (02:44 +0200)
i.e. relative addressing (mainly FS), saturate modifiers, exceeding
the maximum number of constants.

src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c

index d2fa816894ce109e157eb9d33bc571995bfc09c5..59f4efc8883f85ca802d2606bc4659262e6db6fe 100644 (file)
@@ -224,4 +224,14 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
                        r300FragmentProgramDump(c->code);
                }
        }
+
+       /* Check the number of constants. */
+       if (!c->Base.Error) {
+               unsigned max = c->Base.is_r500 ? R500_PFS_NUM_CONST_REGS : R300_PFS_NUM_CONST_REGS;
+
+               if (c->Base.Program.Constants.Count > max) {
+                       rc_error(&c->Base, "Too many constants. Max: %i, Got: %i\n",
+                                max, c->Base.Program.Constants.Count);
+               }
+       }
 }
index 56c5fe6d969defb698a9aa06a244ceb35d2daa53..e54f1d657fda29d3a83357b886bf8f1119aff330 100644 (file)
@@ -484,6 +484,21 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
                if (!valid_dst(compiler->code, &vpi->DstReg))
                        continue;
 
+               if (rc_get_opcode_info(vpi->Opcode)->HasDstReg) {
+                       /* Relative addressing of destination operands is not supported yet. */
+                       if (vpi->DstReg.RelAddr) {
+                               rc_error(&compiler->Base, "Vertex program does not support relative "
+                                        "addressing of destination operands (yet).\n");
+                               return;
+                       }
+
+                       /* Neither is Saturate. */
+                       if (vpi->SaturateMode != RC_SATURATE_NONE) {
+                               rc_error(&compiler->Base, "Vertex program does not support the Saturate "
+                                        "modifier (yet).\n");
+                       }
+               }
+
                if (compiler->code->length >= R500_VS_MAX_ALU_DWORDS ||
                    (compiler->code->length >= R300_VS_MAX_ALU_DWORDS && !compiler->Base.is_r500)) {
                        rc_error(&compiler->Base, "Vertex program has too many instructions\n");
@@ -972,4 +987,11 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
                fprintf(stderr, "Final vertex program code:\n");
                r300_vertex_program_dump(compiler);
        }
+
+       /* Check the number of constants. */
+       if (!compiler->Base.Error &&
+           compiler->Base.Program.Constants.Count > 256) {
+               rc_error(&compiler->Base, "Too many constants. Max: 256, Got: %i\n",
+                        compiler->Base.Program.Constants.Count);
+       }
 }
index 407a0a55ee27155b4855a575f8f3d3bc3b44fcc8..8327e9aced693c7b12e488bf10bd29a950c65815 100644 (file)
@@ -230,6 +230,34 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
 }
 
 
+static void check_opcode_support(struct r300_fragment_program_compiler *c,
+                                struct rc_sub_instruction *inst)
+{
+       const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
+
+       if (opcode->HasDstReg) {
+               if (inst->DstReg.RelAddr) {
+                       rc_error(&c->Base, "Fragment program does not support relative addressing "
+                                "of destination operands.\n");
+                       return;
+               }
+
+               if (inst->SaturateMode == RC_SATURATE_MINUS_PLUS_ONE) {
+                       rc_error(&c->Base, "Fragment program does not support signed Saturate.\n");
+                       return;
+               }
+       }
+
+       for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
+               if (inst->SrcReg[i].RelAddr) {
+                       rc_error(&c->Base, "Fragment program does not support relative addressing "
+                                " of source operands.\n");
+                       return;
+               }
+       }
+}
+
+
 /**
  * Translate all ALU instructions into corresponding pair instructions,
  * performing no other changes.
@@ -249,6 +277,8 @@ void rc_pair_translate(struct r300_fragment_program_compiler *c)
 
                struct rc_sub_instruction copy = inst->U.I;
 
+               check_opcode_support(c, &copy);
+
                final_rewrite(&copy);
                inst->Type = RC_INSTRUCTION_PAIR;
                set_pair_instruction(c, &inst->U.P, &copy);