Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/llvmpipe/lp_scene.h
4570 views
1
/**************************************************************************
2
*
3
* Copyright 2009 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
29
/**
30
* Binner data structures and bin-related functions.
31
* Note: the "setup" code is concerned with building scenes while
32
* The "rast" code is concerned with consuming/executing scenes.
33
*/
34
35
#ifndef LP_SCENE_H
36
#define LP_SCENE_H
37
38
#include "os/os_thread.h"
39
#include "lp_rast.h"
40
#include "lp_debug.h"
41
42
struct lp_scene_queue;
43
struct lp_rast_state;
44
45
/* We're limited to 2K by 2K for 32bit fixed point rasterization.
46
* Will need a 64-bit version for larger framebuffers.
47
*/
48
#define TILES_X (LP_MAX_WIDTH / TILE_SIZE)
49
#define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)
50
51
52
/* Commands per command block (ideally so sizeof(cmd_block) is a power of
53
* two in size.)
54
*/
55
#define CMD_BLOCK_MAX 29
56
57
/* Bytes per data block.
58
*/
59
#define DATA_BLOCK_SIZE (64 * 1024)
60
61
/* Scene temporary storage is clamped to this size:
62
*/
63
#define LP_SCENE_MAX_SIZE (36*1024*1024)
64
65
/* The maximum amount of texture storage referenced by a scene is
66
* clamped to this size:
67
*/
68
#define LP_SCENE_MAX_RESOURCE_SIZE (64*1024*1024)
69
70
71
/* switch to a non-pointer value for this:
72
*/
73
typedef void (*lp_rast_cmd_func)( struct lp_rasterizer_task *,
74
const union lp_rast_cmd_arg );
75
76
77
struct cmd_block {
78
uint8_t cmd[CMD_BLOCK_MAX];
79
union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];
80
unsigned count;
81
struct cmd_block *next;
82
};
83
84
85
struct data_block {
86
ubyte data[DATA_BLOCK_SIZE];
87
unsigned used;
88
struct data_block *next;
89
};
90
91
92
93
/**
94
* For each screen tile we have one of these bins.
95
*/
96
struct cmd_bin {
97
const struct lp_rast_state *last_state; /* most recent state set in bin */
98
struct cmd_block *head;
99
struct cmd_block *tail;
100
};
101
102
103
/**
104
* This stores bulk data which is used for all memory allocations
105
* within a scene.
106
*
107
* Examples include triangle data and state data. The commands in
108
* the per-tile bins will point to chunks of data in this structure.
109
*
110
* Include the first block of data statically to ensure we can always
111
* initiate a scene without relying on malloc succeeding.
112
*/
113
struct data_block_list {
114
struct data_block first;
115
struct data_block *head;
116
};
117
118
struct resource_ref;
119
120
struct shader_ref;
121
122
struct lp_scene_surface {
123
uint8_t *map;
124
unsigned stride;
125
unsigned layer_stride;
126
unsigned format_bytes;
127
unsigned sample_stride;
128
unsigned nr_samples;
129
};
130
131
/**
132
* All bins and bin data are contained here.
133
* Per-bin data goes into the 'tile' bins.
134
* Shared data goes into the 'data' buffer.
135
*
136
* When there are multiple threads, will want to double-buffer between
137
* scenes:
138
*/
139
struct lp_scene {
140
struct pipe_context *pipe;
141
struct lp_fence *fence;
142
143
/* The queries still active at end of scene */
144
struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
145
unsigned num_active_queries;
146
/* If queries were either active or there were begin/end query commands */
147
boolean had_queries;
148
149
/* Framebuffer mappings - valid only between begin_rasterization()
150
* and end_rasterization().
151
*/
152
struct lp_scene_surface zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
153
154
/* The amount of layers in the fb (minimum of all attachments) */
155
unsigned fb_max_layer;
156
157
/* fixed point sample positions. */
158
int32_t fixed_sample_pos[LP_MAX_SAMPLES][2];
159
160
/* max samples for bound framebuffer */
161
unsigned fb_max_samples;
162
163
/** the framebuffer to render the scene into */
164
struct pipe_framebuffer_state fb;
165
166
/** list of resources referenced by the scene commands */
167
struct resource_ref *resources;
168
169
/** list of frag shaders referenced by the scene commands */
170
struct shader_ref *frag_shaders;
171
172
/** Total memory used by the scene (in bytes). This sums all the
173
* data blocks and counts all bins, state, resource references and
174
* other random allocations within the scene.
175
*/
176
unsigned scene_size;
177
178
/** Sum of sizes of all resources referenced by the scene. Sums
179
* all the textures read by the scene:
180
*/
181
unsigned resource_reference_size;
182
183
boolean alloc_failed;
184
/**
185
* Number of active tiles in each dimension.
186
* This basically the framebuffer size divided by tile size
187
*/
188
unsigned tiles_x, tiles_y;
189
190
int curr_x, curr_y; /**< for iterating over bins */
191
mtx_t mutex;
192
193
struct cmd_bin tile[TILES_X][TILES_Y];
194
struct data_block_list data;
195
};
196
197
198
199
struct lp_scene *lp_scene_create(struct pipe_context *pipe);
200
201
void lp_scene_destroy(struct lp_scene *scene);
202
203
boolean lp_scene_is_empty(struct lp_scene *scene );
204
boolean lp_scene_is_oom(struct lp_scene *scene );
205
206
207
struct data_block *lp_scene_new_data_block( struct lp_scene *scene );
208
209
struct cmd_block *lp_scene_new_cmd_block( struct lp_scene *scene,
210
struct cmd_bin *bin );
211
212
boolean lp_scene_add_resource_reference(struct lp_scene *scene,
213
struct pipe_resource *resource,
214
boolean initializing_scene);
215
216
boolean lp_scene_is_resource_referenced(const struct lp_scene *scene,
217
const struct pipe_resource *resource );
218
219
boolean lp_scene_add_frag_shader_reference(struct lp_scene *scene,
220
struct lp_fragment_shader_variant *variant);
221
222
223
224
/**
225
* Allocate space for a command/data in the bin's data buffer.
226
* Grow the block list if needed.
227
*/
228
static inline void *
229
lp_scene_alloc( struct lp_scene *scene, unsigned size)
230
{
231
struct data_block_list *list = &scene->data;
232
struct data_block *block = list->head;
233
234
assert(size <= DATA_BLOCK_SIZE);
235
assert(block != NULL);
236
237
if (LP_DEBUG & DEBUG_MEM)
238
debug_printf("alloc %u block %u/%u tot %u/%u\n",
239
size, block->used, DATA_BLOCK_SIZE,
240
scene->scene_size, LP_SCENE_MAX_SIZE);
241
242
if (block->used + size > DATA_BLOCK_SIZE) {
243
block = lp_scene_new_data_block( scene );
244
if (!block) {
245
/* out of memory */
246
return NULL;
247
}
248
}
249
250
{
251
ubyte *data = block->data + block->used;
252
block->used += size;
253
return data;
254
}
255
}
256
257
258
/**
259
* As above, but with specific alignment.
260
*/
261
static inline void *
262
lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
263
unsigned alignment )
264
{
265
struct data_block_list *list = &scene->data;
266
struct data_block *block = list->head;
267
268
assert(block != NULL);
269
270
if (LP_DEBUG & DEBUG_MEM)
271
debug_printf("alloc %u block %u/%u tot %u/%u\n",
272
size + alignment - 1,
273
block->used, DATA_BLOCK_SIZE,
274
scene->scene_size, LP_SCENE_MAX_SIZE);
275
276
if (block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
277
block = lp_scene_new_data_block( scene );
278
if (!block)
279
return NULL;
280
}
281
282
{
283
ubyte *data = block->data + block->used;
284
unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data;
285
block->used += offset + size;
286
return data + offset;
287
}
288
}
289
290
291
/* Put back data if we decide not to use it, eg. culled triangles.
292
*/
293
static inline void
294
lp_scene_putback_data( struct lp_scene *scene, unsigned size)
295
{
296
struct data_block_list *list = &scene->data;
297
assert(list->head && list->head->used >= size);
298
list->head->used -= size;
299
}
300
301
302
/** Return pointer to a particular tile's bin. */
303
static inline struct cmd_bin *
304
lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y)
305
{
306
return &scene->tile[x][y];
307
}
308
309
310
/** Remove all commands from a bin */
311
void
312
lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y);
313
314
315
/* Add a command to bin[x][y].
316
*/
317
static inline boolean
318
lp_scene_bin_command( struct lp_scene *scene,
319
unsigned x, unsigned y,
320
unsigned cmd,
321
union lp_rast_cmd_arg arg )
322
{
323
struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
324
struct cmd_block *tail = bin->tail;
325
326
assert(x < scene->tiles_x);
327
assert(y < scene->tiles_y);
328
assert(cmd < LP_RAST_OP_MAX);
329
330
if (tail == NULL || tail->count == CMD_BLOCK_MAX) {
331
tail = lp_scene_new_cmd_block( scene, bin );
332
if (!tail) {
333
return FALSE;
334
}
335
assert(tail->count == 0);
336
}
337
338
{
339
unsigned i = tail->count;
340
tail->cmd[i] = cmd & LP_RAST_OP_MASK;
341
tail->arg[i] = arg;
342
tail->count++;
343
}
344
345
return TRUE;
346
}
347
348
349
static inline boolean
350
lp_scene_bin_cmd_with_state( struct lp_scene *scene,
351
unsigned x, unsigned y,
352
const struct lp_rast_state *state,
353
unsigned cmd,
354
union lp_rast_cmd_arg arg )
355
{
356
struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
357
358
if (state != bin->last_state) {
359
bin->last_state = state;
360
if (!lp_scene_bin_command(scene, x, y,
361
LP_RAST_OP_SET_STATE,
362
lp_rast_arg_state(state)))
363
return FALSE;
364
}
365
366
if (!lp_scene_bin_command( scene, x, y, cmd, arg ))
367
return FALSE;
368
369
return TRUE;
370
}
371
372
373
/* Add a command to all active bins.
374
*/
375
static inline boolean
376
lp_scene_bin_everywhere( struct lp_scene *scene,
377
unsigned cmd,
378
const union lp_rast_cmd_arg arg )
379
{
380
unsigned i, j;
381
for (i = 0; i < scene->tiles_x; i++) {
382
for (j = 0; j < scene->tiles_y; j++) {
383
if (!lp_scene_bin_command( scene, i, j, cmd, arg ))
384
return FALSE;
385
}
386
}
387
388
return TRUE;
389
}
390
391
392
static inline unsigned
393
lp_scene_get_num_bins( const struct lp_scene *scene )
394
{
395
return scene->tiles_x * scene->tiles_y;
396
}
397
398
399
void
400
lp_scene_bin_iter_begin( struct lp_scene *scene );
401
402
struct cmd_bin *
403
lp_scene_bin_iter_next( struct lp_scene *scene, int *x, int *y );
404
405
406
407
/* Begin/end binning of a scene
408
*/
409
void
410
lp_scene_begin_binning(struct lp_scene *scene,
411
struct pipe_framebuffer_state *fb);
412
413
void
414
lp_scene_end_binning(struct lp_scene *scene);
415
416
417
/* Begin/end rasterization of a scene
418
*/
419
void
420
lp_scene_begin_rasterization(struct lp_scene *scene);
421
422
void
423
lp_scene_end_rasterization(struct lp_scene *scene);
424
425
426
427
428
429
#endif /* LP_BIN_H */
430
431