~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
 
66
66
        struct hardware_register * HwTemporary;
67
67
        unsigned int NumHwTemporaries;
 
68
        /**
 
69
         * If an instruction is inside of a loop, end_loop will be the
 
70
         * IP of the ENDLOOP instruction, otherwise end_loop will be 0
 
71
         */
 
72
        int end_loop;
68
73
};
69
74
 
70
75
static void print_live_intervals(struct live_intervals * src)
159
164
}
160
165
 
161
166
static void scan_callback(void * data, struct rc_instruction * inst,
162
 
                rc_register_file file, unsigned int index, unsigned int chan)
 
167
                rc_register_file file, unsigned int index, unsigned int mask)
163
168
{
164
169
        struct regalloc_state * s = data;
165
170
        struct register_info * reg;
178
183
                else
179
184
                        reg->Live.Start = inst->IP;
180
185
                reg->Live.End = inst->IP;
181
 
        } else {
182
 
                if (inst->IP > reg->Live.End)
183
 
                        reg->Live.End = inst->IP;
184
 
        }
 
186
        } else if (s->end_loop)
 
187
                reg->Live.End = s->end_loop;
 
188
        else if (inst->IP > reg->Live.End)
 
189
                reg->Live.End = inst->IP;
185
190
}
186
191
 
187
 
static void compute_live_intervals(struct regalloc_state * s)
 
192
static void compute_live_intervals(struct radeon_compiler *c,
 
193
                                   struct regalloc_state *s)
188
194
{
 
195
        memset(s, 0, sizeof(*s));
 
196
        s->C = c;
 
197
        s->NumHwTemporaries = c->max_temp_regs;
 
198
        s->HwTemporary =
 
199
                memory_pool_malloc(&c->Pool,
 
200
                                   s->NumHwTemporaries * sizeof(struct hardware_register));
 
201
        memset(s->HwTemporary, 0, s->NumHwTemporaries * sizeof(struct hardware_register));
 
202
 
189
203
        rc_recompute_ips(s->C);
190
204
 
191
205
        for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
192
206
            inst != &s->C->Program.Instructions;
193
207
            inst = inst->Next) {
194
 
                rc_for_all_reads(inst, scan_callback, s);
195
 
                rc_for_all_writes(inst, scan_callback, s);
 
208
 
 
209
                /* For all instructions inside of a loop, the ENDLOOP
 
210
                 * instruction is used as the end of the live interval. */
 
211
                if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && !s->end_loop) {
 
212
                        int loops = 1;
 
213
                        struct rc_instruction * tmp;
 
214
                        for(tmp = inst->Next;
 
215
                                        tmp != &s->C->Program.Instructions;
 
216
                                        tmp = tmp->Next) {
 
217
                                if (tmp->U.I.Opcode == RC_OPCODE_BGNLOOP) {
 
218
                                        loops++;
 
219
                                } else if (tmp->U.I.Opcode
 
220
                                                        == RC_OPCODE_ENDLOOP) {
 
221
                                        if(!--loops) {
 
222
                                                s->end_loop = tmp->IP;
 
223
                                                break;
 
224
                                        }
 
225
                                }
 
226
                        }
 
227
                }
 
228
 
 
229
                if (inst->IP == s->end_loop)
 
230
                        s->end_loop = 0;
 
231
 
 
232
                rc_for_all_reads_mask(inst, scan_callback, s);
 
233
                rc_for_all_writes_mask(inst, scan_callback, s);
196
234
        }
197
235
}
198
236
 
199
 
static void rewrite_register(struct regalloc_state * s,
 
237
static void remap_register(void * data, struct rc_instruction * inst,
200
238
                rc_register_file * file, unsigned int * index)
201
239
{
 
240
        struct regalloc_state * s = data;
202
241
        const struct register_info * reg;
203
242
 
204
243
        if (*file == RC_FILE_TEMPORARY)
214
253
        }
215
254
}
216
255
 
217
 
static void rewrite_normal_instruction(struct regalloc_state * s, struct rc_sub_instruction * inst)
218
 
{
219
 
        const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
220
 
 
221
 
        if (opcode->HasDstReg) {
222
 
                rc_register_file file = inst->DstReg.File;
223
 
                unsigned int index = inst->DstReg.Index;
224
 
 
225
 
                rewrite_register(s, &file, &index);
226
 
 
227
 
                inst->DstReg.File = file;
228
 
                inst->DstReg.Index = index;
229
 
        }
230
 
 
231
 
        for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
232
 
                rc_register_file file = inst->SrcReg[src].File;
233
 
                unsigned int index = inst->SrcReg[src].Index;
234
 
 
235
 
                rewrite_register(s, &file, &index);
236
 
 
237
 
                inst->SrcReg[src].File = file;
238
 
                inst->SrcReg[src].Index = index;
239
 
        }
240
 
}
241
 
 
242
 
static void rewrite_pair_instruction(struct regalloc_state * s, struct rc_pair_instruction * inst)
243
 
{
244
 
        if (inst->RGB.WriteMask) {
245
 
                rc_register_file file = RC_FILE_TEMPORARY;
246
 
                unsigned int index = inst->RGB.DestIndex;
247
 
 
248
 
                rewrite_register(s, &file, &index);
249
 
 
250
 
                inst->RGB.DestIndex = index;
251
 
        }
252
 
 
253
 
        if (inst->Alpha.WriteMask) {
254
 
                rc_register_file file = RC_FILE_TEMPORARY;
255
 
                unsigned int index = inst->Alpha.DestIndex;
256
 
 
257
 
                rewrite_register(s, &file, &index);
258
 
 
259
 
                inst->Alpha.DestIndex = index;
260
 
        }
261
 
 
262
 
        for(unsigned int src = 0; src < 3; ++src) {
263
 
                if (inst->RGB.Src[src].Used) {
264
 
                        rc_register_file file = inst->RGB.Src[src].File;
265
 
                        unsigned int index = inst->RGB.Src[src].Index;
266
 
 
267
 
                        rewrite_register(s, &file, &index);
268
 
 
269
 
                        inst->RGB.Src[src].File = file;
270
 
                        inst->RGB.Src[src].Index = index;
271
 
                }
272
 
 
273
 
                if (inst->Alpha.Src[src].Used) {
274
 
                        rc_register_file file = inst->Alpha.Src[src].File;
275
 
                        unsigned int index = inst->Alpha.Src[src].Index;
276
 
 
277
 
                        rewrite_register(s, &file, &index);
278
 
 
279
 
                        inst->Alpha.Src[src].File = file;
280
 
                        inst->Alpha.Src[src].Index = index;
281
 
                }
282
 
        }
283
 
}
284
 
 
285
256
static void do_regalloc(struct regalloc_state * s)
286
257
{
287
258
        /* Simple and stupid greedy register allocation */
310
281
        for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
311
282
            inst != &s->C->Program.Instructions;
312
283
            inst = inst->Next) {
313
 
                if (inst->Type == RC_INSTRUCTION_NORMAL)
314
 
                        rewrite_normal_instruction(s, &inst->U.I);
315
 
                else
316
 
                        rewrite_pair_instruction(s, &inst->U.P);
 
284
                rc_remap_registers(inst, &remap_register, s);
317
285
        }
318
286
}
319
287
 
332
300
 
333
301
}
334
302
 
335
 
void rc_pair_regalloc(struct r300_fragment_program_compiler *c, unsigned maxtemps)
 
303
void rc_pair_regalloc(struct radeon_compiler *cc, void *user)
336
304
{
 
305
        struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc;
337
306
        struct regalloc_state s;
338
307
 
339
 
        memset(&s, 0, sizeof(s));
340
 
        s.C = &c->Base;
341
 
        s.NumHwTemporaries = maxtemps;
342
 
        s.HwTemporary = memory_pool_malloc(&s.C->Pool, maxtemps*sizeof(struct hardware_register));
343
 
        memset(s.HwTemporary, 0, maxtemps*sizeof(struct hardware_register));
344
 
 
345
 
        compute_live_intervals(&s);
 
308
        compute_live_intervals(cc, &s);
346
309
 
347
310
        c->AllocateHwInputs(c, &alloc_input, &s);
348
311
 
349
312
        do_regalloc(&s);
350
313
}
 
314
 
 
315
/* This functions offsets the temporary register indices by the number
 
316
 * of input registers, because input registers are actually temporaries and
 
317
 * should not occupy the same space.
 
318
 *
 
319
 * This pass is supposed to be used to maintain correct allocation of inputs
 
320
 * if the standard register allocation is disabled. */
 
321
void rc_pair_regalloc_inputs_only(struct radeon_compiler *cc, void *user)
 
322
{
 
323
        struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc;
 
324
        struct regalloc_state s;
 
325
 
 
326
        compute_live_intervals(cc, &s);
 
327
 
 
328
        c->AllocateHwInputs(c, &alloc_input, &s);
 
329
 
 
330
        int temp_reg_offset = 0;
 
331
        for (unsigned i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
 
332
                if (s.Input[i].Allocated && temp_reg_offset <= s.Input[i].Index)
 
333
                        temp_reg_offset = s.Input[i].Index + 1;
 
334
        }
 
335
 
 
336
        if (temp_reg_offset) {
 
337
                for (unsigned i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
 
338
                        if (s.Temporary[i].Used) {
 
339
                                s.Temporary[i].Allocated = 1;
 
340
                                s.Temporary[i].File = RC_FILE_TEMPORARY;
 
341
                                s.Temporary[i].Index = i + temp_reg_offset;
 
342
                        }
 
343
                }
 
344
 
 
345
                /* Rewrite all registers. */
 
346
                for (struct rc_instruction *inst = cc->Program.Instructions.Next;
 
347
                    inst != &cc->Program.Instructions;
 
348
                    inst = inst->Next) {
 
349
                        rc_remap_registers(inst, &remap_register, &s);
 
350
                }
 
351
        }
 
352
}