Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/postprocess/pp_init.c
4561 views
1
/**************************************************************************
2
*
3
* Copyright 2011 Lauri Kasanen
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 THE AUTHORS OR COPYRIGHT HOLDERS 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 "pipe/p_compiler.h"
29
30
#include "postprocess/filters.h"
31
#include "postprocess/pp_private.h"
32
33
#include "pipe/p_screen.h"
34
#include "util/u_inlines.h"
35
#include "util/u_math.h"
36
#include "util/u_debug.h"
37
#include "util/u_memory.h"
38
#include "cso_cache/cso_context.h"
39
40
/** Initialize the post-processing queue. */
41
struct pp_queue_t *
42
pp_init(struct pipe_context *pipe, const unsigned int *enabled,
43
struct cso_context *cso, struct st_context_iface *st)
44
{
45
unsigned int num_filters = 0;
46
unsigned int curpos = 0, i, tmp_req = 0;
47
struct pp_queue_t *ppq;
48
49
pp_debug("Initializing the post-processing queue.\n");
50
51
/* How many filters were requested? */
52
for (i = 0; i < PP_FILTERS; i++) {
53
if (enabled[i])
54
num_filters++;
55
}
56
if (num_filters == 0)
57
return NULL;
58
59
ppq = CALLOC(1, sizeof(struct pp_queue_t));
60
61
if (!ppq) {
62
pp_debug("Unable to allocate memory for ppq.\n");
63
goto error;
64
}
65
66
ppq->pp_queue = CALLOC(num_filters, sizeof(pp_func));
67
if (ppq->pp_queue == NULL) {
68
pp_debug("Unable to allocate memory for pp_queue.\n");
69
goto error;
70
}
71
72
ppq->shaders = CALLOC(num_filters, sizeof(void *));
73
ppq->filters = CALLOC(num_filters, sizeof(unsigned int));
74
75
if ((ppq->shaders == NULL) ||
76
(ppq->filters == NULL)) {
77
pp_debug("Unable to allocate memory for shaders and filter arrays.\n");
78
goto error;
79
}
80
81
ppq->p = pp_init_prog(ppq, pipe, cso, st);
82
if (ppq->p == NULL) {
83
pp_debug("pp_init_prog returned NULL.\n");
84
goto error;
85
}
86
87
/* Add the enabled filters to the queue, in order */
88
curpos = 0;
89
for (i = 0; i < PP_FILTERS; i++) {
90
if (enabled[i]) {
91
ppq->pp_queue[curpos] = pp_filters[i].main;
92
tmp_req = MAX2(tmp_req, pp_filters[i].inner_tmps);
93
ppq->filters[curpos] = i;
94
95
if (pp_filters[i].shaders) {
96
ppq->shaders[curpos] =
97
CALLOC(pp_filters[i].shaders + 1, sizeof(void *));
98
if (!ppq->shaders[curpos]) {
99
pp_debug("Unable to allocate memory for shader list.\n");
100
goto error;
101
}
102
}
103
104
/* Call the initialization function for the filter. */
105
if (!pp_filters[i].init(ppq, curpos, enabled[i])) {
106
pp_debug("Initialization for filter %u failed.\n", i);
107
goto error;
108
}
109
110
curpos++;
111
}
112
}
113
114
ppq->n_filters = curpos;
115
ppq->n_tmp = (curpos > 2 ? 2 : 1);
116
ppq->n_inner_tmp = tmp_req;
117
118
ppq->fbos_init = false;
119
120
for (i = 0; i < curpos; i++)
121
ppq->shaders[i][0] = ppq->p->passvs;
122
123
pp_debug("Queue successfully allocated. %u filter(s).\n", curpos);
124
125
return ppq;
126
127
error:
128
129
if (ppq) {
130
/* Assign curpos, since we only need to destroy initialized filters. */
131
ppq->n_filters = curpos;
132
133
/* Call the common free function which must handle partial initialization. */
134
pp_free(ppq);
135
}
136
137
return NULL;
138
}
139
140
/** Free any allocated FBOs (temp buffers). Called after resizing for example. */
141
void
142
pp_free_fbos(struct pp_queue_t *ppq)
143
{
144
145
unsigned int i;
146
147
if (!ppq->fbos_init)
148
return;
149
150
for (i = 0; i < ppq->n_tmp; i++) {
151
pipe_surface_reference(&ppq->tmps[i], NULL);
152
pipe_resource_reference(&ppq->tmp[i], NULL);
153
}
154
for (i = 0; i < ppq->n_inner_tmp; i++) {
155
pipe_surface_reference(&ppq->inner_tmps[i], NULL);
156
pipe_resource_reference(&ppq->inner_tmp[i], NULL);
157
}
158
pipe_surface_reference(&ppq->stencils, NULL);
159
pipe_resource_reference(&ppq->stencil, NULL);
160
161
ppq->fbos_init = false;
162
}
163
164
/**
165
* Free the pp queue. Called on context termination and failure in
166
* pp_init.
167
*/
168
void
169
pp_free(struct pp_queue_t *ppq)
170
{
171
unsigned int i, j;
172
173
if (!ppq)
174
return;
175
176
pp_free_fbos(ppq);
177
178
if (ppq->p) {
179
if (ppq->p->pipe && ppq->filters && ppq->shaders) {
180
for (i = 0; i < ppq->n_filters; i++) {
181
unsigned int filter = ppq->filters[i];
182
183
if (ppq->shaders[i] == NULL) {
184
continue;
185
}
186
187
/*
188
* Common shader destruction code for all postprocessing
189
* filters.
190
*/
191
for (j = 0; j < pp_filters[filter].shaders; j++) {
192
if (ppq->shaders[i][j] == NULL) {
193
/* We reached the end of initialized shaders. */
194
break;
195
}
196
197
if (ppq->shaders[i][j] == ppq->p->passvs) {
198
continue;
199
}
200
201
assert(ppq);
202
assert(ppq->p);
203
assert(ppq->p->pipe);
204
205
if (j >= pp_filters[filter].verts) {
206
assert(ppq->p->pipe->delete_fs_state);
207
ppq->p->pipe->delete_fs_state(ppq->p->pipe,
208
ppq->shaders[i][j]);
209
ppq->shaders[i][j] = NULL;
210
} else {
211
assert(ppq->p->pipe->delete_vs_state);
212
ppq->p->pipe->delete_vs_state(ppq->p->pipe,
213
ppq->shaders[i][j]);
214
ppq->shaders[i][j] = NULL;
215
}
216
}
217
218
/* Finally call each filter type's free functionality. */
219
pp_filters[filter].free(ppq, i);
220
}
221
}
222
223
FREE(ppq->p);
224
}
225
226
/*
227
* Handle partial initialization for common resource destruction
228
* in the create path.
229
*/
230
FREE(ppq->filters);
231
FREE(ppq->shaders);
232
FREE(ppq->pp_queue);
233
234
FREE(ppq);
235
236
pp_debug("Queue taken down.\n");
237
}
238
239
/** Internal debug function. Should be available to final users. */
240
void
241
pp_debug(const char *fmt, ...)
242
{
243
va_list ap;
244
245
if (!debug_get_bool_option("PP_DEBUG", FALSE))
246
return;
247
248
va_start(ap, fmt);
249
_debug_vprintf(fmt, ap);
250
va_end(ap);
251
}
252
253
/** Allocate the temp FBOs. Called on makecurrent and resize. */
254
void
255
pp_init_fbos(struct pp_queue_t *ppq, unsigned int w,
256
unsigned int h)
257
{
258
259
struct pp_program *p = ppq->p; /* The lazy will inherit the earth */
260
261
unsigned int i;
262
struct pipe_resource tmp_res;
263
264
if (ppq->fbos_init)
265
return;
266
267
pp_debug("Initializing FBOs, size %ux%u\n", w, h);
268
pp_debug("Requesting %u temps and %u inner temps\n", ppq->n_tmp,
269
ppq->n_inner_tmp);
270
271
memset(&tmp_res, 0, sizeof(tmp_res));
272
tmp_res.target = PIPE_TEXTURE_2D;
273
tmp_res.format = p->surf.format = PIPE_FORMAT_B8G8R8A8_UNORM;
274
tmp_res.width0 = w;
275
tmp_res.height0 = h;
276
tmp_res.depth0 = 1;
277
tmp_res.array_size = 1;
278
tmp_res.last_level = 0;
279
tmp_res.bind = PIPE_BIND_RENDER_TARGET;
280
281
if (!p->screen->is_format_supported(p->screen, tmp_res.format,
282
tmp_res.target, 1, 1, tmp_res.bind))
283
pp_debug("Temp buffers' format fail\n");
284
285
for (i = 0; i < ppq->n_tmp; i++) {
286
ppq->tmp[i] = p->screen->resource_create(p->screen, &tmp_res);
287
ppq->tmps[i] = p->pipe->create_surface(p->pipe, ppq->tmp[i], &p->surf);
288
289
if (!ppq->tmp[i] || !ppq->tmps[i])
290
goto error;
291
}
292
293
for (i = 0; i < ppq->n_inner_tmp; i++) {
294
ppq->inner_tmp[i] = p->screen->resource_create(p->screen, &tmp_res);
295
ppq->inner_tmps[i] = p->pipe->create_surface(p->pipe,
296
ppq->inner_tmp[i],
297
&p->surf);
298
299
if (!ppq->inner_tmp[i] || !ppq->inner_tmps[i])
300
goto error;
301
}
302
303
tmp_res.bind = PIPE_BIND_DEPTH_STENCIL;
304
305
tmp_res.format = p->surf.format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
306
307
if (!p->screen->is_format_supported(p->screen, tmp_res.format,
308
tmp_res.target, 1, 1, tmp_res.bind)) {
309
310
tmp_res.format = p->surf.format = PIPE_FORMAT_Z24_UNORM_S8_UINT;
311
312
if (!p->screen->is_format_supported(p->screen, tmp_res.format,
313
tmp_res.target, 1, 1, tmp_res.bind))
314
pp_debug("Temp Sbuffer format fail\n");
315
}
316
317
ppq->stencil = p->screen->resource_create(p->screen, &tmp_res);
318
ppq->stencils = p->pipe->create_surface(p->pipe, ppq->stencil, &p->surf);
319
if (!ppq->stencil || !ppq->stencils)
320
goto error;
321
322
p->framebuffer.width = w;
323
p->framebuffer.height = h;
324
325
p->viewport.scale[0] = p->viewport.translate[0] = (float) w / 2.0f;
326
p->viewport.scale[1] = p->viewport.translate[1] = (float) h / 2.0f;
327
p->viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
328
p->viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
329
p->viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
330
p->viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
331
332
ppq->fbos_init = true;
333
334
return;
335
336
error:
337
pp_debug("Failed to allocate temp buffers!\n");
338
}
339
340