Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1901 | serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. |
||
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 TUNGSTEN GRAPHICS 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 | |||
44 | #include "draw/draw_private.h" |
||
45 | #include "draw/draw_context.h" |
||
46 | |||
47 | |||
48 | #if FEATURE_feedback || FEATURE_rastpos |
||
49 | |||
50 | /** |
||
51 | * Set the (private) draw module's post-transformed vertex format when in |
||
52 | * GL_SELECT or GL_FEEDBACK mode or for glRasterPos. |
||
53 | */ |
||
54 | static void |
||
55 | set_feedback_vertex_format(struct gl_context *ctx) |
||
56 | { |
||
57 | #if 0 |
||
58 | struct st_context *st = st_context(ctx); |
||
59 | struct vertex_info vinfo; |
||
60 | GLuint i; |
||
61 | |||
62 | memset(&vinfo, 0, sizeof(vinfo)); |
||
63 | |||
64 | if (ctx->RenderMode == GL_SELECT) { |
||
65 | assert(ctx->RenderMode == GL_SELECT); |
||
66 | vinfo.num_attribs = 1; |
||
67 | vinfo.format[0] = FORMAT_4F; |
||
68 | vinfo.interp_mode[0] = INTERP_LINEAR; |
||
69 | } |
||
70 | else { |
||
71 | /* GL_FEEDBACK, or glRasterPos */ |
||
72 | /* emit all attribs (pos, color, texcoord) as GLfloat[4] */ |
||
73 | vinfo.num_attribs = st->state.vs->cso->state.num_outputs; |
||
74 | for (i = 0; i < vinfo.num_attribs; i++) { |
||
75 | vinfo.format[i] = FORMAT_4F; |
||
76 | vinfo.interp_mode[i] = INTERP_LINEAR; |
||
77 | } |
||
78 | } |
||
79 | |||
80 | draw_set_vertex_info(st->draw, &vinfo); |
||
81 | #endif |
||
82 | } |
||
83 | |||
84 | |||
85 | /** |
||
86 | * Called by VBO to draw arrays when in selection or feedback mode and |
||
87 | * to implement glRasterPos. |
||
88 | * This is very much like the normal draw_vbo() function above. |
||
89 | * Look at code refactoring some day. |
||
90 | * Might move this into the failover module some day. |
||
91 | */ |
||
92 | void |
||
93 | st_feedback_draw_vbo(struct gl_context *ctx, |
||
94 | const struct gl_client_array **arrays, |
||
95 | const struct _mesa_prim *prims, |
||
96 | GLuint nr_prims, |
||
97 | const struct _mesa_index_buffer *ib, |
||
98 | GLboolean index_bounds_valid, |
||
99 | GLuint min_index, |
||
100 | GLuint max_index) |
||
101 | { |
||
102 | struct st_context *st = st_context(ctx); |
||
103 | struct pipe_context *pipe = st->pipe; |
||
104 | struct draw_context *draw = st->draw; |
||
105 | const struct st_vertex_program *vp; |
||
106 | const struct pipe_shader_state *vs; |
||
107 | struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS]; |
||
108 | struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; |
||
109 | struct pipe_index_buffer ibuffer; |
||
110 | struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; |
||
111 | struct pipe_transfer *ib_transfer = NULL; |
||
112 | struct pipe_transfer *cb_transfer; |
||
113 | GLuint attr, i; |
||
114 | ubyte *mapped_constants; |
||
115 | const void *mapped_indices = NULL; |
||
116 | |||
117 | assert(draw); |
||
118 | |||
119 | st_validate_state(st); |
||
120 | |||
121 | if (!index_bounds_valid) |
||
122 | vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); |
||
123 | |||
124 | /* must get these after state validation! */ |
||
125 | vp = st->vp; |
||
126 | vs = &st->vp_varient->tgsi; |
||
127 | |||
128 | if (!st->vp_varient->draw_shader) { |
||
129 | st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs); |
||
130 | } |
||
131 | |||
132 | /* |
||
133 | * Set up the draw module's state. |
||
134 | * |
||
135 | * We'd like to do this less frequently, but the normal state-update |
||
136 | * code sends state updates to the pipe, not to our private draw module. |
||
137 | */ |
||
138 | assert(draw); |
||
139 | draw_set_viewport_state(draw, &st->state.viewport); |
||
140 | draw_set_clip_state(draw, &st->state.clip); |
||
141 | draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL); |
||
142 | draw_bind_vertex_shader(draw, st->vp_varient->draw_shader); |
||
143 | set_feedback_vertex_format(ctx); |
||
144 | |||
145 | /* loop over TGSI shader inputs to determine vertex buffer |
||
146 | * and attribute info |
||
147 | */ |
||
148 | for (attr = 0; attr < vp->num_inputs; attr++) { |
||
149 | const GLuint mesaAttr = vp->index_to_input[attr]; |
||
150 | struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; |
||
151 | void *map; |
||
152 | |||
153 | if (bufobj && bufobj->Name) { |
||
154 | /* Attribute data is in a VBO. |
||
155 | * Recall that for VBOs, the gl_client_array->Ptr field is |
||
156 | * really an offset from the start of the VBO, not a pointer. |
||
157 | */ |
||
158 | struct st_buffer_object *stobj = st_buffer_object(bufobj); |
||
159 | assert(stobj->buffer); |
||
160 | |||
161 | vbuffers[attr].buffer = NULL; |
||
162 | pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer); |
||
163 | vbuffers[attr].buffer_offset = pointer_to_offset(arrays[0]->Ptr); |
||
164 | velements[attr].src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr; |
||
165 | } |
||
166 | else { |
||
167 | /* attribute data is in user-space memory, not a VBO */ |
||
168 | uint bytes = (arrays[mesaAttr]->Size |
||
169 | * _mesa_sizeof_type(arrays[mesaAttr]->Type) |
||
170 | * (max_index + 1)); |
||
171 | |||
172 | /* wrap user data */ |
||
173 | vbuffers[attr].buffer |
||
174 | = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr, |
||
175 | bytes, |
||
176 | PIPE_BIND_VERTEX_BUFFER); |
||
177 | vbuffers[attr].buffer_offset = 0; |
||
178 | velements[attr].src_offset = 0; |
||
179 | } |
||
180 | |||
181 | /* common-case setup */ |
||
182 | vbuffers[attr].stride = arrays[mesaAttr]->StrideB; /* in bytes */ |
||
183 | vbuffers[attr].max_index = max_index; |
||
184 | velements[attr].instance_divisor = 0; |
||
185 | velements[attr].vertex_buffer_index = attr; |
||
186 | velements[attr].src_format = |
||
187 | st_pipe_vertex_format(arrays[mesaAttr]->Type, |
||
188 | arrays[mesaAttr]->Size, |
||
189 | arrays[mesaAttr]->Format, |
||
190 | arrays[mesaAttr]->Normalized); |
||
191 | assert(velements[attr].src_format); |
||
192 | |||
193 | /* tell draw about this attribute */ |
||
194 | #if 0 |
||
195 | draw_set_vertex_buffer(draw, attr, &vbuffer[attr]); |
||
196 | #endif |
||
197 | |||
198 | /* map the attrib buffer */ |
||
199 | map = pipe_buffer_map(pipe, vbuffers[attr].buffer, |
||
200 | PIPE_TRANSFER_READ, |
||
201 | &vb_transfer[attr]); |
||
202 | draw_set_mapped_vertex_buffer(draw, attr, map); |
||
203 | } |
||
204 | |||
205 | draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers); |
||
206 | draw_set_vertex_elements(draw, vp->num_inputs, velements); |
||
207 | |||
208 | memset(&ibuffer, 0, sizeof(ibuffer)); |
||
209 | if (ib) { |
||
210 | struct gl_buffer_object *bufobj = ib->obj; |
||
211 | |||
212 | switch (ib->type) { |
||
213 | case GL_UNSIGNED_INT: |
||
214 | ibuffer.index_size = 4; |
||
215 | break; |
||
216 | case GL_UNSIGNED_SHORT: |
||
217 | ibuffer.index_size = 2; |
||
218 | break; |
||
219 | case GL_UNSIGNED_BYTE: |
||
220 | ibuffer.index_size = 1; |
||
221 | break; |
||
222 | default: |
||
223 | assert(0); |
||
224 | return; |
||
225 | } |
||
226 | |||
227 | if (bufobj && bufobj->Name) { |
||
228 | struct st_buffer_object *stobj = st_buffer_object(bufobj); |
||
229 | |||
230 | pipe_resource_reference(&ibuffer.buffer, stobj->buffer); |
||
231 | ibuffer.offset = pointer_to_offset(ib->ptr); |
||
232 | |||
233 | mapped_indices = pipe_buffer_map(pipe, stobj->buffer, |
||
234 | PIPE_TRANSFER_READ, &ib_transfer); |
||
235 | } |
||
236 | else { |
||
237 | /* skip setting ibuffer.buffer as the draw module does not use it */ |
||
238 | mapped_indices = ib->ptr; |
||
239 | } |
||
240 | |||
241 | draw_set_index_buffer(draw, &ibuffer); |
||
242 | draw_set_mapped_index_buffer(draw, mapped_indices); |
||
243 | } |
||
244 | |||
245 | /* map constant buffers */ |
||
246 | mapped_constants = pipe_buffer_map(pipe, |
||
247 | st->state.constants[PIPE_SHADER_VERTEX], |
||
248 | PIPE_TRANSFER_READ, |
||
249 | &cb_transfer); |
||
250 | draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, 0, |
||
251 | mapped_constants, |
||
252 | st->state.constants[PIPE_SHADER_VERTEX]->width0); |
||
253 | |||
254 | |||
255 | /* draw here */ |
||
256 | for (i = 0; i < nr_prims; i++) { |
||
257 | draw_arrays(draw, prims[i].mode, prims[i].start, prims[i].count); |
||
258 | } |
||
259 | |||
260 | |||
261 | /* unmap constant buffers */ |
||
262 | pipe_buffer_unmap(pipe, st->state.constants[PIPE_SHADER_VERTEX], |
||
263 | cb_transfer); |
||
264 | |||
265 | /* |
||
266 | * unmap vertex/index buffers |
||
267 | */ |
||
268 | for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { |
||
269 | if (draw->pt.vertex_buffer[i].buffer) { |
||
270 | pipe_buffer_unmap(pipe, draw->pt.vertex_buffer[i].buffer, |
||
271 | vb_transfer[i]); |
||
272 | pipe_resource_reference(&draw->pt.vertex_buffer[i].buffer, NULL); |
||
273 | draw_set_mapped_vertex_buffer(draw, i, NULL); |
||
274 | } |
||
275 | } |
||
276 | |||
277 | if (ib) { |
||
278 | draw_set_mapped_index_buffer(draw, NULL); |
||
279 | draw_set_index_buffer(draw, NULL); |
||
280 | |||
281 | if (ib_transfer) |
||
282 | pipe_buffer_unmap(pipe, ibuffer.buffer, ib_transfer); |
||
283 | pipe_resource_reference(&ibuffer.buffer, NULL); |
||
284 | } |
||
285 | } |
||
286 | |||
287 | #endif /* FEATURE_feedback || FEATURE_rastpos */>>>> |
||
288 |