Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/draw/draw_pt_emit.c
4565 views
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
#include "util/u_memory.h"
29
#include "draw/draw_context.h"
30
#include "draw/draw_private.h"
31
#include "draw/draw_vbuf.h"
32
#include "draw/draw_vertex.h"
33
#include "draw/draw_pt.h"
34
#include "translate/translate.h"
35
#include "translate/translate_cache.h"
36
#include "util/u_prim.h"
37
38
struct pt_emit {
39
struct draw_context *draw;
40
41
struct translate *translate;
42
43
struct translate_cache *cache;
44
unsigned prim;
45
46
const struct vertex_info *vinfo;
47
48
float zero4[4];
49
50
};
51
52
53
void
54
draw_pt_emit_prepare(struct pt_emit *emit,
55
unsigned prim,
56
unsigned *max_vertices)
57
{
58
struct draw_context *draw = emit->draw;
59
const struct vertex_info *vinfo;
60
unsigned dst_offset;
61
struct translate_key hw_key;
62
unsigned i;
63
64
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
65
*/
66
draw_do_flush(draw, DRAW_FLUSH_BACKEND);
67
68
/* XXX: may need to defensively reset this later on as clipping can
69
* clobber this state in the render backend.
70
*/
71
emit->prim = prim;
72
73
draw->render->set_primitive(draw->render, emit->prim);
74
if (draw->render->set_view_index)
75
draw->render->set_view_index(draw->render, draw->pt.user.viewid);
76
77
/* Must do this after set_primitive() above:
78
*/
79
emit->vinfo = vinfo = draw->render->get_vertex_info(draw->render);
80
81
/* Translate from pipeline vertices to hw vertices.
82
*/
83
dst_offset = 0;
84
for (i = 0; i < vinfo->num_attribs; i++) {
85
unsigned emit_sz = 0;
86
unsigned src_buffer = 0;
87
unsigned output_format;
88
unsigned src_offset = vinfo->attrib[i].src_index * 4 * sizeof(float);
89
90
output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
91
emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
92
93
/* doesn't handle EMIT_OMIT */
94
assert(emit_sz != 0);
95
96
if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
97
src_buffer = 1;
98
src_offset = 0;
99
}
100
else if (vinfo->attrib[i].src_index == DRAW_ATTR_NONEXIST) {
101
/* elements which don't exist will get assigned zeros */
102
src_buffer = 2;
103
src_offset = 0;
104
}
105
106
hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
107
hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
108
hw_key.element[i].input_buffer = src_buffer;
109
hw_key.element[i].input_offset = src_offset;
110
hw_key.element[i].instance_divisor = 0;
111
hw_key.element[i].output_format = output_format;
112
hw_key.element[i].output_offset = dst_offset;
113
114
dst_offset += emit_sz;
115
}
116
117
hw_key.nr_elements = vinfo->num_attribs;
118
hw_key.output_stride = vinfo->size * 4;
119
120
if (!emit->translate ||
121
translate_key_compare(&emit->translate->key, &hw_key) != 0) {
122
translate_key_sanitize(&hw_key);
123
emit->translate = translate_cache_find(emit->cache, &hw_key);
124
125
emit->translate->set_buffer(emit->translate, 2, &emit->zero4[0], 0, ~0);
126
}
127
128
if (!vinfo->size)
129
*max_vertices = 0;
130
else
131
*max_vertices = (draw->render->max_vertex_buffer_bytes /
132
(vinfo->size * 4));
133
}
134
135
136
void
137
draw_pt_emit(struct pt_emit *emit,
138
const struct draw_vertex_info *vert_info,
139
const struct draw_prim_info *prim_info)
140
{
141
const float (*vertex_data)[4] = (const float (*)[4])vert_info->verts->data;
142
unsigned vertex_count = vert_info->count;
143
unsigned stride = vert_info->stride;
144
const ushort *elts = prim_info->elts;
145
struct draw_context *draw = emit->draw;
146
struct translate *translate = emit->translate;
147
struct vbuf_render *render = draw->render;
148
unsigned start, i;
149
void *hw_verts;
150
151
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
152
*/
153
draw_do_flush(draw, DRAW_FLUSH_BACKEND);
154
155
if (vertex_count == 0)
156
return;
157
158
/* XXX: and work out some way to coordinate the render primitive
159
* between vbuf.c and here...
160
*/
161
render->set_primitive(draw->render, prim_info->prim);
162
if (draw->render->set_view_index)
163
draw->render->set_view_index(draw->render, draw->pt.user.viewid);
164
165
assert(vertex_count <= 65535);
166
render->allocate_vertices(render,
167
(ushort)translate->key.output_stride,
168
(ushort)vertex_count);
169
170
hw_verts = render->map_vertices(render);
171
if (!hw_verts) {
172
debug_warn_once("map of vertex buffer failed (out of memory?)");
173
return;
174
}
175
176
translate->set_buffer(translate,
177
0,
178
vertex_data,
179
stride,
180
~0);
181
182
translate->set_buffer(translate,
183
1,
184
&draw->rasterizer->point_size,
185
0,
186
~0);
187
188
/* fetch/translate vertex attribs to fill hw_verts[] */
189
translate->run(translate,
190
0,
191
vertex_count,
192
0,
193
0,
194
hw_verts);
195
196
render->unmap_vertices(render, 0, vertex_count - 1);
197
198
for (start = i = 0;
199
i < prim_info->primitive_count;
200
start += prim_info->primitive_lengths[i], i++)
201
{
202
render->draw_elements(render,
203
elts + start,
204
prim_info->primitive_lengths[i]);
205
}
206
207
render->release_vertices(render);
208
}
209
210
211
void
212
draw_pt_emit_linear(struct pt_emit *emit,
213
const struct draw_vertex_info *vert_info,
214
const struct draw_prim_info *prim_info)
215
{
216
const float (*vertex_data)[4] = (const float (*)[4])vert_info->verts->data;
217
unsigned stride = vert_info->stride;
218
unsigned count = vert_info->count;
219
struct draw_context *draw = emit->draw;
220
struct translate *translate = emit->translate;
221
struct vbuf_render *render = draw->render;
222
void *hw_verts;
223
unsigned start, i;
224
225
#if 0
226
debug_printf("Linear emit\n");
227
#endif
228
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
229
*/
230
draw_do_flush(draw, DRAW_FLUSH_BACKEND);
231
232
/* XXX: and work out some way to coordinate the render primitive
233
* between vbuf.c and here...
234
*/
235
render->set_primitive(draw->render, prim_info->prim);
236
if (draw->render->set_view_index)
237
draw->render->set_view_index(draw->render, draw->pt.user.viewid);
238
239
assert(count <= 65535);
240
if (!render->allocate_vertices(render,
241
(ushort)translate->key.output_stride,
242
(ushort)count))
243
goto fail;
244
245
hw_verts = render->map_vertices(render);
246
if (!hw_verts)
247
goto fail;
248
249
translate->set_buffer(translate, 0,
250
vertex_data, stride, count - 1);
251
252
translate->set_buffer(translate, 1,
253
&draw->rasterizer->point_size,
254
0, ~0);
255
256
translate->run(translate,
257
0,
258
count,
259
0,
260
0,
261
hw_verts);
262
263
if (0) {
264
unsigned i;
265
for (i = 0; i < count; i++) {
266
debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
267
draw_dump_emitted_vertex(emit->vinfo,
268
(const uint8_t *)hw_verts +
269
translate->key.output_stride * i);
270
}
271
}
272
273
render->unmap_vertices(render, 0, count - 1);
274
275
for (start = i = 0;
276
i < prim_info->primitive_count;
277
start += prim_info->primitive_lengths[i], i++)
278
{
279
render->draw_arrays(render,
280
start,
281
prim_info->primitive_lengths[i]);
282
}
283
284
render->release_vertices(render);
285
286
return;
287
288
fail:
289
debug_warn_once("allocate or map of vertex buffer failed (out of memory?)");
290
return;
291
}
292
293
294
struct pt_emit *
295
draw_pt_emit_create(struct draw_context *draw)
296
{
297
struct pt_emit *emit = CALLOC_STRUCT(pt_emit);
298
if (!emit)
299
return NULL;
300
301
emit->draw = draw;
302
emit->cache = translate_cache_create();
303
if (!emit->cache) {
304
FREE(emit);
305
return NULL;
306
}
307
308
emit->zero4[0] = emit->zero4[1] = emit->zero4[2] = emit->zero4[3] = 0.0f;
309
310
return emit;
311
}
312
313
314
void
315
draw_pt_emit_destroy(struct pt_emit *emit)
316
{
317
if (emit->cache)
318
translate_cache_destroy(emit->cache);
319
320
FREE(emit);
321
}
322
323