Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/indices/u_indices.c
4565 views
1
/*
2
* Copyright 2009 VMware, Inc.
3
* All Rights Reserved.
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* on the rights to use, copy, modify, merge, publish, distribute, sub
9
* license, and/or sell copies of the Software, and to permit persons to whom
10
* the Software is furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice (including the next
13
* paragraph) shall be included in all copies or substantial portions of the
14
* Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19
* VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22
* USE OR OTHER DEALINGS IN THE SOFTWARE.
23
*/
24
25
#include "u_indices.h"
26
#include "u_indices_priv.h"
27
28
static void translate_memcpy_ushort( const void *in,
29
unsigned start,
30
unsigned in_nr,
31
unsigned out_nr,
32
unsigned restart_index,
33
void *out )
34
{
35
memcpy(out, &((short *)in)[start], out_nr*sizeof(short));
36
}
37
38
static void translate_memcpy_uint( const void *in,
39
unsigned start,
40
unsigned in_nr,
41
unsigned out_nr,
42
unsigned restart_index,
43
void *out )
44
{
45
memcpy(out, &((int *)in)[start], out_nr*sizeof(int));
46
}
47
48
static void translate_byte_to_ushort( const void *in,
49
unsigned start,
50
UNUSED unsigned in_nr,
51
unsigned out_nr,
52
UNUSED unsigned restart_index,
53
void *out )
54
{
55
uint8_t *src = (uint8_t *)in + start;
56
uint16_t *dst = out;
57
while (out_nr--) {
58
*dst++ = *src++;
59
}
60
}
61
62
enum pipe_prim_type
63
u_index_prim_type_convert(unsigned hw_mask, enum pipe_prim_type prim, bool pv_matches)
64
{
65
if ((hw_mask & (1<<prim)) && pv_matches)
66
return prim;
67
68
switch (prim) {
69
case PIPE_PRIM_POINTS:
70
return PIPE_PRIM_POINTS;
71
case PIPE_PRIM_LINES:
72
case PIPE_PRIM_LINE_STRIP:
73
case PIPE_PRIM_LINE_LOOP:
74
return PIPE_PRIM_LINES;
75
case PIPE_PRIM_TRIANGLES:
76
case PIPE_PRIM_TRIANGLE_STRIP:
77
case PIPE_PRIM_TRIANGLE_FAN:
78
case PIPE_PRIM_QUADS:
79
case PIPE_PRIM_QUAD_STRIP:
80
case PIPE_PRIM_POLYGON:
81
return PIPE_PRIM_TRIANGLES;
82
case PIPE_PRIM_LINES_ADJACENCY:
83
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
84
return PIPE_PRIM_LINES_ADJACENCY;
85
case PIPE_PRIM_TRIANGLES_ADJACENCY:
86
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
87
return PIPE_PRIM_TRIANGLES_ADJACENCY;
88
default:
89
assert(0);
90
break;
91
}
92
return PIPE_PRIM_POINTS;
93
}
94
95
/**
96
* Translate indexes when a driver can't support certain types
97
* of drawing. Example include:
98
* - Translate 1-byte indexes into 2-byte indexes
99
* - Translate PIPE_PRIM_QUADS into PIPE_PRIM_TRIANGLES when the hardware
100
* doesn't support the former.
101
* - Translate from first provoking vertex to last provoking vertex and
102
* vice versa.
103
*
104
* Note that this function is used for indexed primitives.
105
*
106
* \param hw_mask mask of (1 << PIPE_PRIM_x) flags indicating which types
107
* of primitives are supported by the hardware.
108
* \param prim incoming PIPE_PRIM_x
109
* \param in_index_size bytes per index value (1, 2 or 4)
110
* \param nr number of incoming vertices
111
* \param in_pv incoming provoking vertex convention (PV_FIRST or PV_LAST)
112
* \param out_pv desired provoking vertex convention (PV_FIRST or PV_LAST)
113
* \param prim_restart whether primitive restart is disable or enabled
114
* \param out_prim returns new PIPE_PRIM_x we'll translate to
115
* \param out_index_size returns bytes per new index value (2 or 4)
116
* \param out_nr returns number of new vertices
117
* \param out_translate returns the translation function to use by the caller
118
*/
119
enum indices_mode
120
u_index_translator(unsigned hw_mask,
121
enum pipe_prim_type prim,
122
unsigned in_index_size,
123
unsigned nr,
124
unsigned in_pv,
125
unsigned out_pv,
126
unsigned prim_restart,
127
enum pipe_prim_type *out_prim,
128
unsigned *out_index_size,
129
unsigned *out_nr,
130
u_translate_func *out_translate)
131
{
132
unsigned in_idx;
133
unsigned out_idx;
134
enum indices_mode ret = U_TRANSLATE_NORMAL;
135
136
assert(in_index_size == 1 ||
137
in_index_size == 2 ||
138
in_index_size == 4);
139
140
u_index_init();
141
142
in_idx = in_size_idx(in_index_size);
143
*out_index_size = u_index_size_convert(in_index_size);
144
out_idx = out_size_idx(*out_index_size);
145
146
if ((hw_mask & (1<<prim)) &&
147
in_pv == out_pv)
148
{
149
if (in_index_size == 4)
150
*out_translate = translate_memcpy_uint;
151
else if (in_index_size == 2)
152
*out_translate = translate_memcpy_ushort;
153
else
154
*out_translate = translate_byte_to_ushort;
155
156
*out_prim = prim;
157
*out_nr = nr;
158
159
return U_TRANSLATE_MEMCPY;
160
}
161
*out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][prim];
162
*out_prim = u_index_prim_type_convert(hw_mask, prim, in_pv == out_pv);
163
*out_nr = u_index_count_converted_indices(hw_mask, in_pv == out_pv, prim, nr);
164
165
return ret;
166
}
167
168
unsigned
169
u_index_count_converted_indices(unsigned hw_mask, bool pv_matches, enum pipe_prim_type prim, unsigned nr)
170
{
171
if ((hw_mask & (1<<prim)) && pv_matches)
172
return nr;
173
174
switch (prim) {
175
case PIPE_PRIM_POINTS:
176
return nr;
177
case PIPE_PRIM_LINES:
178
return nr;
179
case PIPE_PRIM_LINE_STRIP:
180
return (nr - 1) * 2;
181
case PIPE_PRIM_LINE_LOOP:
182
return nr * 2;
183
case PIPE_PRIM_TRIANGLES:
184
return nr;
185
case PIPE_PRIM_TRIANGLE_STRIP:
186
return (nr - 2) * 3;
187
case PIPE_PRIM_TRIANGLE_FAN:
188
return (nr - 2) * 3;
189
case PIPE_PRIM_QUADS:
190
return (nr / 4) * 6;
191
case PIPE_PRIM_QUAD_STRIP:
192
return (nr - 2) * 3;
193
case PIPE_PRIM_POLYGON:
194
return (nr - 2) * 3;
195
case PIPE_PRIM_LINES_ADJACENCY:
196
return nr;
197
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
198
return (nr - 3) * 4;
199
case PIPE_PRIM_TRIANGLES_ADJACENCY:
200
return nr;
201
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
202
return ((nr - 4) / 2) * 6;
203
default:
204
assert(0);
205
break;
206
}
207
return nr;
208
}
209
210
211
/**
212
* If a driver does not support a particular gallium primitive type
213
* (such as PIPE_PRIM_QUAD_STRIP) this function can be used to help
214
* convert the primitive into a simpler type (like PIPE_PRIM_TRIANGLES).
215
*
216
* The generator functions generates a number of ushort or uint indexes
217
* for drawing the new type of primitive.
218
*
219
* Note that this function is used for non-indexed primitives.
220
*
221
* \param hw_mask a bitmask of (1 << PIPE_PRIM_x) values that indicates
222
* kind of primitives are supported by the driver.
223
* \param prim the PIPE_PRIM_x that the user wants to draw
224
* \param start index of first vertex to draw
225
* \param nr number of vertices to draw
226
* \param in_pv user's provoking vertex (PV_FIRST/LAST)
227
* \param out_pv desired proking vertex for the hardware (PV_FIRST/LAST)
228
* \param out_prim returns the new primitive type for the driver
229
* \param out_index_size returns OUT_USHORT or OUT_UINT
230
* \param out_nr returns new number of vertices to draw
231
* \param out_generate returns pointer to the generator function
232
*/
233
enum indices_mode
234
u_index_generator(unsigned hw_mask,
235
enum pipe_prim_type prim,
236
unsigned start,
237
unsigned nr,
238
unsigned in_pv,
239
unsigned out_pv,
240
enum pipe_prim_type *out_prim,
241
unsigned *out_index_size,
242
unsigned *out_nr,
243
u_generate_func *out_generate)
244
{
245
unsigned out_idx;
246
247
u_index_init();
248
249
*out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
250
out_idx = out_size_idx(*out_index_size);
251
*out_prim = u_index_prim_type_convert(hw_mask, prim, in_pv == out_pv);
252
*out_nr = u_index_count_converted_indices(hw_mask, in_pv == out_pv, prim, nr);
253
254
if ((hw_mask & (1<<prim)) &&
255
(in_pv == out_pv)) {
256
257
*out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
258
return U_GENERATE_LINEAR;
259
}
260
*out_generate = generate[out_idx][in_pv][out_pv][prim];
261
return prim == PIPE_PRIM_LINE_LOOP ? U_GENERATE_ONE_OFF : U_GENERATE_REUSABLE;
262
}
263
264