570ea23ff458ff83c50a3e44af5bd1d6b91eb673
[mesa.git] / src / gallium / drivers / i965 / brw_pipe_vertex.c
1 #include "brw_context.h"
2 #include "brw_defines.h"
3 #include "brw_structs.h"
4
5 #include "util/u_memory.h"
6 #include "util/u_format.h"
7 #include "util/u_transfer.h"
8
9
10 static unsigned brw_translate_surface_format( unsigned id )
11 {
12 switch (id) {
13 case PIPE_FORMAT_R64_FLOAT:
14 return BRW_SURFACEFORMAT_R64_FLOAT;
15 case PIPE_FORMAT_R64G64_FLOAT:
16 return BRW_SURFACEFORMAT_R64G64_FLOAT;
17 case PIPE_FORMAT_R64G64B64_FLOAT:
18 return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
19 case PIPE_FORMAT_R64G64B64A64_FLOAT:
20 return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
21
22 case PIPE_FORMAT_R32_FLOAT:
23 return BRW_SURFACEFORMAT_R32_FLOAT;
24 case PIPE_FORMAT_R32G32_FLOAT:
25 return BRW_SURFACEFORMAT_R32G32_FLOAT;
26 case PIPE_FORMAT_R32G32B32_FLOAT:
27 return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
28 case PIPE_FORMAT_R32G32B32A32_FLOAT:
29 return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
30
31 case PIPE_FORMAT_R32_UNORM:
32 return BRW_SURFACEFORMAT_R32_UNORM;
33 case PIPE_FORMAT_R32G32_UNORM:
34 return BRW_SURFACEFORMAT_R32G32_UNORM;
35 case PIPE_FORMAT_R32G32B32_UNORM:
36 return BRW_SURFACEFORMAT_R32G32B32_UNORM;
37 case PIPE_FORMAT_R32G32B32A32_UNORM:
38 return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
39
40 case PIPE_FORMAT_R32_USCALED:
41 return BRW_SURFACEFORMAT_R32_USCALED;
42 case PIPE_FORMAT_R32G32_USCALED:
43 return BRW_SURFACEFORMAT_R32G32_USCALED;
44 case PIPE_FORMAT_R32G32B32_USCALED:
45 return BRW_SURFACEFORMAT_R32G32B32_USCALED;
46 case PIPE_FORMAT_R32G32B32A32_USCALED:
47 return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
48
49 case PIPE_FORMAT_R32_SNORM:
50 return BRW_SURFACEFORMAT_R32_SNORM;
51 case PIPE_FORMAT_R32G32_SNORM:
52 return BRW_SURFACEFORMAT_R32G32_SNORM;
53 case PIPE_FORMAT_R32G32B32_SNORM:
54 return BRW_SURFACEFORMAT_R32G32B32_SNORM;
55 case PIPE_FORMAT_R32G32B32A32_SNORM:
56 return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
57
58 case PIPE_FORMAT_R32_SSCALED:
59 return BRW_SURFACEFORMAT_R32_SSCALED;
60 case PIPE_FORMAT_R32G32_SSCALED:
61 return BRW_SURFACEFORMAT_R32G32_SSCALED;
62 case PIPE_FORMAT_R32G32B32_SSCALED:
63 return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
64 case PIPE_FORMAT_R32G32B32A32_SSCALED:
65 return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
66
67 case PIPE_FORMAT_R16_UNORM:
68 return BRW_SURFACEFORMAT_R16_UNORM;
69 case PIPE_FORMAT_R16G16_UNORM:
70 return BRW_SURFACEFORMAT_R16G16_UNORM;
71 case PIPE_FORMAT_R16G16B16_UNORM:
72 return BRW_SURFACEFORMAT_R16G16B16_UNORM;
73 case PIPE_FORMAT_R16G16B16A16_UNORM:
74 return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
75
76 case PIPE_FORMAT_R16_USCALED:
77 return BRW_SURFACEFORMAT_R16_USCALED;
78 case PIPE_FORMAT_R16G16_USCALED:
79 return BRW_SURFACEFORMAT_R16G16_USCALED;
80 case PIPE_FORMAT_R16G16B16_USCALED:
81 return BRW_SURFACEFORMAT_R16G16B16_USCALED;
82 case PIPE_FORMAT_R16G16B16A16_USCALED:
83 return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
84
85 case PIPE_FORMAT_R16_SNORM:
86 return BRW_SURFACEFORMAT_R16_SNORM;
87 case PIPE_FORMAT_R16G16_SNORM:
88 return BRW_SURFACEFORMAT_R16G16_SNORM;
89 case PIPE_FORMAT_R16G16B16_SNORM:
90 return BRW_SURFACEFORMAT_R16G16B16_SNORM;
91 case PIPE_FORMAT_R16G16B16A16_SNORM:
92 return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
93
94 case PIPE_FORMAT_R16_SSCALED:
95 return BRW_SURFACEFORMAT_R16_SSCALED;
96 case PIPE_FORMAT_R16G16_SSCALED:
97 return BRW_SURFACEFORMAT_R16G16_SSCALED;
98 case PIPE_FORMAT_R16G16B16_SSCALED:
99 return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
100 case PIPE_FORMAT_R16G16B16A16_SSCALED:
101 return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
102
103 case PIPE_FORMAT_R8_UNORM:
104 return BRW_SURFACEFORMAT_R8_UNORM;
105 case PIPE_FORMAT_R8G8_UNORM:
106 return BRW_SURFACEFORMAT_R8G8_UNORM;
107 case PIPE_FORMAT_R8G8B8_UNORM:
108 return BRW_SURFACEFORMAT_R8G8B8_UNORM;
109 case PIPE_FORMAT_R8G8B8A8_UNORM:
110 return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
111
112 case PIPE_FORMAT_R8_USCALED:
113 return BRW_SURFACEFORMAT_R8_USCALED;
114 case PIPE_FORMAT_R8G8_USCALED:
115 return BRW_SURFACEFORMAT_R8G8_USCALED;
116 case PIPE_FORMAT_R8G8B8_USCALED:
117 return BRW_SURFACEFORMAT_R8G8B8_USCALED;
118 case PIPE_FORMAT_R8G8B8A8_USCALED:
119 return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
120
121 case PIPE_FORMAT_R8_SNORM:
122 return BRW_SURFACEFORMAT_R8_SNORM;
123 case PIPE_FORMAT_R8G8_SNORM:
124 return BRW_SURFACEFORMAT_R8G8_SNORM;
125 case PIPE_FORMAT_R8G8B8_SNORM:
126 return BRW_SURFACEFORMAT_R8G8B8_SNORM;
127 case PIPE_FORMAT_R8G8B8A8_SNORM:
128 return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
129
130 case PIPE_FORMAT_R8_SSCALED:
131 return BRW_SURFACEFORMAT_R8_SSCALED;
132 case PIPE_FORMAT_R8G8_SSCALED:
133 return BRW_SURFACEFORMAT_R8G8_SSCALED;
134 case PIPE_FORMAT_R8G8B8_SSCALED:
135 return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
136 case PIPE_FORMAT_R8G8B8A8_SSCALED:
137 return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
138
139 default:
140 assert(0);
141 return 0;
142 }
143 }
144
145 static void brw_translate_vertex_elements(struct brw_context *brw,
146 struct brw_vertex_element_packet *brw_velems,
147 const struct pipe_vertex_element *attribs,
148 unsigned count)
149 {
150 unsigned i;
151
152 /* If the VS doesn't read any inputs (calculating vertex position from
153 * a state variable for some reason, for example), emit a single pad
154 * VERTEX_ELEMENT struct and bail.
155 *
156 * The stale VB state stays in place, but they don't do anything unless
157 * a VE loads from them.
158 */
159 brw_velems->header.opcode = CMD_VERTEX_ELEMENT;
160
161 if (count == 0) {
162 brw_velems->header.length = 1;
163 brw_velems->ve[0].ve0.src_offset = 0;
164 brw_velems->ve[0].ve0.src_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
165 brw_velems->ve[0].ve0.valid = 1;
166 brw_velems->ve[0].ve0.vertex_buffer_index = 0;
167 brw_velems->ve[0].ve1.dst_offset = 0;
168 brw_velems->ve[0].ve1.vfcomponent0 = BRW_VE1_COMPONENT_STORE_0;
169 brw_velems->ve[0].ve1.vfcomponent1 = BRW_VE1_COMPONENT_STORE_0;
170 brw_velems->ve[0].ve1.vfcomponent2 = BRW_VE1_COMPONENT_STORE_0;
171 brw_velems->ve[0].ve1.vfcomponent3 = BRW_VE1_COMPONENT_STORE_1_FLT;
172 return;
173 }
174
175
176 /* Now emit vertex element (VEP) state packets.
177 *
178 */
179 brw_velems->header.length = (1 + count * 2) - 2;
180 for (i = 0; i < count; i++) {
181 const struct pipe_vertex_element *input = &attribs[i];
182 unsigned nr_components = util_format_get_nr_components(input->src_format);
183
184 uint32_t format = brw_translate_surface_format( input->src_format );
185 uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
186 uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
187 uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
188 uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
189
190 switch (nr_components) {
191 case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
192 case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
193 case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
194 case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
195 break;
196 }
197
198 brw_velems->ve[i].ve0.src_offset = input->src_offset;
199 brw_velems->ve[i].ve0.src_format = format;
200 brw_velems->ve[i].ve0.valid = 1;
201 brw_velems->ve[i].ve0.vertex_buffer_index = input->vertex_buffer_index;
202 brw_velems->ve[i].ve1.vfcomponent0 = comp0;
203 brw_velems->ve[i].ve1.vfcomponent1 = comp1;
204 brw_velems->ve[i].ve1.vfcomponent2 = comp2;
205 brw_velems->ve[i].ve1.vfcomponent3 = comp3;
206
207 if (brw->gen == 5)
208 brw_velems->ve[i].ve1.dst_offset = 0;
209 else
210 brw_velems->ve[i].ve1.dst_offset = i * 4;
211 }
212 }
213
214 static void* brw_create_vertex_elements_state( struct pipe_context *pipe,
215 unsigned count,
216 const struct pipe_vertex_element *attribs )
217 {
218 /* note: for the brw_swtnl.c code (if ever we need draw fallback) we'd also need
219 to store the original data */
220 struct brw_context *brw = brw_context(pipe);
221 struct brw_vertex_element_packet *velems;
222 assert(count <= BRW_VEP_MAX);
223 velems = (struct brw_vertex_element_packet *) MALLOC(sizeof(struct brw_vertex_element_packet));
224 if (velems) {
225 brw_translate_vertex_elements(brw, velems, attribs, count);
226 }
227 return velems;
228 }
229
230 static void brw_bind_vertex_elements_state(struct pipe_context *pipe,
231 void *velems)
232 {
233 struct brw_context *brw = brw_context(pipe);
234 struct brw_vertex_element_packet *brw_velems = (struct brw_vertex_element_packet *) velems;
235
236 brw->curr.velems = brw_velems;
237
238 brw->state.dirty.mesa |= PIPE_NEW_VERTEX_ELEMENT;
239 }
240
241 static void brw_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
242 {
243 FREE( velems );
244 }
245
246
247 static void brw_set_vertex_buffers(struct pipe_context *pipe,
248 unsigned count,
249 const struct pipe_vertex_buffer *buffers)
250 {
251 struct brw_context *brw = brw_context(pipe);
252
253 /* Check for no change */
254 if (count == brw->curr.num_vertex_buffers &&
255 memcmp(brw->curr.vertex_buffer,
256 buffers,
257 count * sizeof buffers[0]) == 0)
258 return;
259
260 util_copy_vertex_buffers(brw->curr.vertex_buffer,
261 &brw->curr.num_vertex_buffers,
262 buffers, count);
263
264 brw->state.dirty.mesa |= PIPE_NEW_VERTEX_BUFFER;
265 }
266
267
268 static void brw_set_index_buffer(struct pipe_context *pipe,
269 const struct pipe_index_buffer *ib)
270 {
271 struct brw_context *brw = brw_context(pipe);
272
273 if (ib) {
274 if (brw->curr.index_buffer == ib->buffer &&
275 brw->curr.index_offset == ib->offset &&
276 brw->curr.index_size == ib->index_size)
277 return;
278
279 pipe_resource_reference(&brw->curr.index_buffer, ib->buffer);
280 brw->curr.index_offset = ib->offset;
281 brw->curr.index_size = ib->index_size;
282 }
283 else {
284 if (!brw->curr.index_buffer &&
285 !brw->curr.index_offset &&
286 !brw->curr.index_size)
287 return;
288
289 pipe_resource_reference(&brw->curr.index_buffer, NULL);
290 brw->curr.index_offset = 0;
291 brw->curr.index_size = 0;
292 }
293
294 brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
295 }
296
297
298 void
299 brw_pipe_vertex_init( struct brw_context *brw )
300 {
301 brw->base.set_vertex_buffers = brw_set_vertex_buffers;
302 brw->base.set_index_buffer = brw_set_index_buffer;
303 brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
304 brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
305 brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;
306 brw->base.redefine_user_buffer = u_default_redefine_user_buffer;
307 }
308
309
310 void
311 brw_pipe_vertex_cleanup( struct brw_context *brw )
312 {
313 unsigned i;
314
315 /* Release bound pipe vertex_buffers
316 */
317 for (i = 0; i < brw->curr.num_vertex_buffers; i++) {
318 pipe_resource_reference(&brw->curr.vertex_buffer[i].buffer, NULL);
319 }
320
321 /* Release some other stuff
322 */
323 #if 0
324 for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
325 bo_reference(&brw->vb.inputs[i].bo, NULL);
326 brw->vb.inputs[i].bo = NULL;
327 }
328 #endif
329 }