~ubuntu-branches/ubuntu/precise/mesa/precise-security

« back to all changes in this revision

Viewing changes to src/gallium/drivers/r300/r300_vs_draw.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers, Steve Beattie
  • Date: 2012-10-19 09:04:04 UTC
  • mfrom: (163.1.4 precise-proposed)
  • Revision ID: package-import@ubuntu.com-20121019090404-5zbjpsp6knv7zl3b
Tags: 8.0.4-0ubuntu0.2
[ Steve Beattie ]
* SECURITY UPDATE: samplers array overflow (LP: #1046933)
  - debian/patches/50-CVE-2012-2864.patch: ensure that more than
    MAX_SAMPLERS are not used
  - CVE-2012-2864

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 *
30
30
 * Transformations:
31
31
 * 1) If the secondary color output is present, the primary color must be
32
 
 *    inserted before it.
 
32
 *    present too.
33
33
 * 2) If any back-face color output is present, there must be all 4 color
34
34
 *    outputs and missing ones must be inserted.
35
35
 * 3) Insert a trailing texcoord output containing a copy of POS, for WPOS.
52
52
 
53
53
    boolean color_used[2];
54
54
    boolean bcolor_used[2];
55
 
    boolean temp_used[128];
56
55
 
57
56
    /* Index of the pos output, typically 0. */
58
57
    unsigned pos_output;
72
71
    boolean first_instruction;
73
72
    /* End instruction processed? */
74
73
    boolean end_instruction;
 
74
 
 
75
    boolean temp_used[1024];
75
76
};
76
77
 
77
78
static void emit_temp(struct tgsi_transform_context *ctx, unsigned reg)
102
103
    ++vsctx->num_outputs;
103
104
}
104
105
 
105
 
static void insert_output(struct tgsi_transform_context *ctx,
106
 
                          struct tgsi_full_declaration *before,
107
 
                          unsigned name, unsigned index, unsigned interp)
 
106
static void insert_output_before(struct tgsi_transform_context *ctx,
 
107
                                 struct tgsi_full_declaration *before,
 
108
                                 unsigned name, unsigned index, unsigned interp)
108
109
{
109
110
    struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
110
111
    unsigned i;
115
116
    }
116
117
 
117
118
    /* Insert the new output. */
118
 
    emit_output(ctx, name, index, interp, before->Range.First);
 
119
    emit_output(ctx, name, index, interp,
 
120
                before->Range.First + vsctx->decl_shift);
119
121
 
120
122
    ++vsctx->decl_shift;
121
123
}
122
124
 
123
 
static void insert_trailing_bcolor(struct tgsi_transform_context *ctx,
124
 
                                   struct tgsi_full_declaration *before)
 
125
static void insert_output_after(struct tgsi_transform_context *ctx,
 
126
                                struct tgsi_full_declaration *after,
 
127
                                unsigned name, unsigned index, unsigned interp)
125
128
{
126
129
    struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
 
130
    unsigned i;
127
131
 
128
 
    /* If BCOLOR0 is used, make sure BCOLOR1 is present too. Otherwise
129
 
     * the rasterizer doesn't do the color selection correctly. */
130
 
    if (vsctx->bcolor_used[0] && !vsctx->bcolor_used[1]) {
131
 
        if (before) {
132
 
            insert_output(ctx, before, TGSI_SEMANTIC_BCOLOR, 1,
133
 
                          TGSI_INTERPOLATE_LINEAR);
134
 
        } else {
135
 
            emit_output(ctx, TGSI_SEMANTIC_BCOLOR, 1,
136
 
                        TGSI_INTERPOLATE_LINEAR, vsctx->num_outputs);
137
 
        }
138
 
        vsctx->bcolor_used[1] = TRUE;
 
132
    /* Make a place for the new output. */
 
133
    for (i = after->Range.First+1; i < Elements(vsctx->out_remap); i++) {
 
134
        ++vsctx->out_remap[i];
139
135
    }
 
136
 
 
137
    /* Insert the new output. */
 
138
    emit_output(ctx, name, index, interp,
 
139
                after->Range.First + 1);
 
140
 
 
141
    ++vsctx->decl_shift;
140
142
}
141
143
 
142
144
static void transform_decl(struct tgsi_transform_context *ctx,
153
155
 
154
156
            case TGSI_SEMANTIC_COLOR:
155
157
                assert(decl->Semantic.Index < 2);
156
 
                vsctx->color_used[decl->Semantic.Index] = TRUE;
157
158
 
158
159
                /* We must rasterize the first color if the second one is
159
160
                 * used, otherwise the rasterizer doesn't do the color
160
161
                 * selection correctly. Declare it, but don't write to it. */
161
162
                if (decl->Semantic.Index == 1 && !vsctx->color_used[0]) {
162
 
                    insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
163
 
                                  TGSI_INTERPOLATE_LINEAR);
 
163
                    insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
 
164
                                         TGSI_INTERPOLATE_LINEAR);
164
165
                    vsctx->color_used[0] = TRUE;
165
166
                }
166
167
                break;
167
168
 
168
169
            case TGSI_SEMANTIC_BCOLOR:
169
170
                assert(decl->Semantic.Index < 2);
170
 
                vsctx->bcolor_used[decl->Semantic.Index] = TRUE;
171
171
 
172
172
                /* We must rasterize all 4 colors if back-face colors are
173
173
                 * used, otherwise the rasterizer doesn't do the color
174
174
                 * selection correctly. Declare it, but don't write to it. */
175
175
                if (!vsctx->color_used[0]) {
176
 
                    insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
177
 
                                  TGSI_INTERPOLATE_LINEAR);
 
176
                    insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
 
177
                                         TGSI_INTERPOLATE_LINEAR);
178
178
                    vsctx->color_used[0] = TRUE;
179
179
                }
180
180
                if (!vsctx->color_used[1]) {
181
 
                    insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 1,
182
 
                                  TGSI_INTERPOLATE_LINEAR);
 
181
                    insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 1,
 
182
                                         TGSI_INTERPOLATE_LINEAR);
183
183
                    vsctx->color_used[1] = TRUE;
184
184
                }
185
185
                if (decl->Semantic.Index == 1 && !vsctx->bcolor_used[0]) {
186
 
                    insert_output(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0,
187
 
                                  TGSI_INTERPOLATE_LINEAR);
 
186
                    insert_output_before(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0,
 
187
                                         TGSI_INTERPOLATE_LINEAR);
188
188
                    vsctx->bcolor_used[0] = TRUE;
189
189
                }
190
 
                /* One more case is handled in insert_trailing_bcolor. */
191
190
                break;
192
191
 
193
192
            case TGSI_SEMANTIC_GENERIC:
195
194
                break;
196
195
        }
197
196
 
198
 
        if (decl->Semantic.Name != TGSI_SEMANTIC_BCOLOR) {
199
 
            /* Insert it as soon as possible. */
200
 
            insert_trailing_bcolor(ctx, decl);
201
 
        }
202
 
 
203
197
        /* Since we're inserting new outputs in between, the following outputs
204
198
         * should be moved to the right so that they don't overlap with
205
199
         * the newly added ones. */
214
208
    }
215
209
 
216
210
    ctx->emit_declaration(ctx, decl);
 
211
 
 
212
    /* Insert BCOLOR1 if needed. */
 
213
    if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
 
214
        decl->Semantic.Name == TGSI_SEMANTIC_BCOLOR &&
 
215
        !vsctx->bcolor_used[1]) {
 
216
        insert_output_after(ctx, decl, TGSI_SEMANTIC_BCOLOR, 1,
 
217
                            TGSI_INTERPOLATE_LINEAR);
 
218
    }
217
219
}
218
220
 
219
221
static void transform_inst(struct tgsi_transform_context *ctx,
226
228
    if (!vsctx->first_instruction) {
227
229
        vsctx->first_instruction = TRUE;
228
230
 
229
 
        /* The trailing BCOLOR should be inserted before the code
230
 
         * if it hasn't already been done so. */
231
 
        insert_trailing_bcolor(ctx, NULL);
232
 
 
233
231
        /* Insert the generic output for WPOS. */
234
232
        emit_output(ctx, TGSI_SEMANTIC_GENERIC, vsctx->last_generic + 1,
235
233
                    TGSI_INTERPOLATE_PERSPECTIVE, vsctx->num_outputs);
309
307
    ctx->emit_instruction(ctx, inst);
310
308
}
311
309
 
312
 
void r300_draw_init_vertex_shader(struct draw_context *draw,
 
310
void r300_draw_init_vertex_shader(struct r300_context *r300,
313
311
                                  struct r300_vertex_shader *vs)
314
312
{
 
313
    struct draw_context *draw = r300->draw;
315
314
    struct pipe_shader_state new_vs;
 
315
    struct tgsi_shader_info info;
316
316
    struct vs_transform_context transform;
317
317
    const uint newLen = tgsi_num_tokens(vs->state.tokens) + 100 /* XXX */;
318
318
    unsigned i;
319
319
 
 
320
    tgsi_scan_shader(vs->state.tokens, &info);
 
321
 
320
322
    new_vs.tokens = tgsi_alloc_tokens(newLen);
321
323
    if (new_vs.tokens == NULL)
322
324
        return;
329
331
    transform.base.transform_instruction = transform_inst;
330
332
    transform.base.transform_declaration = transform_decl;
331
333
 
 
334
    for (i = 0; i < info.num_outputs; i++) {
 
335
        unsigned index = info.output_semantic_index[i];
 
336
 
 
337
        switch (info.output_semantic_name[i]) {
 
338
            case TGSI_SEMANTIC_COLOR:
 
339
                assert(index < 2);
 
340
                transform.color_used[index] = TRUE;
 
341
                break;
 
342
 
 
343
            case TGSI_SEMANTIC_BCOLOR:
 
344
                assert(index < 2);
 
345
                transform.bcolor_used[index] = TRUE;
 
346
                break;
 
347
        }
 
348
    }
 
349
 
332
350
    tgsi_transform_shader(vs->state.tokens,
333
351
                          (struct tgsi_token*)new_vs.tokens,
334
352
                          newLen, &transform.base);
350
368
    vs->state.tokens = new_vs.tokens;
351
369
 
352
370
    /* Init the VS output table for the rasterizer. */
353
 
    r300_init_vs_outputs(vs);
 
371
    r300_init_vs_outputs(r300, vs);
354
372
 
355
373
    /* Make the last generic be WPOS. */
356
374
    vs->outputs.wpos = vs->outputs.generic[transform.last_generic + 1];