d6a840857ec0fd7b20e853847ccc683e624b210c
[profile/ivi/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 }