Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright 2007 VMware, Inc. |
||
4 | * All Rights Reserved. |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * copy of this software and associated documentation files (the |
||
8 | * "Software"), to deal in the Software without restriction, including |
||
9 | * without limitation the rights to use, copy, modify, merge, publish, |
||
10 | * distribute, sub license, and/or sell copies of the Software, and to |
||
11 | * permit persons to whom the Software is furnished to do so, subject to |
||
12 | * the following conditions: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice (including the |
||
15 | * next paragraph) shall be included in all copies or substantial portions |
||
16 | * of the Software. |
||
17 | * |
||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||
21 | * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
||
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
25 | * |
||
26 | **************************************************************************/ |
||
27 | |||
28 | #include "main/imports.h" |
||
29 | #include "main/image.h" |
||
30 | #include "main/macros.h" |
||
31 | |||
32 | #include "vbo/vbo.h" |
||
33 | |||
34 | #include "st_context.h" |
||
35 | #include "st_atom.h" |
||
36 | #include "st_cb_bufferobjects.h" |
||
37 | #include "st_draw.h" |
||
38 | #include "st_program.h" |
||
39 | |||
40 | #include "pipe/p_context.h" |
||
41 | #include "pipe/p_defines.h" |
||
42 | #include "util/u_inlines.h" |
||
43 | #include "util/u_draw.h" |
||
44 | |||
45 | #include "draw/draw_private.h" |
||
46 | #include "draw/draw_context.h" |
||
47 | |||
48 | |||
49 | /** |
||
50 | * Set the (private) draw module's post-transformed vertex format when in |
||
51 | * GL_SELECT or GL_FEEDBACK mode or for glRasterPos. |
||
52 | */ |
||
53 | static void |
||
54 | set_feedback_vertex_format(struct gl_context *ctx) |
||
55 | { |
||
56 | #if 0 |
||
57 | struct st_context *st = st_context(ctx); |
||
58 | struct vertex_info vinfo; |
||
59 | GLuint i; |
||
60 | |||
61 | memset(&vinfo, 0, sizeof(vinfo)); |
||
62 | |||
63 | if (ctx->RenderMode == GL_SELECT) { |
||
64 | assert(ctx->RenderMode == GL_SELECT); |
||
65 | vinfo.num_attribs = 1; |
||
66 | vinfo.format[0] = FORMAT_4F; |
||
67 | vinfo.interp_mode[0] = INTERP_LINEAR; |
||
68 | } |
||
69 | else { |
||
70 | /* GL_FEEDBACK, or glRasterPos */ |
||
71 | /* emit all attribs (pos, color, texcoord) as GLfloat[4] */ |
||
72 | vinfo.num_attribs = st->state.vs->cso->state.num_outputs; |
||
73 | for (i = 0; i < vinfo.num_attribs; i++) { |
||
74 | vinfo.format[i] = FORMAT_4F; |
||
75 | vinfo.interp_mode[i] = INTERP_LINEAR; |
||
76 | } |
||
77 | } |
||
78 | |||
79 | draw_set_vertex_info(st->draw, &vinfo); |
||
80 | #endif |
||
81 | } |
||
82 | |||
83 | |||
84 | /** |
||
85 | * Helper for drawing current vertex arrays. |
||
86 | */ |
||
87 | static void |
||
88 | draw_arrays(struct draw_context *draw, unsigned mode, |
||
89 | unsigned start, unsigned count) |
||
90 | { |
||
91 | struct pipe_draw_info info; |
||
92 | |||
93 | util_draw_init_info(&info); |
||
94 | |||
95 | info.mode = mode; |
||
96 | info.start = start; |
||
97 | info.count = count; |
||
98 | info.min_index = start; |
||
99 | info.max_index = start + count - 1; |
||
100 | |||
101 | draw_vbo(draw, &info); |
||
102 | } |
||
103 | |||
104 | |||
105 | /** |
||
106 | * Called by VBO to draw arrays when in selection or feedback mode and |
||
107 | * to implement glRasterPos. |
||
108 | * This is very much like the normal draw_vbo() function above. |
||
109 | * Look at code refactoring some day. |
||
110 | */ |
||
111 | void |
||
112 | st_feedback_draw_vbo(struct gl_context *ctx, |
||
113 | const struct _mesa_prim *prims, |
||
114 | GLuint nr_prims, |
||
115 | const struct _mesa_index_buffer *ib, |
||
116 | GLboolean index_bounds_valid, |
||
117 | GLuint min_index, |
||
118 | GLuint max_index, |
||
119 | struct gl_transform_feedback_object *tfb_vertcount, |
||
120 | struct gl_buffer_object *indirect) |
||
121 | { |
||
122 | struct st_context *st = st_context(ctx); |
||
123 | struct pipe_context *pipe = st->pipe; |
||
124 | struct draw_context *draw = st->draw; |
||
125 | const struct st_vertex_program *vp; |
||
126 | const struct pipe_shader_state *vs; |
||
127 | struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS]; |
||
128 | struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; |
||
129 | struct pipe_index_buffer ibuffer; |
||
130 | struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL}; |
||
131 | struct pipe_transfer *ib_transfer = NULL; |
||
132 | const struct gl_client_array **arrays = ctx->Array._DrawArrays; |
||
133 | GLuint attr, i; |
||
134 | const GLubyte *low_addr = NULL; |
||
135 | const void *mapped_indices = NULL; |
||
136 | |||
137 | assert(draw); |
||
138 | |||
139 | st_validate_state(st); |
||
140 | |||
141 | if (!index_bounds_valid) |
||
142 | vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims); |
||
143 | |||
144 | /* must get these after state validation! */ |
||
145 | vp = st->vp; |
||
146 | vs = &st->vp_variant->tgsi; |
||
147 | |||
148 | if (!st->vp_variant->draw_shader) { |
||
149 | st->vp_variant->draw_shader = draw_create_vertex_shader(draw, vs); |
||
150 | } |
||
151 | |||
152 | /* |
||
153 | * Set up the draw module's state. |
||
154 | * |
||
155 | * We'd like to do this less frequently, but the normal state-update |
||
156 | * code sends state updates to the pipe, not to our private draw module. |
||
157 | */ |
||
158 | assert(draw); |
||
159 | draw_set_viewport_states(draw, 0, 1, &st->state.viewport[0]); |
||
160 | draw_set_clip_state(draw, &st->state.clip); |
||
161 | draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL); |
||
162 | draw_bind_vertex_shader(draw, st->vp_variant->draw_shader); |
||
163 | set_feedback_vertex_format(ctx); |
||
164 | |||
165 | /* Find the lowest address of the arrays we're drawing */ |
||
166 | if (vp->num_inputs) { |
||
167 | low_addr = arrays[vp->index_to_input[0]]->Ptr; |
||
168 | |||
169 | for (attr = 1; attr < vp->num_inputs; attr++) { |
||
170 | const GLubyte *start = arrays[vp->index_to_input[attr]]->Ptr; |
||
171 | low_addr = MIN2(low_addr, start); |
||
172 | } |
||
173 | } |
||
174 | |||
175 | /* loop over TGSI shader inputs to determine vertex buffer |
||
176 | * and attribute info |
||
177 | */ |
||
178 | for (attr = 0; attr < vp->num_inputs; attr++) { |
||
179 | const GLuint mesaAttr = vp->index_to_input[attr]; |
||
180 | struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; |
||
181 | void *map; |
||
182 | |||
183 | if (bufobj && bufobj->Name) { |
||
184 | /* Attribute data is in a VBO. |
||
185 | * Recall that for VBOs, the gl_client_array->Ptr field is |
||
186 | * really an offset from the start of the VBO, not a pointer. |
||
187 | */ |
||
188 | struct st_buffer_object *stobj = st_buffer_object(bufobj); |
||
189 | assert(stobj->buffer); |
||
190 | |||
191 | vbuffers[attr].buffer = NULL; |
||
192 | vbuffers[attr].user_buffer = NULL; |
||
193 | pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer); |
||
194 | vbuffers[attr].buffer_offset = pointer_to_offset(low_addr); |
||
195 | velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr; |
||
196 | |||
197 | /* map the attrib buffer */ |
||
198 | map = pipe_buffer_map(pipe, vbuffers[attr].buffer, |
||
199 | PIPE_TRANSFER_READ, |
||
200 | &vb_transfer[attr]); |
||
201 | draw_set_mapped_vertex_buffer(draw, attr, map, |
||
202 | vbuffers[attr].buffer->width0); |
||
203 | } |
||
204 | else { |
||
205 | vbuffers[attr].buffer = NULL; |
||
206 | vbuffers[attr].user_buffer = arrays[mesaAttr]->Ptr; |
||
207 | vbuffers[attr].buffer_offset = 0; |
||
208 | velements[attr].src_offset = 0; |
||
209 | |||
210 | draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer, |
||
211 | ~0); |
||
212 | } |
||
213 | |||
214 | /* common-case setup */ |
||
215 | vbuffers[attr].stride = arrays[mesaAttr]->StrideB; /* in bytes */ |
||
216 | velements[attr].instance_divisor = 0; |
||
217 | velements[attr].vertex_buffer_index = attr; |
||
218 | velements[attr].src_format = |
||
219 | st_pipe_vertex_format(arrays[mesaAttr]->Type, |
||
220 | arrays[mesaAttr]->Size, |
||
221 | arrays[mesaAttr]->Format, |
||
222 | arrays[mesaAttr]->Normalized, |
||
223 | arrays[mesaAttr]->Integer); |
||
224 | assert(velements[attr].src_format); |
||
225 | |||
226 | /* tell draw about this attribute */ |
||
227 | #if 0 |
||
228 | draw_set_vertex_buffer(draw, attr, &vbuffer[attr]); |
||
229 | #endif |
||
230 | } |
||
231 | |||
232 | draw_set_vertex_buffers(draw, 0, vp->num_inputs, vbuffers); |
||
233 | draw_set_vertex_elements(draw, vp->num_inputs, velements); |
||
234 | |||
235 | memset(&ibuffer, 0, sizeof(ibuffer)); |
||
236 | if (ib) { |
||
237 | struct gl_buffer_object *bufobj = ib->obj; |
||
238 | |||
239 | ibuffer.index_size = vbo_sizeof_ib_type(ib->type); |
||
240 | if (ibuffer.index_size == 0) |
||
241 | goto out_unref_vertex; |
||
242 | |||
243 | if (bufobj && bufobj->Name) { |
||
244 | struct st_buffer_object *stobj = st_buffer_object(bufobj); |
||
245 | |||
246 | pipe_resource_reference(&ibuffer.buffer, stobj->buffer); |
||
247 | ibuffer.offset = pointer_to_offset(ib->ptr); |
||
248 | |||
249 | mapped_indices = pipe_buffer_map(pipe, stobj->buffer, |
||
250 | PIPE_TRANSFER_READ, &ib_transfer); |
||
251 | } |
||
252 | else { |
||
253 | /* skip setting ibuffer.buffer as the draw module does not use it */ |
||
254 | mapped_indices = ib->ptr; |
||
255 | } |
||
256 | |||
257 | draw_set_indexes(draw, |
||
258 | (ubyte *) mapped_indices + ibuffer.offset, |
||
259 | ibuffer.index_size, ~0); |
||
260 | } |
||
261 | |||
262 | /* set the constant buffer */ |
||
263 | draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, 0, |
||
264 | st->state.constants[PIPE_SHADER_VERTEX].ptr, |
||
265 | st->state.constants[PIPE_SHADER_VERTEX].size); |
||
266 | |||
267 | |||
268 | /* draw here */ |
||
269 | for (i = 0; i < nr_prims; i++) { |
||
270 | draw_arrays(draw, prims[i].mode, prims[i].start, prims[i].count); |
||
271 | } |
||
272 | |||
273 | |||
274 | /* |
||
275 | * unmap vertex/index buffers |
||
276 | */ |
||
277 | if (ib) { |
||
278 | draw_set_indexes(draw, NULL, 0, 0); |
||
279 | if (ib_transfer) |
||
280 | pipe_buffer_unmap(pipe, ib_transfer); |
||
281 | pipe_resource_reference(&ibuffer.buffer, NULL); |
||
282 | } |
||
283 | |||
284 | out_unref_vertex: |
||
285 | for (attr = 0; attr < vp->num_inputs; attr++) { |
||
286 | if (vb_transfer[attr]) |
||
287 | pipe_buffer_unmap(pipe, vb_transfer[attr]); |
||
288 | draw_set_mapped_vertex_buffer(draw, attr, NULL, 0); |
||
289 | pipe_resource_reference(&vbuffers[attr].buffer, NULL); |
||
290 | } |
||
291 | draw_set_vertex_buffers(draw, 0, vp->num_inputs, NULL); |
||
292 | }>>>>> |