1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
34 #include "pipe/p_defines.h"
35 #include "pipe/p_context.h"
36 #include "util/u_prim.h"
37 #include "util/u_draw_quad.h"
39 #include "lp_context.h"
42 #include "draw/draw_context.h"
47 * Draw vertex arrays, with optional indexing, optional instancing.
48 * All the other drawing functions are implemented in terms of this function.
49 * Basically, map the vertex buffers (and drawing surfaces), then hand off
50 * the drawing to the 'draw' module.
53 llvmpipe_draw_vbo(struct pipe_context
*pipe
, const struct pipe_draw_info
*info
)
55 struct llvmpipe_context
*lp
= llvmpipe_context(pipe
);
56 struct draw_context
*draw
= lp
->draw
;
57 void *mapped_indices
= NULL
;
61 llvmpipe_update_derived( lp
);
66 for (i
= 0; i
< lp
->num_vertex_buffers
; i
++) {
67 void *buf
= llvmpipe_resource_data(lp
->vertex_buffer
[i
].buffer
);
68 draw_set_mapped_vertex_buffer(draw
, i
, buf
);
71 /* Map index buffer, if present */
72 if (info
->indexed
&& lp
->index_buffer
.buffer
) {
73 mapped_indices
= llvmpipe_resource_data(lp
->index_buffer
.buffer
);
74 mapped_indices
+= lp
->index_buffer
.offset
;
77 draw_set_mapped_element_buffer_range(draw
, (mapped_indices
) ?
78 lp
->index_buffer
.index_size
: 0,
84 llvmpipe_prepare_vertex_sampling(lp
,
85 lp
->num_vertex_sampler_views
,
86 lp
->vertex_sampler_views
);
89 draw_arrays_instanced(draw
, info
->mode
, info
->start
, info
->count
,
90 info
->start_instance
, info
->instance_count
);
93 * unmap vertex/index buffers
95 for (i
= 0; i
< lp
->num_vertex_buffers
; i
++) {
96 draw_set_mapped_vertex_buffer(draw
, i
, NULL
);
99 draw_set_mapped_element_buffer(draw
, 0, 0, NULL
);
101 llvmpipe_cleanup_vertex_sampling(lp
);
104 * TODO: Flush only when a user vertex/index buffer is present
105 * (or even better, modify draw module to do this
106 * internally when this condition is seen?)
113 llvmpipe_draw_range_elements_instanced(struct pipe_context
*pipe
,
114 struct pipe_resource
*indexBuffer
,
122 unsigned startInstance
,
123 unsigned instanceCount
)
125 struct llvmpipe_context
*lp
= llvmpipe_context(pipe
);
126 struct pipe_draw_info info
;
127 struct pipe_index_buffer saved_ib
, ib
;
129 util_draw_init_info(&info
);
133 info
.start_instance
= startInstance
;
134 info
.instance_count
= instanceCount
;
136 info
.index_bias
= indexBias
;
137 info
.min_index
= minIndex
;
138 info
.max_index
= maxIndex
;
142 saved_ib
= lp
->index_buffer
;
144 ib
.buffer
= indexBuffer
;
146 ib
.index_size
= indexSize
;
147 pipe
->set_index_buffer(pipe
, &ib
);
150 llvmpipe_draw_vbo(pipe
, &info
);
153 pipe
->set_index_buffer(pipe
, &saved_ib
);
157 llvmpipe_draw_arrays_instanced(struct pipe_context
*pipe
,
161 unsigned startInstance
,
162 unsigned instanceCount
)
164 llvmpipe_draw_range_elements_instanced(pipe
,
165 NULL
, /* no indexBuffer */
166 0, 0, /* indexSize, indexBias */
167 0, ~0, /* minIndex, maxIndex */
177 llvmpipe_draw_elements_instanced(struct pipe_context
*pipe
,
178 struct pipe_resource
*indexBuffer
,
184 unsigned startInstance
,
185 unsigned instanceCount
)
187 llvmpipe_draw_range_elements_instanced(pipe
,
189 indexSize
, indexBias
,
190 0, ~0, /* minIndex, maxIndex */
200 llvmpipe_draw_elements(struct pipe_context
*pipe
,
201 struct pipe_resource
*indexBuffer
,
208 llvmpipe_draw_range_elements_instanced(pipe
,
210 indexSize
, indexBias
,
211 0, 0xffffffff, /* min, maxIndex */
213 0, /* startInstance */
214 1); /* instanceCount */
219 llvmpipe_draw_range_elements(struct pipe_context
*pipe
,
220 struct pipe_resource
*indexBuffer
,
229 llvmpipe_draw_range_elements_instanced(pipe
,
231 indexSize
, indexBias
,
232 min_index
, max_index
,
234 0, /* startInstance */
235 1); /* instanceCount */
240 llvmpipe_draw_arrays(struct pipe_context
*pipe
,
245 llvmpipe_draw_range_elements_instanced(pipe
,
246 NULL
, /* indexBuffer */
249 0, ~0, /* min, maxIndex */
251 0, /* startInstance */
252 1); /* instanceCount */
257 llvmpipe_init_draw_funcs(struct llvmpipe_context
*llvmpipe
)
259 llvmpipe
->pipe
.draw_arrays
= llvmpipe_draw_arrays
;
260 llvmpipe
->pipe
.draw_elements
= llvmpipe_draw_elements
;
261 llvmpipe
->pipe
.draw_range_elements
= llvmpipe_draw_range_elements
;
262 llvmpipe
->pipe
.draw_arrays_instanced
= llvmpipe_draw_arrays_instanced
;
263 llvmpipe
->pipe
.draw_elements_instanced
= llvmpipe_draw_elements_instanced
;
265 llvmpipe
->pipe
.draw_vbo
= llvmpipe_draw_vbo
;