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