aa254faf15925ef48622a81cff465641246a9b9c
[mesa.git] / src / gallium / drivers / r600 / r600_draw.c
1 /*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 *
23 * Authors:
24 * Jerome Glisse
25 * Corbin Simpson
26 */
27 #include <stdio.h>
28 #include <errno.h>
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>
34 #include "r600_screen.h"
35 #include "r600_context.h"
36 #include "r600d.h"
37
38 struct r600_draw {
39 struct pipe_context *ctx;
40 struct radeon_state *draw;
41 struct radeon_state *vgt;
42 unsigned mode;
43 unsigned start;
44 unsigned count;
45 unsigned index_size;
46 struct pipe_buffer *index_buffer;
47 };
48
49 static int r600_draw_common(struct r600_draw *draw)
50 {
51 struct r600_context *rctx = (struct r600_context*)draw->ctx;
52 struct r600_screen *rscreen = (struct r600_screen*)draw->ctx->screen;
53 struct radeon_state *vs_resource;
54 struct r600_buffer *rbuffer;
55 unsigned i, j, offset, format, prim;
56 u32 vgt_dma_index_type, vgt_draw_initiator;
57 int r;
58
59 switch (draw->index_size) {
60 case 2:
61 vgt_draw_initiator = 0;
62 vgt_dma_index_type = 0;
63 break;
64 case 4:
65 vgt_draw_initiator = 0;
66 vgt_dma_index_type = 1;
67 break;
68 case 0:
69 vgt_draw_initiator = 2;
70 vgt_dma_index_type = 0;
71 break;
72 default:
73 fprintf(stderr, "%s %d unsupported index size %d\n", __func__, __LINE__, draw->index_size);
74 return -EINVAL;
75 }
76 r = r600_conv_pipe_prim(draw->mode, &prim);
77 if (r)
78 return r;
79 /* rebuild vertex shader if input format changed */
80 r = r600_pipe_shader_update(draw->ctx, rctx->vs_shader);
81 if (r)
82 return r;
83 r = r600_pipe_shader_update(draw->ctx, rctx->ps_shader);
84 if (r)
85 return r;
86 r = radeon_draw_set(rctx->draw, rctx->vs_shader->state);
87 if (r)
88 return r;
89 r = radeon_draw_set(rctx->draw, rctx->ps_shader->state);
90 if (r)
91 return r;
92 r = radeon_draw_set(rctx->draw, rctx->cb_cntl);
93 if (r)
94 return r;
95 r = radeon_draw_set(rctx->draw, rctx->db);
96 if (r)
97 return r;
98 r = radeon_draw_set(rctx->draw, rctx->config);
99 if (r)
100 return r;
101
102 for (i = 0 ; i < rctx->nvertex_element; i++) {
103 j = rctx->vertex_element[i].vertex_buffer_index;
104 rbuffer = (struct r600_buffer*)rctx->vertex_buffer[j].buffer;
105 offset = rctx->vertex_element[i].src_offset + rctx->vertex_buffer[j].buffer_offset;
106 r = r600_conv_pipe_format(rctx->vertex_element[i].src_format, &format);
107 if (r)
108 return r;
109 vs_resource = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i);
110 if (vs_resource == NULL)
111 return -ENOMEM;
112 vs_resource->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
113 vs_resource->nbo = 1;
114 vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset;
115 vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset;
116 vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(rctx->vertex_buffer[j].stride) |
117 S_038008_DATA_FORMAT(format);
118 vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000;
119 vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000;
120 vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD5] = 0x00000000;
121 vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD6] = 0xC0000000;
122 vs_resource->placement[0] = RADEON_GEM_DOMAIN_GTT;
123 vs_resource->placement[1] = RADEON_GEM_DOMAIN_GTT;
124 r = radeon_draw_set_new(rctx->draw, vs_resource);
125 if (r)
126 return r;
127 }
128 /* FIXME start need to change winsys */
129 draw->draw = radeon_state(rscreen->rw, R600_DRAW_TYPE, R600_DRAW);
130 if (draw->draw == NULL)
131 return -ENOMEM;
132 draw->draw->states[R600_DRAW__VGT_NUM_INDICES] = draw->count;
133 draw->draw->states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator;
134 if (draw->index_buffer) {
135 rbuffer = (struct r600_buffer*)draw->index_buffer;
136 draw->draw->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
137 draw->draw->placement[0] = RADEON_GEM_DOMAIN_GTT;
138 draw->draw->placement[1] = RADEON_GEM_DOMAIN_GTT;
139 draw->draw->nbo = 1;
140 }
141 r = radeon_draw_set_new(rctx->draw, draw->draw);
142 if (r)
143 return r;
144 draw->vgt = radeon_state(rscreen->rw, R600_VGT_TYPE, R600_VGT);
145 if (draw->vgt == NULL)
146 return -ENOMEM;
147 draw->vgt->states[R600_VGT__VGT_PRIMITIVE_TYPE] = prim;
148 draw->vgt->states[R600_VGT__VGT_MAX_VTX_INDX] = 0x00FFFFFF;
149 draw->vgt->states[R600_VGT__VGT_MIN_VTX_INDX] = 0x00000000;
150 draw->vgt->states[R600_VGT__VGT_INDX_OFFSET] = draw->start;
151 draw->vgt->states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX] = 0x00000000;
152 draw->vgt->states[R600_VGT__VGT_DMA_INDEX_TYPE] = vgt_dma_index_type;
153 draw->vgt->states[R600_VGT__VGT_PRIMITIVEID_EN] = 0x00000000;
154 draw->vgt->states[R600_VGT__VGT_DMA_NUM_INSTANCES] = 0x00000001;
155 draw->vgt->states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_EN] = 0x00000000;
156 draw->vgt->states[R600_VGT__VGT_INSTANCE_STEP_RATE_0] = 0x00000000;
157 draw->vgt->states[R600_VGT__VGT_INSTANCE_STEP_RATE_1] = 0x00000000;
158 r = radeon_draw_set_new(rctx->draw, draw->vgt);
159 if (r)
160 return r;
161 /* FIXME */
162 r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw);
163 if (r)
164 return r;
165 rctx->draw = radeon_draw_duplicate(rctx->draw);
166 return 0;
167 }
168
169 void r600_draw_range_elements(struct pipe_context *ctx,
170 struct pipe_buffer *index_buffer,
171 unsigned index_size, unsigned index_bias, unsigned min_index,
172 unsigned max_index, unsigned mode,
173 unsigned start, unsigned count)
174 {
175 struct r600_draw draw;
176 assert(index_bias == 0);
177
178 draw.ctx = ctx;
179 draw.mode = mode;
180 draw.start = start;
181 draw.count = count;
182 draw.index_size = index_size;
183 draw.index_buffer = index_buffer;
184 printf("index_size %d min %d max %d start %d count %d\n", index_size, min_index, max_index, start, count);
185 r600_draw_common(&draw);
186 }
187
188 void r600_draw_elements(struct pipe_context *ctx,
189 struct pipe_buffer *index_buffer,
190 unsigned index_size, unsigned index_bias, unsigned mode,
191 unsigned start, unsigned count)
192 {
193 struct r600_draw draw;
194 assert(index_bias == 0);
195
196 draw.ctx = ctx;
197 draw.mode = mode;
198 draw.start = start;
199 draw.count = count;
200 draw.index_size = index_size;
201 draw.index_buffer = index_buffer;
202 r600_draw_common(&draw);
203 }
204
205 void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
206 unsigned start, unsigned count)
207 {
208 struct r600_draw draw;
209
210 draw.ctx = ctx;
211 draw.mode = mode;
212 draw.start = start;
213 draw.count = count;
214 draw.index_size = 0;
215 draw.index_buffer = NULL;
216 r600_draw_common(&draw);
217 }