1/**************************************************************************
2 *
3 * Copyright 2008 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#ifndef U_DRAW_H
29#define U_DRAW_H
30
31
32#include "pipe/p_compiler.h"
33#include "pipe/p_context.h"
34#include "pipe/p_state.h"
35
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41
42static inline void
43util_draw_init_info(struct pipe_draw_info *info)
44{
45   memset(info, 0, sizeof(*info));
46   info->instance_count = 1;
47   info->max_index = 0xffffffff;
48}
49
50
51static inline void
52util_draw_arrays(struct pipe_context *pipe,
53                 enum pipe_prim_type mode,
54                 uint start,
55                 uint count)
56{
57   struct pipe_draw_info info;
58   struct pipe_draw_start_count_bias draw;
59
60   util_draw_init_info(&info);
61   info.mode = mode;
62   info.min_index = start;
63   info.max_index = start + count - 1;
64
65   draw.start = start;
66   draw.count = count;
67   draw.index_bias = 0;
68
69   pipe->draw_vbo(pipe, &info, 0, NULL, &draw, 1);
70}
71
72static inline void
73util_draw_elements(struct pipe_context *pipe,
74                   void *indices,
75                   unsigned index_size,
76                   int index_bias, enum pipe_prim_type mode,
77                   uint start,
78                   uint count)
79{
80   struct pipe_draw_info info;
81   struct pipe_draw_start_count_bias draw;
82
83   util_draw_init_info(&info);
84   info.index.user = indices;
85   info.has_user_indices = true;
86   info.index_size = index_size;
87   info.mode = mode;
88   draw.index_bias = index_bias;
89
90   draw.start = start;
91   draw.count = count;
92
93   pipe->draw_vbo(pipe, &info, 0, NULL, &draw, 1);
94}
95
96static inline void
97util_draw_arrays_instanced(struct pipe_context *pipe,
98                           enum pipe_prim_type mode,
99                           uint start,
100                           uint count,
101                           uint start_instance,
102                           uint instance_count)
103{
104   struct pipe_draw_info info;
105   struct pipe_draw_start_count_bias draw;
106
107   util_draw_init_info(&info);
108   info.mode = mode;
109   info.start_instance = start_instance;
110   info.instance_count = instance_count;
111   info.index_bounds_valid = true;
112   info.min_index = start;
113   info.max_index = start + count - 1;
114
115   draw.start = start;
116   draw.count = count;
117   draw.index_bias = 0;
118
119   pipe->draw_vbo(pipe, &info, 0, NULL, &draw, 1);
120}
121
122static inline void
123util_draw_elements_instanced(struct pipe_context *pipe,
124                             void *indices,
125                             unsigned index_size,
126                             int index_bias,
127                             enum pipe_prim_type mode,
128                             uint start,
129                             uint count,
130                             uint start_instance,
131                             uint instance_count)
132{
133   struct pipe_draw_info info;
134   struct pipe_draw_start_count_bias draw;
135
136   util_draw_init_info(&info);
137   info.index.user = indices;
138   info.has_user_indices = true;
139   info.index_size = index_size;
140   info.mode = mode;
141   draw.index_bias = index_bias;
142   info.start_instance = start_instance;
143   info.instance_count = instance_count;
144
145   draw.start = start;
146   draw.count = count;
147
148   pipe->draw_vbo(pipe, &info, 0, NULL, &draw, 1);
149}
150
151struct u_indirect_params {
152   struct pipe_draw_info info;
153   struct pipe_draw_start_count_bias draw;
154};
155
156/* caller must free the return value */
157struct u_indirect_params *
158util_draw_indirect_read(struct pipe_context *pipe,
159                        const struct pipe_draw_info *info_in,
160                        const struct pipe_draw_indirect_info *indirect,
161                        unsigned *num_draws);
162
163/* This converts an indirect draw into a direct draw by mapping the indirect
164 * buffer, extracting its arguments, and calling pipe->draw_vbo.
165 */
166void
167util_draw_indirect(struct pipe_context *pipe,
168                   const struct pipe_draw_info *info,
169                   const struct pipe_draw_indirect_info *indirect);
170
171/* Helper to handle multi-draw by splitting into individual draws.  You
172 * don't want to call this if num_draws==1
173 */
174void
175util_draw_multi(struct pipe_context *pctx, const struct pipe_draw_info *info,
176                unsigned drawid_offset,
177                const struct pipe_draw_indirect_info *indirect,
178                const struct pipe_draw_start_count_bias *draws,
179                unsigned num_draws);
180
181unsigned
182util_draw_max_index(
183      const struct pipe_vertex_buffer *vertex_buffers,
184      const struct pipe_vertex_element *vertex_elements,
185      unsigned nr_vertex_elements,
186      const struct pipe_draw_info *info);
187
188
189#ifdef __cplusplus
190}
191#endif
192
193#endif /* !U_DRAW_H */
194