Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / r600 / r600_state_common.c
1 /*
2  * Copyright 2010 Red Hat Inc.
3  *           2010 Jerome Glisse
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Dave Airlie <airlied@redhat.com>
25  *          Jerome Glisse <jglisse@redhat.com>
26  */
27 #include <util/u_memory.h>
28 #include <util/u_format.h>
29 #include <pipebuffer/pb_buffer.h>
30 #include "pipe/p_shader_tokens.h"
31 #include "tgsi/tgsi_parse.h"
32 #include "r600_formats.h"
33 #include "r600_pipe.h"
34 #include "r600d.h"
35
36 static void r600_spi_update(struct r600_pipe_context *rctx);
37
38 static int r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
39 {
40         static const int prim_conv[] = {
41                 V_008958_DI_PT_POINTLIST,
42                 V_008958_DI_PT_LINELIST,
43                 V_008958_DI_PT_LINELOOP,
44                 V_008958_DI_PT_LINESTRIP,
45                 V_008958_DI_PT_TRILIST,
46                 V_008958_DI_PT_TRISTRIP,
47                 V_008958_DI_PT_TRIFAN,
48                 V_008958_DI_PT_QUADLIST,
49                 V_008958_DI_PT_QUADSTRIP,
50                 V_008958_DI_PT_POLYGON,
51                 -1,
52                 -1,
53                 -1,
54                 -1
55         };
56
57         *prim = prim_conv[pprim];
58         if (*prim == -1) {
59                 fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim);
60                 return -1;
61         }
62         return 0;
63 }
64
65 /* common state between evergreen and r600 */
66 void r600_bind_blend_state(struct pipe_context *ctx, void *state)
67 {
68         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
69         struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
70         struct r600_pipe_state *rstate;
71
72         if (state == NULL)
73                 return;
74         rstate = &blend->rstate;
75         rctx->states[rstate->id] = rstate;
76         rctx->cb_target_mask = blend->cb_target_mask;
77         r600_context_pipe_state_set(&rctx->ctx, rstate);
78 }
79
80 void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
81 {
82         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
83         struct r600_pipe_dsa *dsa = state;
84         struct r600_pipe_state *rstate;
85
86         if (state == NULL)
87                 return;
88         rstate = &dsa->rstate;
89         rctx->states[rstate->id] = rstate;
90         rctx->alpha_ref = dsa->alpha_ref;
91         rctx->alpha_ref_dirty = true;
92         r600_context_pipe_state_set(&rctx->ctx, rstate);
93 }
94
95 void r600_bind_rs_state(struct pipe_context *ctx, void *state)
96 {
97         struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
98         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
99
100         if (state == NULL)
101                 return;
102
103         rctx->clamp_vertex_color = rs->clamp_vertex_color;
104         rctx->clamp_fragment_color = rs->clamp_fragment_color;
105         rctx->flatshade = rs->flatshade;
106         rctx->sprite_coord_enable = rs->sprite_coord_enable;
107         rctx->rasterizer = rs;
108
109         rctx->states[rs->rstate.id] = &rs->rstate;
110         r600_context_pipe_state_set(&rctx->ctx, &rs->rstate);
111
112         if (rctx->family >= CHIP_CEDAR) {
113                 evergreen_polygon_offset_update(rctx);
114         } else {
115                 r600_polygon_offset_update(rctx);
116         }
117         if (rctx->ps_shader && rctx->vs_shader)
118                 rctx->spi_dirty = true;
119 }
120
121 void r600_delete_rs_state(struct pipe_context *ctx, void *state)
122 {
123         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
124         struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
125
126         if (rctx->rasterizer == rs) {
127                 rctx->rasterizer = NULL;
128         }
129         if (rctx->states[rs->rstate.id] == &rs->rstate) {
130                 rctx->states[rs->rstate.id] = NULL;
131         }
132         free(rs);
133 }
134
135 void r600_sampler_view_destroy(struct pipe_context *ctx,
136                                struct pipe_sampler_view *state)
137 {
138         struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state;
139
140         pipe_resource_reference(&state->texture, NULL);
141         FREE(resource);
142 }
143
144 void r600_delete_state(struct pipe_context *ctx, void *state)
145 {
146         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
147         struct r600_pipe_state *rstate = (struct r600_pipe_state *)state;
148
149         if (rctx->states[rstate->id] == rstate) {
150                 rctx->states[rstate->id] = NULL;
151         }
152         for (int i = 0; i < rstate->nregs; i++) {
153                 r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL);
154         }
155         free(rstate);
156 }
157
158 void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
159 {
160         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
161         struct r600_vertex_element *v = (struct r600_vertex_element*)state;
162
163         rctx->vertex_elements = v;
164         if (v) {
165                 u_vbuf_bind_vertex_elements(rctx->vbuf_mgr, state,
166                                                 v->vmgr_elements);
167
168                 rctx->states[v->rstate.id] = &v->rstate;
169                 r600_context_pipe_state_set(&rctx->ctx, &v->rstate);
170         }
171 }
172
173 void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
174 {
175         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
176         struct r600_vertex_element *v = (struct r600_vertex_element*)state;
177
178         if (rctx->states[v->rstate.id] == &v->rstate) {
179                 rctx->states[v->rstate.id] = NULL;
180         }
181         if (rctx->vertex_elements == state)
182                 rctx->vertex_elements = NULL;
183
184         r600_bo_reference(rctx->radeon, &v->fetch_shader, NULL);
185         u_vbuf_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements);
186         FREE(state);
187 }
188
189
190 void r600_set_index_buffer(struct pipe_context *ctx,
191                            const struct pipe_index_buffer *ib)
192 {
193         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
194
195         if (ib) {
196                 pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer);
197                 memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer));
198         } else {
199                 pipe_resource_reference(&rctx->index_buffer.buffer, NULL);
200                 memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer));
201         }
202
203         /* TODO make this more like a state */
204 }
205
206 void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
207                              const struct pipe_vertex_buffer *buffers)
208 {
209         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
210         int i;
211
212         /* Zero states. */
213         for (i = 0; i < count; i++) {
214                 if (!buffers[i].buffer) {
215                         if (rctx->family >= CHIP_CEDAR) {
216                                 evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
217                         } else {
218                                 r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
219                         }
220                 }
221         }
222         for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) {
223                 if (rctx->family >= CHIP_CEDAR) {
224                         evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
225                 } else {
226                         r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
227                 }
228         }
229
230         u_vbuf_set_vertex_buffers(rctx->vbuf_mgr, count, buffers);
231 }
232
233 void *r600_create_vertex_elements(struct pipe_context *ctx,
234                                   unsigned count,
235                                   const struct pipe_vertex_element *elements)
236 {
237         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
238         struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
239
240         assert(count < 32);
241         if (!v)
242                 return NULL;
243
244         v->count = count;
245         v->vmgr_elements =
246                 u_vbuf_create_vertex_elements(rctx->vbuf_mgr, count,
247                                                   elements, v->elements);
248
249         if (r600_vertex_elements_build_fetch_shader(rctx, v)) {
250                 FREE(v);
251                 return NULL;
252         }
253
254         return v;
255 }
256
257 void *r600_create_shader_state(struct pipe_context *ctx,
258                                const struct pipe_shader_state *state)
259 {
260         struct r600_pipe_shader *shader =  CALLOC_STRUCT(r600_pipe_shader);
261         int r;
262
263         shader->tokens = tgsi_dup_tokens(state->tokens);
264
265         r =  r600_pipe_shader_create(ctx, shader);
266         if (r) {
267                 return NULL;
268         }
269         return shader;
270 }
271
272 void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
273 {
274         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
275
276         /* TODO delete old shader */
277         rctx->ps_shader = (struct r600_pipe_shader *)state;
278         if (state) {
279                 r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate);
280         }
281         if (rctx->ps_shader && rctx->vs_shader) {
282                 rctx->spi_dirty = true;
283                 r600_adjust_gprs(rctx);
284         }
285 }
286
287 void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
288 {
289         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
290
291         /* TODO delete old shader */
292         rctx->vs_shader = (struct r600_pipe_shader *)state;
293         if (state) {
294                 r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate);
295         }
296         if (rctx->ps_shader && rctx->vs_shader) {
297                 rctx->spi_dirty = true;
298                 r600_adjust_gprs(rctx);
299         }
300 }
301
302 void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
303 {
304         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
305         struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state;
306
307         if (rctx->ps_shader == shader) {
308                 rctx->ps_shader = NULL;
309         }
310
311         free(shader->tokens);
312         r600_pipe_shader_destroy(ctx, shader);
313         free(shader);
314 }
315
316 void r600_delete_vs_shader(struct pipe_context *ctx, void *state)
317 {
318         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
319         struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state;
320
321         if (rctx->vs_shader == shader) {
322                 rctx->vs_shader = NULL;
323         }
324
325         free(shader->tokens);
326         r600_pipe_shader_destroy(ctx, shader);
327         free(shader);
328 }
329
330 static void r600_update_alpha_ref(struct r600_pipe_context *rctx)
331 {
332         unsigned alpha_ref;
333         struct r600_pipe_state rstate;
334
335         alpha_ref = rctx->alpha_ref;
336         rstate.nregs = 0;
337         if (rctx->export_16bpc)
338                 alpha_ref &= ~0x1FFF;
339         r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL);
340
341         r600_context_pipe_state_set(&rctx->ctx, &rstate);
342         rctx->alpha_ref_dirty = false;
343 }
344
345 /* FIXME optimize away spi update when it's not needed */
346 static void r600_spi_block_init(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate)
347 {
348         int i;
349         rstate->nregs = 0;
350         rstate->id = R600_PIPE_STATE_SPI;
351         for (i = 0; i < 32; i++) {
352                 r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, 0, 0xFFFFFFFF, NULL);
353         }
354 }
355
356 static void r600_spi_update(struct r600_pipe_context *rctx)
357 {
358         struct r600_pipe_shader *shader = rctx->ps_shader;
359         struct r600_pipe_state *rstate = &rctx->spi;
360         struct r600_shader *rshader = &shader->shader;
361         unsigned i, tmp, sid;
362
363         if (rctx->spi.id == 0)
364                 r600_spi_block_init(rctx, &rctx->spi);
365
366         rstate->nregs = 0;
367         for (i = 0; i < rshader->ninput; i++) {
368                 if (rshader->input[i].name == TGSI_SEMANTIC_POSITION ||
369                     rshader->input[i].name == TGSI_SEMANTIC_FACE)
370                         if (rctx->family >= CHIP_CEDAR)
371                                 continue;
372                         else
373                                 sid=0;
374                 else
375                         sid=r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i);
376
377                 tmp = S_028644_SEMANTIC(sid);
378
379                 if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
380                     rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
381                     rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
382                         tmp |= S_028644_FLAT_SHADE(rctx->flatshade);
383                 }
384
385                 if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
386                     rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
387                         tmp |= S_028644_PT_SPRITE_TEX(1);
388                 }
389
390                 if (rctx->family < CHIP_CEDAR) {
391                         if (rshader->input[i].centroid)
392                                 tmp |= S_028644_SEL_CENTROID(1);
393
394                         if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
395                                 tmp |= S_028644_SEL_LINEAR(1);
396                 }
397
398                 r600_pipe_state_mod_reg(rstate, tmp);
399         }
400
401         rctx->spi_dirty = false;
402         r600_context_pipe_state_set(&rctx->ctx, rstate);
403 }
404
405 void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
406                               struct pipe_resource *buffer)
407 {
408         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
409         struct r600_resource_buffer *rbuffer = r600_buffer(buffer);
410         struct r600_pipe_resource_state *rstate;
411         uint32_t offset;
412
413         /* Note that the state tracker can unbind constant buffers by
414          * passing NULL here.
415          */
416         if (buffer == NULL) {
417                 return;
418         }
419
420         r600_upload_const_buffer(rctx, &rbuffer, &offset);
421         offset += r600_bo_offset(rbuffer->r.bo);
422
423         switch (shader) {
424         case PIPE_SHADER_VERTEX:
425                 rctx->vs_const_buffer.nregs = 0;
426                 r600_pipe_state_add_reg(&rctx->vs_const_buffer,
427                                         R_028180_ALU_CONST_BUFFER_SIZE_VS_0,
428                                         ALIGN_DIVUP(buffer->width0 >> 4, 16),
429                                         0xFFFFFFFF, NULL);
430                 r600_pipe_state_add_reg(&rctx->vs_const_buffer,
431                                         R_028980_ALU_CONST_CACHE_VS_0,
432                                         offset >> 8, 0xFFFFFFFF, rbuffer->r.bo);
433                 r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_const_buffer);
434
435                 rstate = &rctx->vs_const_buffer_resource[index];
436                 if (!rstate->id) {
437                         if (rctx->family >= CHIP_CEDAR) {
438                                 evergreen_pipe_init_buffer_resource(rctx, rstate);
439                         } else {
440                                 r600_pipe_init_buffer_resource(rctx, rstate);
441                         }
442                 }
443
444                 if (rctx->family >= CHIP_CEDAR) {
445                         evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
446                         evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index);
447                 } else {
448                         r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
449                         r600_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index);
450                 }
451                 break;
452         case PIPE_SHADER_FRAGMENT:
453                 rctx->ps_const_buffer.nregs = 0;
454                 r600_pipe_state_add_reg(&rctx->ps_const_buffer,
455                                         R_028140_ALU_CONST_BUFFER_SIZE_PS_0,
456                                         ALIGN_DIVUP(buffer->width0 >> 4, 16),
457                                         0xFFFFFFFF, NULL);
458                 r600_pipe_state_add_reg(&rctx->ps_const_buffer,
459                                         R_028940_ALU_CONST_CACHE_PS_0,
460                                         offset >> 8, 0xFFFFFFFF, rbuffer->r.bo);
461                 r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_const_buffer);
462
463                 rstate = &rctx->ps_const_buffer_resource[index];
464                 if (!rstate->id) {
465                         if (rctx->family >= CHIP_CEDAR) {
466                                 evergreen_pipe_init_buffer_resource(rctx, rstate);
467                         } else {
468                                 r600_pipe_init_buffer_resource(rctx, rstate);
469                         }
470                 }
471                 if (rctx->family >= CHIP_CEDAR) {
472                         evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
473                         evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index);
474                 } else {
475                         r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
476                         r600_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index);
477                 }
478                 break;
479         default:
480                 R600_ERR("unsupported %d\n", shader);
481                 return;
482         }
483
484         if (buffer != &rbuffer->r.b.b.b)
485                 pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL);
486 }
487
488 static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
489 {
490         struct r600_pipe_resource_state *rstate;
491         struct r600_resource *rbuffer;
492         struct pipe_vertex_buffer *vertex_buffer;
493         unsigned i, count, offset;
494
495         if (rctx->vertex_elements->vbuffer_need_offset) {
496                 /* one resource per vertex elements */
497                 count = rctx->vertex_elements->count;
498         } else {
499                 /* bind vertex buffer once */
500                 count = rctx->vbuf_mgr->nr_real_vertex_buffers;
501         }
502
503         for (i = 0 ; i < count; i++) {
504                 rstate = &rctx->fs_resource[i];
505
506                 if (rctx->vertex_elements->vbuffer_need_offset) {
507                         /* one resource per vertex elements */
508                         unsigned vbuffer_index;
509                         vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index;
510                         vertex_buffer = &rctx->vbuf_mgr->real_vertex_buffer[vbuffer_index];
511                         rbuffer = (struct r600_resource*)vertex_buffer->buffer;
512                         offset = rctx->vertex_elements->vbuffer_offset[i];
513                 } else {
514                         /* bind vertex buffer once */
515                         vertex_buffer = &rctx->vbuf_mgr->real_vertex_buffer[i];
516                         rbuffer = (struct r600_resource*)vertex_buffer->buffer;
517                         offset = 0;
518                 }
519                 if (vertex_buffer == NULL || rbuffer == NULL)
520                         continue;
521                 offset += vertex_buffer->buffer_offset + r600_bo_offset(rbuffer->bo);
522
523                 if (!rstate->id) {
524                         if (rctx->family >= CHIP_CEDAR) {
525                                 evergreen_pipe_init_buffer_resource(rctx, rstate);
526                         } else {
527                                 r600_pipe_init_buffer_resource(rctx, rstate);
528                         }
529                 }
530
531                 if (rctx->family >= CHIP_CEDAR) {
532                         evergreen_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride);
533                         evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
534                 } else {
535                         r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride);
536                         r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
537                 }
538         }
539 }
540
541 static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader)
542 {
543         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
544         int r;
545
546         r600_pipe_shader_destroy(ctx, shader);
547         r = r600_pipe_shader_create(ctx, shader);
548         if (r) {
549                 return r;
550         }
551         r600_context_pipe_state_set(&rctx->ctx, &shader->rstate);
552
553         return 0;
554 }
555
556 void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
557 {
558         struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
559         struct r600_resource *rbuffer;
560         struct r600_draw rdraw;
561         struct r600_drawl draw;
562         unsigned prim, mask;
563
564         if (!rctx->blit) {
565                 if (rctx->have_depth_fb || rctx->have_depth_texture)
566                         r600_flush_depth_textures(rctx);
567         }
568         u_vbuf_draw_begin(rctx->vbuf_mgr, info);
569         r600_vertex_buffer_update(rctx);
570
571         draw.info = *info;
572         if (draw.info.max_index != ~0) {
573                 draw.info.min_index += info->index_bias;
574                 draw.info.max_index += info->index_bias;
575         }
576
577         draw.ctx = ctx;
578         draw.index_buffer = NULL;
579         if (info->indexed && rctx->index_buffer.buffer) {
580                 draw.info.start += rctx->index_buffer.offset / rctx->index_buffer.index_size;
581                 pipe_resource_reference(&draw.index_buffer, rctx->index_buffer.buffer);
582
583                 r600_translate_index_buffer(rctx, &draw.index_buffer,
584                                             &rctx->index_buffer.index_size,
585                                             &draw.info.start,
586                                             info->count);
587
588                 draw.index_size = rctx->index_buffer.index_size;
589                 draw.index_buffer_offset = draw.info.start * draw.index_size;
590                 draw.info.start = 0;
591
592                 if (u_vbuf_resource(draw.index_buffer)->user_ptr) {
593                         r600_upload_index_buffer(rctx, &draw);
594                 }
595         } else {
596                 draw.index_size = 0;
597                 draw.index_buffer_offset = 0;
598                 draw.info.index_bias = info->start;
599         }
600
601         if (r600_conv_pipe_prim(draw.info.mode, &prim))
602                 return;
603
604         if (rctx->vs_shader->shader.clamp_color != rctx->clamp_vertex_color)
605                 r600_shader_rebuild(ctx, rctx->vs_shader);
606
607         if ((rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color) ||
608             ((rctx->family >= CHIP_CEDAR) && rctx->ps_shader->shader.fs_write_all &&
609              (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs)))
610                 r600_shader_rebuild(ctx, rctx->ps_shader);
611
612         if (rctx->spi_dirty)
613                 r600_spi_update(rctx);
614
615         if (rctx->alpha_ref_dirty)
616                 r600_update_alpha_ref(rctx);
617
618         mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1;
619
620         if (rctx->vgt.id != R600_PIPE_STATE_VGT) {
621                 rctx->vgt.id = R600_PIPE_STATE_VGT;
622                 rctx->vgt.nregs = 0;
623                 r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, 0xFFFFFFFF, NULL);
624                 r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL);
625                 r600_pipe_state_add_reg(&rctx->vgt, R_028400_VGT_MAX_VTX_INDX, draw.info.max_index, 0xFFFFFFFF, NULL);
626                 r600_pipe_state_add_reg(&rctx->vgt, R_028404_VGT_MIN_VTX_INDX, draw.info.min_index, 0xFFFFFFFF, NULL);
627                 r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, draw.info.index_bias, 0xFFFFFFFF, NULL);
628                 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL);
629                 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, draw.info.start_instance, 0xFFFFFFFF, NULL);
630                 r600_pipe_state_add_reg(&rctx->vgt, R_028814_PA_SU_SC_MODE_CNTL,
631                                         0,
632                                         S_028814_PROVOKING_VTX_LAST(1), NULL);
633
634         }
635
636         rctx->vgt.nregs = 0;
637         r600_pipe_state_mod_reg(&rctx->vgt, prim);
638         r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask);
639         r600_pipe_state_mod_reg(&rctx->vgt, draw.info.max_index);
640         r600_pipe_state_mod_reg(&rctx->vgt, draw.info.min_index);
641         r600_pipe_state_mod_reg(&rctx->vgt, draw.info.index_bias);
642         r600_pipe_state_mod_reg(&rctx->vgt, 0);
643         r600_pipe_state_mod_reg(&rctx->vgt, draw.info.start_instance);
644         if (draw.info.mode == PIPE_PRIM_QUADS || draw.info.mode == PIPE_PRIM_QUAD_STRIP || draw.info.mode == PIPE_PRIM_POLYGON) {
645                 r600_pipe_state_mod_reg(&rctx->vgt, S_028814_PROVOKING_VTX_LAST(1));
646         }
647
648         r600_context_pipe_state_set(&rctx->ctx, &rctx->vgt);
649
650         rdraw.vgt_num_indices = draw.info.count;
651         rdraw.vgt_num_instances = draw.info.instance_count;
652         rdraw.vgt_index_type = ((draw.index_size == 4) ? 1 : 0);
653         if (R600_BIG_ENDIAN)
654                 rdraw.vgt_index_type |= (draw.index_size >> 1) << 2;
655         rdraw.vgt_draw_initiator = draw.index_size ? 0 : 2;
656         rdraw.indices = NULL;
657         if (draw.index_buffer) {
658                 rbuffer = (struct r600_resource*)draw.index_buffer;
659                 rdraw.indices = rbuffer->bo;
660                 rdraw.indices_bo_offset = draw.index_buffer_offset;
661         }
662
663         if (rctx->family >= CHIP_CEDAR) {
664                 evergreen_context_draw(&rctx->ctx, &rdraw);
665         } else {
666                 r600_context_draw(&rctx->ctx, &rdraw);
667         }
668
669         if (rctx->framebuffer.zsbuf)
670         {
671                 struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture;
672                 ((struct r600_resource_texture *)tex)->dirty_db = TRUE;
673         }
674
675         pipe_resource_reference(&draw.index_buffer, NULL);
676
677         u_vbuf_draw_end(rctx->vbuf_mgr);
678 }
679
680 void _r600_pipe_state_add_reg(struct r600_context *ctx,
681                               struct r600_pipe_state *state,
682                               u32 offset, u32 value, u32 mask,
683                               u32 range_id, u32 block_id,
684                               struct r600_bo *bo)
685 {
686         struct r600_range *range;
687         struct r600_block *block;
688
689         range = &ctx->range[range_id];
690         block = range->blocks[block_id];
691         state->regs[state->nregs].block = block;
692         state->regs[state->nregs].id = (offset - block->start_offset) >> 2;
693
694         state->regs[state->nregs].value = value;
695         state->regs[state->nregs].mask = mask;
696         state->regs[state->nregs].bo = bo;
697
698         state->nregs++;
699         assert(state->nregs < R600_BLOCK_MAX_REG);
700 }
701
702 void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state,
703                                      u32 offset, u32 value, u32 mask,
704                                      struct r600_bo *bo)
705 {
706         state->regs[state->nregs].id = offset;
707         state->regs[state->nregs].block = NULL;
708         state->regs[state->nregs].value = value;
709         state->regs[state->nregs].mask = mask;
710         state->regs[state->nregs].bo = bo;
711
712         state->nregs++;
713         assert(state->nregs < R600_BLOCK_MAX_REG);
714 }