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 "r600_formats.h"
32 #include "r600_pipe.h"
35 static int r600_conv_pipe_prim(unsigned pprim
, unsigned *prim
)
38 case PIPE_PRIM_POINTS
:
39 *prim
= V_008958_DI_PT_POINTLIST
;
42 *prim
= V_008958_DI_PT_LINELIST
;
44 case PIPE_PRIM_LINE_STRIP
:
45 *prim
= V_008958_DI_PT_LINESTRIP
;
47 case PIPE_PRIM_LINE_LOOP
:
48 *prim
= V_008958_DI_PT_LINELOOP
;
50 case PIPE_PRIM_TRIANGLES
:
51 *prim
= V_008958_DI_PT_TRILIST
;
53 case PIPE_PRIM_TRIANGLE_STRIP
:
54 *prim
= V_008958_DI_PT_TRISTRIP
;
56 case PIPE_PRIM_TRIANGLE_FAN
:
57 *prim
= V_008958_DI_PT_TRIFAN
;
59 case PIPE_PRIM_POLYGON
:
60 *prim
= V_008958_DI_PT_POLYGON
;
63 *prim
= V_008958_DI_PT_QUADLIST
;
65 case PIPE_PRIM_QUAD_STRIP
:
66 *prim
= V_008958_DI_PT_QUADSTRIP
;
69 fprintf(stderr
, "%s:%d unsupported %d\n", __func__
, __LINE__
, pprim
);
74 /* common state between evergreen and r600 */
75 void r600_bind_blend_state(struct pipe_context
*ctx
, void *state
)
77 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
78 struct r600_pipe_blend
*blend
= (struct r600_pipe_blend
*)state
;
79 struct r600_pipe_state
*rstate
;
83 rstate
= &blend
->rstate
;
84 rctx
->states
[rstate
->id
] = rstate
;
85 rctx
->cb_target_mask
= blend
->cb_target_mask
;
86 r600_context_pipe_state_set(&rctx
->ctx
, rstate
);
89 void r600_bind_rs_state(struct pipe_context
*ctx
, void *state
)
91 struct r600_pipe_rasterizer
*rs
= (struct r600_pipe_rasterizer
*)state
;
92 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
97 rctx
->flatshade
= rs
->flatshade
;
98 rctx
->sprite_coord_enable
= rs
->sprite_coord_enable
;
99 rctx
->rasterizer
= rs
;
101 rctx
->states
[rs
->rstate
.id
] = &rs
->rstate
;
102 r600_context_pipe_state_set(&rctx
->ctx
, &rs
->rstate
);
104 if (rctx
->family
>= CHIP_CEDAR
) {
105 evergreen_polygon_offset_update(rctx
);
107 r600_polygon_offset_update(rctx
);
111 void r600_delete_rs_state(struct pipe_context
*ctx
, void *state
)
113 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
114 struct r600_pipe_rasterizer
*rs
= (struct r600_pipe_rasterizer
*)state
;
116 if (rctx
->rasterizer
== rs
) {
117 rctx
->rasterizer
= NULL
;
119 if (rctx
->states
[rs
->rstate
.id
] == &rs
->rstate
) {
120 rctx
->states
[rs
->rstate
.id
] = NULL
;
125 void r600_sampler_view_destroy(struct pipe_context
*ctx
,
126 struct pipe_sampler_view
*state
)
128 struct r600_pipe_sampler_view
*resource
= (struct r600_pipe_sampler_view
*)state
;
130 pipe_resource_reference(&state
->texture
, NULL
);
134 void r600_bind_state(struct pipe_context
*ctx
, void *state
)
136 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
137 struct r600_pipe_state
*rstate
= (struct r600_pipe_state
*)state
;
141 rctx
->states
[rstate
->id
] = rstate
;
142 r600_context_pipe_state_set(&rctx
->ctx
, rstate
);
145 void r600_delete_state(struct pipe_context
*ctx
, void *state
)
147 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
148 struct r600_pipe_state
*rstate
= (struct r600_pipe_state
*)state
;
150 if (rctx
->states
[rstate
->id
] == rstate
) {
151 rctx
->states
[rstate
->id
] = NULL
;
153 for (int i
= 0; i
< rstate
->nregs
; i
++) {
154 r600_bo_reference(rctx
->radeon
, &rstate
->regs
[i
].bo
, NULL
);
159 void r600_bind_vertex_elements(struct pipe_context
*ctx
, void *state
)
161 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
162 struct r600_vertex_element
*v
= (struct r600_vertex_element
*)state
;
164 rctx
->vertex_elements
= v
;
166 u_vbuf_mgr_bind_vertex_elements(rctx
->vbuf_mgr
, state
,
169 rctx
->states
[v
->rstate
.id
] = &v
->rstate
;
170 r600_context_pipe_state_set(&rctx
->ctx
, &v
->rstate
);
174 void r600_delete_vertex_element(struct pipe_context
*ctx
, void *state
)
176 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
177 struct r600_vertex_element
*v
= (struct r600_vertex_element
*)state
;
179 if (rctx
->states
[v
->rstate
.id
] == &v
->rstate
) {
180 rctx
->states
[v
->rstate
.id
] = NULL
;
182 if (rctx
->vertex_elements
== state
)
183 rctx
->vertex_elements
= NULL
;
185 r600_bo_reference(rctx
->radeon
, &v
->fetch_shader
, NULL
);
186 u_vbuf_mgr_destroy_vertex_elements(rctx
->vbuf_mgr
, v
->vmgr_elements
);
191 void r600_set_index_buffer(struct pipe_context
*ctx
,
192 const struct pipe_index_buffer
*ib
)
194 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
197 pipe_resource_reference(&rctx
->index_buffer
.buffer
, ib
->buffer
);
198 memcpy(&rctx
->index_buffer
, ib
, sizeof(rctx
->index_buffer
));
200 pipe_resource_reference(&rctx
->index_buffer
.buffer
, NULL
);
201 memset(&rctx
->index_buffer
, 0, sizeof(rctx
->index_buffer
));
204 /* TODO make this more like a state */
207 void r600_set_vertex_buffers(struct pipe_context
*ctx
, unsigned count
,
208 const struct pipe_vertex_buffer
*buffers
)
210 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
214 for (i
= 0; i
< count
; i
++) {
215 if (!buffers
[i
].buffer
) {
216 if (rctx
->family
>= CHIP_CEDAR
) {
217 evergreen_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
219 r600_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
223 for (; i
< rctx
->vbuf_mgr
->nr_real_vertex_buffers
; i
++) {
224 if (rctx
->family
>= CHIP_CEDAR
) {
225 evergreen_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
227 r600_context_pipe_state_set_fs_resource(&rctx
->ctx
, NULL
, i
);
231 u_vbuf_mgr_set_vertex_buffers(rctx
->vbuf_mgr
, count
, buffers
);
234 void *r600_create_vertex_elements(struct pipe_context
*ctx
,
236 const struct pipe_vertex_element
*elements
)
238 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
239 struct r600_vertex_element
*v
= CALLOC_STRUCT(r600_vertex_element
);
247 u_vbuf_mgr_create_vertex_elements(rctx
->vbuf_mgr
, count
,
248 elements
, v
->elements
);
250 if (r600_vertex_elements_build_fetch_shader(rctx
, v
)) {
258 void *r600_create_shader_state(struct pipe_context
*ctx
,
259 const struct pipe_shader_state
*state
)
261 struct r600_pipe_shader
*shader
= CALLOC_STRUCT(r600_pipe_shader
);
264 r
= r600_pipe_shader_create(ctx
, shader
, state
->tokens
);
271 void r600_bind_ps_shader(struct pipe_context
*ctx
, void *state
)
273 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
275 /* TODO delete old shader */
276 rctx
->ps_shader
= (struct r600_pipe_shader
*)state
;
278 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->ps_shader
->rstate
);
282 void r600_bind_vs_shader(struct pipe_context
*ctx
, void *state
)
284 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
286 /* TODO delete old shader */
287 rctx
->vs_shader
= (struct r600_pipe_shader
*)state
;
289 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->vs_shader
->rstate
);
293 void r600_delete_ps_shader(struct pipe_context
*ctx
, void *state
)
295 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
296 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
298 if (rctx
->ps_shader
== shader
) {
299 rctx
->ps_shader
= NULL
;
302 r600_pipe_shader_destroy(ctx
, shader
);
306 void r600_delete_vs_shader(struct pipe_context
*ctx
, void *state
)
308 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
309 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
311 if (rctx
->vs_shader
== shader
) {
312 rctx
->vs_shader
= NULL
;
315 r600_pipe_shader_destroy(ctx
, shader
);
319 /* FIXME optimize away spi update when it's not needed */
320 static void r600_spi_update(struct r600_pipe_context
*rctx
, unsigned prim
)
322 struct r600_pipe_shader
*shader
= rctx
->ps_shader
;
323 struct r600_pipe_state rstate
;
324 struct r600_shader
*rshader
= &shader
->shader
;
328 for (i
= 0; i
< rshader
->ninput
; i
++) {
329 tmp
= S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx
->vs_shader
->shader
, rshader
, i
));
331 if (rshader
->input
[i
].name
== TGSI_SEMANTIC_COLOR
||
332 rshader
->input
[i
].name
== TGSI_SEMANTIC_BCOLOR
||
333 rshader
->input
[i
].name
== TGSI_SEMANTIC_POSITION
) {
334 tmp
|= S_028644_FLAT_SHADE(rctx
->flatshade
);
337 if (rshader
->input
[i
].name
== TGSI_SEMANTIC_GENERIC
&&
338 rctx
->sprite_coord_enable
& (1 << rshader
->input
[i
].sid
)) {
339 tmp
|= S_028644_PT_SPRITE_TEX(1);
342 if (rctx
->family
< CHIP_CEDAR
) {
343 if (rshader
->input
[i
].centroid
)
344 tmp
|= S_028644_SEL_CENTROID(1);
346 if (rshader
->input
[i
].interpolate
== TGSI_INTERPOLATE_LINEAR
)
347 tmp
|= S_028644_SEL_LINEAR(1);
350 r600_pipe_state_add_reg(&rstate
, R_028644_SPI_PS_INPUT_CNTL_0
+ i
* 4, tmp
, 0xFFFFFFFF, NULL
);
353 if (prim
== PIPE_PRIM_QUADS
|| prim
== PIPE_PRIM_QUAD_STRIP
|| prim
== PIPE_PRIM_POLYGON
) {
354 r600_pipe_state_add_reg(&rstate
, R_028814_PA_SU_SC_MODE_CNTL
,
355 S_028814_PROVOKING_VTX_LAST(1),
356 S_028814_PROVOKING_VTX_LAST(1), NULL
);
358 r600_context_pipe_state_set(&rctx
->ctx
, &rstate
);
361 void r600_set_constant_buffer(struct pipe_context
*ctx
, uint shader
, uint index
,
362 struct pipe_resource
*buffer
)
364 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
365 struct r600_resource_buffer
*rbuffer
= r600_buffer(buffer
);
366 struct r600_pipe_state
*rstate
;
369 /* Note that the state tracker can unbind constant buffers by
372 if (buffer
== NULL
) {
376 r600_upload_const_buffer(rctx
, &rbuffer
, &offset
);
377 offset
+= r600_bo_offset(rbuffer
->r
.bo
);
380 case PIPE_SHADER_VERTEX
:
381 rctx
->vs_const_buffer
.nregs
= 0;
382 r600_pipe_state_add_reg(&rctx
->vs_const_buffer
,
383 R_028180_ALU_CONST_BUFFER_SIZE_VS_0
,
384 ALIGN_DIVUP(buffer
->width0
>> 4, 16),
386 r600_pipe_state_add_reg(&rctx
->vs_const_buffer
,
387 R_028980_ALU_CONST_CACHE_VS_0
,
388 offset
>> 8, 0xFFFFFFFF, rbuffer
->r
.bo
);
389 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->vs_const_buffer
);
391 rstate
= &rctx
->vs_const_buffer_resource
[index
];
392 rstate
->id
= R600_PIPE_STATE_RESOURCE
;
394 if (rctx
->family
>= CHIP_CEDAR
) {
395 evergreen_pipe_set_buffer_resource(rctx
, rstate
, &rbuffer
->r
, offset
, 16);
396 evergreen_context_pipe_state_set_vs_resource(&rctx
->ctx
, rstate
, index
);
398 r600_pipe_set_buffer_resource(rctx
, rstate
, &rbuffer
->r
, offset
, 16);
399 r600_context_pipe_state_set_vs_resource(&rctx
->ctx
, rstate
, index
);
402 case PIPE_SHADER_FRAGMENT
:
403 rctx
->ps_const_buffer
.nregs
= 0;
404 r600_pipe_state_add_reg(&rctx
->ps_const_buffer
,
405 R_028140_ALU_CONST_BUFFER_SIZE_PS_0
,
406 ALIGN_DIVUP(buffer
->width0
>> 4, 16),
408 r600_pipe_state_add_reg(&rctx
->ps_const_buffer
,
409 R_028940_ALU_CONST_CACHE_PS_0
,
410 offset
>> 8, 0xFFFFFFFF, rbuffer
->r
.bo
);
411 r600_context_pipe_state_set(&rctx
->ctx
, &rctx
->ps_const_buffer
);
413 rstate
= &rctx
->ps_const_buffer_resource
[index
];
414 rstate
->id
= R600_PIPE_STATE_RESOURCE
;
416 if (rctx
->family
>= CHIP_CEDAR
) {
417 evergreen_pipe_set_buffer_resource(rctx
, rstate
, &rbuffer
->r
, offset
, 16);
418 evergreen_context_pipe_state_set_ps_resource(&rctx
->ctx
, rstate
, index
);
420 r600_pipe_set_buffer_resource(rctx
, rstate
, &rbuffer
->r
, offset
, 16);
421 r600_context_pipe_state_set_ps_resource(&rctx
->ctx
, rstate
, index
);
425 R600_ERR("unsupported %d\n", shader
);
429 if (buffer
!= &rbuffer
->r
.b
.b
.b
)
430 pipe_resource_reference((struct pipe_resource
**)&rbuffer
, NULL
);
433 static void r600_vertex_buffer_update(struct r600_pipe_context
*rctx
)
435 struct r600_pipe_state
*rstate
;
436 struct r600_resource
*rbuffer
;
437 struct pipe_vertex_buffer
*vertex_buffer
;
438 unsigned i
, count
, offset
;
440 if (rctx
->vertex_elements
->vbuffer_need_offset
) {
441 /* one resource per vertex elements */
442 count
= rctx
->vertex_elements
->count
;
444 /* bind vertex buffer once */
445 count
= rctx
->vbuf_mgr
->nr_real_vertex_buffers
;
448 for (i
= 0 ; i
< count
; i
++) {
449 rstate
= &rctx
->fs_resource
[i
];
450 rstate
->id
= R600_PIPE_STATE_RESOURCE
;
453 if (rctx
->vertex_elements
->vbuffer_need_offset
) {
454 /* one resource per vertex elements */
455 unsigned vbuffer_index
;
456 vbuffer_index
= rctx
->vertex_elements
->elements
[i
].vertex_buffer_index
;
457 vertex_buffer
= &rctx
->vbuf_mgr
->vertex_buffer
[vbuffer_index
];
458 rbuffer
= (struct r600_resource
*)rctx
->vbuf_mgr
->real_vertex_buffer
[vbuffer_index
];
459 offset
= rctx
->vertex_elements
->vbuffer_offset
[i
];
461 /* bind vertex buffer once */
462 vertex_buffer
= &rctx
->vbuf_mgr
->vertex_buffer
[i
];
463 rbuffer
= (struct r600_resource
*)rctx
->vbuf_mgr
->real_vertex_buffer
[i
];
466 if (vertex_buffer
== NULL
|| rbuffer
== NULL
)
468 offset
+= vertex_buffer
->buffer_offset
+ r600_bo_offset(rbuffer
->bo
);
470 if (rctx
->family
>= CHIP_CEDAR
) {
471 evergreen_pipe_set_buffer_resource(rctx
, rstate
, rbuffer
, offset
, vertex_buffer
->stride
);
472 evergreen_context_pipe_state_set_fs_resource(&rctx
->ctx
, rstate
, i
);
474 r600_pipe_set_buffer_resource(rctx
, rstate
, rbuffer
, offset
, vertex_buffer
->stride
);
475 r600_context_pipe_state_set_fs_resource(&rctx
->ctx
, rstate
, i
);
480 void r600_draw_vbo(struct pipe_context
*ctx
, const struct pipe_draw_info
*info
)
482 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
483 struct r600_resource
*rbuffer
;
484 u32 vgt_dma_index_type
, vgt_dma_swap_mode
, vgt_draw_initiator
, mask
;
485 struct r600_draw rdraw
;
486 struct r600_pipe_state vgt
;
487 struct r600_drawl draw
= {};
490 r600_flush_depth_textures(rctx
);
491 u_vbuf_mgr_draw_begin(rctx
->vbuf_mgr
, info
, NULL
, NULL
);
492 r600_vertex_buffer_update(rctx
);
496 if (info
->indexed
&& rctx
->index_buffer
.buffer
) {
497 draw
.info
.start
+= rctx
->index_buffer
.offset
/ rctx
->index_buffer
.index_size
;
498 pipe_resource_reference(&draw
.index_buffer
, rctx
->index_buffer
.buffer
);
500 r600_translate_index_buffer(rctx
, &draw
.index_buffer
,
501 &rctx
->index_buffer
.index_size
,
505 draw
.index_size
= rctx
->index_buffer
.index_size
;
506 draw
.index_buffer_offset
= draw
.info
.start
* draw
.index_size
;
509 if (u_vbuf_resource(draw
.index_buffer
)->user_ptr
) {
510 r600_upload_index_buffer(rctx
, &draw
);
513 draw
.info
.index_bias
= info
->start
;
516 vgt_dma_swap_mode
= 0;
517 switch (draw
.index_size
) {
519 vgt_draw_initiator
= 0;
520 vgt_dma_index_type
= 0;
521 if (R600_BIG_ENDIAN
) {
522 vgt_dma_swap_mode
= ENDIAN_8IN16
;
526 vgt_draw_initiator
= 0;
527 vgt_dma_index_type
= 1;
528 if (R600_BIG_ENDIAN
) {
529 vgt_dma_swap_mode
= ENDIAN_8IN32
;
533 vgt_draw_initiator
= 2;
534 vgt_dma_index_type
= 0;
537 R600_ERR("unsupported index size %d\n", draw
.index_size
);
540 if (r600_conv_pipe_prim(draw
.info
.mode
, &prim
))
542 if (unlikely(rctx
->ps_shader
== NULL
)) {
543 R600_ERR("missing vertex shader\n");
546 if (unlikely(rctx
->vs_shader
== NULL
)) {
547 R600_ERR("missing vertex shader\n");
550 /* there should be enough input */
551 if (rctx
->vertex_elements
->count
< rctx
->vs_shader
->shader
.bc
.nresource
) {
552 R600_ERR("%d resources provided, expecting %d\n",
553 rctx
->vertex_elements
->count
, rctx
->vs_shader
->shader
.bc
.nresource
);
557 r600_spi_update(rctx
, draw
.info
.mode
);
560 for (int i
= 0; i
< rctx
->framebuffer
.nr_cbufs
; i
++) {
561 mask
|= (0xF << (i
* 4));
564 vgt
.id
= R600_PIPE_STATE_VGT
;
566 r600_pipe_state_add_reg(&vgt
, R_008958_VGT_PRIMITIVE_TYPE
, prim
, 0xFFFFFFFF, NULL
);
567 r600_pipe_state_add_reg(&vgt
, R_028408_VGT_INDX_OFFSET
, draw
.info
.index_bias
, 0xFFFFFFFF, NULL
);
568 r600_pipe_state_add_reg(&vgt
, R_028400_VGT_MAX_VTX_INDX
, draw
.info
.max_index
, 0xFFFFFFFF, NULL
);
569 r600_pipe_state_add_reg(&vgt
, R_028404_VGT_MIN_VTX_INDX
, draw
.info
.min_index
, 0xFFFFFFFF, NULL
);
570 r600_pipe_state_add_reg(&vgt
, R_028238_CB_TARGET_MASK
, rctx
->cb_target_mask
& mask
, 0xFFFFFFFF, NULL
);
571 r600_pipe_state_add_reg(&vgt
, R_03CFF0_SQ_VTX_BASE_VTX_LOC
, 0, 0xFFFFFFFF, NULL
);
572 r600_pipe_state_add_reg(&vgt
, R_03CFF4_SQ_VTX_START_INST_LOC
, draw
.info
.start_instance
, 0xFFFFFFFF, NULL
);
573 r600_context_pipe_state_set(&rctx
->ctx
, &vgt
);
575 rdraw
.vgt_num_indices
= draw
.info
.count
;
576 rdraw
.vgt_num_instances
= draw
.info
.instance_count
;
577 rdraw
.vgt_index_type
= vgt_dma_index_type
| (vgt_dma_swap_mode
<< 2);
578 rdraw
.vgt_draw_initiator
= vgt_draw_initiator
;
579 rdraw
.indices
= NULL
;
580 if (draw
.index_buffer
) {
581 rbuffer
= (struct r600_resource
*)draw
.index_buffer
;
582 rdraw
.indices
= rbuffer
->bo
;
583 rdraw
.indices_bo_offset
= draw
.index_buffer_offset
;
586 if (rctx
->family
>= CHIP_CEDAR
) {
587 evergreen_context_draw(&rctx
->ctx
, &rdraw
);
589 r600_context_draw(&rctx
->ctx
, &rdraw
);
592 if (rctx
->framebuffer
.zsbuf
)
594 struct pipe_resource
*tex
= rctx
->framebuffer
.zsbuf
->texture
;
595 ((struct r600_resource_texture
*)tex
)->dirty_db
= TRUE
;
598 pipe_resource_reference(&draw
.index_buffer
, NULL
);
600 u_vbuf_mgr_draw_end(rctx
->vbuf_mgr
);