2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include <pipe/p_screen.h>
30 #include <util/u_format.h>
31 #include <util/u_math.h>
32 #include <util/u_inlines.h>
33 #include <util/u_memory.h>
35 #include "r600_screen.h"
36 #include "r600_context.h"
37 #include "r600_resource.h"
38 #include "r600_state_inlines.h"
41 struct pipe_context
*ctx
;
42 struct radeon_state draw
;
43 struct radeon_state vgt
;
48 struct pipe_resource
*index_buffer
;
51 static int r600_draw_common(struct r600_draw
*draw
)
53 struct r600_context
*rctx
= r600_context(draw
->ctx
);
54 struct r600_screen
*rscreen
= rctx
->screen
;
55 /* FIXME vs_resource */
56 struct radeon_state
*vs_resource
;
57 struct r600_resource
*rbuffer
;
58 unsigned i
, j
, offset
, format
, prim
;
59 u32 vgt_dma_index_type
, vgt_draw_initiator
;
60 struct pipe_vertex_buffer
*vertex_buffer
;
63 r
= r600_context_hw_states(draw
->ctx
);
66 switch (draw
->index_size
) {
68 vgt_draw_initiator
= 0;
69 vgt_dma_index_type
= 0;
72 vgt_draw_initiator
= 0;
73 vgt_dma_index_type
= 1;
76 vgt_draw_initiator
= 2;
77 vgt_dma_index_type
= 0;
80 fprintf(stderr
, "%s %d unsupported index size %d\n", __func__
, __LINE__
, draw
->index_size
);
83 r
= r600_conv_pipe_prim(draw
->mode
, &prim
);
87 /* rebuild vertex shader if input format changed */
88 r
= r600_pipe_shader_update(draw
->ctx
, rctx
->vs_shader
);
91 r
= r600_pipe_shader_update(draw
->ctx
, rctx
->ps_shader
);
94 radeon_draw_bind(&rctx
->draw
, &rctx
->vs_shader
->rstate
[0]);
95 radeon_draw_bind(&rctx
->draw
, &rctx
->ps_shader
->rstate
[0]);
97 for (i
= 0 ; i
< rctx
->vertex_elements
->count
; i
++) {
98 vs_resource
= &rctx
->vs_resource
[i
];
99 j
= rctx
->vertex_elements
->elements
[i
].vertex_buffer_index
;
100 vertex_buffer
= &rctx
->vertex_buffer
[j
];
101 rbuffer
= (struct r600_resource
*)vertex_buffer
->buffer
;
102 offset
= rctx
->vertex_elements
->elements
[i
].src_offset
+ vertex_buffer
->buffer_offset
;
103 format
= r600_translate_colorformat(rctx
->vertex_elements
->elements
[i
].src_format
);
104 radeon_state_init(vs_resource
, rscreen
->rw
, R600_STATE_RESOURCE
, i
, R600_SHADER_VS
);
105 vs_resource
->bo
[0] = radeon_bo_incref(rscreen
->rw
, rbuffer
->bo
);
106 vs_resource
->nbo
= 1;
107 vs_resource
->states
[R600_PS_RESOURCE__RESOURCE0_WORD0
] = offset
;
108 vs_resource
->states
[R600_PS_RESOURCE__RESOURCE0_WORD1
] = rbuffer
->bo
->size
- offset
- 1;
109 vs_resource
->states
[R600_PS_RESOURCE__RESOURCE0_WORD2
] = S_038008_STRIDE(vertex_buffer
->stride
) |
110 S_038008_DATA_FORMAT(format
);
111 vs_resource
->states
[R600_PS_RESOURCE__RESOURCE0_WORD3
] = 0x00000000;
112 vs_resource
->states
[R600_PS_RESOURCE__RESOURCE0_WORD4
] = 0x00000000;
113 vs_resource
->states
[R600_PS_RESOURCE__RESOURCE0_WORD5
] = 0x00000000;
114 vs_resource
->states
[R600_PS_RESOURCE__RESOURCE0_WORD6
] = 0xC0000000;
115 vs_resource
->placement
[0] = RADEON_GEM_DOMAIN_GTT
;
116 vs_resource
->placement
[1] = RADEON_GEM_DOMAIN_GTT
;
117 r
= radeon_state_pm4(vs_resource
);
121 radeon_draw_bind(&rctx
->draw
, vs_resource
);
123 /* FIXME start need to change winsys */
124 radeon_state_init(&draw
->draw
, rscreen
->rw
, R600_STATE_DRAW
, 0, 0);
125 draw
->draw
.states
[R600_DRAW__VGT_NUM_INDICES
] = draw
->count
;
126 draw
->draw
.states
[R600_DRAW__VGT_DRAW_INITIATOR
] = vgt_draw_initiator
;
127 if (draw
->index_buffer
) {
128 rbuffer
= (struct r600_resource
*)draw
->index_buffer
;
129 draw
->draw
.bo
[0] = radeon_bo_incref(rscreen
->rw
, rbuffer
->bo
);
130 draw
->draw
.placement
[0] = RADEON_GEM_DOMAIN_GTT
;
131 draw
->draw
.placement
[1] = RADEON_GEM_DOMAIN_GTT
;
134 r
= radeon_state_pm4(&draw
->draw
);
138 radeon_draw_bind(&rctx
->draw
, &draw
->draw
);
140 radeon_state_init(&draw
->vgt
, rscreen
->rw
, R600_STATE_VGT
, 0, 0);
141 draw
->vgt
.states
[R600_VGT__VGT_PRIMITIVE_TYPE
] = prim
;
142 draw
->vgt
.states
[R600_VGT__VGT_MAX_VTX_INDX
] = 0x00FFFFFF;
143 draw
->vgt
.states
[R600_VGT__VGT_MIN_VTX_INDX
] = 0x00000000;
144 draw
->vgt
.states
[R600_VGT__VGT_INDX_OFFSET
] = draw
->start
;
145 draw
->vgt
.states
[R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX
] = 0x00000000;
146 draw
->vgt
.states
[R600_VGT__VGT_DMA_INDEX_TYPE
] = vgt_dma_index_type
;
147 draw
->vgt
.states
[R600_VGT__VGT_PRIMITIVEID_EN
] = 0x00000000;
148 draw
->vgt
.states
[R600_VGT__VGT_DMA_NUM_INSTANCES
] = 0x00000001;
149 draw
->vgt
.states
[R600_VGT__VGT_MULTI_PRIM_IB_RESET_EN
] = 0x00000000;
150 draw
->vgt
.states
[R600_VGT__VGT_INSTANCE_STEP_RATE_0
] = 0x00000000;
151 draw
->vgt
.states
[R600_VGT__VGT_INSTANCE_STEP_RATE_1
] = 0x00000000;
152 r
= radeon_state_pm4(&draw
->vgt
);
156 radeon_draw_bind(&rctx
->draw
, &draw
->vgt
);
158 r
= radeon_ctx_set_draw(&rctx
->ctx
, &rctx
->draw
);
160 r600_flush(draw
->ctx
, 0, NULL
);
161 r
= radeon_ctx_set_draw(&rctx
->ctx
, &rctx
->draw
);
166 void r600_draw_vbo(struct pipe_context
*ctx
, const struct pipe_draw_info
*info
)
168 struct r600_context
*rctx
= r600_context(ctx
);
169 struct r600_draw draw
;
172 assert(info
->index_bias
== 0);
175 draw
.mode
= info
->mode
;
176 draw
.start
= info
->start
;
177 draw
.count
= info
->count
;
178 if (info
->indexed
&& rctx
->index_buffer
.buffer
) {
179 draw
.index_size
= rctx
->index_buffer
.index_size
;
180 draw
.index_buffer
= rctx
->index_buffer
.buffer
;
182 assert(rctx
->index_buffer
.offset
%
183 rctx
->index_buffer
.index_size
== 0);
184 draw
.start
+= rctx
->index_buffer
.offset
/
185 rctx
->index_buffer
.index_size
;
189 draw
.index_buffer
= NULL
;
191 r
= r600_draw_common(&draw
);
193 fprintf(stderr
,"draw common failed %d\n", r
);