Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/vdpau/device.c
4565 views
1
/**************************************************************************
2
*
3
* Copyright 2010 Younes Manton og Thomas Balling Sørensen.
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 "pipe/p_compiler.h"
29
30
#include "util/u_memory.h"
31
#include "util/u_debug.h"
32
#include "util/format/u_format.h"
33
#include "util/u_sampler.h"
34
35
#include "vdpau_private.h"
36
37
/**
38
* Create a VdpDevice object for use with X11.
39
*/
40
PUBLIC VdpStatus
41
vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device,
42
VdpGetProcAddress **get_proc_address)
43
{
44
struct pipe_screen *pscreen;
45
struct pipe_resource *res, res_tmpl;
46
struct pipe_sampler_view sv_tmpl;
47
vlVdpDevice *dev = NULL;
48
VdpStatus ret;
49
50
if (!(display && device && get_proc_address))
51
return VDP_STATUS_INVALID_POINTER;
52
53
if (!vlCreateHTAB()) {
54
ret = VDP_STATUS_RESOURCES;
55
goto no_htab;
56
}
57
58
dev = CALLOC(1, sizeof(vlVdpDevice));
59
if (!dev) {
60
ret = VDP_STATUS_RESOURCES;
61
goto no_dev;
62
}
63
64
pipe_reference_init(&dev->reference, 1);
65
66
dev->vscreen = vl_dri3_screen_create(display, screen);
67
if (!dev->vscreen)
68
dev->vscreen = vl_dri2_screen_create(display, screen);
69
if (!dev->vscreen) {
70
ret = VDP_STATUS_RESOURCES;
71
goto no_vscreen;
72
}
73
74
pscreen = dev->vscreen->pscreen;
75
dev->context = pipe_create_multimedia_context(pscreen);
76
if (!dev->context) {
77
ret = VDP_STATUS_RESOURCES;
78
goto no_context;
79
}
80
81
if (!pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) {
82
ret = VDP_STATUS_NO_IMPLEMENTATION;
83
goto no_context;
84
}
85
86
memset(&res_tmpl, 0, sizeof(res_tmpl));
87
88
res_tmpl.target = PIPE_TEXTURE_2D;
89
res_tmpl.format = PIPE_FORMAT_R8G8B8A8_UNORM;
90
res_tmpl.width0 = 1;
91
res_tmpl.height0 = 1;
92
res_tmpl.depth0 = 1;
93
res_tmpl.array_size = 1;
94
res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
95
res_tmpl.usage = PIPE_USAGE_DEFAULT;
96
97
if (!CheckSurfaceParams(pscreen, &res_tmpl)) {
98
ret = VDP_STATUS_NO_IMPLEMENTATION;
99
goto no_resource;
100
}
101
102
res = pscreen->resource_create(pscreen, &res_tmpl);
103
if (!res) {
104
ret = VDP_STATUS_RESOURCES;
105
goto no_resource;
106
}
107
108
memset(&sv_tmpl, 0, sizeof(sv_tmpl));
109
u_sampler_view_default_template(&sv_tmpl, res, res->format);
110
111
sv_tmpl.swizzle_r = PIPE_SWIZZLE_1;
112
sv_tmpl.swizzle_g = PIPE_SWIZZLE_1;
113
sv_tmpl.swizzle_b = PIPE_SWIZZLE_1;
114
sv_tmpl.swizzle_a = PIPE_SWIZZLE_1;
115
116
dev->dummy_sv = dev->context->create_sampler_view(dev->context, res, &sv_tmpl);
117
pipe_resource_reference(&res, NULL);
118
if (!dev->dummy_sv) {
119
ret = VDP_STATUS_RESOURCES;
120
goto no_resource;
121
}
122
123
*device = vlAddDataHTAB(dev);
124
if (*device == 0) {
125
ret = VDP_STATUS_ERROR;
126
goto no_handle;
127
}
128
129
if (!vl_compositor_init(&dev->compositor, dev->context)) {
130
ret = VDP_STATUS_ERROR;
131
goto no_compositor;
132
}
133
134
(void) mtx_init(&dev->mutex, mtx_plain);
135
136
*get_proc_address = &vlVdpGetProcAddress;
137
138
return VDP_STATUS_OK;
139
140
no_compositor:
141
vlRemoveDataHTAB(*device);
142
no_handle:
143
pipe_sampler_view_reference(&dev->dummy_sv, NULL);
144
no_resource:
145
dev->context->destroy(dev->context);
146
no_context:
147
dev->vscreen->destroy(dev->vscreen);
148
no_vscreen:
149
FREE(dev);
150
no_dev:
151
vlDestroyHTAB();
152
no_htab:
153
return ret;
154
}
155
156
/**
157
* Create a VdpPresentationQueueTarget for use with X11.
158
*/
159
VdpStatus
160
vlVdpPresentationQueueTargetCreateX11(VdpDevice device, Drawable drawable,
161
VdpPresentationQueueTarget *target)
162
{
163
vlVdpPresentationQueueTarget *pqt;
164
VdpStatus ret;
165
166
if (!drawable)
167
return VDP_STATUS_INVALID_HANDLE;
168
169
vlVdpDevice *dev = vlGetDataHTAB(device);
170
if (!dev)
171
return VDP_STATUS_INVALID_HANDLE;
172
173
pqt = CALLOC(1, sizeof(vlVdpPresentationQueueTarget));
174
if (!pqt)
175
return VDP_STATUS_RESOURCES;
176
177
DeviceReference(&pqt->device, dev);
178
pqt->drawable = drawable;
179
180
*target = vlAddDataHTAB(pqt);
181
if (*target == 0) {
182
ret = VDP_STATUS_ERROR;
183
goto no_handle;
184
}
185
186
return VDP_STATUS_OK;
187
188
no_handle:
189
FREE(pqt);
190
return ret;
191
}
192
193
/**
194
* Destroy a VdpPresentationQueueTarget.
195
*/
196
VdpStatus
197
vlVdpPresentationQueueTargetDestroy(VdpPresentationQueueTarget presentation_queue_target)
198
{
199
vlVdpPresentationQueueTarget *pqt;
200
201
pqt = vlGetDataHTAB(presentation_queue_target);
202
if (!pqt)
203
return VDP_STATUS_INVALID_HANDLE;
204
205
vlRemoveDataHTAB(presentation_queue_target);
206
DeviceReference(&pqt->device, NULL);
207
FREE(pqt);
208
209
return VDP_STATUS_OK;
210
}
211
212
/**
213
* Destroy a VdpDevice.
214
*/
215
VdpStatus
216
vlVdpDeviceDestroy(VdpDevice device)
217
{
218
vlVdpDevice *dev = vlGetDataHTAB(device);
219
if (!dev)
220
return VDP_STATUS_INVALID_HANDLE;
221
222
vlRemoveDataHTAB(device);
223
DeviceReference(&dev, NULL);
224
225
return VDP_STATUS_OK;
226
}
227
228
/**
229
* Free a VdpDevice.
230
*/
231
void
232
vlVdpDeviceFree(vlVdpDevice *dev)
233
{
234
mtx_destroy(&dev->mutex);
235
vl_compositor_cleanup(&dev->compositor);
236
pipe_sampler_view_reference(&dev->dummy_sv, NULL);
237
dev->context->destroy(dev->context);
238
dev->vscreen->destroy(dev->vscreen);
239
FREE(dev);
240
vlDestroyHTAB();
241
}
242
243
/**
244
* Retrieve a VDPAU function pointer.
245
*/
246
VdpStatus
247
vlVdpGetProcAddress(VdpDevice device, VdpFuncId function_id, void **function_pointer)
248
{
249
vlVdpDevice *dev = vlGetDataHTAB(device);
250
if (!dev)
251
return VDP_STATUS_INVALID_HANDLE;
252
253
if (!function_pointer)
254
return VDP_STATUS_INVALID_POINTER;
255
256
if (!vlGetFuncFTAB(function_id, function_pointer))
257
return VDP_STATUS_INVALID_FUNC_ID;
258
259
VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Got proc address %p for id %d\n", *function_pointer, function_id);
260
261
return VDP_STATUS_OK;
262
}
263
264
#define _ERROR_TYPE(TYPE,STRING) case TYPE: return STRING;
265
266
/**
267
* Retrieve a string describing an error code.
268
*/
269
char const *
270
vlVdpGetErrorString (VdpStatus status)
271
{
272
switch (status) {
273
_ERROR_TYPE(VDP_STATUS_OK,"The operation completed successfully; no error.");
274
_ERROR_TYPE(VDP_STATUS_NO_IMPLEMENTATION,"No backend implementation could be loaded.");
275
_ERROR_TYPE(VDP_STATUS_DISPLAY_PREEMPTED,"The display was preempted, or a fatal error occurred. The application must re-initialize VDPAU.");
276
_ERROR_TYPE(VDP_STATUS_INVALID_HANDLE,"An invalid handle value was provided. Either the handle does not exist at all, or refers to an object of an incorrect type.");
277
_ERROR_TYPE(VDP_STATUS_INVALID_POINTER,"An invalid pointer was provided. Typically, this means that a NULL pointer was provided for an 'output' parameter.");
278
_ERROR_TYPE(VDP_STATUS_INVALID_CHROMA_TYPE,"An invalid/unsupported VdpChromaType value was supplied.");
279
_ERROR_TYPE(VDP_STATUS_INVALID_Y_CB_CR_FORMAT,"An invalid/unsupported VdpYCbCrFormat value was supplied.");
280
_ERROR_TYPE(VDP_STATUS_INVALID_RGBA_FORMAT,"An invalid/unsupported VdpRGBAFormat value was supplied.");
281
_ERROR_TYPE(VDP_STATUS_INVALID_INDEXED_FORMAT,"An invalid/unsupported VdpIndexedFormat value was supplied.");
282
_ERROR_TYPE(VDP_STATUS_INVALID_COLOR_STANDARD,"An invalid/unsupported VdpColorStandard value was supplied.");
283
_ERROR_TYPE(VDP_STATUS_INVALID_COLOR_TABLE_FORMAT,"An invalid/unsupported VdpColorTableFormat value was supplied.");
284
_ERROR_TYPE(VDP_STATUS_INVALID_BLEND_FACTOR,"An invalid/unsupported VdpOutputSurfaceRenderBlendFactor value was supplied.");
285
_ERROR_TYPE(VDP_STATUS_INVALID_BLEND_EQUATION,"An invalid/unsupported VdpOutputSurfaceRenderBlendEquation value was supplied.");
286
_ERROR_TYPE(VDP_STATUS_INVALID_FLAG,"An invalid/unsupported flag value/combination was supplied.");
287
_ERROR_TYPE(VDP_STATUS_INVALID_DECODER_PROFILE,"An invalid/unsupported VdpDecoderProfile value was supplied.");
288
_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE,"An invalid/unsupported VdpVideoMixerFeature value was supplied.");
289
_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER,"An invalid/unsupported VdpVideoMixerParameter value was supplied.");
290
_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE,"An invalid/unsupported VdpVideoMixerAttribute value was supplied.");
291
_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE,"An invalid/unsupported VdpVideoMixerPictureStructure value was supplied.");
292
_ERROR_TYPE(VDP_STATUS_INVALID_FUNC_ID,"An invalid/unsupported VdpFuncId value was supplied.");
293
_ERROR_TYPE(VDP_STATUS_INVALID_SIZE,"The size of a supplied object does not match the object it is being used with.\
294
For example, a VdpVideoMixer is configured to process VdpVideoSurface objects of a specific size.\
295
If presented with a VdpVideoSurface of a different size, this error will be raised.");
296
_ERROR_TYPE(VDP_STATUS_INVALID_VALUE,"An invalid/unsupported value was supplied.\
297
This is a catch-all error code for values of type other than those with a specific error code.");
298
_ERROR_TYPE(VDP_STATUS_INVALID_STRUCT_VERSION,"An invalid/unsupported structure version was specified in a versioned structure. \
299
This implies that the implementation is older than the header file the application was built against.");
300
_ERROR_TYPE(VDP_STATUS_RESOURCES,"The system does not have enough resources to complete the requested operation at this time.");
301
_ERROR_TYPE(VDP_STATUS_HANDLE_DEVICE_MISMATCH,"The set of handles supplied are not all related to the same VdpDevice.When performing operations \
302
that operate on multiple surfaces, such as VdpOutputSurfaceRenderOutputSurface or VdpVideoMixerRender, \
303
all supplied surfaces must have been created within the context of the same VdpDevice object. \
304
This error is raised if they were not.");
305
_ERROR_TYPE(VDP_STATUS_ERROR,"A catch-all error, used when no other error code applies.");
306
default: return "Unknown Error";
307
}
308
}
309
310
void
311
vlVdpDefaultSamplerViewTemplate(struct pipe_sampler_view *templ, struct pipe_resource *res)
312
{
313
const struct util_format_description *desc;
314
315
memset(templ, 0, sizeof(*templ));
316
u_sampler_view_default_template(templ, res, res->format);
317
318
desc = util_format_description(res->format);
319
if (desc->swizzle[0] == PIPE_SWIZZLE_0)
320
templ->swizzle_r = PIPE_SWIZZLE_1;
321
if (desc->swizzle[1] == PIPE_SWIZZLE_0)
322
templ->swizzle_g = PIPE_SWIZZLE_1;
323
if (desc->swizzle[2] == PIPE_SWIZZLE_0)
324
templ->swizzle_b = PIPE_SWIZZLE_1;
325
if (desc->swizzle[3] == PIPE_SWIZZLE_0)
326
templ->swizzle_a = PIPE_SWIZZLE_1;
327
}
328
329