Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/hgl/hgl.c
4561 views
1
/*
2
* Copyright 2012-2014, Haiku, Inc. All Rights Reserved.
3
* Distributed under the terms of the MIT License.
4
*
5
* Authors:
6
* Artur Wyszynski, [email protected]
7
* Alexander von Gluck IV, [email protected]
8
*/
9
10
#include "hgl_context.h"
11
12
#include <stdio.h>
13
14
#include "pipe/p_format.h"
15
#include "util/u_atomic.h"
16
#include "util/format/u_format.h"
17
#include "util/u_memory.h"
18
#include "util/u_inlines.h"
19
#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
20
21
#include "GLView.h"
22
23
24
#ifdef DEBUG
25
# define TRACE(x...) printf("hgl:frontend: " x)
26
# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
27
#else
28
# define TRACE(x...)
29
# define CALLED()
30
#endif
31
#define ERROR(x...) printf("hgl:frontend: " x)
32
33
34
// Perform a safe void to hgl_context cast
35
static inline struct hgl_context*
36
hgl_st_context(struct st_context_iface *stctxi)
37
{
38
struct hgl_context* context;
39
assert(stctxi);
40
context = (struct hgl_context*)stctxi->st_manager_private;
41
assert(context);
42
return context;
43
}
44
45
46
// Perform a safe void to hgl_buffer cast
47
//static inline struct hgl_buffer*
48
struct hgl_buffer*
49
hgl_st_framebuffer(struct st_framebuffer_iface *stfbi)
50
{
51
struct hgl_buffer* buffer;
52
assert(stfbi);
53
buffer = (struct hgl_buffer*)stfbi->st_manager_private;
54
assert(buffer);
55
return buffer;
56
}
57
58
59
static bool
60
hgl_st_framebuffer_flush_front(struct st_context_iface* stctxi,
61
struct st_framebuffer_iface* stfbi, enum st_attachment_type statt)
62
{
63
CALLED();
64
65
struct hgl_buffer* buffer = hgl_st_framebuffer(stfbi);
66
struct pipe_resource* ptex = buffer->textures[statt];
67
68
if (statt != ST_ATTACHMENT_FRONT_LEFT)
69
return false;
70
71
if (!ptex)
72
return true;
73
74
// TODO: pipe_context here??? Might be needed for hw renderers
75
buffer->screen->flush_frontbuffer(buffer->screen, NULL, ptex, 0, 0,
76
buffer->winsysContext, NULL);
77
78
return true;
79
}
80
81
82
static bool
83
hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
84
unsigned width, unsigned height, unsigned mask)
85
{
86
struct hgl_buffer* buffer;
87
enum st_attachment_type i;
88
struct pipe_resource templat;
89
90
CALLED();
91
92
buffer = hgl_st_framebuffer(stfbi);
93
94
if (buffer->width != width || buffer->height != height) {
95
TRACE("validate_textures: size changed: %d, %d -> %d, %d\n",
96
buffer->width, buffer->height, width, height);
97
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
98
pipe_resource_reference(&buffer->textures[i], NULL);
99
}
100
101
memset(&templat, 0, sizeof(templat));
102
templat.target = buffer->target;
103
templat.width0 = width;
104
templat.height0 = height;
105
templat.depth0 = 1;
106
templat.array_size = 1;
107
templat.last_level = 0;
108
109
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
110
enum pipe_format format;
111
unsigned bind;
112
113
if (((1 << i) & buffer->visual->buffer_mask) && buffer->textures[i] == NULL) {
114
switch (i) {
115
case ST_ATTACHMENT_FRONT_LEFT:
116
case ST_ATTACHMENT_BACK_LEFT:
117
case ST_ATTACHMENT_FRONT_RIGHT:
118
case ST_ATTACHMENT_BACK_RIGHT:
119
format = buffer->visual->color_format;
120
bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
121
break;
122
case ST_ATTACHMENT_DEPTH_STENCIL:
123
format = buffer->visual->depth_stencil_format;
124
bind = PIPE_BIND_DEPTH_STENCIL;
125
break;
126
default:
127
format = PIPE_FORMAT_NONE;
128
bind = 0;
129
break;
130
}
131
132
if (format != PIPE_FORMAT_NONE) {
133
templat.format = format;
134
templat.bind = bind;
135
TRACE("resource_create(%d, %d, %d)\n", i, format, bind);
136
buffer->textures[i] = buffer->screen->resource_create(buffer->screen,
137
&templat);
138
if (!buffer->textures[i])
139
return FALSE;
140
}
141
}
142
}
143
144
buffer->width = width;
145
buffer->height = height;
146
buffer->mask = mask;
147
148
return true;
149
}
150
151
152
/**
153
* Called by the st manager to validate the framebuffer (allocate
154
* its resources).
155
*/
156
static bool
157
hgl_st_framebuffer_validate(struct st_context_iface *stctxi,
158
struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts,
159
unsigned count, struct pipe_resource **out)
160
{
161
struct hgl_context* context;
162
struct hgl_buffer* buffer;
163
unsigned stAttachmentMask, newMask;
164
unsigned i;
165
bool resized;
166
167
CALLED();
168
169
context = hgl_st_context(stctxi);
170
buffer = hgl_st_framebuffer(stfbi);
171
172
// Build mask of current attachments
173
stAttachmentMask = 0;
174
for (i = 0; i < count; i++)
175
stAttachmentMask |= 1 << statts[i];
176
177
newMask = stAttachmentMask & ~buffer->mask;
178
179
resized = (buffer->width != context->width)
180
|| (buffer->height != context->height);
181
182
if (resized || newMask) {
183
boolean ret;
184
TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__,
185
buffer->width, buffer->height, context->width, context->height);
186
187
ret = hgl_st_framebuffer_validate_textures(stfbi,
188
context->width, context->height, stAttachmentMask);
189
190
if (!ret)
191
return ret;
192
}
193
194
for (i = 0; i < count; i++)
195
pipe_resource_reference(&out[i], buffer->textures[statts[i]]);
196
197
return true;
198
}
199
200
201
static int
202
hgl_st_manager_get_param(struct st_manager *smapi, enum st_manager_param param)
203
{
204
CALLED();
205
206
switch (param) {
207
case ST_MANAGER_BROKEN_INVALIDATE:
208
return 1;
209
}
210
211
return 0;
212
}
213
214
215
static uint32_t hgl_fb_ID = 0;
216
217
/**
218
* Create new framebuffer
219
*/
220
struct hgl_buffer *
221
hgl_create_st_framebuffer(struct hgl_context* context, void *winsysContext)
222
{
223
struct hgl_buffer *buffer;
224
CALLED();
225
226
// Our requires before creating a framebuffer
227
assert(context);
228
assert(context->display);
229
assert(context->stVisual);
230
231
buffer = CALLOC_STRUCT(hgl_buffer);
232
assert(buffer);
233
234
// calloc and configure our st_framebuffer interface
235
buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface);
236
assert(buffer->stfbi);
237
238
// Prepare our buffer
239
buffer->visual = context->stVisual;
240
buffer->screen = context->display->manager->screen;
241
buffer->winsysContext = winsysContext;
242
243
if (buffer->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES))
244
buffer->target = PIPE_TEXTURE_2D;
245
else
246
buffer->target = PIPE_TEXTURE_RECT;
247
248
// Prepare our frontend interface
249
buffer->stfbi->flush_front = hgl_st_framebuffer_flush_front;
250
buffer->stfbi->validate = hgl_st_framebuffer_validate;
251
buffer->stfbi->visual = context->stVisual;
252
253
p_atomic_set(&buffer->stfbi->stamp, 1);
254
buffer->stfbi->st_manager_private = (void*)buffer;
255
buffer->stfbi->ID = p_atomic_inc_return(&hgl_fb_ID);
256
buffer->stfbi->state_manager = context->display->manager;
257
258
return buffer;
259
}
260
261
262
void
263
hgl_destroy_st_framebuffer(struct hgl_buffer *buffer)
264
{
265
CALLED();
266
267
int i;
268
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
269
pipe_resource_reference(&buffer->textures[i], NULL);
270
271
FREE(buffer->stfbi);
272
FREE(buffer);
273
}
274
275
276
struct st_api*
277
hgl_create_st_api()
278
{
279
CALLED();
280
return st_gl_api_create();
281
}
282
283
284
struct st_visual*
285
hgl_create_st_visual(ulong options)
286
{
287
struct st_visual* visual;
288
289
CALLED();
290
291
visual = CALLOC_STRUCT(st_visual);
292
assert(visual);
293
294
// Determine color format
295
if ((options & BGL_INDEX) != 0) {
296
// Index color
297
visual->color_format = PIPE_FORMAT_B5G6R5_UNORM;
298
// TODO: Indexed color depth buffer?
299
visual->depth_stencil_format = PIPE_FORMAT_NONE;
300
} else {
301
// RGB color
302
visual->color_format = (options & BGL_ALPHA)
303
? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM;
304
// TODO: Determine additional stencil formats
305
visual->depth_stencil_format = (options & BGL_DEPTH)
306
? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE;
307
}
308
309
visual->accum_format = (options & BGL_ACCUM)
310
? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
311
312
visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
313
314
if ((options & BGL_DOUBLE) != 0) {
315
TRACE("double buffer enabled\n");
316
visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
317
}
318
319
#if 0
320
if ((options & BGL_STEREO) != 0) {
321
visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
322
if ((options & BGL_DOUBLE) != 0)
323
visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
324
}
325
#endif
326
327
if ((options & BGL_DEPTH) || (options & BGL_STENCIL))
328
visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
329
330
TRACE("%s: Visual color format: %s\n", __func__,
331
util_format_name(visual->color_format));
332
333
return visual;
334
}
335
336
337
void
338
hgl_destroy_st_visual(struct st_visual* visual)
339
{
340
CALLED();
341
342
FREE(visual);
343
}
344
345
346
struct hgl_display*
347
hgl_create_display(struct pipe_screen* screen)
348
{
349
struct hgl_display* display;
350
351
display = CALLOC_STRUCT(hgl_display);
352
assert(display);
353
display->api = st_gl_api_create();
354
display->manager = CALLOC_STRUCT(st_manager);
355
assert(display->manager);
356
display->manager->screen = screen;
357
display->manager->get_param = hgl_st_manager_get_param;
358
// display->manager->st_manager_private is used by llvmpipe
359
360
return display;
361
}
362
363
364
void
365
hgl_destroy_display(struct hgl_display *display)
366
{
367
if (display->manager->destroy)
368
display->manager->destroy(display->manager);
369
FREE(display->manager);
370
if (display->api->destroy)
371
display->api->destroy(display->api);
372
FREE(display);
373
}
374
375