2 * Copyright 2010 Red Hat Inc.
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:
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
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.
24 * Authors: Dave Airlie <airlied@redhat.com>
25 * Jerome Glisse <jglisse@redhat.com>
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"
36 static void r600_spi_update(struct r600_pipe_context
*rctx
);
38 static int r600_conv_pipe_prim(unsigned pprim
, unsigned *prim
)
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
,
57 *prim
= prim_conv
[pprim
];
59 fprintf(stderr
, "%s:%d unsupported %d\n", __func__
, __LINE__
, pprim
);
65 /* common state between evergreen and r600 */
66 void r600_bind_blend_state(struct pipe_context
*ctx
, void *state
)
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
;
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
);
80 void r600_bind_dsa_state(struct pipe_context
*ctx
, void *state
)
82 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
83 struct r600_pipe_dsa
*dsa
= state
;
84 struct r600_pipe_state
*rstate
;
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
);
95 void r600_bind_rs_state(struct pipe_context
*ctx
, void *state
)
97 struct r600_pipe_rasterizer
*rs
= (struct r600_pipe_rasterizer
*)state
;
98 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
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
;
109 rctx
->states
[rs
->rstate
.id
] = &rs
->rstate
;
110 r600_context_pipe_state_set(&rctx
->ctx
, &rs
->rstate
);
112 if (rctx
->chip_class
>= EVERGREEN
) {
113 evergreen_polygon_offset_update(rctx
);
115 r600_polygon_offset_update(rctx
);
117 if (rctx
->ps_shader
&& rctx
->vs_shader
)
118 rctx
->spi_dirty
= true;
121 void r600_delete_rs_state(struct pipe_context
*ctx
, void *state
)
123 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
124 struct r600_pipe_rasterizer
*rs
= (struct r600_pipe_rasterizer
*)state
;
126 if (rctx
->rasterizer
== rs
) {
127 rctx
->rasterizer
= NULL
;
129 if (rctx
->states
[rs
->rstate
.id
] == &rs
->rstate
) {
130 rctx
->states
[rs
->rstate
.id
] = NULL
;
135 void r600_sampler_view_destroy(struct pipe_context
*ctx
,
136 struct pipe_sampler_view
*state
)
138 struct r600_pipe_sampler_view
*resource
= (struct r600_pipe_sampler_view
*)state
;
140 pipe_resource_reference(&state
->texture
, NULL
);
144 void r600_delete_state(struct pipe_context
*ctx
, void *state
)
146 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
147 struct r600_pipe_state
*rstate
= (struct r600_pipe_state
*)state
;
149 if (rctx
->states
[rstate
->id
] == rstate
) {
150 rctx
->states
[rstate
->id
] = NULL
;
152 for (int i
= 0; i
< rstate
->nregs
; i
++) {
153 r600_bo_reference(&rstate
->regs
[i
].bo
, NULL
);
158 void r600_bind_vertex_elements(struct pipe_context
*ctx
, void *state
)
160 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
161 struct r600_vertex_element
*v
= (struct r600_vertex_element
*)state
;
163 rctx
->vertex_elements
= v
;
165 u_vbuf_mgr_bind_vertex_elements(rctx
->vbuf_mgr
, state
,
168 rctx
->states
[v
->rstate
.id
] = &v
->rstate
;
169 r600_context_pipe_state_set(&rctx
->ctx
, &v
->rstate
);
173 void r600_delete_vertex_element(struct pipe_context
*ctx
, void *state
)
175 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
176 struct r600_vertex_element
*v
= (struct r600_vertex_element
*)state
;
178 if (rctx
->states
[v
->rstate
.id
] == &v
->rstate
) {
179 rctx
->states
[v
->rstate
.id
] = NULL
;
181 if (rctx
->vertex_elements
== state
)
182 rctx
->vertex_elements
= NULL
;
184 r600_bo_reference(&v
->fetch_shader
, NULL
);
185 u_vbuf_mgr_destroy_vertex_elements(rctx
->vbuf_mgr
, v
->vmgr_elements
);
190 void r600_set_index_buffer(struct pipe_context
*ctx
,
191 const struct pipe_index_buffer
*ib
)
193 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
196 pipe_resource_reference(&rctx
->index_buffer
.buffer
, ib
->buffer
);
197 memcpy(&rctx
->index_buffer
, ib
, sizeof(rctx
->index_buffer
));
199 pipe_resource_reference(&rctx
->index_buffer
.buffer
, NULL
);
200 memset(&rctx
->index_buffer
, 0, sizeof(rctx
->index_buffer
));
203 /* TODO make this more like a state */
206 void r600_set_vertex_buffers(struct pipe_context
*ctx
, unsigned count
,
207 const struct pipe_vertex_buffer
*buffers
)
209 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
213 for (i
= 0; i
< count
; i
++) {
214 if (!buffers
[i
].buffer
) {
215 if (rctx
->chip_class
>= EVERGREEN
) {
216 evergreen_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
218 r600_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
222 for (; i
< rctx
->vbuf_mgr
->nr_real_vertex_buffers
; i
++) {
223 if (rctx
->chip_class
>= EVERGREEN
) {
224 evergreen_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
226 r600_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
230 u_vbuf_mgr_set_vertex_buffers(rctx
->vbuf_mgr
, count
, buffers
);
233 void *r600_create_vertex_elements(struct pipe_context
*ctx
,
235 const struct pipe_vertex_element
*elements
)
237 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
238 struct r600_vertex_element
*v
= CALLOC_STRUCT(r600_vertex_element
);
246 u_vbuf_mgr_create_vertex_elements(rctx
->vbuf_mgr
, count
,
247 elements
, v
->elements
);
249 if (r600_vertex_elements_build_fetch_shader(rctx
, v
)) {
257 void *r600_create_shader_state(struct pipe_context
*ctx
,
258 const struct pipe_shader_state
*state
)
260 struct r600_pipe_shader
*shader
= CALLOC_STRUCT(r600_pipe_shader
);
263 shader
->tokens
= tgsi_dup_tokens(state
->tokens
);
265 r
= r600_pipe_shader_create(ctx
, shader
);
272 void r600_bind_ps_shader(struct pipe_context
*ctx
, void *state
)
274 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
276 /* TODO delete old shader */
277 rctx
->ps_shader
= (struct r600_pipe_shader
*)state
;
279 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->ps_shader
->rstate
);
281 if (rctx
->ps_shader
&& rctx
->vs_shader
) {
282 rctx
->spi_dirty
= true;
283 r600_adjust_gprs(rctx
);
287 void r600_bind_vs_shader(struct pipe_context
*ctx
, void *state
)
289 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
291 /* TODO delete old shader */
292 rctx
->vs_shader
= (struct r600_pipe_shader
*)state
;
294 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->vs_shader
->rstate
);
296 if (rctx
->ps_shader
&& rctx
->vs_shader
) {
297 rctx
->spi_dirty
= true;
298 r600_adjust_gprs(rctx
);
302 void r600_delete_ps_shader(struct pipe_context
*ctx
, void *state
)
304 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
305 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
307 if (rctx
->ps_shader
== shader
) {
308 rctx
->ps_shader
= NULL
;
311 free(shader
->tokens
);
312 r600_pipe_shader_destroy(ctx
, shader
);
316 void r600_delete_vs_shader(struct pipe_context
*ctx
, void *state
)
318 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
319 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
321 if (rctx
->vs_shader
== shader
) {
322 rctx
->vs_shader
= NULL
;
325 free(shader
->tokens
);
326 r600_pipe_shader_destroy(ctx
, shader
);
330 static void r600_update_alpha_ref(struct r600_pipe_context
*rctx
)
333 struct r600_pipe_state rstate
;
335 alpha_ref
= rctx
->alpha_ref
;
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
, 0);
341 r600_context_pipe_state_set(&rctx
->ctx
, &rstate
);
342 rctx
->alpha_ref_dirty
= false;
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
)
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
, 0);
356 static void r600_spi_update(struct r600_pipe_context
*rctx
)
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
;
363 if (rctx
->spi
.id
== 0)
364 r600_spi_block_init(rctx
, &rctx
->spi
);
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
->chip_class
>= EVERGREEN
)
375 sid
=r600_find_vs_semantic_index(&rctx
->vs_shader
->shader
, rshader
, i
);
377 tmp
= S_028644_SEMANTIC(sid
);
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
);
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);
390 if (rctx
->chip_class
< EVERGREEN
) {
391 if (rshader
->input
[i
].centroid
)
392 tmp
|= S_028644_SEL_CENTROID(1);
394 if (rshader
->input
[i
].interpolate
== TGSI_INTERPOLATE_LINEAR
)
395 tmp
|= S_028644_SEL_LINEAR(1);
398 r600_pipe_state_mod_reg(rstate
, tmp
);
401 rctx
->spi_dirty
= false;
402 r600_context_pipe_state_set(&rctx
->ctx
, rstate
);
405 void r600_set_constant_buffer(struct pipe_context
*ctx
, uint shader
, uint index
,
406 struct pipe_resource
*buffer
)
408 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
409 struct r600_resource
*rbuffer
= r600_resource(buffer
);
410 struct r600_pipe_resource_state
*rstate
;
413 /* Note that the state tracker can unbind constant buffers by
416 if (buffer
== NULL
) {
420 r600_upload_const_buffer(rctx
, &rbuffer
, &offset
);
423 case PIPE_SHADER_VERTEX
:
424 rctx
->vs_const_buffer
.nregs
= 0;
425 r600_pipe_state_add_reg(&rctx
->vs_const_buffer
,
426 R_028180_ALU_CONST_BUFFER_SIZE_VS_0
,
427 ALIGN_DIVUP(buffer
->width0
>> 4, 16),
428 0xFFFFFFFF, NULL
, 0);
429 r600_pipe_state_add_reg(&rctx
->vs_const_buffer
,
430 R_028980_ALU_CONST_CACHE_VS_0
,
431 offset
>> 8, 0xFFFFFFFF, rbuffer
->bo
, RADEON_USAGE_READ
);
432 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->vs_const_buffer
);
434 rstate
= &rctx
->vs_const_buffer_resource
[index
];
436 if (rctx
->chip_class
>= EVERGREEN
) {
437 evergreen_pipe_init_buffer_resource(rctx
, rstate
);
439 r600_pipe_init_buffer_resource(rctx
, rstate
);
443 if (rctx
->chip_class
>= EVERGREEN
) {
444 evergreen_pipe_mod_buffer_resource(rstate
, rbuffer
, offset
, 16, RADEON_USAGE_READ
);
445 evergreen_context_pipe_state_set_vs_resource(&rctx
->ctx
, rstate
, index
);
447 r600_pipe_mod_buffer_resource(rstate
, rbuffer
, offset
, 16, RADEON_USAGE_READ
);
448 r600_context_pipe_state_set_vs_resource(&rctx
->ctx
, rstate
, index
);
451 case PIPE_SHADER_FRAGMENT
:
452 rctx
->ps_const_buffer
.nregs
= 0;
453 r600_pipe_state_add_reg(&rctx
->ps_const_buffer
,
454 R_028140_ALU_CONST_BUFFER_SIZE_PS_0
,
455 ALIGN_DIVUP(buffer
->width0
>> 4, 16),
456 0xFFFFFFFF, NULL
, 0);
457 r600_pipe_state_add_reg(&rctx
->ps_const_buffer
,
458 R_028940_ALU_CONST_CACHE_PS_0
,
459 offset
>> 8, 0xFFFFFFFF, rbuffer
->bo
, RADEON_USAGE_READ
);
460 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->ps_const_buffer
);
462 rstate
= &rctx
->ps_const_buffer_resource
[index
];
464 if (rctx
->chip_class
>= EVERGREEN
) {
465 evergreen_pipe_init_buffer_resource(rctx
, rstate
);
467 r600_pipe_init_buffer_resource(rctx
, rstate
);
470 if (rctx
->chip_class
>= EVERGREEN
) {
471 evergreen_pipe_mod_buffer_resource(rstate
, rbuffer
, offset
, 16, RADEON_USAGE_READ
);
472 evergreen_context_pipe_state_set_ps_resource(&rctx
->ctx
, rstate
, index
);
474 r600_pipe_mod_buffer_resource(rstate
, rbuffer
, offset
, 16, RADEON_USAGE_READ
);
475 r600_context_pipe_state_set_ps_resource(&rctx
->ctx
, rstate
, index
);
479 R600_ERR("unsupported %d\n", shader
);
483 if (buffer
!= &rbuffer
->b
.b
.b
)
484 pipe_resource_reference((struct pipe_resource
**)&rbuffer
, NULL
);
487 static void r600_vertex_buffer_update(struct r600_pipe_context
*rctx
)
489 struct r600_pipe_resource_state
*rstate
;
490 struct r600_resource
*rbuffer
;
491 struct pipe_vertex_buffer
*vertex_buffer
;
492 unsigned i
, count
, offset
;
494 if (rctx
->vertex_elements
->vbuffer_need_offset
) {
495 /* one resource per vertex elements */
496 count
= rctx
->vertex_elements
->count
;
498 /* bind vertex buffer once */
499 count
= rctx
->vbuf_mgr
->nr_real_vertex_buffers
;
502 for (i
= 0 ; i
< count
; i
++) {
503 rstate
= &rctx
->fs_resource
[i
];
505 if (rctx
->vertex_elements
->vbuffer_need_offset
) {
506 /* one resource per vertex elements */
507 unsigned vbuffer_index
;
508 vbuffer_index
= rctx
->vertex_elements
->elements
[i
].vertex_buffer_index
;
509 vertex_buffer
= &rctx
->vbuf_mgr
->vertex_buffer
[vbuffer_index
];
510 rbuffer
= (struct r600_resource
*)rctx
->vbuf_mgr
->real_vertex_buffer
[vbuffer_index
];
511 offset
= rctx
->vertex_elements
->vbuffer_offset
[i
];
513 /* bind vertex buffer once */
514 vertex_buffer
= &rctx
->vbuf_mgr
->vertex_buffer
[i
];
515 rbuffer
= (struct r600_resource
*)rctx
->vbuf_mgr
->real_vertex_buffer
[i
];
518 if (vertex_buffer
== NULL
|| rbuffer
== NULL
)
520 offset
+= vertex_buffer
->buffer_offset
;
523 if (rctx
->chip_class
>= EVERGREEN
) {
524 evergreen_pipe_init_buffer_resource(rctx
, rstate
);
526 r600_pipe_init_buffer_resource(rctx
, rstate
);
530 if (rctx
->chip_class
>= EVERGREEN
) {
531 evergreen_pipe_mod_buffer_resource(rstate
, rbuffer
, offset
, vertex_buffer
->stride
, RADEON_USAGE_READ
);
532 evergreen_context_pipe_state_set_fs_resource(&rctx
->ctx
, rstate
, i
);
534 r600_pipe_mod_buffer_resource(rstate
, rbuffer
, offset
, vertex_buffer
->stride
, RADEON_USAGE_READ
);
535 r600_context_pipe_state_set_fs_resource(&rctx
->ctx
, rstate
, i
);
540 static int r600_shader_rebuild(struct pipe_context
* ctx
, struct r600_pipe_shader
* shader
)
542 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
545 r600_pipe_shader_destroy(ctx
, shader
);
546 r
= r600_pipe_shader_create(ctx
, shader
);
550 r600_context_pipe_state_set(&rctx
->ctx
, &shader
->rstate
);
555 void r600_draw_vbo(struct pipe_context
*ctx
, const struct pipe_draw_info
*info
)
557 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
558 struct r600_resource
*rbuffer
;
559 struct r600_draw rdraw
;
560 struct r600_drawl draw
;
564 if (rctx
->have_depth_fb
|| rctx
->have_depth_texture
)
565 r600_flush_depth_textures(rctx
);
568 if (rctx
->chip_class
< EVERGREEN
)
569 r600_update_sampler_states(rctx
);
571 u_vbuf_mgr_draw_begin(rctx
->vbuf_mgr
, info
);
572 r600_vertex_buffer_update(rctx
);
576 draw
.index_buffer
= NULL
;
577 if (info
->indexed
&& rctx
->index_buffer
.buffer
) {
578 draw
.info
.start
+= rctx
->index_buffer
.offset
/ rctx
->index_buffer
.index_size
;
579 pipe_resource_reference(&draw
.index_buffer
, rctx
->index_buffer
.buffer
);
581 r600_translate_index_buffer(rctx
, &draw
.index_buffer
,
582 &rctx
->index_buffer
.index_size
,
586 draw
.index_size
= rctx
->index_buffer
.index_size
;
587 draw
.index_buffer_offset
= draw
.info
.start
* draw
.index_size
;
590 if (u_vbuf_resource(draw
.index_buffer
)->user_ptr
) {
591 r600_upload_index_buffer(rctx
, &draw
);
595 draw
.index_buffer_offset
= 0;
596 draw
.info
.index_bias
= info
->start
;
599 if (r600_conv_pipe_prim(draw
.info
.mode
, &prim
))
602 if (rctx
->vs_shader
->shader
.clamp_color
!= rctx
->clamp_vertex_color
)
603 r600_shader_rebuild(ctx
, rctx
->vs_shader
);
605 if ((rctx
->ps_shader
->shader
.clamp_color
!= rctx
->clamp_fragment_color
) ||
606 ((rctx
->chip_class
>= EVERGREEN
) && rctx
->ps_shader
->shader
.fs_write_all
&&
607 (rctx
->ps_shader
->shader
.nr_cbufs
!= rctx
->nr_cbufs
)))
608 r600_shader_rebuild(ctx
, rctx
->ps_shader
);
611 r600_spi_update(rctx
);
613 if (rctx
->alpha_ref_dirty
)
614 r600_update_alpha_ref(rctx
);
616 mask
= (1ULL << ((unsigned)rctx
->framebuffer
.nr_cbufs
* 4)) - 1;
618 if (rctx
->vgt
.id
!= R600_PIPE_STATE_VGT
) {
619 rctx
->vgt
.id
= R600_PIPE_STATE_VGT
;
621 r600_pipe_state_add_reg(&rctx
->vgt
, R_008958_VGT_PRIMITIVE_TYPE
, prim
, 0xFFFFFFFF, NULL
, 0);
622 r600_pipe_state_add_reg(&rctx
->vgt
, R_028238_CB_TARGET_MASK
, rctx
->cb_target_mask
& mask
, 0xFFFFFFFF, NULL
, 0);
623 r600_pipe_state_add_reg(&rctx
->vgt
, R_028400_VGT_MAX_VTX_INDX
, draw
.info
.max_index
, 0xFFFFFFFF, NULL
, 0);
624 r600_pipe_state_add_reg(&rctx
->vgt
, R_028404_VGT_MIN_VTX_INDX
, draw
.info
.min_index
, 0xFFFFFFFF, NULL
, 0);
625 r600_pipe_state_add_reg(&rctx
->vgt
, R_028408_VGT_INDX_OFFSET
, draw
.info
.index_bias
, 0xFFFFFFFF, NULL
, 0);
626 r600_pipe_state_add_reg(&rctx
->vgt
, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX
, draw
.info
.restart_index
, 0xFFFFFFFF, NULL
, 0);
627 r600_pipe_state_add_reg(&rctx
->vgt
, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN
, draw
.info
.primitive_restart
, 0xFFFFFFFF, NULL
, 0);
628 r600_pipe_state_add_reg(&rctx
->vgt
, R_03CFF0_SQ_VTX_BASE_VTX_LOC
, 0, 0xFFFFFFFF, NULL
, 0);
629 r600_pipe_state_add_reg(&rctx
->vgt
, R_03CFF4_SQ_VTX_START_INST_LOC
, draw
.info
.start_instance
, 0xFFFFFFFF, NULL
, 0);
630 r600_pipe_state_add_reg(&rctx
->vgt
, R_028814_PA_SU_SC_MODE_CNTL
,
632 S_028814_PROVOKING_VTX_LAST(1), NULL
, 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
, draw
.info
.restart_index
);
643 r600_pipe_state_mod_reg(&rctx
->vgt
, draw
.info
.primitive_restart
);
644 r600_pipe_state_mod_reg(&rctx
->vgt
, 0);
645 r600_pipe_state_mod_reg(&rctx
->vgt
, draw
.info
.start_instance
);
646 if (draw
.info
.mode
== PIPE_PRIM_QUADS
|| draw
.info
.mode
== PIPE_PRIM_QUAD_STRIP
|| draw
.info
.mode
== PIPE_PRIM_POLYGON
) {
647 r600_pipe_state_mod_reg(&rctx
->vgt
, S_028814_PROVOKING_VTX_LAST(1));
650 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->vgt
);
652 rdraw
.vgt_num_indices
= draw
.info
.count
;
653 rdraw
.vgt_num_instances
= draw
.info
.instance_count
;
654 rdraw
.vgt_index_type
= ((draw
.index_size
== 4) ? 1 : 0);
656 rdraw
.vgt_index_type
|= (draw
.index_size
>> 1) << 2;
657 rdraw
.vgt_draw_initiator
= draw
.index_size
? 0 : 2;
658 rdraw
.indices
= NULL
;
659 if (draw
.index_buffer
) {
660 rbuffer
= (struct r600_resource
*)draw
.index_buffer
;
661 rdraw
.indices
= rbuffer
->bo
;
662 rdraw
.indices_bo_offset
= draw
.index_buffer_offset
;
665 if (rctx
->chip_class
>= EVERGREEN
) {
666 evergreen_context_draw(&rctx
->ctx
, &rdraw
);
668 r600_context_draw(&rctx
->ctx
, &rdraw
);
671 if (rctx
->framebuffer
.zsbuf
)
673 struct pipe_resource
*tex
= rctx
->framebuffer
.zsbuf
->texture
;
674 ((struct r600_resource_texture
*)tex
)->dirty_db
= TRUE
;
677 pipe_resource_reference(&draw
.index_buffer
, NULL
);
679 u_vbuf_mgr_draw_end(rctx
->vbuf_mgr
);
682 void _r600_pipe_state_add_reg(struct r600_context
*ctx
,
683 struct r600_pipe_state
*state
,
684 u32 offset
, u32 value
, u32 mask
,
685 u32 range_id
, u32 block_id
,
687 enum radeon_bo_usage usage
)
689 struct r600_range
*range
;
690 struct r600_block
*block
;
692 if (bo
) assert(usage
);
694 range
= &ctx
->range
[range_id
];
695 block
= range
->blocks
[block_id
];
696 state
->regs
[state
->nregs
].block
= block
;
697 state
->regs
[state
->nregs
].id
= (offset
- block
->start_offset
) >> 2;
699 state
->regs
[state
->nregs
].value
= value
;
700 state
->regs
[state
->nregs
].mask
= mask
;
701 state
->regs
[state
->nregs
].bo
= bo
;
702 state
->regs
[state
->nregs
].bo_usage
= usage
;
705 assert(state
->nregs
< R600_BLOCK_MAX_REG
);
708 void r600_pipe_state_add_reg_noblock(struct r600_pipe_state
*state
,
709 u32 offset
, u32 value
, u32 mask
,
711 enum radeon_bo_usage usage
)
713 if (bo
) assert(usage
);
715 state
->regs
[state
->nregs
].id
= offset
;
716 state
->regs
[state
->nregs
].block
= NULL
;
717 state
->regs
[state
->nregs
].value
= value
;
718 state
->regs
[state
->nregs
].mask
= mask
;
719 state
->regs
[state
->nregs
].bo
= bo
;
720 state
->regs
[state
->nregs
].bo_usage
= usage
;
723 assert(state
->nregs
< R600_BLOCK_MAX_REG
);