1 /*
2  * Copyright (c) 2008-2015 NVIDIA Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #define __STDC_FORMAT_MACROS
25 #define __STDC_LIMIT_MACROS
26 #include <inttypes.h>
27 
28 #include <dlfcn.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <vdpau/vdpau_x11.h>
33 
34 #include "../src/util.h"
35 
36 #define _VDP_TRACE_ARSIZE(_x_) ((sizeof (_x_)) / (sizeof ((_x_)[0])))
37 
38 #if DEBUG
39 
_vdp_trace_error_breakpoint(char const * file,int line,char const * function)40 static void _vdp_trace_error_breakpoint(char const * file, int line, char const * function)
41 {
42     fprintf(stderr, "VDPAU trace: Error detected at %s:%d %s()\n", file, line, function);
43 }
44 
45 #define _VDP_TRACE_ERROR_BREAKPOINT() _vdp_trace_error_breakpoint(__FILE__, __LINE__, __FUNCTION__)
46 
47 #else
48 
49 #define _VDP_TRACE_ERROR_BREAKPOINT()
50 
51 #endif
52 
53 #define LEVEL_PARAMS 1
54 #define LEVEL_DATA   2
55 
56 struct _VdpCapData {
57     void * dll;
58 
59     int    level;
60     FILE * fp;
61 
62     VdpDevice           vdp_device;
63     VdpGetProcAddress * vdp_get_proc_address;
64 
65     VdpGetErrorString * vdp_get_error_string;
66     VdpGetApiVersion * vdp_get_api_version;
67     VdpGetInformationString * vdp_get_information_string;
68     VdpDeviceDestroy * vdp_device_destroy;
69     VdpGenerateCSCMatrix * vdp_generate_csc_matrix;
70     VdpVideoSurfaceQueryCapabilities * vdp_video_surface_query_capabilities;
71     VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities * vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities;
72     VdpVideoSurfaceCreate * vdp_video_surface_create;
73     VdpVideoSurfaceDestroy * vdp_video_surface_destroy;
74     VdpVideoSurfaceGetParameters * vdp_video_surface_get_parameters;
75     VdpVideoSurfaceGetBitsYCbCr * vdp_video_surface_get_bits_y_cb_cr;
76     VdpVideoSurfacePutBitsYCbCr * vdp_video_surface_put_bits_y_cb_cr;
77     VdpOutputSurfaceQueryCapabilities * vdp_output_surface_query_capabilities;
78     VdpOutputSurfaceQueryGetPutBitsNativeCapabilities * vdp_output_surface_query_get_put_bits_native_capabilities;
79     VdpOutputSurfaceQueryPutBitsIndexedCapabilities * vdp_output_surface_query_put_bits_indexed_capabilities;
80     VdpOutputSurfaceQueryPutBitsYCbCrCapabilities * vdp_output_surface_query_put_bits_y_cb_cr_capabilities;
81     VdpOutputSurfaceCreate * vdp_output_surface_create;
82     VdpOutputSurfaceDestroy * vdp_output_surface_destroy;
83     VdpOutputSurfaceGetParameters * vdp_output_surface_get_parameters;
84     VdpOutputSurfaceGetBitsNative * vdp_output_surface_get_bits_native;
85     VdpOutputSurfacePutBitsNative * vdp_output_surface_put_bits_native;
86     VdpOutputSurfacePutBitsIndexed * vdp_output_surface_put_bits_indexed;
87     VdpOutputSurfacePutBitsYCbCr * vdp_output_surface_put_bits_y_cb_cr;
88     VdpBitmapSurfaceQueryCapabilities * vdp_bitmap_surface_query_capabilities;
89     VdpBitmapSurfaceCreate * vdp_bitmap_surface_create;
90     VdpBitmapSurfaceDestroy * vdp_bitmap_surface_destroy;
91     VdpBitmapSurfaceGetParameters * vdp_bitmap_surface_get_parameters;
92     VdpBitmapSurfacePutBitsNative * vdp_bitmap_surface_put_bits_native;
93     VdpOutputSurfaceRenderOutputSurface * vdp_output_surface_render_output_surface;
94     VdpOutputSurfaceRenderBitmapSurface * vdp_output_surface_render_bitmap_surface;
95     VdpDecoderQueryCapabilities * vdp_decoder_query_capabilities;
96     VdpDecoderCreate * vdp_decoder_create;
97     VdpDecoderDestroy * vdp_decoder_destroy;
98     VdpDecoderGetParameters * vdp_decoder_get_parameters;
99     VdpDecoderRender * vdp_decoder_render;
100     VdpVideoMixerQueryFeatureSupport * vdp_video_mixer_query_feature_support;
101     VdpVideoMixerQueryParameterSupport * vdp_video_mixer_query_parameter_support;
102     VdpVideoMixerQueryAttributeSupport * vdp_video_mixer_query_attribute_support;
103     VdpVideoMixerQueryParameterValueRange * vdp_video_mixer_query_parameter_value_range;
104     VdpVideoMixerQueryAttributeValueRange * vdp_video_mixer_query_attribute_value_range;
105     VdpVideoMixerCreate * vdp_video_mixer_create;
106     VdpVideoMixerSetFeatureEnables * vdp_video_mixer_set_feature_enables;
107     VdpVideoMixerSetAttributeValues * vdp_video_mixer_set_attribute_values;
108     VdpVideoMixerGetFeatureSupport * vdp_video_mixer_get_feature_support;
109     VdpVideoMixerGetFeatureEnables * vdp_video_mixer_get_feature_enables;
110     VdpVideoMixerGetParameterValues * vdp_video_mixer_get_parameter_values;
111     VdpVideoMixerGetAttributeValues * vdp_video_mixer_get_attribute_values;
112     VdpVideoMixerDestroy * vdp_video_mixer_destroy;
113     VdpVideoMixerRender * vdp_video_mixer_render;
114     VdpPresentationQueueTargetDestroy * vdp_presentation_queue_target_destroy;
115     VdpPresentationQueueCreate * vdp_presentation_queue_create;
116     VdpPresentationQueueDestroy * vdp_presentation_queue_destroy;
117     VdpPresentationQueueSetBackgroundColor * vdp_presentation_queue_set_background_color;
118     VdpPresentationQueueGetBackgroundColor * vdp_presentation_queue_get_background_color;
119     VdpPresentationQueueGetTime * vdp_presentation_queue_get_time;
120     VdpPresentationQueueDisplay * vdp_presentation_queue_display;
121     VdpPresentationQueueBlockUntilSurfaceIdle * vdp_presentation_queue_block_until_surface_idle;
122     VdpPresentationQueueQuerySurfaceStatus * vdp_presentation_queue_query_surface_status;
123     VdpPreemptionCallbackRegister * vdp_preemption_callback_register;
124     VdpPresentationQueueTargetCreateX11 * vdp_presentation_queue_target_create_x11;
125 };
126 
127 static _VdpCapData _vdp_cap_data;
128 
delta(T const & a,T const & b)129 template<class T> static inline T const delta(T const & a, T const & b)
130 {
131     if (a < b) {
132         return b - a;
133     }
134     else {
135         return a - b;
136     }
137 }
138 
_vdp_cap_dump_procamp(VdpProcamp * procamp)139 static void _vdp_cap_dump_procamp(VdpProcamp * procamp)
140 {
141     if (!procamp) {
142         fprintf(_vdp_cap_data.fp, "NULL");
143         return;
144     }
145 
146     fprintf(
147         _vdp_cap_data.fp,
148         "{(ver=%d)%s %f, %f, %f, %f}",
149         procamp->struct_version,
150         (procamp->struct_version > 0)
151             ? "(unsupported; cannot dump all fields)"
152             : "",
153         procamp->brightness,
154         procamp->contrast,
155         procamp->saturation,
156         procamp->hue
157     );
158 }
159 
_vdp_cap_dump_color(VdpColor const * color)160 static void _vdp_cap_dump_color(
161     VdpColor const * color
162 )
163 {
164     if (!color) {
165         fputs("NULL", _vdp_cap_data.fp);
166         return;
167     }
168 
169     fprintf(
170         _vdp_cap_data.fp,
171         "{%f, %f, %f, %f}",
172         color->red,
173         color->green,
174         color->blue,
175         color->alpha
176     );
177 }
178 
_vdp_cap_dump_rect(VdpRect const * rect)179 static void _vdp_cap_dump_rect(
180     VdpRect const * rect
181 )
182 {
183     if (!rect) {
184         fprintf(_vdp_cap_data.fp, "NULL");
185         return;
186     }
187 
188     fprintf(
189         _vdp_cap_data.fp,
190         "{%u, %u, %u, %u}",
191         rect->x0,
192         rect->y0,
193         rect->x1,
194         rect->y1
195     );
196 }
197 
_vdp_cap_dump_csc_matrix(VdpCSCMatrix const * matrix)198 static void _vdp_cap_dump_csc_matrix(
199     VdpCSCMatrix const * matrix
200 )
201 {
202     if (!matrix) {
203         fprintf(_vdp_cap_data.fp, "NULL");
204         return;
205     }
206 
207     fprintf(
208         _vdp_cap_data.fp,
209         "{{%f, %f, %f, %f}, {%f, %f, %f, %f}, {%f, %f, %f, %f}}",
210         (*matrix)[0][0],
211         (*matrix)[0][1],
212         (*matrix)[0][2],
213         (*matrix)[0][3],
214         (*matrix)[1][0],
215         (*matrix)[1][1],
216         (*matrix)[1][2],
217         (*matrix)[1][3],
218         (*matrix)[2][0],
219         (*matrix)[2][1],
220         (*matrix)[2][2],
221         (*matrix)[2][3]
222     );
223 }
224 
_vdp_cap_dump_blend_state(VdpOutputSurfaceRenderBlendState const * blend_state)225 static void _vdp_cap_dump_blend_state(
226     VdpOutputSurfaceRenderBlendState const * blend_state
227 )
228 {
229     if (!blend_state) {
230         fprintf(_vdp_cap_data.fp, "NULL");
231         return;
232     }
233 
234     fprintf(
235         _vdp_cap_data.fp,
236         "{(ver=%d)%s %u, %u, %u, %u, %u, %u, ",
237         blend_state->struct_version,
238         (blend_state->struct_version > 0)
239             ? "(unsupported; cannot dump all fields)"
240             : "",
241         blend_state->blend_factor_source_color,
242         blend_state->blend_factor_destination_color,
243         blend_state->blend_factor_source_alpha,
244         blend_state->blend_factor_destination_alpha,
245         blend_state->blend_equation_color,
246         blend_state->blend_equation_alpha
247     );
248     _vdp_cap_dump_color(&(blend_state->blend_constant));
249     fputs("}", _vdp_cap_data.fp);
250 }
251 
_vdp_cap_dump_picture_info(VdpDecoderProfile profile,VdpPictureInfo const * picture_info)252 static void _vdp_cap_dump_picture_info(
253     VdpDecoderProfile      profile,
254     VdpPictureInfo const * picture_info
255 )
256 {
257     switch (profile) {
258     case VDP_DECODER_PROFILE_MPEG1:
259     case VDP_DECODER_PROFILE_MPEG2_SIMPLE:
260     case VDP_DECODER_PROFILE_MPEG2_MAIN:
261         {
262             VdpPictureInfoMPEG1Or2 const * picture_info_mpeg1or2 =
263                 (VdpPictureInfoMPEG1Or2 const *)picture_info;
264 
265             fprintf(
266                 _vdp_cap_data.fp,
267                 "{%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, {{%u, %u}, {%u, %u}}, {",
268                 picture_info_mpeg1or2->forward_reference,
269                 picture_info_mpeg1or2->backward_reference,
270                 picture_info_mpeg1or2->slice_count,
271                 (uint32_t)picture_info_mpeg1or2->picture_structure,
272                 (uint32_t)picture_info_mpeg1or2->picture_coding_type,
273                 (uint32_t)picture_info_mpeg1or2->intra_dc_precision,
274                 (uint32_t)picture_info_mpeg1or2->frame_pred_frame_dct,
275                 (uint32_t)picture_info_mpeg1or2->concealment_motion_vectors,
276                 (uint32_t)picture_info_mpeg1or2->intra_vlc_format,
277                 (uint32_t)picture_info_mpeg1or2->alternate_scan,
278                 (uint32_t)picture_info_mpeg1or2->q_scale_type,
279                 (uint32_t)picture_info_mpeg1or2->top_field_first,
280                 (uint32_t)picture_info_mpeg1or2->full_pel_forward_vector,
281                 (uint32_t)picture_info_mpeg1or2->full_pel_backward_vector,
282                 (uint32_t)picture_info_mpeg1or2->f_code[0][0],
283                 (uint32_t)picture_info_mpeg1or2->f_code[0][1],
284                 (uint32_t)picture_info_mpeg1or2->f_code[1][0],
285                 (uint32_t)picture_info_mpeg1or2->f_code[1][1]
286             );
287             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_mpeg1or2->intra_quantizer_matrix); ++i) {
288                 fprintf(
289                     _vdp_cap_data.fp,
290                     "%s%u",
291                     (i == 0) ? "" : ", ",
292                     (uint32_t)picture_info_mpeg1or2->intra_quantizer_matrix[i]
293                 );
294             }
295             fputs("}, {", _vdp_cap_data.fp);
296             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_mpeg1or2->non_intra_quantizer_matrix); ++i) {
297                 fprintf(
298                     _vdp_cap_data.fp,
299                     "%s%u",
300                     (i == 0) ? "" : ", ",
301                     (uint32_t)picture_info_mpeg1or2->non_intra_quantizer_matrix[i]
302                 );
303             }
304             fputs("}}", _vdp_cap_data.fp);
305         }
306         break;
307     case VDP_DECODER_PROFILE_H264_BASELINE:
308     case VDP_DECODER_PROFILE_H264_MAIN:
309     case VDP_DECODER_PROFILE_H264_HIGH:
310         {
311             VdpPictureInfoH264 const * picture_info_h264 =
312                 (VdpPictureInfoH264 const *)picture_info;
313 
314             fprintf(
315                 _vdp_cap_data.fp,
316                 "{%u, {%d, %d}, %d, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %d, %d, %d, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, {",
317                 picture_info_h264->slice_count,
318                 picture_info_h264->field_order_cnt[0],
319                 picture_info_h264->field_order_cnt[1],
320                 (int32_t)picture_info_h264->is_reference,
321                 (uint32_t)picture_info_h264->frame_num,
322                 (uint32_t)picture_info_h264->field_pic_flag,
323                 (uint32_t)picture_info_h264->bottom_field_flag,
324                 (uint32_t)picture_info_h264->num_ref_frames,
325                 (uint32_t)picture_info_h264->mb_adaptive_frame_field_flag,
326                 (uint32_t)picture_info_h264->constrained_intra_pred_flag,
327                 (uint32_t)picture_info_h264->weighted_pred_flag,
328                 (uint32_t)picture_info_h264->weighted_bipred_idc,
329                 (uint32_t)picture_info_h264->frame_mbs_only_flag,
330                 (uint32_t)picture_info_h264->transform_8x8_mode_flag,
331                 (int32_t)picture_info_h264->chroma_qp_index_offset,
332                 (int32_t)picture_info_h264->second_chroma_qp_index_offset,
333                 (int32_t)picture_info_h264->pic_init_qp_minus26,
334                 (uint32_t)picture_info_h264->num_ref_idx_l0_active_minus1,
335                 (uint32_t)picture_info_h264->num_ref_idx_l1_active_minus1,
336                 (uint32_t)picture_info_h264->log2_max_frame_num_minus4,
337                 (uint32_t)picture_info_h264->pic_order_cnt_type,
338                 (uint32_t)picture_info_h264->log2_max_pic_order_cnt_lsb_minus4,
339                 (uint32_t)picture_info_h264->delta_pic_order_always_zero_flag,
340                 (uint32_t)picture_info_h264->direct_8x8_inference_flag,
341                 (uint32_t)picture_info_h264->entropy_coding_mode_flag,
342                 (uint32_t)picture_info_h264->pic_order_present_flag,
343                 (uint32_t)picture_info_h264->deblocking_filter_control_present_flag,
344                 (uint32_t)picture_info_h264->redundant_pic_cnt_present_flag
345             );
346             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_h264->scaling_lists_4x4); ++i) {
347                 fputs((i == 0) ? "{" : "}, {", _vdp_cap_data.fp);
348                 for (uint32_t j = 0; j < _VDP_TRACE_ARSIZE(picture_info_h264->scaling_lists_4x4[0]); ++j) {
349                     fprintf(
350                         _vdp_cap_data.fp,
351                         "%s%u",
352                         (j == 0) ? "" : ", ",
353                         (uint32_t)picture_info_h264->scaling_lists_4x4[i][j]
354                     );
355                 }
356             }
357             fputs("}}, {", _vdp_cap_data.fp);
358             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_h264->scaling_lists_8x8); ++i) {
359                 fputs((i == 0) ? "{" : "}, {", _vdp_cap_data.fp);
360                 for (uint32_t j = 0; j < _VDP_TRACE_ARSIZE(picture_info_h264->scaling_lists_8x8[0]); ++j) {
361                     fprintf(
362                         _vdp_cap_data.fp,
363                         "%s%u",
364                         (j == 0) ? "" : ", ",
365                         (uint32_t)picture_info_h264->scaling_lists_8x8[i][j]
366                     );
367                 }
368             }
369             fputs("}}, {", _vdp_cap_data.fp);
370             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_h264->referenceFrames); ++i) {
371                 VdpReferenceFrameH264 const * rf = &(picture_info_h264->referenceFrames[i]);
372                 fprintf(
373                     _vdp_cap_data.fp,
374                     "%s{%u, %d, %d, %d, {%d, %d}, %u}",
375                     (i == 0) ? "" : ", ",
376                     rf->surface,
377                     (int32_t)rf->is_long_term,
378                     (int32_t)rf->top_is_reference,
379                     (int32_t)rf->bottom_is_reference,
380                     (int32_t)rf->field_order_cnt[0],
381                     (int32_t)rf->field_order_cnt[1],
382                     (uint32_t)rf->frame_idx
383                 );
384             }
385             fputs("}}", _vdp_cap_data.fp);
386         }
387         break;
388     case VDP_DECODER_PROFILE_VC1_SIMPLE:
389     case VDP_DECODER_PROFILE_VC1_MAIN:
390     case VDP_DECODER_PROFILE_VC1_ADVANCED:
391         {
392             VdpPictureInfoVC1 const * picture_info_vc1 =
393                 (VdpPictureInfoVC1 const *)picture_info;
394 
395             fprintf(
396                 _vdp_cap_data.fp,
397                 "{%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u}",
398                 picture_info_vc1->forward_reference,
399                 picture_info_vc1->backward_reference,
400                 picture_info_vc1->slice_count,
401                 (uint32_t)picture_info_vc1->picture_type,
402                 (uint32_t)picture_info_vc1->frame_coding_mode,
403                 (uint32_t)picture_info_vc1->postprocflag,
404                 (uint32_t)picture_info_vc1->pulldown,
405                 (uint32_t)picture_info_vc1->interlace,
406                 (uint32_t)picture_info_vc1->tfcntrflag,
407                 (uint32_t)picture_info_vc1->finterpflag,
408                 (uint32_t)picture_info_vc1->psf,
409                 (uint32_t)picture_info_vc1->dquant,
410                 (uint32_t)picture_info_vc1->panscan_flag,
411                 (uint32_t)picture_info_vc1->refdist_flag,
412                 (uint32_t)picture_info_vc1->quantizer,
413                 (uint32_t)picture_info_vc1->extended_mv,
414                 (uint32_t)picture_info_vc1->extended_dmv,
415                 (uint32_t)picture_info_vc1->overlap,
416                 (uint32_t)picture_info_vc1->vstransform,
417                 (uint32_t)picture_info_vc1->loopfilter,
418                 (uint32_t)picture_info_vc1->fastuvmc,
419                 (uint32_t)picture_info_vc1->range_mapy_flag,
420                 (uint32_t)picture_info_vc1->range_mapy,
421                 (uint32_t)picture_info_vc1->range_mapuv_flag,
422                 (uint32_t)picture_info_vc1->range_mapuv,
423                 (uint32_t)picture_info_vc1->multires,
424                 (uint32_t)picture_info_vc1->syncmarker,
425                 (uint32_t)picture_info_vc1->rangered,
426                 (uint32_t)picture_info_vc1->maxbframes,
427                 (uint32_t)picture_info_vc1->deblockEnable,
428                 (uint32_t)picture_info_vc1->pquant
429             );
430         }
431         break;
432     case VDP_DECODER_PROFILE_MPEG4_PART2_SP:
433     case VDP_DECODER_PROFILE_MPEG4_PART2_ASP:
434     case VDP_DECODER_PROFILE_DIVX4_QMOBILE:
435     case VDP_DECODER_PROFILE_DIVX4_MOBILE:
436     case VDP_DECODER_PROFILE_DIVX4_HOME_THEATER:
437     case VDP_DECODER_PROFILE_DIVX4_HD_1080P:
438     case VDP_DECODER_PROFILE_DIVX5_QMOBILE:
439     case VDP_DECODER_PROFILE_DIVX5_MOBILE:
440     case VDP_DECODER_PROFILE_DIVX5_HOME_THEATER:
441     case VDP_DECODER_PROFILE_DIVX5_HD_1080P:
442         {
443             VdpPictureInfoMPEG4Part2 const * picture_info_mpeg4 =
444                 (VdpPictureInfoMPEG4Part2 const *)picture_info;
445 
446             fprintf(
447                 _vdp_cap_data.fp,
448                 "{%u, %u, {%d, %d}, {%d, %d}, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, {",
449                 picture_info_mpeg4->forward_reference,
450                 picture_info_mpeg4->backward_reference,
451                 (int32_t)picture_info_mpeg4->trd[0],
452                 (int32_t)picture_info_mpeg4->trd[1],
453                 (int32_t)picture_info_mpeg4->trb[0],
454                 (int32_t)picture_info_mpeg4->trb[1],
455                 (uint32_t)picture_info_mpeg4->vop_time_increment_resolution,
456                 (uint32_t)picture_info_mpeg4->vop_coding_type,
457                 (uint32_t)picture_info_mpeg4->vop_fcode_forward,
458                 (uint32_t)picture_info_mpeg4->vop_fcode_backward,
459                 (uint32_t)picture_info_mpeg4->resync_marker_disable,
460                 (uint32_t)picture_info_mpeg4->interlaced,
461                 (uint32_t)picture_info_mpeg4->quant_type,
462                 (uint32_t)picture_info_mpeg4->quarter_sample,
463                 (uint32_t)picture_info_mpeg4->short_video_header,
464                 (uint32_t)picture_info_mpeg4->rounding_control,
465                 (uint32_t)picture_info_mpeg4->alternate_vertical_scan_flag,
466                 (uint32_t)picture_info_mpeg4->top_field_first
467             );
468             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_mpeg4->intra_quantizer_matrix); ++i) {
469                 fprintf(
470                     _vdp_cap_data.fp,
471                     "%s%u",
472                     (i == 0) ? "" : ", ",
473                     (uint32_t)picture_info_mpeg4->intra_quantizer_matrix[i]
474                 );
475             }
476             fputs("}, {", _vdp_cap_data.fp);
477             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_mpeg4->non_intra_quantizer_matrix); ++i) {
478                 fprintf(
479                     _vdp_cap_data.fp,
480                     "%s%u",
481                     (i == 0) ? "" : ", ",
482                     (uint32_t)picture_info_mpeg4->non_intra_quantizer_matrix[i]
483                 );
484             }
485             fputs("}}", _vdp_cap_data.fp);
486         }
487         break;
488     case VDP_DECODER_PROFILE_HEVC_MAIN:
489     case VDP_DECODER_PROFILE_HEVC_MAIN_10:
490     case VDP_DECODER_PROFILE_HEVC_MAIN_STILL:
491     case VDP_DECODER_PROFILE_HEVC_MAIN_12:
492     case VDP_DECODER_PROFILE_HEVC_MAIN_444:
493         {
494             VdpPictureInfoHEVC const * picture_info_hevc =
495                 (VdpPictureInfoHEVC const *)picture_info;
496 
497             fprintf(
498                 _vdp_cap_data.fp,
499                 "{%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, {",
500                 (uint32_t)picture_info_hevc->chroma_format_idc,
501                 (uint32_t)picture_info_hevc->separate_colour_plane_flag,
502                 (uint32_t)picture_info_hevc->pic_width_in_luma_samples,
503                 (uint32_t)picture_info_hevc->pic_height_in_luma_samples,
504                 (uint32_t)picture_info_hevc->bit_depth_luma_minus8,
505                 (uint32_t)picture_info_hevc->bit_depth_chroma_minus8,
506                 (uint32_t)picture_info_hevc->log2_max_pic_order_cnt_lsb_minus4,
507                 (uint32_t)picture_info_hevc->sps_max_dec_pic_buffering_minus1,
508                 (uint32_t)picture_info_hevc->log2_min_luma_coding_block_size_minus3,
509                 (uint32_t)picture_info_hevc->log2_diff_max_min_luma_coding_block_size,
510                 (uint32_t)picture_info_hevc->log2_min_transform_block_size_minus2,
511                 (uint32_t)picture_info_hevc->log2_diff_max_min_transform_block_size,
512                 (uint32_t)picture_info_hevc->max_transform_hierarchy_depth_inter,
513                 (uint32_t)picture_info_hevc->max_transform_hierarchy_depth_intra,
514                 (uint32_t)picture_info_hevc->scaling_list_enabled_flag
515             );
516             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList4x4); ++i) {
517                 fputs((i == 0) ? "{" : "}, {", _vdp_cap_data.fp);
518                 for (uint32_t j = 0; j < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList4x4[0]); ++j) {
519                     fprintf(
520                         _vdp_cap_data.fp,
521                         "%s%u",
522                         (j == 0) ? "" : ", ",
523                         (uint32_t)picture_info_hevc->ScalingList4x4[i][j]
524                     );
525                 }
526             }
527             fputs("}}, {", _vdp_cap_data.fp);
528             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList8x8); ++i) {
529                 fputs((i == 0) ? "{" : "}, {", _vdp_cap_data.fp);
530                 for (uint32_t j = 0; j < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList8x8[0]); ++j) {
531                     fprintf(
532                         _vdp_cap_data.fp,
533                         "%s%u",
534                         (j == 0) ? "" : ", ",
535                         (uint32_t)picture_info_hevc->ScalingList8x8[i][j]
536                     );
537                 }
538             }
539             fputs("}}, {", _vdp_cap_data.fp);
540             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList16x16); ++i) {
541                 fputs((i == 0) ? "{" : "}, {", _vdp_cap_data.fp);
542                 for (uint32_t j = 0; j < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList16x16[0]); ++j) {
543                     fprintf(
544                         _vdp_cap_data.fp,
545                         "%s%u",
546                         (j == 0) ? "" : ", ",
547                         (uint32_t)picture_info_hevc->ScalingList16x16[i][j]
548                     );
549                 }
550             }
551             fputs("}}, {", _vdp_cap_data.fp);
552             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList32x32); ++i) {
553                 fputs((i == 0) ? "{" : "}, {", _vdp_cap_data.fp);
554                 for (uint32_t j = 0; j < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingList32x32[0]); ++j) {
555                     fprintf(
556                         _vdp_cap_data.fp,
557                         "%s%u",
558                         (j == 0) ? "" : ", ",
559                         (uint32_t)picture_info_hevc->ScalingList32x32[i][j]
560                     );
561                 }
562             }
563             fputs("}}, {", _vdp_cap_data.fp);
564             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingListDCCoeff16x16); ++i) {
565                 fprintf(
566                     _vdp_cap_data.fp,
567                     "%s%u",
568                     (i == 0) ? "" : ", ",
569                     (uint32_t)picture_info_hevc->ScalingListDCCoeff16x16[i]
570                 );
571             }
572             fputs("}, {", _vdp_cap_data.fp);
573             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->ScalingListDCCoeff32x32); ++i) {
574                 fprintf(
575                     _vdp_cap_data.fp,
576                     "%s%u",
577                     (i == 0) ? "" : ", ",
578                     (uint32_t)picture_info_hevc->ScalingListDCCoeff32x32[i]
579                 );
580             }
581             fputs("}, ", _vdp_cap_data.fp);
582             fprintf(
583                 _vdp_cap_data.fp,
584                 "%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %d, %u, %u, %u, %u, %d, %d, %u, %u, %u, %u, %u, %u, %u, %u, %u, {",
585                 (uint32_t)picture_info_hevc->amp_enabled_flag,
586                 (uint32_t)picture_info_hevc->sample_adaptive_offset_enabled_flag,
587                 (uint32_t)picture_info_hevc->pcm_enabled_flag,
588                 (uint32_t)picture_info_hevc->pcm_sample_bit_depth_luma_minus1,
589                 (uint32_t)picture_info_hevc->pcm_sample_bit_depth_chroma_minus1,
590                 (uint32_t)picture_info_hevc->log2_min_pcm_luma_coding_block_size_minus3,
591                 (uint32_t)picture_info_hevc->log2_diff_max_min_pcm_luma_coding_block_size,
592                 (uint32_t)picture_info_hevc->pcm_loop_filter_disabled_flag,
593                 (uint32_t)picture_info_hevc->num_short_term_ref_pic_sets,
594                 (uint32_t)picture_info_hevc->long_term_ref_pics_present_flag,
595                 (uint32_t)picture_info_hevc->num_long_term_ref_pics_sps,
596                 (uint32_t)picture_info_hevc->sps_temporal_mvp_enabled_flag,
597                 (uint32_t)picture_info_hevc->strong_intra_smoothing_enabled_flag,
598                 (uint32_t)picture_info_hevc->dependent_slice_segments_enabled_flag,
599                 (uint32_t)picture_info_hevc->output_flag_present_flag,
600                 (uint32_t)picture_info_hevc->num_extra_slice_header_bits,
601                 (uint32_t)picture_info_hevc->sign_data_hiding_enabled_flag,
602                 (uint32_t)picture_info_hevc->cabac_init_present_flag,
603                 (uint32_t)picture_info_hevc->num_ref_idx_l0_default_active_minus1,
604                 (uint32_t)picture_info_hevc->num_ref_idx_l1_default_active_minus1,
605                 (int32_t)picture_info_hevc->init_qp_minus26,
606                 (uint32_t)picture_info_hevc->constrained_intra_pred_flag,
607                 (uint32_t)picture_info_hevc->transform_skip_enabled_flag,
608                 (uint32_t)picture_info_hevc->cu_qp_delta_enabled_flag,
609                 (uint32_t)picture_info_hevc->diff_cu_qp_delta_depth,
610                 (int32_t)picture_info_hevc->pps_cb_qp_offset,
611                 (int32_t)picture_info_hevc->pps_cr_qp_offset,
612                 (uint32_t)picture_info_hevc->pps_slice_chroma_qp_offsets_present_flag,
613                 (uint32_t)picture_info_hevc->weighted_pred_flag,
614                 (uint32_t)picture_info_hevc->weighted_bipred_flag,
615                 (uint32_t)picture_info_hevc->transquant_bypass_enabled_flag,
616                 (uint32_t)picture_info_hevc->tiles_enabled_flag,
617                 (uint32_t)picture_info_hevc->entropy_coding_sync_enabled_flag,
618                 (uint32_t)picture_info_hevc->num_tile_columns_minus1,
619                 (uint32_t)picture_info_hevc->num_tile_rows_minus1,
620                 (uint32_t)picture_info_hevc->uniform_spacing_flag
621             );
622             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->column_width_minus1); ++i) {
623                 fprintf(
624                     _vdp_cap_data.fp,
625                     "%s%u",
626                     (i == 0) ? "" : ", ",
627                     (uint32_t)picture_info_hevc->column_width_minus1[i]
628                 );
629             }
630             fputs("}, {", _vdp_cap_data.fp);
631             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->row_height_minus1); ++i) {
632                 fprintf(
633                     _vdp_cap_data.fp,
634                     "%s%u",
635                     (i == 0) ? "" : ", ",
636                     (uint32_t)picture_info_hevc->row_height_minus1[i]
637                 );
638             }
639             fputs("}, ", _vdp_cap_data.fp);
640             fprintf(
641                 _vdp_cap_data.fp,
642                 "%u, %u, %u, %u, %u, %d, %d, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %d, {",
643                 (uint32_t)picture_info_hevc->loop_filter_across_tiles_enabled_flag,
644                 (uint32_t)picture_info_hevc->pps_loop_filter_across_slices_enabled_flag,
645                 (uint32_t)picture_info_hevc->deblocking_filter_control_present_flag,
646                 (uint32_t)picture_info_hevc->deblocking_filter_override_enabled_flag,
647                 (uint32_t)picture_info_hevc->pps_deblocking_filter_disabled_flag,
648                 (int32_t)picture_info_hevc->pps_beta_offset_div2,
649                 (int32_t)picture_info_hevc->pps_tc_offset_div2,
650                 (uint32_t)picture_info_hevc->lists_modification_present_flag,
651                 (uint32_t)picture_info_hevc->log2_parallel_merge_level_minus2,
652                 (uint32_t)picture_info_hevc->slice_segment_header_extension_present_flag,
653                 (uint32_t)picture_info_hevc->IDRPicFlag,
654                 (uint32_t)picture_info_hevc->RAPPicFlag,
655                 (uint32_t)picture_info_hevc->CurrRpsIdx,
656                 (uint32_t)picture_info_hevc->NumPocTotalCurr,
657                 (uint32_t)picture_info_hevc->NumDeltaPocsOfRefRpsIdx,
658                 (uint32_t)picture_info_hevc->NumShortTermPictureSliceHeaderBits,
659                 (uint32_t)picture_info_hevc->NumLongTermPictureSliceHeaderBits,
660                 (int32_t)picture_info_hevc->CurrPicOrderCntVal
661             );
662             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->RefPics); ++i) {
663                 fprintf(
664                     _vdp_cap_data.fp,
665                     "%s%u",
666                     (i == 0) ? "" : ", ",
667                     (uint32_t)picture_info_hevc->RefPics[i]
668                 );
669             }
670             fputs("}, {", _vdp_cap_data.fp);
671             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->PicOrderCntVal); ++i) {
672                 fprintf(
673                     _vdp_cap_data.fp,
674                     "%s%d",
675                     (i == 0) ? "" : ", ",
676                     (int32_t)picture_info_hevc->PicOrderCntVal[i]
677                 );
678             }
679             fputs("}, {", _vdp_cap_data.fp);
680             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->IsLongTerm); ++i) {
681                 fprintf(
682                     _vdp_cap_data.fp,
683                     "%s%u",
684                     (i == 0) ? "" : ", ",
685                     (uint32_t)picture_info_hevc->IsLongTerm[i]
686                 );
687             }
688             fputs("}, ", _vdp_cap_data.fp);
689             fprintf(
690                 _vdp_cap_data.fp,
691                 "%u, %u, %u, {",
692                 (uint32_t)picture_info_hevc->NumPocStCurrBefore,
693                 (uint32_t)picture_info_hevc->NumPocStCurrAfter,
694                 (uint32_t)picture_info_hevc->NumPocLtCurr
695             );
696             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->RefPicSetStCurrBefore); ++i) {
697                 fprintf(
698                     _vdp_cap_data.fp,
699                     "%s%u",
700                     (i == 0) ? "" : ", ",
701                     (uint32_t)picture_info_hevc->RefPicSetStCurrBefore[i]
702                 );
703             }
704             fputs("}, {", _vdp_cap_data.fp);
705             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->RefPicSetStCurrAfter); ++i) {
706                 fprintf(
707                     _vdp_cap_data.fp,
708                     "%s%u",
709                     (i == 0) ? "" : ", ",
710                     (uint32_t)picture_info_hevc->RefPicSetStCurrAfter[i]
711                 );
712             }
713             fputs("}, {", _vdp_cap_data.fp);
714             for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_hevc->RefPicSetLtCurr); ++i) {
715                 fprintf(
716                     _vdp_cap_data.fp,
717                     "%s%u",
718                     (i == 0) ? "" : ", ",
719                     (uint32_t)picture_info_hevc->RefPicSetLtCurr[i]
720                 );
721             }
722             fputs("}}", _vdp_cap_data.fp);
723         }
724         break;
725     default:
726         fputs("{...}", _vdp_cap_data.fp);
727         break;
728     }
729 }
730 
_vdp_cap_dump_video_mixer_parameter_value(VdpVideoMixerParameter parameter,void const * value)731 static void _vdp_cap_dump_video_mixer_parameter_value(
732     VdpVideoMixerParameter parameter,
733     void const *           value
734 )
735 {
736     switch (parameter) {
737     case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
738     case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
739     case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
740     case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
741         if (!value) {
742             fputs("???", _vdp_cap_data.fp);
743         }
744         else {
745             fprintf(_vdp_cap_data.fp, "%u", *(uint32_t const *)value);
746         }
747         break;
748     default:
749         fputs("???", _vdp_cap_data.fp);
750         break;
751     }
752 }
753 
_vdp_cap_dump_video_mixer_attribute_value(VdpVideoMixerAttribute attribute,void const * value,bool get_operation)754 static void _vdp_cap_dump_video_mixer_attribute_value(
755     VdpVideoMixerAttribute attribute,
756     void const *           value,
757     bool                   get_operation
758 )
759 {
760     if (!value) {
761         fputs("NULL", _vdp_cap_data.fp);
762         return;
763     }
764 
765     switch (attribute) {
766     case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
767         _vdp_cap_dump_color((VdpColor const *)value);
768         break;
769     case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
770         {
771             VdpCSCMatrix const * ptr;
772 
773             // For some objects, the "default" value is a NULL pointer.
774             // So, VdpVideoMixerGetAttributeValues expects a double pointer to
775             // the value, so it can either fill in the value, or NULL out the
776             // pointer.
777             if (get_operation) {
778                 ptr = *(VdpCSCMatrix const * const *)value;
779             }
780             else {
781                 ptr = (VdpCSCMatrix const *)value;
782             }
783             _vdp_cap_dump_csc_matrix(ptr);
784         }
785         break;
786     case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
787     case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
788     case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
789     case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
790         fprintf(_vdp_cap_data.fp, "%f", *(float const *)value);
791         break;
792     case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
793         fprintf(_vdp_cap_data.fp, "%u", *(uint8_t const *)value);
794         break;
795     default:
796         fputs("???", _vdp_cap_data.fp);
797         break;
798     }
799 }
800 
_vdp_cap_dump_uint8_t_stream(uint32_t count,uint8_t const * values)801 static void _vdp_cap_dump_uint8_t_stream(
802     uint32_t        count,
803     uint8_t const * values
804 )
805 {
806     if (!values) {
807         fputs("NULL", _vdp_cap_data.fp);
808         return;
809     }
810 
811     fputs("{", _vdp_cap_data.fp);
812     while (count) {
813         fprintf(
814             _vdp_cap_data.fp,
815             "%02x",
816             values[0]
817         );
818 
819         --count;
820         ++values;
821     }
822     fputs("}", _vdp_cap_data.fp);
823 }
824 
_vdp_cap_dump_uint32_t_stream(uint32_t count,uint32_t const * values)825 static void _vdp_cap_dump_uint32_t_stream(
826     uint32_t         count,
827     uint32_t const * values
828 )
829 {
830     if (!values) {
831         fputs("NULL", _vdp_cap_data.fp);
832         return;
833     }
834 
835     fputs("{", _vdp_cap_data.fp);
836     while (count) {
837         fprintf(
838             _vdp_cap_data.fp,
839             "%08x%s",
840             values[0],
841             (count > 1) ? " " : ""
842         );
843 
844         --count;
845         ++values;
846     }
847     fputs("}", _vdp_cap_data.fp);
848 }
849 
850 struct _VdpcapPlane {
851     void const * data;
852     uint32_t     pitch;
853     uint32_t     item_count;
854     uint32_t     item_size;
855     uint32_t     lines;
856 };
857 
858 typedef void _VdpcapPlaneDumper(uint32_t count, void const * values);
859 
_vdp_cap_dump_plane_list(uint32_t plane_count,_VdpcapPlane const * planes)860 static void _vdp_cap_dump_plane_list(
861     uint32_t             plane_count,
862     _VdpcapPlane const * planes
863 )
864 {
865     if (!planes) {
866         fputs("NULL", _vdp_cap_data.fp);
867         return;
868     }
869 
870     fputs("{", _vdp_cap_data.fp);
871     while (plane_count) {
872         uint32_t lines = planes[0].lines;
873 
874         _VdpcapPlaneDumper * dumper;
875         if (planes[0].item_size == 4) {
876             dumper = (_VdpcapPlaneDumper*)_vdp_cap_dump_uint32_t_stream;
877         }
878         else {
879             dumper = (_VdpcapPlaneDumper*)_vdp_cap_dump_uint8_t_stream;
880         }
881 
882         fputs("{", _vdp_cap_data.fp);
883         uint8_t const * ptr = (uint8_t const *)planes[0].data;
884         while (lines) {
885             dumper(planes[0].item_count, ptr);
886             if (lines > 1) {
887                 fputs(", ", _vdp_cap_data.fp);
888             }
889 
890             ptr += planes[0].pitch;
891             --lines;
892         }
893         fputs("}", _vdp_cap_data.fp);
894 
895         if (plane_count > 1) {
896             fputs(", ", _vdp_cap_data.fp);
897         }
898 
899         --plane_count;
900         ++planes;
901     }
902     fputs("}", _vdp_cap_data.fp);
903 }
904 
_vdp_cap_init_planes_for_ycbcr_format(uint32_t * plane_count,_VdpcapPlane * planes,VdpYCbCrFormat format,uint32_t region_width,uint32_t region_height)905 static bool _vdp_cap_init_planes_for_ycbcr_format(
906     uint32_t *     plane_count,
907     _VdpcapPlane * planes,
908     VdpYCbCrFormat format,
909     uint32_t       region_width,
910     uint32_t       region_height
911 )
912 {
913     switch (format) {
914     case VDP_YCBCR_FORMAT_NV12:
915         if (*plane_count < 2) {
916             return false;
917         }
918         *plane_count = 2;
919         planes[0].item_size = 1;
920         planes[0].item_count = region_width;
921         planes[0].lines = region_height;
922         planes[1].item_size = 1;
923         planes[1].item_count = region_width;
924         planes[1].lines = region_height / 2;
925         break;
926     case VDP_YCBCR_FORMAT_YV12:
927         if (*plane_count < 3) {
928             return false;
929         }
930         *plane_count = 3;
931         planes[0].item_size = 1;
932         planes[0].item_count = region_width;
933         planes[0].lines = region_height;
934         planes[1].item_size = 1;
935         planes[1].item_count = region_width / 2;
936         planes[1].lines = region_height / 2;
937         planes[2].item_size = 1;
938         planes[2].item_count = region_width / 2;
939         planes[2].lines = region_height / 2;
940         break;
941     case VDP_YCBCR_FORMAT_UYVY:
942     case VDP_YCBCR_FORMAT_YUYV:
943         if (*plane_count < 1) {
944             return false;
945         }
946         *plane_count = 1;
947         planes[0].item_size = 1;
948         planes[0].item_count = region_width * 2;
949         planes[0].lines = region_height;
950         break;
951     case VDP_YCBCR_FORMAT_Y8U8V8A8:
952     case VDP_YCBCR_FORMAT_V8U8Y8A8:
953         if (*plane_count < 1) {
954             return false;
955         }
956         *plane_count = 1;
957         planes[0].item_size = 4;
958         planes[0].item_count = region_width;
959         planes[0].lines = region_height;
960         break;
961     default:
962         return false;
963     }
964 
965     return true;
966 }
967 
_vdp_cap_init_planes_for_rgba_format(uint32_t * plane_count,_VdpcapPlane * planes,VdpRGBAFormat format,uint32_t region_width,uint32_t region_height)968 static bool _vdp_cap_init_planes_for_rgba_format(
969     uint32_t *     plane_count,
970     _VdpcapPlane * planes,
971     VdpRGBAFormat  format,
972     uint32_t       region_width,
973     uint32_t       region_height
974 )
975 {
976     switch (format) {
977     case VDP_RGBA_FORMAT_B8G8R8A8:
978     case VDP_RGBA_FORMAT_R8G8B8A8:
979     case VDP_RGBA_FORMAT_R10G10B10A2:
980     case VDP_RGBA_FORMAT_B10G10R10A2:
981         if (*plane_count < 1) {
982             return false;
983         }
984         *plane_count = 1;
985         planes[0].item_size = 4;
986         break;
987     case VDP_RGBA_FORMAT_A8:
988         if (*plane_count < 1) {
989             return false;
990         }
991         *plane_count = 1;
992         planes[0].item_size = 1;
993         break;
994     default:
995         return false;
996     }
997     planes[0].item_count = region_width;
998     planes[0].lines = region_height;
999 
1000     return true;
1001 }
1002 
_vdp_cap_init_planes_for_indexed_format(uint32_t * plane_count,_VdpcapPlane * planes,VdpIndexedFormat format,uint32_t region_width,uint32_t region_height)1003 static bool _vdp_cap_init_planes_for_indexed_format(
1004     uint32_t *       plane_count,
1005     _VdpcapPlane *   planes,
1006     VdpIndexedFormat format,
1007     uint32_t         region_width,
1008     uint32_t         region_height
1009 )
1010 {
1011     uint32_t width_multiplier;
1012 
1013     switch (format) {
1014     case VDP_INDEXED_FORMAT_A4I4:
1015     case VDP_INDEXED_FORMAT_I4A4:
1016         width_multiplier = 1;
1017         break;
1018     case VDP_INDEXED_FORMAT_A8I8:
1019     case VDP_INDEXED_FORMAT_I8A8:
1020         width_multiplier = 2;
1021         break;
1022     default:
1023         return false;
1024     }
1025 
1026     if (*plane_count < 1) {
1027         return false;
1028     }
1029     *plane_count = 1;
1030     planes[0].item_size = 1;
1031     planes[0].item_count = region_width * width_multiplier;
1032     planes[0].lines = region_height;
1033 
1034     return true;
1035 }
1036 
_vdp_cap_init_planes_adapt_format_bits_ycbcr(uint32_t * plane_count,_VdpcapPlane * planes,uint32_t surface_format,uint32_t bits_format,uint32_t region_width,uint32_t region_height)1037 static bool _vdp_cap_init_planes_adapt_format_bits_ycbcr(
1038     uint32_t *     plane_count,
1039     _VdpcapPlane * planes,
1040     uint32_t       surface_format,
1041     uint32_t       bits_format,
1042     uint32_t       region_width,
1043     uint32_t       region_height
1044 )
1045 {
1046     return _vdp_cap_init_planes_for_ycbcr_format(
1047         plane_count,
1048         planes,
1049         bits_format,
1050         region_width,
1051         region_height
1052     );
1053 }
1054 
_vdp_cap_init_planes_adapt_format_surface_rgba(uint32_t * plane_count,_VdpcapPlane * planes,uint32_t surface_format,uint32_t bits_format,uint32_t region_width,uint32_t region_height)1055 static bool _vdp_cap_init_planes_adapt_format_surface_rgba(
1056     uint32_t *     plane_count,
1057     _VdpcapPlane * planes,
1058     uint32_t       surface_format,
1059     uint32_t       bits_format,
1060     uint32_t       region_width,
1061     uint32_t       region_height
1062 )
1063 {
1064     return _vdp_cap_init_planes_for_rgba_format(
1065         plane_count,
1066         planes,
1067         surface_format,
1068         region_width,
1069         region_height
1070     );
1071 }
1072 
_vdp_cap_init_planes_adapt_format_bits_indexed(uint32_t * plane_count,_VdpcapPlane * planes,uint32_t surface_format,uint32_t bits_format,uint32_t region_width,uint32_t region_height)1073 static bool _vdp_cap_init_planes_adapt_format_bits_indexed(
1074     uint32_t *     plane_count,
1075     _VdpcapPlane * planes,
1076     uint32_t       surface_format,
1077     uint32_t       bits_format,
1078     uint32_t       region_width,
1079     uint32_t       region_height
1080 )
1081 {
1082     return _vdp_cap_init_planes_for_indexed_format(
1083         plane_count,
1084         planes,
1085         bits_format,
1086         region_width,
1087         region_height
1088     );
1089 }
1090 
_vdp_cap_init_planes_adapt_surface_video(uint32_t surface,uint32_t * surface_format,uint32_t * width,uint32_t * height)1091 static bool _vdp_cap_init_planes_adapt_surface_video(
1092     uint32_t   surface,
1093     uint32_t * surface_format,
1094     uint32_t * width,
1095     uint32_t * height
1096 )
1097 {
1098     VdpStatus ret;
1099 
1100     VdpChromaType chroma_type;
1101     ret = _vdp_cap_data.vdp_video_surface_get_parameters(
1102         surface,
1103         &chroma_type,
1104         width,
1105         height
1106     );
1107     if (ret != VDP_STATUS_OK) {
1108         return false;
1109     }
1110 
1111     *surface_format = chroma_type;
1112 
1113     return true;
1114 }
1115 
_vdp_cap_init_planes_adapt_surface_output(uint32_t surface,uint32_t * surface_format,uint32_t * width,uint32_t * height)1116 static bool _vdp_cap_init_planes_adapt_surface_output(
1117     uint32_t   surface,
1118     uint32_t * surface_format,
1119     uint32_t * width,
1120     uint32_t * height
1121 )
1122 {
1123     VdpStatus ret;
1124 
1125     VdpRGBAFormat rgba_format;
1126     ret = _vdp_cap_data.vdp_output_surface_get_parameters(
1127         surface,
1128         &rgba_format,
1129         width,
1130         height
1131     );
1132     if (ret != VDP_STATUS_OK) {
1133         return false;
1134     }
1135 
1136     *surface_format = rgba_format;
1137 
1138     return true;
1139 }
1140 
_vdp_cap_init_planes_adapt_surface_bitmap(uint32_t surface,uint32_t * surface_format,uint32_t * width,uint32_t * height)1141 static bool _vdp_cap_init_planes_adapt_surface_bitmap(
1142     uint32_t   surface,
1143     uint32_t * surface_format,
1144     uint32_t * width,
1145     uint32_t * height
1146 )
1147 {
1148     VdpStatus ret;
1149 
1150     VdpRGBAFormat rgba_format;
1151     VdpBool       frequently_accessed;
1152     ret = _vdp_cap_data.vdp_bitmap_surface_get_parameters(
1153         surface,
1154         &rgba_format,
1155         width,
1156         height,
1157         &frequently_accessed
1158     );
1159     if (ret != VDP_STATUS_OK) {
1160         return false;
1161     }
1162 
1163     *surface_format = rgba_format;
1164 
1165     return true;
1166 }
1167 
1168 typedef bool _Vdpcap_Init_Planes_Adapt_Format(
1169     uint32_t *     plane_count,
1170     _VdpcapPlane * planes,
1171     uint32_t       surface_format,
1172     uint32_t       bits_format,
1173     uint32_t       region_width,
1174     uint32_t       region_height
1175 );
1176 
1177 typedef bool _Vdpcap_Init_Planes_Adapt_Surface(
1178     uint32_t   surface,
1179     uint32_t * surface_format,
1180     uint32_t * width,
1181     uint32_t * height
1182 );
1183 
_vdp_cap_init_planes(uint32_t surface,void const * const * source_data,uint32_t const * source_pitches,VdpRect const * destination_rect,uint32_t * plane_count,_VdpcapPlane * planes,_Vdpcap_Init_Planes_Adapt_Surface * adapt_surface,_Vdpcap_Init_Planes_Adapt_Format * adapt_format,uint32_t adapt_format_bits_format)1184 static bool _vdp_cap_init_planes(
1185     uint32_t                            surface,
1186     void const * const *                source_data,
1187     uint32_t const *                    source_pitches,
1188     VdpRect const *                     destination_rect,
1189     uint32_t *                          plane_count,
1190     _VdpcapPlane *                      planes,
1191     _Vdpcap_Init_Planes_Adapt_Surface * adapt_surface,
1192     _Vdpcap_Init_Planes_Adapt_Format *  adapt_format,
1193     uint32_t                            adapt_format_bits_format
1194 )
1195 {
1196     bool ok;
1197 
1198     if (!source_data || !source_pitches) {
1199         return false;
1200     }
1201 
1202     if (_vdp_cap_data.level < LEVEL_PARAMS) {
1203         return false;
1204     }
1205 
1206     uint32_t surface_format;
1207     uint32_t width;
1208     uint32_t height;
1209     ok = adapt_surface(
1210         surface,
1211         &surface_format,
1212         &width,
1213         &height
1214     );
1215     if (!ok) {
1216         return false;
1217     }
1218 
1219     if (destination_rect) {
1220         width = delta<uint32_t>(destination_rect->x0, destination_rect->x1);
1221         height = delta<uint32_t>(destination_rect->y0, destination_rect->y1);
1222     }
1223 
1224     ok = adapt_format(
1225         plane_count,
1226         planes,
1227         surface_format,
1228         adapt_format_bits_format,
1229         width,
1230         height
1231     );
1232     if (!ok) {
1233         return false;
1234     }
1235 
1236     for (uint32_t i = 0; i < *plane_count; ++i) {
1237         planes[i].data = source_data[i];
1238         planes[i].pitch = source_pitches[i];
1239     }
1240 
1241     return true;
1242 }
1243 
_vdp_cap_dump_bool_list(uint32_t count,VdpBool const * values)1244 static void _vdp_cap_dump_bool_list(
1245     uint32_t        count,
1246     VdpBool const * values
1247 )
1248 {
1249     if (!values) {
1250         fputs("NULL", _vdp_cap_data.fp);
1251         return;
1252     }
1253 
1254     fputs("{", _vdp_cap_data.fp);
1255     while (count) {
1256         fprintf(
1257             _vdp_cap_data.fp,
1258             "%d%s",
1259             (int)values[0],
1260             (count > 1) ? ", " : ""
1261         );
1262 
1263         --count;
1264         ++values;
1265     }
1266     fputs("}", _vdp_cap_data.fp);
1267 }
1268 
_vdp_cap_dump_void_pointer_list(uint32_t count,void const * const * values,bool zero_count_question_marks)1269 static void _vdp_cap_dump_void_pointer_list(
1270     uint32_t             count,
1271     void const * const * values,
1272     bool                 zero_count_question_marks
1273 )
1274 {
1275     if (!values) {
1276         fputs("NULL", _vdp_cap_data.fp);
1277         return;
1278     }
1279 
1280     fputs("{", _vdp_cap_data.fp);
1281     if (!count && zero_count_question_marks) {
1282         fputs("???", _vdp_cap_data.fp);
1283     }
1284     while (count) {
1285         fprintf(
1286             _vdp_cap_data.fp,
1287             "%p%s",
1288             values[0],
1289             (count > 1) ? ", " : ""
1290         );
1291 
1292         --count;
1293         ++values;
1294     }
1295     fputs("}", _vdp_cap_data.fp);
1296 }
1297 
_vdp_cap_dump_uint32_t_list(uint32_t count,uint32_t const * values,bool zero_count_question_marks)1298 static void _vdp_cap_dump_uint32_t_list(
1299     uint32_t         count,
1300     uint32_t const * values,
1301     bool             zero_count_question_marks
1302 )
1303 {
1304     if (!values) {
1305         fputs("NULL", _vdp_cap_data.fp);
1306         return;
1307     }
1308 
1309     fputs("{", _vdp_cap_data.fp);
1310     if (!count && zero_count_question_marks) {
1311         fputs("???", _vdp_cap_data.fp);
1312     }
1313     while (count) {
1314         fprintf(
1315             _vdp_cap_data.fp,
1316             "%u%s",
1317             values[0],
1318             (count > 1) ? ", " : ""
1319         );
1320 
1321         --count;
1322         ++values;
1323     }
1324     fputs("}", _vdp_cap_data.fp);
1325 }
1326 
_vdp_cap_dump_color_list(uint32_t count,VdpColor const * colors)1327 static void _vdp_cap_dump_color_list(
1328     uint32_t         count,
1329     VdpColor const * colors
1330 )
1331 {
1332     if (!colors) {
1333         fputs("NULL", _vdp_cap_data.fp);
1334         return;
1335     }
1336 
1337     fputs("{", _vdp_cap_data.fp);
1338     while (count) {
1339         _vdp_cap_dump_color(&colors[0]);
1340         fputs(
1341             (count > 1) ? ", " : "",
1342             _vdp_cap_data.fp
1343         );
1344 
1345         --count;
1346         ++colors;
1347     }
1348     fputs("}", _vdp_cap_data.fp);
1349 }
1350 
_vdp_cap_dump_color_table(VdpIndexedFormat indexed_format,VdpColorTableFormat format,void const * table)1351 static void _vdp_cap_dump_color_table(
1352     VdpIndexedFormat    indexed_format,
1353     VdpColorTableFormat format,
1354     void const *        table
1355 )
1356 {
1357     if (!table) {
1358         fprintf(_vdp_cap_data.fp, "NULL");
1359         return;
1360     }
1361 
1362     uint32_t count;
1363     switch (indexed_format) {
1364     case VDP_INDEXED_FORMAT_A4I4:
1365     case VDP_INDEXED_FORMAT_I4A4:
1366         count = 1 << 4;
1367         break;
1368     case VDP_INDEXED_FORMAT_A8I8:
1369     case VDP_INDEXED_FORMAT_I8A8:
1370         count = 1 << 8;
1371         break;
1372     default:
1373         fprintf(_vdp_cap_data.fp, "???");
1374         return;
1375     }
1376 
1377     switch (format) {
1378     case VDP_COLOR_TABLE_FORMAT_B8G8R8X8:
1379         break;
1380     default:
1381         fprintf(_vdp_cap_data.fp, "???");
1382         return;
1383     }
1384 
1385     _vdp_cap_dump_uint32_t_list(
1386         count,
1387         (uint32_t const *)table,
1388         true
1389     );
1390 }
1391 
_vdp_cap_dump_bitstream_buffer_list(uint32_t count,VdpBitstreamBuffer const * buffers)1392 static void _vdp_cap_dump_bitstream_buffer_list(
1393     uint32_t                   count,
1394     VdpBitstreamBuffer const * buffers
1395 )
1396 {
1397     if (!buffers) {
1398         fputs("NULL", _vdp_cap_data.fp);
1399         return;
1400     }
1401 
1402     fputs("{", _vdp_cap_data.fp);
1403     while (count) {
1404         fprintf(
1405             _vdp_cap_data.fp,
1406              "{(ver %d)%s %u, ",
1407             buffers[0].struct_version,
1408             (buffers[0].struct_version > 0)
1409                 ? "(unsupported; cannot dump all fields)"
1410                 : "",
1411             buffers[0].bitstream_bytes
1412         );
1413         if (_vdp_cap_data.level >= LEVEL_DATA) {
1414             const uint8_t * ptr = (const uint8_t * )buffers[0].bitstream;
1415             for (uint32_t i = 0; i < buffers[0].bitstream_bytes; ++i) {
1416                 fprintf(_vdp_cap_data.fp, "%02x ", ptr[i]);
1417             }
1418         }
1419         else {
1420             fputs("...", _vdp_cap_data.fp);
1421         }
1422         fputs(
1423             (count > 1) ? "}, " : "}",
1424             _vdp_cap_data.fp
1425         );
1426 
1427         --count;
1428         ++buffers;
1429     }
1430     fputs("}", _vdp_cap_data.fp);
1431 }
1432 
_vdp_cap_dump_video_mixer_feature_list(uint32_t feature_count,VdpVideoMixerFeature const * features)1433 static void _vdp_cap_dump_video_mixer_feature_list(
1434     uint32_t                     feature_count,
1435     VdpVideoMixerFeature const * features
1436 )
1437 {
1438     _vdp_cap_dump_uint32_t_list(
1439         feature_count,
1440         features,
1441         false
1442     );
1443 }
1444 
_vdp_cap_dump_video_mixer_parameter_list(uint32_t parameter_count,VdpVideoMixerParameter const * parameters)1445 static void _vdp_cap_dump_video_mixer_parameter_list(
1446     uint32_t                       parameter_count,
1447     VdpVideoMixerParameter const * parameters
1448 )
1449 {
1450     _vdp_cap_dump_uint32_t_list(
1451         parameter_count,
1452         parameters,
1453         false
1454     );
1455 }
1456 
_vdp_cap_dump_video_mixer_attribute_list(uint32_t attribute_count,VdpVideoMixerAttribute const * attributes)1457 static void _vdp_cap_dump_video_mixer_attribute_list(
1458     uint32_t                       attribute_count,
1459     VdpVideoMixerAttribute const * attributes
1460 )
1461 {
1462     _vdp_cap_dump_uint32_t_list(
1463         attribute_count,
1464         attributes,
1465         false
1466     );
1467 }
1468 
_vdp_cap_dump_video_mixer_parameter_value_list(uint32_t parameter_count,VdpVideoMixerParameter const * parameters,void const * const * parameter_values)1469 static void _vdp_cap_dump_video_mixer_parameter_value_list(
1470     uint32_t                       parameter_count,
1471     VdpVideoMixerParameter const * parameters,
1472     void const * const *           parameter_values
1473 )
1474 {
1475     if (!parameters || !parameter_values) {
1476         fputs("NULL", _vdp_cap_data.fp);
1477         return;
1478     }
1479 
1480     fputs("{", _vdp_cap_data.fp);
1481     while (parameter_count) {
1482         _vdp_cap_dump_video_mixer_parameter_value(parameters[0], parameter_values[0]);
1483         fputs((parameter_count > 1) ? ", " : "", _vdp_cap_data.fp);
1484 
1485         --parameter_count;
1486         ++parameters;
1487         ++parameter_values;
1488     }
1489     fputs("}", _vdp_cap_data.fp);
1490 }
1491 
_vdp_cap_dump_video_mixer_attribute_value_list(uint32_t attribute_count,VdpVideoMixerAttribute const * attributes,void const * const * attribute_values,bool get_operation)1492 static void _vdp_cap_dump_video_mixer_attribute_value_list(
1493     uint32_t                       attribute_count,
1494     VdpVideoMixerAttribute const * attributes,
1495     void const * const *           attribute_values,
1496     bool                           get_operation
1497 )
1498 {
1499     if (!attributes || !attribute_values) {
1500         fputs("NULL", _vdp_cap_data.fp);
1501         return;
1502     }
1503 
1504     fputs("{", _vdp_cap_data.fp);
1505     while (attribute_count) {
1506         _vdp_cap_dump_video_mixer_attribute_value(
1507             attributes[0],
1508             attribute_values[0],
1509             get_operation
1510         );
1511         fputs((attribute_count > 1) ? ", " : "", _vdp_cap_data.fp);
1512 
1513         --attribute_count;
1514         ++attributes;
1515         ++attribute_values;
1516     }
1517     fputs("}", _vdp_cap_data.fp);
1518 }
1519 
_vdp_cap_dump_layers_list(uint32_t layer_count,VdpLayer const * layers)1520 static void _vdp_cap_dump_layers_list(
1521     uint32_t         layer_count,
1522     VdpLayer const * layers
1523 )
1524 {
1525     if (!layers) {
1526         fputs("NULL", _vdp_cap_data.fp);
1527         return;
1528     }
1529 
1530     fputs("{", _vdp_cap_data.fp);
1531     while (layer_count) {
1532         fprintf(
1533             _vdp_cap_data.fp,
1534             "{(ver %d)%s %u,",
1535             layers[0].struct_version,
1536             (layers[0].struct_version > 0)
1537                 ? "(unsupported; cannot dump all fields)"
1538                 : "",
1539             layers[0].source_surface
1540         );
1541 
1542         _vdp_cap_dump_rect(layers[0].source_rect);
1543         fputs(", ", _vdp_cap_data.fp);
1544         _vdp_cap_dump_rect(layers[0].destination_rect);
1545 
1546         fputs((layer_count > 1) ? "}, " : "}", _vdp_cap_data.fp);
1547 
1548         --layer_count;
1549         ++layers;
1550     }
1551     fputs("}", _vdp_cap_data.fp);
1552 }
1553 
_vdp_cap_get_error_string(VdpStatus status)1554 static char const * _vdp_cap_get_error_string(
1555     VdpStatus status
1556 )
1557 {
1558     char const * ret;
1559 
1560     fputs("vdp_get_error_string(", _vdp_cap_data.fp);
1561     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1562         fprintf(
1563             _vdp_cap_data.fp,
1564             "%d",
1565             status
1566         );
1567     }
1568     fputs(")\n", _vdp_cap_data.fp);
1569 
1570     ret = _vdp_cap_data.vdp_get_error_string(
1571         status
1572     );
1573 
1574     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1575         if (ret) {
1576             fprintf(_vdp_cap_data.fp, "    -> '%s'\n", ret);
1577         }
1578         else {
1579             fprintf(_vdp_cap_data.fp, "    -> NULL\n");
1580         }
1581     }
1582 
1583     return ret;
1584 }
1585 
_vdp_cap_get_api_version(uint32_t * api_version)1586 static VdpStatus _vdp_cap_get_api_version(
1587     /* output parameters follow */
1588     uint32_t * api_version
1589 )
1590 {
1591     VdpStatus ret;
1592 
1593     fputs("vdp_get_api_version(", _vdp_cap_data.fp);
1594     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1595         fprintf(
1596             _vdp_cap_data.fp,
1597             "%s",
1598             api_version ? "-" : "NULL"
1599         );
1600     }
1601     fputs(")\n", _vdp_cap_data.fp);
1602 
1603     ret = _vdp_cap_data.vdp_get_api_version(
1604         api_version
1605     );
1606 
1607     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1608         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
1609         if (ret == VDP_STATUS_OK) {
1610             if (api_version) {
1611                 fprintf(_vdp_cap_data.fp, ", %u", *api_version);
1612             }
1613             else {
1614                 fputs(", ???", _vdp_cap_data.fp);
1615             }
1616         }
1617         fputs("\n", _vdp_cap_data.fp);
1618     }
1619 
1620     return ret;
1621 }
1622 
_vdp_cap_get_information_string(char const ** information_string)1623 static VdpStatus _vdp_cap_get_information_string(
1624     /* output parameters follow */
1625     char const * * information_string
1626 )
1627 {
1628     VdpStatus ret;
1629 
1630     fputs("vdp_get_information_string(", _vdp_cap_data.fp);
1631     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1632         fprintf(
1633             _vdp_cap_data.fp,
1634             "%s",
1635             information_string ? "-" : "NULL"
1636         );
1637     }
1638     fputs(")\n", _vdp_cap_data.fp);
1639 
1640     ret = _vdp_cap_data.vdp_get_information_string(
1641         information_string
1642     );
1643 
1644     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1645         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
1646         if (ret == VDP_STATUS_OK) {
1647             if (information_string && *information_string) {
1648                 fprintf(_vdp_cap_data.fp, ", \"%s\"", *information_string);
1649             }
1650             else if (information_string) {
1651                 fputs(", (null)", _vdp_cap_data.fp);
1652             }
1653             else {
1654                 fputs(", ???", _vdp_cap_data.fp);
1655             }
1656         }
1657         fputs("\n", _vdp_cap_data.fp);
1658     }
1659 
1660     return ret;
1661 }
1662 
_vdp_cap_device_destroy(VdpDevice device)1663 static VdpStatus _vdp_cap_device_destroy(
1664     VdpDevice device
1665 )
1666 {
1667     VdpStatus ret;
1668 
1669     fputs("vdp_device_destroy(", _vdp_cap_data.fp);
1670     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1671         fprintf(
1672             _vdp_cap_data.fp,
1673             "%u",
1674             device
1675         );
1676     }
1677     fputs(")\n", _vdp_cap_data.fp);
1678 
1679     ret = _vdp_cap_data.vdp_device_destroy(
1680         device
1681     );
1682 
1683     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1684         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
1685     }
1686 
1687     return ret;
1688 }
1689 
_vdp_cap_generate_csc_matrix(VdpProcamp * procamp,VdpColorStandard standard,VdpCSCMatrix * csc_matrix)1690 static VdpStatus _vdp_cap_generate_csc_matrix(
1691     VdpProcamp *     procamp,
1692     VdpColorStandard standard,
1693     /* output parameters follow */
1694     VdpCSCMatrix *   csc_matrix
1695 )
1696 {
1697     VdpStatus ret;
1698 
1699     fputs("vdp_generate_csc_matrix(", _vdp_cap_data.fp);
1700     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1701         _vdp_cap_dump_procamp(procamp);
1702         fprintf(
1703             _vdp_cap_data.fp,
1704             ", %u, %s",
1705             standard,
1706             csc_matrix ? "-" : "NULL"
1707         );
1708     }
1709     fputs(")\n", _vdp_cap_data.fp);
1710 
1711     ret = _vdp_cap_data.vdp_generate_csc_matrix(
1712         procamp,
1713         standard,
1714         csc_matrix
1715     );
1716 
1717     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1718         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
1719         if (ret == VDP_STATUS_OK) {
1720             if (csc_matrix) {
1721                 fputs(", ", _vdp_cap_data.fp);
1722                 _vdp_cap_dump_csc_matrix(csc_matrix);
1723             }
1724             else {
1725                 fputs(", ???", _vdp_cap_data.fp);
1726             }
1727         }
1728         fputs("\n", _vdp_cap_data.fp);
1729     }
1730 
1731     return ret;
1732 }
1733 
_vdp_cap_video_surface_query_capabilities(VdpDevice device,VdpChromaType surface_chroma_type,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)1734 static VdpStatus _vdp_cap_video_surface_query_capabilities(
1735     VdpDevice     device,
1736     VdpChromaType surface_chroma_type,
1737     /* output parameters follow */
1738     VdpBool *     is_supported,
1739     uint32_t *    max_width,
1740     uint32_t *    max_height
1741 )
1742 {
1743     VdpStatus ret;
1744 
1745     fputs("vdp_video_surface_query_capabilities(", _vdp_cap_data.fp);
1746     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1747         fprintf(
1748             _vdp_cap_data.fp,
1749             "%u, %u, %s, %s, %s",
1750             device,
1751             surface_chroma_type,
1752             is_supported ? "-" : "NULL",
1753             max_width ? "-" : "NULL",
1754             max_height ? "-" : "NULL"
1755         );
1756     }
1757     fputs(")\n", _vdp_cap_data.fp);
1758 
1759     ret = _vdp_cap_data.vdp_video_surface_query_capabilities(
1760         device,
1761         surface_chroma_type,
1762         is_supported,
1763         max_width,
1764         max_height
1765     );
1766 
1767     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1768         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
1769         if (ret == VDP_STATUS_OK) {
1770             if (is_supported) {
1771                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
1772             }
1773             else {
1774                 fputs(", ???", _vdp_cap_data.fp);
1775             }
1776             if (max_width) {
1777                 fprintf(_vdp_cap_data.fp, ", %u", *max_width);
1778             }
1779             else {
1780                 fputs(", ???", _vdp_cap_data.fp);
1781             }
1782             if (max_height) {
1783                 fprintf(_vdp_cap_data.fp, ", %u", *max_height);
1784             }
1785             else {
1786                 fputs(", ???", _vdp_cap_data.fp);
1787             }
1788         }
1789         fputs("\n", _vdp_cap_data.fp);
1790     }
1791 
1792     return ret;
1793 }
1794 
_vdp_cap_video_surface_query_get_put_bits_y_cb_cr_capabilities(VdpDevice device,VdpChromaType surface_chroma_type,VdpYCbCrFormat bits_ycbcr_format,VdpBool * is_supported)1795 static VdpStatus _vdp_cap_video_surface_query_get_put_bits_y_cb_cr_capabilities(
1796     VdpDevice      device,
1797     VdpChromaType  surface_chroma_type,
1798     VdpYCbCrFormat bits_ycbcr_format,
1799     /* output parameters follow */
1800     VdpBool *      is_supported
1801 )
1802 {
1803     VdpStatus ret;
1804 
1805     fputs("vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(", _vdp_cap_data.fp);
1806     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1807         fprintf(
1808             _vdp_cap_data.fp,
1809             "%u, %u, %u, %s",
1810             device,
1811             surface_chroma_type,
1812             bits_ycbcr_format,
1813             is_supported ? "-" : "NULL"
1814         );
1815     }
1816     fputs(")\n", _vdp_cap_data.fp);
1817 
1818     ret = _vdp_cap_data.vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
1819         device,
1820         surface_chroma_type,
1821         bits_ycbcr_format,
1822         is_supported
1823     );
1824 
1825     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1826         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
1827         if (ret == VDP_STATUS_OK) {
1828             if (is_supported) {
1829                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
1830             }
1831             else {
1832                 fputs(", ???", _vdp_cap_data.fp);
1833             }
1834         }
1835         fputs("\n", _vdp_cap_data.fp);
1836     }
1837 
1838     return ret;
1839 }
1840 
_vdp_cap_video_surface_create(VdpDevice device,VdpChromaType chroma_type,uint32_t width,uint32_t height,VdpVideoSurface * surface)1841 static VdpStatus _vdp_cap_video_surface_create(
1842     VdpDevice         device,
1843     VdpChromaType     chroma_type,
1844     uint32_t          width,
1845     uint32_t          height,
1846     /* output parameters follow */
1847     VdpVideoSurface * surface
1848 )
1849 {
1850     VdpStatus ret;
1851 
1852     fputs("vdp_video_surface_create(", _vdp_cap_data.fp);
1853     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1854         fprintf(
1855             _vdp_cap_data.fp,
1856             "%u, %u, %u, %u, %s",
1857             device,
1858             chroma_type,
1859             width,
1860             height,
1861             surface ? "-" : "NULL"
1862         );
1863     }
1864     fputs(")\n", _vdp_cap_data.fp);
1865 
1866     ret = _vdp_cap_data.vdp_video_surface_create(
1867         device,
1868         chroma_type,
1869         width,
1870         height,
1871         surface
1872     );
1873 
1874     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1875         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
1876         if (ret == VDP_STATUS_OK) {
1877             if (surface) {
1878                 fprintf(_vdp_cap_data.fp, ", %u", *surface);
1879             }
1880             else {
1881                 fputs(", ???", _vdp_cap_data.fp);
1882             }
1883         }
1884         fputs("\n", _vdp_cap_data.fp);
1885     }
1886 
1887     return ret;
1888 }
1889 
_vdp_cap_video_surface_destroy(VdpVideoSurface surface)1890 static VdpStatus _vdp_cap_video_surface_destroy(
1891     VdpVideoSurface surface
1892 )
1893 {
1894     VdpStatus ret;
1895 
1896     fputs("vdp_video_surface_destroy(", _vdp_cap_data.fp);
1897     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1898         fprintf(
1899             _vdp_cap_data.fp,
1900             "%u",
1901             surface
1902         );
1903     }
1904     fputs(")\n", _vdp_cap_data.fp);
1905 
1906     ret = _vdp_cap_data.vdp_video_surface_destroy(
1907         surface
1908     );
1909 
1910     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1911         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
1912     }
1913 
1914     return ret;
1915 }
1916 
_vdp_cap_video_surface_get_parameters(VdpVideoSurface surface,VdpChromaType * chroma_type,uint32_t * width,uint32_t * height)1917 static VdpStatus _vdp_cap_video_surface_get_parameters(
1918     VdpVideoSurface surface,
1919     /* output parameters follow */
1920     VdpChromaType * chroma_type,
1921     uint32_t *      width,
1922     uint32_t *      height
1923 )
1924 {
1925     VdpStatus ret;
1926 
1927     fputs("vdp_video_surface_get_parameters(", _vdp_cap_data.fp);
1928     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1929         fprintf(
1930             _vdp_cap_data.fp,
1931             "%u, %s, %s, %s",
1932             surface,
1933             chroma_type ? "-" : "NULL",
1934             width ? "-" : "NULL",
1935             height ? "-" : "NULL"
1936         );
1937     }
1938     fputs(")\n", _vdp_cap_data.fp);
1939 
1940     ret = _vdp_cap_data.vdp_video_surface_get_parameters(
1941         surface,
1942         chroma_type,
1943         width,
1944         height
1945     );
1946 
1947     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
1948         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
1949         if (ret == VDP_STATUS_OK) {
1950             if (chroma_type) {
1951                 fprintf(_vdp_cap_data.fp, ", %u", *chroma_type);
1952             }
1953             else {
1954                 fputs(", ???", _vdp_cap_data.fp);
1955             }
1956             if (width) {
1957                 fprintf(_vdp_cap_data.fp, ", %u", *width);
1958             }
1959             else {
1960                 fputs(", ???", _vdp_cap_data.fp);
1961             }
1962             if (height) {
1963                 fprintf(_vdp_cap_data.fp, ", %u", *height);
1964             }
1965             else {
1966                 fputs(", ???", _vdp_cap_data.fp);
1967             }
1968         }
1969         fputs("\n", _vdp_cap_data.fp);
1970     }
1971 
1972     return ret;
1973 }
1974 
_vdp_cap_video_surface_get_bits_y_cb_cr(VdpVideoSurface surface,VdpYCbCrFormat destination_ycbcr_format,void * const * destination_data,uint32_t const * destination_pitches)1975 static VdpStatus _vdp_cap_video_surface_get_bits_y_cb_cr(
1976     VdpVideoSurface  surface,
1977     VdpYCbCrFormat   destination_ycbcr_format,
1978     void * const *   destination_data,
1979     uint32_t const * destination_pitches
1980 )
1981 {
1982     VdpStatus ret;
1983 
1984     _VdpcapPlane planes[3];
1985     uint32_t    plane_count = _VDP_TRACE_ARSIZE(planes);
1986     bool dump_data = _vdp_cap_init_planes(
1987         surface,
1988         destination_data,
1989         destination_pitches,
1990         0,
1991         &plane_count,
1992         planes,
1993         _vdp_cap_init_planes_adapt_surface_video,
1994         _vdp_cap_init_planes_adapt_format_bits_ycbcr,
1995         destination_ycbcr_format
1996     );
1997     if (!dump_data) {
1998         plane_count = 0;
1999     }
2000 
2001     fputs("vdp_video_surface_get_bits_y_cb_cr(", _vdp_cap_data.fp);
2002     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2003         fprintf(
2004             _vdp_cap_data.fp,
2005             "%u, %u, ",
2006             surface,
2007             destination_ycbcr_format
2008         );
2009         _vdp_cap_dump_void_pointer_list(plane_count, destination_data, true);
2010         fputs(", ", _vdp_cap_data.fp);
2011         _vdp_cap_dump_uint32_t_list(plane_count, destination_pitches, true);
2012     }
2013     fputs(")\n", _vdp_cap_data.fp);
2014 
2015     ret = _vdp_cap_data.vdp_video_surface_get_bits_y_cb_cr(
2016         surface,
2017         destination_ycbcr_format,
2018         destination_data,
2019         destination_pitches
2020     );
2021 
2022     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2023         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2024     }
2025     if (_vdp_cap_data.level >= LEVEL_DATA) {
2026         fputs("    ... Data: ", _vdp_cap_data.fp);
2027         if (dump_data) {
2028             _vdp_cap_dump_plane_list(plane_count, planes);
2029         }
2030         else {
2031            fputs("???", _vdp_cap_data.fp);
2032         }
2033         fputs("\n", _vdp_cap_data.fp);
2034     }
2035 
2036     return ret;
2037 }
2038 
_vdp_cap_video_surface_put_bits_y_cb_cr(VdpVideoSurface surface,VdpYCbCrFormat source_ycbcr_format,void const * const * source_data,uint32_t const * source_pitches)2039 static VdpStatus _vdp_cap_video_surface_put_bits_y_cb_cr(
2040     VdpVideoSurface      surface,
2041     VdpYCbCrFormat       source_ycbcr_format,
2042     void const * const * source_data,
2043     uint32_t const *     source_pitches
2044 )
2045 {
2046     VdpStatus ret;
2047 
2048     _VdpcapPlane planes[3];
2049     uint32_t    plane_count = _VDP_TRACE_ARSIZE(planes);
2050     bool dump_data = _vdp_cap_init_planes(
2051         surface,
2052         source_data,
2053         source_pitches,
2054         0,
2055         &plane_count,
2056         planes,
2057         _vdp_cap_init_planes_adapt_surface_video,
2058         _vdp_cap_init_planes_adapt_format_bits_ycbcr,
2059         source_ycbcr_format
2060     );
2061     if (!dump_data) {
2062         plane_count = 0;
2063     }
2064 
2065     fputs("vdp_video_surface_put_bits_y_cb_cr(", _vdp_cap_data.fp);
2066     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2067         fprintf(
2068             _vdp_cap_data.fp,
2069             "%u, %u, ",
2070             surface,
2071             source_ycbcr_format
2072         );
2073         _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
2074         fputs(", ", _vdp_cap_data.fp);
2075         _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
2076         fputs(", ", _vdp_cap_data.fp);
2077     }
2078     fputs(")\n", _vdp_cap_data.fp);
2079     if (_vdp_cap_data.level >= LEVEL_DATA) {
2080         fputs("    ... Data: ", _vdp_cap_data.fp);
2081         if (dump_data) {
2082             _vdp_cap_dump_plane_list(plane_count, planes);
2083         }
2084         else {
2085            fputs("???", _vdp_cap_data.fp);
2086         }
2087         fputs("\n", _vdp_cap_data.fp);
2088     }
2089 
2090     ret = _vdp_cap_data.vdp_video_surface_put_bits_y_cb_cr(
2091         surface,
2092         source_ycbcr_format,
2093         source_data,
2094         source_pitches
2095     );
2096 
2097     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2098         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2099     }
2100 
2101     return ret;
2102 }
2103 
_vdp_cap_output_surface_query_capabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)2104 static VdpStatus _vdp_cap_output_surface_query_capabilities(
2105     VdpDevice     device,
2106     VdpRGBAFormat surface_rgba_format,
2107     /* output parameters follow */
2108     VdpBool *     is_supported,
2109     uint32_t *    max_width,
2110     uint32_t *    max_height
2111 )
2112 {
2113     VdpStatus ret;
2114 
2115     fputs("vdp_output_surface_query_capabilities(", _vdp_cap_data.fp);
2116     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2117         fprintf(
2118             _vdp_cap_data.fp,
2119             "%u, %u, %s, %s, %s",
2120             device,
2121             surface_rgba_format,
2122             is_supported ? "-" : "NULL",
2123             max_width ? "-" : "NULL",
2124             max_height ? "-" : "NULL"
2125         );
2126     }
2127     fputs(")\n", _vdp_cap_data.fp);
2128 
2129     ret = _vdp_cap_data.vdp_output_surface_query_capabilities(
2130         device,
2131         surface_rgba_format,
2132         is_supported,
2133         max_width,
2134         max_height
2135     );
2136 
2137     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2138         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2139         if (ret == VDP_STATUS_OK) {
2140             if (is_supported) {
2141                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
2142             }
2143             else {
2144                 fputs(", ???", _vdp_cap_data.fp);
2145             }
2146             if (max_width) {
2147                 fprintf(_vdp_cap_data.fp, ", %u", *max_width);
2148             }
2149             else {
2150                 fputs(", ???", _vdp_cap_data.fp);
2151             }
2152             if (max_height) {
2153                 fprintf(_vdp_cap_data.fp, ", %u", *max_height);
2154             }
2155             else {
2156                 fputs(", ???", _vdp_cap_data.fp);
2157             }
2158         }
2159         fputs("\n", _vdp_cap_data.fp);
2160     }
2161 
2162     return ret;
2163 }
2164 
_vdp_cap_output_surface_query_get_put_bits_native_capabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported)2165 static VdpStatus _vdp_cap_output_surface_query_get_put_bits_native_capabilities(
2166     VdpDevice     device,
2167     VdpRGBAFormat surface_rgba_format,
2168     /* output parameters follow */
2169     VdpBool *     is_supported
2170 )
2171 {
2172     VdpStatus ret;
2173 
2174     fputs("vdp_output_surface_query_get_put_bits_native_capabilities(", _vdp_cap_data.fp);
2175     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2176         fprintf(
2177             _vdp_cap_data.fp,
2178             "%u, %u, %s",
2179             device,
2180             surface_rgba_format,
2181             is_supported ? "-" : "NULL"
2182         );
2183     }
2184     fputs(")\n", _vdp_cap_data.fp);
2185 
2186     ret = _vdp_cap_data.vdp_output_surface_query_get_put_bits_native_capabilities(
2187         device,
2188         surface_rgba_format,
2189         is_supported
2190     );
2191 
2192     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2193         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2194         if (ret == VDP_STATUS_OK) {
2195             if (is_supported) {
2196                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
2197             }
2198             else {
2199                 fputs(", ???", _vdp_cap_data.fp);
2200             }
2201         }
2202         fputs("\n", _vdp_cap_data.fp);
2203     }
2204 
2205     return ret;
2206 }
2207 
_vdp_cap_output_surface_query_put_bits_indexed_capabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpIndexedFormat bits_indexed_format,VdpColorTableFormat color_table_format,VdpBool * is_supported)2208 static VdpStatus _vdp_cap_output_surface_query_put_bits_indexed_capabilities(
2209     VdpDevice           device,
2210     VdpRGBAFormat       surface_rgba_format,
2211     VdpIndexedFormat    bits_indexed_format,
2212     VdpColorTableFormat color_table_format,
2213     /* output parameters follow */
2214     VdpBool *           is_supported
2215 )
2216 {
2217     VdpStatus ret;
2218 
2219     fputs("vdp_output_surface_query_put_bits_indexed_capabilities(", _vdp_cap_data.fp);
2220     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2221         fprintf(
2222             _vdp_cap_data.fp,
2223             "%u, %u, %u, %u, %s",
2224             device,
2225             surface_rgba_format,
2226             bits_indexed_format,
2227             color_table_format,
2228             is_supported ? "-" : "NULL"
2229         );
2230     }
2231     fputs(")\n", _vdp_cap_data.fp);
2232 
2233     ret = _vdp_cap_data.vdp_output_surface_query_put_bits_indexed_capabilities(
2234         device,
2235         surface_rgba_format,
2236         bits_indexed_format,
2237         color_table_format,
2238         is_supported
2239     );
2240 
2241     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2242         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2243         if (ret == VDP_STATUS_OK) {
2244             if (is_supported) {
2245                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
2246             }
2247             else {
2248                 fputs(", ???", _vdp_cap_data.fp);
2249             }
2250         }
2251         fputs("\n", _vdp_cap_data.fp);
2252     }
2253 
2254     return ret;
2255 }
2256 
_vdp_cap_output_surface_query_put_bits_y_cb_cr_capabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpYCbCrFormat bits_ycbcr_format,VdpBool * is_supported)2257 static VdpStatus _vdp_cap_output_surface_query_put_bits_y_cb_cr_capabilities(
2258     VdpDevice      device,
2259     VdpRGBAFormat  surface_rgba_format,
2260     VdpYCbCrFormat bits_ycbcr_format,
2261     /* output parameters follow */
2262     VdpBool *      is_supported
2263 )
2264 {
2265     VdpStatus ret;
2266 
2267     fputs("vdp_output_surface_query_put_bits_y_cb_cr_capabilities(", _vdp_cap_data.fp);
2268     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2269         fprintf(
2270             _vdp_cap_data.fp,
2271             "%u, %u, %u, %s",
2272             device,
2273             surface_rgba_format,
2274             bits_ycbcr_format,
2275             is_supported ? "-" : "NULL"
2276         );
2277     }
2278     fputs(")\n", _vdp_cap_data.fp);
2279 
2280     ret = _vdp_cap_data.vdp_output_surface_query_put_bits_y_cb_cr_capabilities(
2281         device,
2282         surface_rgba_format,
2283         bits_ycbcr_format,
2284         is_supported
2285     );
2286 
2287     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2288         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2289         if (ret == VDP_STATUS_OK) {
2290             if (is_supported) {
2291                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
2292             }
2293             else {
2294                 fputs(", ???", _vdp_cap_data.fp);
2295             }
2296         }
2297         fputs("\n", _vdp_cap_data.fp);
2298     }
2299 
2300     return ret;
2301 }
2302 
_vdp_cap_output_surface_create(VdpDevice device,VdpRGBAFormat rgba_format,uint32_t width,uint32_t height,VdpOutputSurface * surface)2303 static VdpStatus _vdp_cap_output_surface_create(
2304     VdpDevice          device,
2305     VdpRGBAFormat      rgba_format,
2306     uint32_t           width,
2307     uint32_t           height,
2308     /* output parameters follow */
2309     VdpOutputSurface * surface
2310 )
2311 {
2312     VdpStatus ret;
2313 
2314     fputs("vdp_output_surface_create(", _vdp_cap_data.fp);
2315     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2316         fprintf(
2317             _vdp_cap_data.fp,
2318             "%u, %u, %u, %u, %s",
2319             device,
2320             rgba_format,
2321             width,
2322             height,
2323             surface ? "-" : "NULL"
2324         );
2325     }
2326     fputs(")\n", _vdp_cap_data.fp);
2327 
2328     ret = _vdp_cap_data.vdp_output_surface_create(
2329         device,
2330         rgba_format,
2331         width,
2332         height,
2333         surface
2334     );
2335 
2336     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2337         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2338         if (ret == VDP_STATUS_OK) {
2339             if (surface) {
2340                 fprintf(_vdp_cap_data.fp, ", %u", *surface);
2341             }
2342             else {
2343                 fputs(", ???", _vdp_cap_data.fp);
2344             }
2345         }
2346         fputs("\n", _vdp_cap_data.fp);
2347     }
2348 
2349     return ret;
2350 }
2351 
_vdp_cap_output_surface_destroy(VdpOutputSurface surface)2352 static VdpStatus _vdp_cap_output_surface_destroy(
2353     VdpOutputSurface surface
2354 )
2355 {
2356     VdpStatus ret;
2357 
2358     fputs("vdp_output_surface_destroy(", _vdp_cap_data.fp);
2359     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2360         fprintf(
2361             _vdp_cap_data.fp,
2362             "%u",
2363             surface
2364         );
2365     }
2366     fputs(")\n", _vdp_cap_data.fp);
2367 
2368     ret = _vdp_cap_data.vdp_output_surface_destroy(
2369         surface
2370     );
2371 
2372     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2373         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2374     }
2375 
2376     return ret;
2377 }
2378 
_vdp_cap_output_surface_get_parameters(VdpOutputSurface surface,VdpRGBAFormat * rgba_format,uint32_t * width,uint32_t * height)2379 static VdpStatus _vdp_cap_output_surface_get_parameters(
2380     VdpOutputSurface surface,
2381     /* output parameters follow */
2382     VdpRGBAFormat *  rgba_format,
2383     uint32_t *       width,
2384     uint32_t *       height
2385 )
2386 {
2387     VdpStatus ret;
2388 
2389     fputs("vdp_output_surface_get_parameters(", _vdp_cap_data.fp);
2390     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2391         fprintf(
2392             _vdp_cap_data.fp,
2393             "%u, %s, %s, %s",
2394             surface,
2395             rgba_format ? "-" : "NULL",
2396             width ? "-" : "NULL",
2397             height ? "-" : "NULL"
2398         );
2399     }
2400     fputs(")\n", _vdp_cap_data.fp);
2401 
2402     ret = _vdp_cap_data.vdp_output_surface_get_parameters(
2403         surface,
2404         rgba_format,
2405         width,
2406         height
2407     );
2408 
2409     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2410         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2411         if (ret == VDP_STATUS_OK) {
2412             if (rgba_format) {
2413                 fprintf(_vdp_cap_data.fp, ", %u", *rgba_format);
2414             }
2415             else {
2416                 fputs(", ???", _vdp_cap_data.fp);
2417             }
2418             if (width) {
2419                 fprintf(_vdp_cap_data.fp, ", %u", *width);
2420             }
2421             else {
2422                 fputs(", ???", _vdp_cap_data.fp);
2423             }
2424             if (height) {
2425                 fprintf(_vdp_cap_data.fp, ", %u", *height);
2426             }
2427             else {
2428                 fputs(", ???", _vdp_cap_data.fp);
2429             }
2430         }
2431         fputs("\n", _vdp_cap_data.fp);
2432     }
2433 
2434     return ret;
2435 }
2436 
_vdp_cap_output_surface_get_bits_native(VdpOutputSurface surface,VdpRect const * source_rect,void * const * destination_data,uint32_t const * destination_pitches)2437 static VdpStatus _vdp_cap_output_surface_get_bits_native(
2438     VdpOutputSurface  surface,
2439     VdpRect const *   source_rect,
2440     void * const *    destination_data,
2441     uint32_t const *  destination_pitches
2442 )
2443 {
2444     VdpStatus ret;
2445 
2446     _VdpcapPlane planes[1];
2447     uint32_t    plane_count = _VDP_TRACE_ARSIZE(planes);
2448     bool dump_data = _vdp_cap_init_planes(
2449         surface,
2450         destination_data,
2451         destination_pitches,
2452         source_rect,
2453         &plane_count,
2454         planes,
2455         _vdp_cap_init_planes_adapt_surface_output,
2456         _vdp_cap_init_planes_adapt_format_surface_rgba,
2457         0
2458     );
2459     if (!dump_data) {
2460         plane_count = 0;
2461     }
2462 
2463     fputs("vdp_output_surface_get_bits_native(", _vdp_cap_data.fp);
2464     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2465         fprintf(
2466             _vdp_cap_data.fp,
2467             "%u, ",
2468             surface
2469         );
2470         _vdp_cap_dump_rect(source_rect);
2471         fputs(", ", _vdp_cap_data.fp);
2472         _vdp_cap_dump_void_pointer_list(plane_count, destination_data, true);
2473         fputs(", ", _vdp_cap_data.fp);
2474         _vdp_cap_dump_uint32_t_list(plane_count, destination_pitches, true);
2475     }
2476     fputs(")\n", _vdp_cap_data.fp);
2477 
2478     ret = _vdp_cap_data.vdp_output_surface_get_bits_native(
2479         surface,
2480         source_rect,
2481         destination_data,
2482         destination_pitches
2483     );
2484 
2485     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2486         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2487     }
2488     if (_vdp_cap_data.level >= LEVEL_DATA) {
2489         fputs("    ... Data: ", _vdp_cap_data.fp);
2490         if (dump_data) {
2491             _vdp_cap_dump_plane_list(plane_count, planes);
2492         }
2493         else {
2494            fputs("???", _vdp_cap_data.fp);
2495         }
2496         fputs("\n", _vdp_cap_data.fp);
2497     }
2498 
2499     return ret;
2500 }
2501 
_vdp_cap_output_surface_put_bits_native(VdpOutputSurface surface,void const * const * source_data,uint32_t const * source_pitches,VdpRect const * destination_rect)2502 static VdpStatus _vdp_cap_output_surface_put_bits_native(
2503     VdpOutputSurface     surface,
2504     void const * const * source_data,
2505     uint32_t const *     source_pitches,
2506     VdpRect const *      destination_rect
2507 )
2508 {
2509     VdpStatus ret;
2510 
2511     _VdpcapPlane planes[1];
2512     uint32_t    plane_count = _VDP_TRACE_ARSIZE(planes);
2513     bool dump_data = _vdp_cap_init_planes(
2514         surface,
2515         source_data,
2516         source_pitches,
2517         destination_rect,
2518         &plane_count,
2519         planes,
2520         _vdp_cap_init_planes_adapt_surface_output,
2521         _vdp_cap_init_planes_adapt_format_surface_rgba,
2522         0
2523     );
2524     if (!dump_data) {
2525         plane_count = 0;
2526     }
2527 
2528     fputs("vdp_output_surface_put_bits_native(", _vdp_cap_data.fp);
2529     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2530         fprintf(
2531             _vdp_cap_data.fp,
2532             "%u, ",
2533             surface
2534         );
2535         _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
2536         fputs(", ", _vdp_cap_data.fp);
2537         _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
2538         fputs(", ", _vdp_cap_data.fp);
2539         _vdp_cap_dump_rect(destination_rect);
2540     }
2541     fputs(")\n", _vdp_cap_data.fp);
2542     if (_vdp_cap_data.level >= LEVEL_DATA) {
2543         fputs("    ... Data: ", _vdp_cap_data.fp);
2544         if (dump_data) {
2545             _vdp_cap_dump_plane_list(plane_count, planes);
2546         }
2547         else {
2548            fputs("???", _vdp_cap_data.fp);
2549         }
2550         fputs("\n", _vdp_cap_data.fp);
2551     }
2552 
2553     ret = _vdp_cap_data.vdp_output_surface_put_bits_native(
2554         surface,
2555         source_data,
2556         source_pitches,
2557         destination_rect
2558     );
2559 
2560     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2561         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2562     }
2563 
2564     return ret;
2565 }
2566 
_vdp_cap_output_surface_put_bits_indexed(VdpOutputSurface surface,VdpIndexedFormat source_indexed_format,void const * const * source_data,uint32_t const * source_pitches,VdpRect const * destination_rect,VdpColorTableFormat color_table_format,void const * color_table)2567 static VdpStatus _vdp_cap_output_surface_put_bits_indexed(
2568     VdpOutputSurface     surface,
2569     VdpIndexedFormat     source_indexed_format,
2570     void const * const * source_data,
2571     uint32_t const *     source_pitches,
2572     VdpRect const *      destination_rect,
2573     VdpColorTableFormat  color_table_format,
2574     void const *         color_table
2575 )
2576 {
2577     VdpStatus ret;
2578 
2579     _VdpcapPlane planes[1];
2580     uint32_t    plane_count = _VDP_TRACE_ARSIZE(planes);
2581     bool dump_data = _vdp_cap_init_planes(
2582         surface,
2583         source_data,
2584         source_pitches,
2585         destination_rect,
2586         &plane_count,
2587         planes,
2588         _vdp_cap_init_planes_adapt_surface_output,
2589         _vdp_cap_init_planes_adapt_format_bits_indexed,
2590         source_indexed_format
2591     );
2592     if (!dump_data) {
2593         plane_count = 0;
2594     }
2595 
2596     fputs("vdp_output_surface_put_bits_indexed(", _vdp_cap_data.fp);
2597     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2598         fprintf(
2599             _vdp_cap_data.fp,
2600             "%u, %u, ",
2601             surface,
2602             source_indexed_format
2603         );
2604         _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
2605         fputs(", ", _vdp_cap_data.fp);
2606         _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
2607         fputs(", ", _vdp_cap_data.fp);
2608         _vdp_cap_dump_rect(destination_rect);
2609         fprintf(
2610             _vdp_cap_data.fp,
2611             ", %u, ",
2612             color_table_format
2613         );
2614         _vdp_cap_dump_color_table(
2615             source_indexed_format,
2616             color_table_format,
2617             color_table
2618         );
2619     }
2620     fputs(")\n", _vdp_cap_data.fp);
2621     if (_vdp_cap_data.level >= LEVEL_DATA) {
2622         fputs("    ... Data: ", _vdp_cap_data.fp);
2623         if (dump_data) {
2624             _vdp_cap_dump_plane_list(plane_count, planes);
2625         }
2626         else {
2627            fputs("???", _vdp_cap_data.fp);
2628         }
2629         fputs("\n", _vdp_cap_data.fp);
2630     }
2631 
2632     ret = _vdp_cap_data.vdp_output_surface_put_bits_indexed(
2633         surface,
2634         source_indexed_format,
2635         source_data,
2636         source_pitches,
2637         destination_rect,
2638         color_table_format,
2639         color_table
2640     );
2641 
2642     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2643         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2644     }
2645 
2646     return ret;
2647 }
2648 
_vdp_cap_output_surface_put_bits_y_cb_cr(VdpOutputSurface surface,VdpYCbCrFormat source_ycbcr_format,void const * const * source_data,uint32_t const * source_pitches,VdpRect const * destination_rect,VdpCSCMatrix const * csc_matrix)2649 static VdpStatus _vdp_cap_output_surface_put_bits_y_cb_cr(
2650     VdpOutputSurface     surface,
2651     VdpYCbCrFormat       source_ycbcr_format,
2652     void const * const * source_data,
2653     uint32_t const *     source_pitches,
2654     VdpRect const *      destination_rect,
2655     VdpCSCMatrix const * csc_matrix
2656 )
2657 {
2658     VdpStatus ret;
2659 
2660     _VdpcapPlane planes[1];
2661     uint32_t    plane_count = _VDP_TRACE_ARSIZE(planes);
2662     bool dump_data = _vdp_cap_init_planes(
2663         surface,
2664         source_data,
2665         source_pitches,
2666         destination_rect,
2667         &plane_count,
2668         planes,
2669         _vdp_cap_init_planes_adapt_surface_output,
2670         _vdp_cap_init_planes_adapt_format_bits_ycbcr,
2671         source_ycbcr_format
2672     );
2673     if (!dump_data) {
2674         plane_count = 0;
2675     }
2676 
2677     fputs("vdp_output_surface_put_bits_y_cb_cr(", _vdp_cap_data.fp);
2678     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2679         fprintf(
2680             _vdp_cap_data.fp,
2681             "%u, %u, ",
2682             surface,
2683             source_ycbcr_format
2684         );
2685         _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
2686         fputs(", ", _vdp_cap_data.fp);
2687         _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
2688         fputs(", ", _vdp_cap_data.fp);
2689         _vdp_cap_dump_rect(destination_rect);
2690         fputs(", ", _vdp_cap_data.fp);
2691         _vdp_cap_dump_csc_matrix(csc_matrix);
2692     }
2693     fputs(")\n", _vdp_cap_data.fp);
2694     if (_vdp_cap_data.level >= LEVEL_DATA) {
2695         fputs("    ... Data: ", _vdp_cap_data.fp);
2696         if (dump_data) {
2697             _vdp_cap_dump_plane_list(plane_count, planes);
2698         }
2699         else {
2700            fputs("???", _vdp_cap_data.fp);
2701         }
2702         fputs("\n", _vdp_cap_data.fp);
2703     }
2704 
2705     ret = _vdp_cap_data.vdp_output_surface_put_bits_y_cb_cr(
2706         surface,
2707         source_ycbcr_format,
2708         source_data,
2709         source_pitches,
2710         destination_rect,
2711         csc_matrix
2712     );
2713 
2714     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2715         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2716     }
2717 
2718     return ret;
2719 }
2720 
_vdp_cap_bitmap_surface_query_capabilities(VdpDevice device,VdpRGBAFormat surface_rgba_format,VdpBool * is_supported,uint32_t * max_width,uint32_t * max_height)2721 static VdpStatus _vdp_cap_bitmap_surface_query_capabilities(
2722     VdpDevice     device,
2723     VdpRGBAFormat surface_rgba_format,
2724     /* output parameters follow */
2725     VdpBool *     is_supported,
2726     uint32_t *    max_width,
2727     uint32_t *    max_height
2728 )
2729 {
2730     VdpStatus ret;
2731 
2732     fputs("vdp_bitmap_surface_query_capabilities(", _vdp_cap_data.fp);
2733     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2734         fprintf(
2735             _vdp_cap_data.fp,
2736             "%u, %u, %s, %s, %s",
2737             device,
2738             surface_rgba_format,
2739             is_supported ? "-" : "NULL",
2740             max_width ? "-" : "NULL",
2741             max_height ? "-" : "NULL"
2742         );
2743     }
2744     fputs(")\n", _vdp_cap_data.fp);
2745 
2746     ret = _vdp_cap_data.vdp_bitmap_surface_query_capabilities(
2747         device,
2748         surface_rgba_format,
2749         is_supported,
2750         max_width,
2751         max_height
2752     );
2753 
2754     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2755         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2756         if (ret == VDP_STATUS_OK) {
2757             if (is_supported) {
2758                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
2759             }
2760             else {
2761                 fputs(", ???", _vdp_cap_data.fp);
2762             }
2763             if (max_width) {
2764                 fprintf(_vdp_cap_data.fp, ", %u", *max_width);
2765             }
2766             else {
2767                 fputs(", ???", _vdp_cap_data.fp);
2768             }
2769             if (max_height) {
2770                 fprintf(_vdp_cap_data.fp, ", %u", *max_height);
2771             }
2772             else {
2773                 fputs(", ???", _vdp_cap_data.fp);
2774             }
2775         }
2776         fputs("\n", _vdp_cap_data.fp);
2777     }
2778 
2779     return ret;
2780 }
2781 
_vdp_cap_bitmap_surface_create(VdpDevice device,VdpRGBAFormat rgba_format,uint32_t width,uint32_t height,VdpBool frequently_accessed,VdpBitmapSurface * surface)2782 static VdpStatus _vdp_cap_bitmap_surface_create(
2783     VdpDevice         device,
2784     VdpRGBAFormat     rgba_format,
2785     uint32_t          width,
2786     uint32_t          height,
2787     VdpBool           frequently_accessed,
2788     /* output parameters follow */
2789     VdpBitmapSurface * surface
2790 )
2791 {
2792     VdpStatus ret;
2793 
2794     fputs("vdp_bitmap_surface_create(", _vdp_cap_data.fp);
2795     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2796         fprintf(
2797             _vdp_cap_data.fp,
2798             "%u, %u, %u, %u, %d, %s",
2799             device,
2800             rgba_format,
2801             width,
2802             height,
2803             frequently_accessed,
2804             surface ? "-" : "NULL"
2805         );
2806     }
2807     fputs(")\n", _vdp_cap_data.fp);
2808 
2809     ret = _vdp_cap_data.vdp_bitmap_surface_create(
2810         device,
2811         rgba_format,
2812         width,
2813         height,
2814         frequently_accessed,
2815         surface
2816     );
2817 
2818     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2819         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2820         if (ret == VDP_STATUS_OK) {
2821             if (surface) {
2822                 fprintf(_vdp_cap_data.fp, ", %u", *surface);
2823             }
2824             else {
2825                 fputs(", ???", _vdp_cap_data.fp);
2826             }
2827         }
2828         fputs("\n", _vdp_cap_data.fp);
2829     }
2830 
2831     return ret;
2832 }
2833 
_vdp_cap_bitmap_surface_destroy(VdpBitmapSurface surface)2834 static VdpStatus _vdp_cap_bitmap_surface_destroy(
2835     VdpBitmapSurface surface
2836 )
2837 {
2838     VdpStatus ret;
2839 
2840     fputs("vdp_bitmap_surface_destroy(", _vdp_cap_data.fp);
2841     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2842         fprintf(
2843             _vdp_cap_data.fp,
2844             "%u",
2845             surface
2846         );
2847     }
2848     fputs(")\n", _vdp_cap_data.fp);
2849 
2850     ret = _vdp_cap_data.vdp_bitmap_surface_destroy(
2851         surface
2852     );
2853 
2854     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2855         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2856     }
2857 
2858     return ret;
2859 }
2860 
_vdp_cap_bitmap_surface_get_parameters(VdpBitmapSurface surface,VdpRGBAFormat * rgba_format,uint32_t * width,uint32_t * height,VdpBool * frequently_accessed)2861 static VdpStatus _vdp_cap_bitmap_surface_get_parameters(
2862     VdpBitmapSurface surface,
2863     /* output parameters follow */
2864     VdpRGBAFormat * rgba_format,
2865     uint32_t *      width,
2866     uint32_t *      height,
2867     VdpBool *       frequently_accessed
2868 )
2869 {
2870     VdpStatus ret;
2871 
2872     fputs("vdp_bitmap_surface_get_parameters(", _vdp_cap_data.fp);
2873     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2874         fprintf(
2875             _vdp_cap_data.fp,
2876             "%u, %s, %s, %s, %s",
2877             surface,
2878             rgba_format ? "-" : "NULL",
2879             width ? "-" : "NULL",
2880             height ? "-" : "NULL",
2881             frequently_accessed ? "-" : "NULL"
2882         );
2883     }
2884     fputs(")\n", _vdp_cap_data.fp);
2885 
2886     ret = _vdp_cap_data.vdp_bitmap_surface_get_parameters(
2887         surface,
2888         rgba_format,
2889         width,
2890         height,
2891         frequently_accessed
2892     );
2893 
2894     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2895         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
2896         if (ret == VDP_STATUS_OK) {
2897             if (rgba_format) {
2898                 fprintf(_vdp_cap_data.fp, ", %u", *rgba_format);
2899             }
2900             else {
2901                 fputs(", ???", _vdp_cap_data.fp);
2902             }
2903             if (width) {
2904                 fprintf(_vdp_cap_data.fp, ", %u", *width);
2905             }
2906             else {
2907                 fputs(", ???", _vdp_cap_data.fp);
2908             }
2909             if (height) {
2910                 fprintf(_vdp_cap_data.fp, ", %u", *height);
2911             }
2912             else {
2913                 fputs(", ???", _vdp_cap_data.fp);
2914             }
2915             if (frequently_accessed) {
2916                 fprintf(_vdp_cap_data.fp, ", %d", *frequently_accessed);
2917             }
2918             else {
2919                 fputs(", ???", _vdp_cap_data.fp);
2920             }
2921         }
2922         fputs("\n", _vdp_cap_data.fp);
2923     }
2924 
2925     return ret;
2926 }
2927 
_vdp_cap_bitmap_surface_put_bits_native(VdpBitmapSurface surface,void const * const * source_data,uint32_t const * source_pitches,VdpRect const * destination_rect)2928 static VdpStatus _vdp_cap_bitmap_surface_put_bits_native(
2929     VdpBitmapSurface     surface,
2930     void const * const * source_data,
2931     uint32_t const *     source_pitches,
2932     VdpRect const *      destination_rect
2933 )
2934 {
2935     VdpStatus ret;
2936 
2937     _VdpcapPlane planes[1];
2938     uint32_t    plane_count = _VDP_TRACE_ARSIZE(planes);
2939     bool dump_data = _vdp_cap_init_planes(
2940         surface,
2941         source_data,
2942         source_pitches,
2943         destination_rect,
2944         &plane_count,
2945         planes,
2946         _vdp_cap_init_planes_adapt_surface_bitmap,
2947         _vdp_cap_init_planes_adapt_format_surface_rgba,
2948         0
2949     );
2950     if (!dump_data) {
2951         plane_count = 0;
2952     }
2953 
2954     fputs("vdp_bitmap_surface_put_bits_native(", _vdp_cap_data.fp);
2955     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2956         fprintf(
2957             _vdp_cap_data.fp,
2958             "%u, ",
2959             surface
2960         );
2961         _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
2962         fputs(", ", _vdp_cap_data.fp);
2963         _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
2964         fputs(", ", _vdp_cap_data.fp);
2965         _vdp_cap_dump_rect(destination_rect);
2966     }
2967     fputs(")\n", _vdp_cap_data.fp);
2968     if (_vdp_cap_data.level >= LEVEL_DATA) {
2969         fputs("    ... Data: ", _vdp_cap_data.fp);
2970         if (dump_data) {
2971             _vdp_cap_dump_plane_list(plane_count, planes);
2972         }
2973         else {
2974            fputs("???", _vdp_cap_data.fp);
2975         }
2976         fputs("\n", _vdp_cap_data.fp);
2977     }
2978 
2979     ret = _vdp_cap_data.vdp_bitmap_surface_put_bits_native(
2980         surface,
2981         source_data,
2982         source_pitches,
2983         destination_rect
2984     );
2985 
2986     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
2987         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
2988     }
2989 
2990     return ret;
2991 }
2992 
_vdp_cap_output_surface_render_output_surface(VdpOutputSurface destination_surface,VdpRect const * destination_rect,VdpOutputSurface source_surface,VdpRect const * source_rect,VdpColor const * colors,VdpOutputSurfaceRenderBlendState const * blend_state,uint32_t flags)2993 static VdpStatus _vdp_cap_output_surface_render_output_surface(
2994     VdpOutputSurface                         destination_surface,
2995     VdpRect const *                          destination_rect,
2996     VdpOutputSurface                         source_surface,
2997     VdpRect const *                          source_rect,
2998     VdpColor const *                         colors,
2999     VdpOutputSurfaceRenderBlendState const * blend_state,
3000     uint32_t                                 flags
3001 )
3002 {
3003     VdpStatus ret;
3004 
3005     fputs("vdp_output_surface_render_output_surface(", _vdp_cap_data.fp);
3006     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3007         fprintf(
3008             _vdp_cap_data.fp,
3009             "%u, ",
3010             destination_surface
3011         );
3012         _vdp_cap_dump_rect(destination_rect);
3013         fprintf(
3014             _vdp_cap_data.fp,
3015             ", %u, ",
3016             source_surface
3017         );
3018         _vdp_cap_dump_rect(source_rect);
3019         fputs(", ", _vdp_cap_data.fp);
3020         _vdp_cap_dump_color_list((flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) ? 4 : 1, colors);
3021         fputs(", ", _vdp_cap_data.fp);
3022         _vdp_cap_dump_blend_state(blend_state);
3023         fprintf(
3024             _vdp_cap_data.fp,
3025             ", %u",
3026             flags
3027         );
3028     }
3029     fputs(")\n", _vdp_cap_data.fp);
3030 
3031     ret = _vdp_cap_data.vdp_output_surface_render_output_surface(
3032         destination_surface,
3033         destination_rect,
3034         source_surface,
3035         source_rect,
3036         colors,
3037         blend_state,
3038         flags
3039     );
3040 
3041     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3042         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3043     }
3044 
3045     return ret;
3046 }
3047 
_vdp_cap_output_surface_render_bitmap_surface(VdpOutputSurface destination_surface,VdpRect const * destination_rect,VdpBitmapSurface source_surface,VdpRect const * source_rect,VdpColor const * colors,VdpOutputSurfaceRenderBlendState const * blend_state,uint32_t flags)3048 static VdpStatus _vdp_cap_output_surface_render_bitmap_surface(
3049     VdpOutputSurface                         destination_surface,
3050     VdpRect const *                          destination_rect,
3051     VdpBitmapSurface                         source_surface,
3052     VdpRect const *                          source_rect,
3053     VdpColor const *                         colors,
3054     VdpOutputSurfaceRenderBlendState const * blend_state,
3055     uint32_t                                 flags
3056 )
3057 {
3058     VdpStatus ret;
3059 
3060     fputs("vdp_output_surface_render_bitmap_surface(", _vdp_cap_data.fp);
3061     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3062         fprintf(
3063             _vdp_cap_data.fp,
3064             "%u, ",
3065             destination_surface
3066         );
3067         _vdp_cap_dump_rect(destination_rect);
3068         fprintf(
3069             _vdp_cap_data.fp,
3070             ", %u, ",
3071             source_surface
3072         );
3073         _vdp_cap_dump_rect(source_rect);
3074         fputs(", ", _vdp_cap_data.fp);
3075         _vdp_cap_dump_color_list((flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) ? 4 : 1, colors);
3076         fputs(", ", _vdp_cap_data.fp);
3077         _vdp_cap_dump_blend_state(blend_state);
3078         fprintf(
3079             _vdp_cap_data.fp,
3080             ", %u",
3081             flags
3082         );
3083     }
3084     fputs(")\n", _vdp_cap_data.fp);
3085 
3086     ret = _vdp_cap_data.vdp_output_surface_render_bitmap_surface(
3087         destination_surface,
3088         destination_rect,
3089         source_surface,
3090         source_rect,
3091         colors,
3092         blend_state,
3093         flags
3094     );
3095 
3096     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3097         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3098     }
3099 
3100     return ret;
3101 }
3102 
_vdp_cap_decoder_query_capabilities(VdpDevice device,VdpDecoderProfile profile,VdpBool * is_supported,uint32_t * max_level,uint32_t * max_macroblocks,uint32_t * max_width,uint32_t * max_height)3103 static VdpStatus _vdp_cap_decoder_query_capabilities(
3104     VdpDevice         device,
3105     VdpDecoderProfile profile,
3106     /* output parameters follow */
3107     VdpBool *         is_supported,
3108     uint32_t *        max_level,
3109     uint32_t *        max_macroblocks,
3110     uint32_t *        max_width,
3111     uint32_t *        max_height
3112 )
3113 {
3114     VdpStatus ret;
3115 
3116     fputs("vdp_decoder_query_capabilities(", _vdp_cap_data.fp);
3117     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3118         fprintf(
3119             _vdp_cap_data.fp,
3120             "%u, %u, %s, %s, %s, %s, %s",
3121             device,
3122             profile,
3123             is_supported ? "-" : "NULL",
3124             max_level ? "-" : "NULL",
3125             max_macroblocks ? "-" : "NULL",
3126             max_width ? "-" : "NULL",
3127             max_height ? "-" : "NULL"
3128         );
3129     }
3130     fputs(")\n", _vdp_cap_data.fp);
3131 
3132     ret = _vdp_cap_data.vdp_decoder_query_capabilities(
3133         device,
3134         profile,
3135         is_supported,
3136         max_level,
3137         max_macroblocks,
3138         max_width,
3139         max_height
3140     );
3141 
3142     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3143         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3144         if (ret == VDP_STATUS_OK) {
3145             if (is_supported) {
3146                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
3147             }
3148             else {
3149                 fputs(", ???", _vdp_cap_data.fp);
3150             }
3151             if (max_level) {
3152                 fprintf(_vdp_cap_data.fp, ", %u", *max_level);
3153             }
3154             else {
3155                 fputs(", ???", _vdp_cap_data.fp);
3156             }
3157             if (max_macroblocks) {
3158                 fprintf(_vdp_cap_data.fp, ", %u", *max_macroblocks);
3159             }
3160             else {
3161                 fputs(", ???", _vdp_cap_data.fp);
3162             }
3163             if (max_width) {
3164                 fprintf(_vdp_cap_data.fp, ", %u", *max_width);
3165             }
3166             else {
3167                 fputs(", ???", _vdp_cap_data.fp);
3168             }
3169             if (max_height) {
3170                 fprintf(_vdp_cap_data.fp, ", %u", *max_height);
3171             }
3172             else {
3173                 fputs(", ???", _vdp_cap_data.fp);
3174             }
3175         }
3176         fputs("\n", _vdp_cap_data.fp);
3177     }
3178 
3179     return ret;
3180 }
3181 
_vdp_cap_decoder_create(VdpDevice device,VdpDecoderProfile profile,uint32_t width,uint32_t height,uint32_t max_references,VdpDecoder * decoder)3182 static VdpStatus _vdp_cap_decoder_create(
3183     VdpDevice         device,
3184     VdpDecoderProfile profile,
3185     uint32_t          width,
3186     uint32_t          height,
3187     uint32_t          max_references,
3188     /* output parameters follow */
3189     VdpDecoder *      decoder
3190 )
3191 {
3192     VdpStatus ret;
3193 
3194     fputs("vdp_decoder_create(", _vdp_cap_data.fp);
3195     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3196         fprintf(
3197             _vdp_cap_data.fp,
3198             "%u, %u, %u, %u, %u, %s",
3199             device,
3200             profile,
3201             width,
3202             height,
3203             max_references,
3204             decoder ? "-" : "NULL"
3205         );
3206     }
3207     fputs(")\n", _vdp_cap_data.fp);
3208 
3209     ret = _vdp_cap_data.vdp_decoder_create(
3210         device,
3211         profile,
3212         width,
3213         height,
3214         max_references,
3215         decoder
3216     );
3217 
3218     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3219         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3220         if (ret == VDP_STATUS_OK) {
3221             if (decoder) {
3222                 fprintf(_vdp_cap_data.fp, ", %u", *decoder);
3223             }
3224             else {
3225                 fputs(", ???", _vdp_cap_data.fp);
3226             }
3227         }
3228         fputs("\n", _vdp_cap_data.fp);
3229     }
3230 
3231     return ret;
3232 }
3233 
_vdp_cap_decoder_destroy(VdpDecoder decoder)3234 static VdpStatus _vdp_cap_decoder_destroy(
3235     VdpDecoder decoder
3236 )
3237 {
3238     VdpStatus ret;
3239 
3240     fputs("vdp_decoder_destroy(", _vdp_cap_data.fp);
3241     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3242         fprintf(
3243             _vdp_cap_data.fp,
3244             "%u",
3245             decoder
3246         );
3247     }
3248     fputs(")\n", _vdp_cap_data.fp);
3249 
3250     ret = _vdp_cap_data.vdp_decoder_destroy(
3251         decoder
3252     );
3253 
3254     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3255         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3256     }
3257 
3258     return ret;
3259 }
3260 
_vdp_cap_decoder_get_parameters(VdpDecoder decoder,VdpDecoderProfile * profile,uint32_t * width,uint32_t * height)3261 static VdpStatus _vdp_cap_decoder_get_parameters(
3262     VdpDecoder          decoder,
3263     /* output parameters follow */
3264     VdpDecoderProfile * profile,
3265     uint32_t *          width,
3266     uint32_t *          height
3267 )
3268 {
3269     VdpStatus ret;
3270 
3271     fputs("vdp_decoder_get_parameters(", _vdp_cap_data.fp);
3272     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3273         fprintf(
3274             _vdp_cap_data.fp,
3275             "%u, %s, %s, %s",
3276             decoder,
3277             profile ? "-" : "NULL",
3278             width ? "-" : "NULL",
3279             height ? "-" : "NULL"
3280         );
3281     }
3282     fputs(")\n", _vdp_cap_data.fp);
3283 
3284     ret = _vdp_cap_data.vdp_decoder_get_parameters(
3285         decoder,
3286         profile,
3287         width,
3288         height
3289     );
3290 
3291     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3292         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3293         if (ret == VDP_STATUS_OK) {
3294             if (profile) {
3295                 fprintf(_vdp_cap_data.fp, ", %u", *profile);
3296             }
3297             else {
3298                 fputs(", ???", _vdp_cap_data.fp);
3299             }
3300             if (width) {
3301                 fprintf(_vdp_cap_data.fp, ", %u", *width);
3302             }
3303             else {
3304                 fputs(", ???", _vdp_cap_data.fp);
3305             }
3306             if (height) {
3307                 fprintf(_vdp_cap_data.fp, ", %u", *height);
3308             }
3309             else {
3310                 fputs(", ???", _vdp_cap_data.fp);
3311             }
3312         }
3313         fputs("\n", _vdp_cap_data.fp);
3314     }
3315 
3316     return ret;
3317 }
3318 
_vdp_cap_decoder_render(VdpDecoder decoder,VdpVideoSurface target,VdpPictureInfo const * picture_info,uint32_t bitstream_buffer_count,VdpBitstreamBuffer const * bitstream_buffers)3319 static VdpStatus _vdp_cap_decoder_render(
3320     VdpDecoder                 decoder,
3321     VdpVideoSurface            target,
3322     VdpPictureInfo const *     picture_info,
3323     uint32_t                   bitstream_buffer_count,
3324     VdpBitstreamBuffer const * bitstream_buffers
3325 )
3326 {
3327     VdpStatus ret;
3328 
3329     fputs("vdp_decoder_render(", _vdp_cap_data.fp);
3330     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3331         VdpDecoderProfile profile;
3332         uint32_t          width;
3333         uint32_t          height;
3334 
3335         ret = _vdp_cap_data.vdp_decoder_get_parameters(
3336             decoder,
3337             &profile,
3338             &width,
3339             &height
3340         );
3341 
3342         fprintf(
3343             _vdp_cap_data.fp,
3344             "%u, %u, ",
3345             decoder,
3346             target
3347         );
3348         _vdp_cap_dump_picture_info(profile, picture_info);
3349         fprintf(
3350             _vdp_cap_data.fp,
3351             ", %u, ",
3352             bitstream_buffer_count
3353         );
3354         _vdp_cap_dump_bitstream_buffer_list(bitstream_buffer_count, bitstream_buffers);
3355     }
3356     fputs(")\n", _vdp_cap_data.fp);
3357 
3358     ret = _vdp_cap_data.vdp_decoder_render(
3359         decoder,
3360         target,
3361         picture_info,
3362         bitstream_buffer_count,
3363         bitstream_buffers
3364     );
3365 
3366     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3367         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3368     }
3369 
3370     return ret;
3371 }
3372 
3373 
_vdp_cap_video_mixer_query_feature_support(VdpDevice device,VdpVideoMixerFeature feature,VdpBool * is_supported)3374 static VdpStatus _vdp_cap_video_mixer_query_feature_support(
3375     VdpDevice            device,
3376     VdpVideoMixerFeature feature,
3377     /* output parameters follow */
3378     VdpBool *            is_supported
3379 )
3380 {
3381     VdpStatus ret;
3382 
3383     fputs("vdp_video_mixer_query_feature_support(", _vdp_cap_data.fp);
3384     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3385         fprintf(
3386             _vdp_cap_data.fp,
3387             "%u, %u, %s",
3388             device,
3389             feature,
3390             is_supported ? "-" : "NULL"
3391         );
3392     }
3393     fputs(")\n", _vdp_cap_data.fp);
3394 
3395     ret = _vdp_cap_data.vdp_video_mixer_query_feature_support(
3396         device,
3397         feature,
3398         is_supported
3399     );
3400 
3401     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3402         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3403         if (ret == VDP_STATUS_OK) {
3404             if (is_supported) {
3405                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
3406             }
3407             else {
3408                 fputs(", ???", _vdp_cap_data.fp);
3409             }
3410         }
3411         fputs("\n", _vdp_cap_data.fp);
3412     }
3413 
3414     return ret;
3415 }
3416 
_vdp_cap_video_mixer_query_parameter_support(VdpDevice device,VdpVideoMixerParameter parameter,VdpBool * is_supported)3417 static VdpStatus _vdp_cap_video_mixer_query_parameter_support(
3418     VdpDevice              device,
3419     VdpVideoMixerParameter parameter,
3420     /* output parameters follow */
3421     VdpBool *              is_supported
3422 )
3423 {
3424     VdpStatus ret;
3425 
3426     fputs("vdp_video_mixer_query_parameter_support(", _vdp_cap_data.fp);
3427     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3428         fprintf(
3429             _vdp_cap_data.fp,
3430             "%u, %u, %s",
3431             device,
3432             parameter,
3433             is_supported ? "-" : "NULL"
3434         );
3435     }
3436     fputs(")\n", _vdp_cap_data.fp);
3437 
3438     ret = _vdp_cap_data.vdp_video_mixer_query_parameter_support(
3439         device,
3440         parameter,
3441         is_supported
3442     );
3443 
3444     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3445         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3446         if (ret == VDP_STATUS_OK) {
3447             if (is_supported) {
3448                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
3449             }
3450             else {
3451                 fputs(", ???", _vdp_cap_data.fp);
3452             }
3453         }
3454         fputs("\n", _vdp_cap_data.fp);
3455     }
3456 
3457     return ret;
3458 }
3459 
_vdp_cap_video_mixer_query_attribute_support(VdpDevice device,VdpVideoMixerAttribute attribute,VdpBool * is_supported)3460 static VdpStatus _vdp_cap_video_mixer_query_attribute_support(
3461     VdpDevice              device,
3462     VdpVideoMixerAttribute attribute,
3463     /* output parameters follow */
3464     VdpBool *              is_supported
3465 )
3466 {
3467     VdpStatus ret;
3468 
3469     fputs("vdp_video_mixer_query_attribute_support(", _vdp_cap_data.fp);
3470     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3471         fprintf(
3472             _vdp_cap_data.fp,
3473             "%u, %u, %s",
3474             device,
3475             attribute,
3476             is_supported ? "-" : "NULL"
3477         );
3478     }
3479     fputs(")\n", _vdp_cap_data.fp);
3480 
3481     ret = _vdp_cap_data.vdp_video_mixer_query_attribute_support(
3482         device,
3483         attribute,
3484         is_supported
3485     );
3486 
3487     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3488         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3489         if (ret == VDP_STATUS_OK) {
3490             if (is_supported) {
3491                 fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
3492             }
3493             else {
3494                 fputs(", ???", _vdp_cap_data.fp);
3495             }
3496         }
3497         fputs("\n", _vdp_cap_data.fp);
3498     }
3499 
3500     return ret;
3501 }
3502 
_vdp_cap_video_mixer_query_parameter_value_range(VdpDevice device,VdpVideoMixerParameter parameter,void * min_value,void * max_value)3503 static VdpStatus _vdp_cap_video_mixer_query_parameter_value_range(
3504     VdpDevice              device,
3505     VdpVideoMixerParameter parameter,
3506     /* output parameters follow */
3507     void *                 min_value,
3508     void *                 max_value
3509 )
3510 {
3511     VdpStatus ret;
3512 
3513     fputs("vdp_video_mixer_query_parameter_value_range(", _vdp_cap_data.fp);
3514     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3515         fprintf(
3516             _vdp_cap_data.fp,
3517             "%u, %u, %s, %s",
3518             device,
3519             parameter,
3520             min_value ? "-" : "NULL",
3521             max_value ? "-" : "NULL"
3522         );
3523     }
3524     fputs(")\n", _vdp_cap_data.fp);
3525 
3526     ret = _vdp_cap_data.vdp_video_mixer_query_parameter_value_range(
3527         device,
3528         parameter,
3529         min_value,
3530         max_value
3531     );
3532 
3533     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3534         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3535         if (ret == VDP_STATUS_OK) {
3536             fputs(", ", _vdp_cap_data.fp);
3537             _vdp_cap_dump_video_mixer_parameter_value(parameter, min_value);
3538             fputs(", ", _vdp_cap_data.fp);
3539             _vdp_cap_dump_video_mixer_parameter_value(parameter, max_value);
3540         }
3541         fputs("\n", _vdp_cap_data.fp);
3542     }
3543 
3544     return ret;
3545 }
3546 
_vdp_cap_video_mixer_query_attribute_value_range(VdpDevice device,VdpVideoMixerAttribute attribute,void * min_value,void * max_value)3547 static VdpStatus _vdp_cap_video_mixer_query_attribute_value_range(
3548     VdpDevice              device,
3549     VdpVideoMixerAttribute attribute,
3550     /* output parameters follow */
3551     void *                 min_value,
3552     void *                 max_value
3553 )
3554 {
3555     VdpStatus ret;
3556 
3557     fputs("vdp_video_mixer_query_attribute_value_range(", _vdp_cap_data.fp);
3558     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3559         fprintf(
3560             _vdp_cap_data.fp,
3561             "%u, %u, %s, %s",
3562             device,
3563             attribute,
3564             min_value ? "-" : "NULL",
3565             max_value ? "-" : "NULL"
3566         );
3567     }
3568     fputs(")\n", _vdp_cap_data.fp);
3569 
3570     ret = _vdp_cap_data.vdp_video_mixer_query_attribute_value_range(
3571         device,
3572         attribute,
3573         min_value,
3574         max_value
3575     );
3576 
3577     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3578         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3579         if (ret == VDP_STATUS_OK) {
3580             fputs(", ", _vdp_cap_data.fp);
3581             _vdp_cap_dump_video_mixer_attribute_value(attribute, min_value, false);
3582             fputs(", ", _vdp_cap_data.fp);
3583             _vdp_cap_dump_video_mixer_attribute_value(attribute, max_value, false);
3584         }
3585         fputs("\n", _vdp_cap_data.fp);
3586     }
3587 
3588     return ret;
3589 }
3590 
_vdp_cap_video_mixer_create(VdpDevice device,uint32_t feature_count,VdpVideoMixerFeature const * features,uint32_t parameter_count,VdpVideoMixerParameter const * parameters,void const * const * parameter_values,VdpVideoMixer * mixer)3591 static VdpStatus _vdp_cap_video_mixer_create(
3592     VdpDevice                      device,
3593     uint32_t                       feature_count,
3594     VdpVideoMixerFeature const *   features,
3595     uint32_t                       parameter_count,
3596     VdpVideoMixerParameter const * parameters,
3597     void const * const *           parameter_values,
3598     /* output parameters follow */
3599     VdpVideoMixer *                mixer
3600 )
3601 {
3602     VdpStatus ret;
3603 
3604     fputs("vdp_video_mixer_create(", _vdp_cap_data.fp);
3605     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3606         fprintf(_vdp_cap_data.fp, "%u, %u, ", device, feature_count);
3607         _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
3608         fprintf(_vdp_cap_data.fp, ", %u, ", parameter_count);
3609         _vdp_cap_dump_video_mixer_parameter_list(parameter_count, parameters);
3610         fputs(", ", _vdp_cap_data.fp);
3611         _vdp_cap_dump_video_mixer_parameter_value_list(
3612             parameter_count,
3613             parameters,
3614             parameter_values
3615         );
3616         fprintf(_vdp_cap_data.fp, ", %s", mixer ? "-" : "NULL");
3617     }
3618     fputs(")\n", _vdp_cap_data.fp);
3619 
3620     ret = _vdp_cap_data.vdp_video_mixer_create(
3621         device,
3622         feature_count,
3623         features,
3624         parameter_count,
3625         parameters,
3626         parameter_values,
3627         mixer
3628     );
3629 
3630     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3631         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3632         if (ret == VDP_STATUS_OK) {
3633             if (mixer) {
3634                 fprintf(_vdp_cap_data.fp, ", %u", *mixer);
3635             }
3636             else {
3637                 fputs(", ???", _vdp_cap_data.fp);
3638             }
3639         }
3640         fputs("\n", _vdp_cap_data.fp);
3641     }
3642 
3643     return ret;
3644 }
3645 
_vdp_cap_video_mixer_set_feature_enables(VdpVideoMixer mixer,uint32_t feature_count,VdpVideoMixerFeature const * features,VdpBool const * feature_enables)3646 static VdpStatus _vdp_cap_video_mixer_set_feature_enables(
3647     VdpVideoMixer                mixer,
3648     uint32_t                     feature_count,
3649     VdpVideoMixerFeature const * features,
3650     VdpBool const *              feature_enables
3651 )
3652 {
3653     VdpStatus ret;
3654 
3655     fputs("vdp_video_mixer_set_feature_enables(", _vdp_cap_data.fp);
3656     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3657         fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, feature_count);
3658         _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
3659         fputs(", ", _vdp_cap_data.fp);
3660         _vdp_cap_dump_bool_list(feature_count, feature_enables);
3661     }
3662     fputs(")\n", _vdp_cap_data.fp);
3663 
3664     ret = _vdp_cap_data.vdp_video_mixer_set_feature_enables(
3665         mixer,
3666         feature_count,
3667         features,
3668         feature_enables
3669     );
3670 
3671     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3672         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3673     }
3674 
3675     return ret;
3676 }
3677 
_vdp_cap_video_mixer_set_attribute_values(VdpVideoMixer mixer,uint32_t attribute_count,VdpVideoMixerAttribute const * attributes,void const * const * attribute_values)3678 static VdpStatus _vdp_cap_video_mixer_set_attribute_values(
3679     VdpVideoMixer                  mixer,
3680     uint32_t                       attribute_count,
3681     VdpVideoMixerAttribute const * attributes,
3682     void const * const *           attribute_values
3683 )
3684 {
3685     VdpStatus ret;
3686 
3687     fputs("vdp_video_mixer_set_attribute_values(", _vdp_cap_data.fp);
3688     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3689         fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, attribute_count);
3690         _vdp_cap_dump_video_mixer_attribute_list(attribute_count, attributes);
3691         fputs(", ", _vdp_cap_data.fp);
3692         _vdp_cap_dump_video_mixer_attribute_value_list(
3693             attribute_count,
3694             attributes,
3695             attribute_values,
3696             false
3697         );
3698     }
3699     fputs(")\n", _vdp_cap_data.fp);
3700 
3701     ret = _vdp_cap_data.vdp_video_mixer_set_attribute_values(
3702         mixer,
3703         attribute_count,
3704         attributes,
3705         attribute_values
3706     );
3707 
3708     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3709         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3710     }
3711 
3712     return ret;
3713 }
3714 
_vdp_cap_video_mixer_get_feature_support(VdpVideoMixer mixer,uint32_t feature_count,VdpVideoMixerFeature const * features,VdpBool * feature_supports)3715 static VdpStatus _vdp_cap_video_mixer_get_feature_support(
3716     VdpVideoMixer                mixer,
3717     uint32_t                     feature_count,
3718     VdpVideoMixerFeature const * features,
3719     /* output parameters follow */
3720     VdpBool *                    feature_supports
3721 )
3722 {
3723     VdpStatus ret;
3724 
3725     fputs("vdp_video_mixer_get_feature_support(", _vdp_cap_data.fp);
3726     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3727         fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, feature_count);
3728         _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
3729         fputs(feature_supports ? "-" : "NULL", _vdp_cap_data.fp);
3730     }
3731     fputs(")\n", _vdp_cap_data.fp);
3732 
3733     ret = _vdp_cap_data.vdp_video_mixer_get_feature_support(
3734         mixer,
3735         feature_count,
3736         features,
3737         feature_supports
3738     );
3739 
3740     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3741         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3742         if (ret == VDP_STATUS_OK) {
3743             fputs(", ", _vdp_cap_data.fp);
3744             _vdp_cap_dump_bool_list(feature_count, feature_supports);
3745         }
3746         fputs("\n", _vdp_cap_data.fp);
3747     }
3748 
3749     return ret;
3750 }
3751 
_vdp_cap_video_mixer_get_feature_enables(VdpVideoMixer mixer,uint32_t feature_count,VdpVideoMixerFeature const * features,VdpBool * feature_enables)3752 static VdpStatus _vdp_cap_video_mixer_get_feature_enables(
3753     VdpVideoMixer                mixer,
3754     uint32_t                     feature_count,
3755     VdpVideoMixerFeature const * features,
3756     /* output parameters follow */
3757     VdpBool *                    feature_enables
3758 )
3759 {
3760     VdpStatus ret;
3761 
3762     fputs("vdp_video_mixer_get_feature_enables(", _vdp_cap_data.fp);
3763     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3764         fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, feature_count);
3765         _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
3766         fprintf(_vdp_cap_data.fp, ", %s", feature_enables ? "-" : "NULL");
3767     }
3768     fputs(")\n", _vdp_cap_data.fp);
3769 
3770     ret = _vdp_cap_data.vdp_video_mixer_get_feature_enables(
3771         mixer,
3772         feature_count,
3773         features,
3774         feature_enables
3775     );
3776 
3777     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3778         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3779         if (ret == VDP_STATUS_OK) {
3780             fputs(", ", _vdp_cap_data.fp);
3781             _vdp_cap_dump_bool_list(feature_count, feature_enables);
3782         }
3783         fputs("\n", _vdp_cap_data.fp);
3784     }
3785 
3786     return ret;
3787 }
3788 
_vdp_cap_video_mixer_get_parameter_values(VdpVideoMixer mixer,uint32_t parameter_count,VdpVideoMixerParameter const * parameters,void * const * parameter_values)3789 static VdpStatus _vdp_cap_video_mixer_get_parameter_values(
3790     VdpVideoMixer                  mixer,
3791     uint32_t                       parameter_count,
3792     VdpVideoMixerParameter const * parameters,
3793     /* output parameters follow */
3794     void * const *                 parameter_values
3795 )
3796 {
3797     VdpStatus ret;
3798 
3799     fputs("vdp_video_mixer_get_parameter_values(", _vdp_cap_data.fp);
3800     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3801         fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, parameter_count);
3802         _vdp_cap_dump_video_mixer_parameter_list(parameter_count, parameters);
3803         fprintf(_vdp_cap_data.fp, ", %s", parameter_values ? "-" : "NULL");
3804     }
3805     fputs(")\n", _vdp_cap_data.fp);
3806 
3807     ret = _vdp_cap_data.vdp_video_mixer_get_parameter_values(
3808         mixer,
3809         parameter_count,
3810         parameters,
3811         parameter_values
3812     );
3813 
3814     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3815         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3816         if (ret == VDP_STATUS_OK) {
3817             fputs(", ", _vdp_cap_data.fp);
3818             _vdp_cap_dump_video_mixer_parameter_value_list(
3819                 parameter_count,
3820                 parameters,
3821                 parameter_values
3822             );
3823         }
3824         fputs("\n", _vdp_cap_data.fp);
3825     }
3826 
3827     return ret;
3828 }
3829 
_vdp_cap_video_mixer_get_attribute_values(VdpVideoMixer mixer,uint32_t attribute_count,VdpVideoMixerAttribute const * attributes,void * const * attribute_values)3830 static VdpStatus _vdp_cap_video_mixer_get_attribute_values(
3831     VdpVideoMixer                  mixer,
3832     uint32_t                       attribute_count,
3833     VdpVideoMixerAttribute const * attributes,
3834     /* output parameters follow */
3835     void * const *                 attribute_values
3836 )
3837 {
3838     VdpStatus ret;
3839 
3840     fputs("vdp_video_mixer_get_attribute_values(", _vdp_cap_data.fp);
3841     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3842         fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, attribute_count);
3843         _vdp_cap_dump_video_mixer_attribute_list(attribute_count, attributes);
3844         fprintf(_vdp_cap_data.fp, ", %s", attribute_values ? "-" : "NULL");
3845     }
3846     fputs(")\n", _vdp_cap_data.fp);
3847 
3848     ret = _vdp_cap_data.vdp_video_mixer_get_attribute_values(
3849         mixer,
3850         attribute_count,
3851         attributes,
3852         attribute_values
3853     );
3854 
3855     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3856         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
3857         if (ret == VDP_STATUS_OK) {
3858             fputs(", ", _vdp_cap_data.fp);
3859             _vdp_cap_dump_video_mixer_attribute_value_list(
3860                 attribute_count,
3861                 attributes,
3862                 attribute_values,
3863                 true
3864             );
3865         }
3866         fputs("\n", _vdp_cap_data.fp);
3867     }
3868 
3869     return ret;
3870 }
3871 
_vdp_cap_video_mixer_destroy(VdpVideoMixer mixer)3872 static VdpStatus _vdp_cap_video_mixer_destroy(
3873     VdpVideoMixer mixer
3874 )
3875 {
3876     VdpStatus ret;
3877 
3878     fputs("vdp_video_mixer_destroy(", _vdp_cap_data.fp);
3879     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3880         fprintf(
3881             _vdp_cap_data.fp,
3882             "%u",
3883             mixer
3884         );
3885     }
3886     fputs(")\n", _vdp_cap_data.fp);
3887 
3888     ret = _vdp_cap_data.vdp_video_mixer_destroy(
3889         mixer
3890     );
3891 
3892     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3893         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3894     }
3895 
3896     return ret;
3897 }
3898 
_vdp_cap_video_mixer_render(VdpVideoMixer mixer,VdpOutputSurface background_surface,VdpRect const * background_source_rect,VdpVideoMixerPictureStructure current_picture_structure,uint32_t video_surface_past_count,VdpVideoSurface const * video_surface_past,VdpVideoSurface video_surface_current,uint32_t video_surface_future_count,VdpVideoSurface const * video_surface_future,VdpRect const * video_source_rect,VdpOutputSurface destination_surface,VdpRect const * destination_rect,VdpRect const * destination_video_rect,uint32_t layer_count,VdpLayer const * layers)3899 static VdpStatus _vdp_cap_video_mixer_render(
3900     VdpVideoMixer                 mixer,
3901     VdpOutputSurface              background_surface,
3902     VdpRect const *               background_source_rect,
3903     VdpVideoMixerPictureStructure current_picture_structure,
3904     uint32_t                      video_surface_past_count,
3905     VdpVideoSurface const *       video_surface_past,
3906     VdpVideoSurface               video_surface_current,
3907     uint32_t                      video_surface_future_count,
3908     VdpVideoSurface const *       video_surface_future,
3909     VdpRect const *               video_source_rect,
3910     VdpOutputSurface              destination_surface,
3911     VdpRect const *               destination_rect,
3912     VdpRect const *               destination_video_rect,
3913     uint32_t                      layer_count,
3914     VdpLayer const *              layers
3915 )
3916 {
3917     VdpStatus ret;
3918 
3919     fputs("vdp_video_mixer_render(", _vdp_cap_data.fp);
3920     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3921         fprintf(
3922             _vdp_cap_data.fp,
3923             "%u, %u, ",
3924             mixer,
3925             background_surface
3926         );
3927         _vdp_cap_dump_rect(background_source_rect);
3928         fprintf(
3929             _vdp_cap_data.fp,
3930             ", %d, %u, ",
3931             current_picture_structure,
3932             video_surface_past_count
3933         );
3934         _vdp_cap_dump_uint32_t_list(video_surface_past_count, video_surface_past, false);
3935         fprintf(
3936             _vdp_cap_data.fp,
3937             ", %u, %u, ",
3938             video_surface_current,
3939             video_surface_future_count
3940         );
3941         _vdp_cap_dump_uint32_t_list(video_surface_future_count, video_surface_future, false);
3942         fputs(", ", _vdp_cap_data.fp);
3943         _vdp_cap_dump_rect(video_source_rect);
3944         fprintf(
3945             _vdp_cap_data.fp,
3946             ", %u, ",
3947             destination_surface
3948         );
3949         _vdp_cap_dump_rect(destination_rect);
3950         fputs(", ", _vdp_cap_data.fp);
3951         _vdp_cap_dump_rect(destination_video_rect);
3952         fprintf(
3953             _vdp_cap_data.fp,
3954             ", %u, ",
3955             layer_count
3956         );
3957         _vdp_cap_dump_layers_list(layer_count, layers);
3958     }
3959     fputs(")\n", _vdp_cap_data.fp);
3960 
3961     ret = _vdp_cap_data.vdp_video_mixer_render(
3962         mixer,
3963         background_surface,
3964         background_source_rect,
3965         current_picture_structure,
3966         video_surface_past_count,
3967         video_surface_past,
3968         video_surface_current,
3969         video_surface_future_count,
3970         video_surface_future,
3971         video_source_rect,
3972         destination_surface,
3973         destination_rect,
3974         destination_video_rect,
3975         layer_count,
3976         layers
3977     );
3978 
3979     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3980         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
3981     }
3982 
3983     return ret;
3984 }
3985 
_vdp_cap_presentation_queue_target_destroy(VdpPresentationQueueTarget presentation_queue_target)3986 static VdpStatus _vdp_cap_presentation_queue_target_destroy(
3987     VdpPresentationQueueTarget presentation_queue_target
3988 )
3989 {
3990     VdpStatus ret;
3991 
3992     fputs("vdp_presentation_queue_target_destroy(", _vdp_cap_data.fp);
3993     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
3994         fprintf(
3995             _vdp_cap_data.fp,
3996             "%u",
3997             presentation_queue_target
3998         );
3999     }
4000     fputs(")\n", _vdp_cap_data.fp);
4001 
4002     ret = _vdp_cap_data.vdp_presentation_queue_target_destroy(
4003         presentation_queue_target
4004     );
4005 
4006     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4007         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
4008     }
4009 
4010     return ret;
4011 }
4012 
_vdp_cap_presentation_queue_create(VdpDevice device,VdpPresentationQueueTarget presentation_queue_target,VdpPresentationQueue * presentation_queue)4013 static VdpStatus _vdp_cap_presentation_queue_create(
4014     VdpDevice                  device,
4015     VdpPresentationQueueTarget presentation_queue_target,
4016     /* output parameters follow */
4017     VdpPresentationQueue *     presentation_queue
4018 )
4019 {
4020     VdpStatus ret;
4021 
4022     fputs("vdp_presentation_queue_create(", _vdp_cap_data.fp);
4023     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4024         fprintf(
4025             _vdp_cap_data.fp,
4026             "%u, %u, %s",
4027             device,
4028             presentation_queue_target,
4029             presentation_queue ? "-" : "NULL"
4030         );
4031     }
4032     fputs(")\n", _vdp_cap_data.fp);
4033 
4034     ret = _vdp_cap_data.vdp_presentation_queue_create(
4035         device,
4036         presentation_queue_target,
4037         presentation_queue
4038     );
4039 
4040     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4041         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
4042         if (ret == VDP_STATUS_OK) {
4043             if (presentation_queue) {
4044                 fprintf(_vdp_cap_data.fp, ", %u", *presentation_queue);
4045             }
4046             else {
4047                 fputs(", ???", _vdp_cap_data.fp);
4048             }
4049         }
4050         fputs("\n", _vdp_cap_data.fp);
4051     }
4052 
4053     return ret;
4054 }
4055 
_vdp_cap_presentation_queue_destroy(VdpPresentationQueue presentation_queue)4056 static VdpStatus _vdp_cap_presentation_queue_destroy(
4057     VdpPresentationQueue presentation_queue
4058 )
4059 {
4060     VdpStatus ret;
4061 
4062     fputs("vdp_presentation_queue_destroy(", _vdp_cap_data.fp);
4063     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4064         fprintf(
4065             _vdp_cap_data.fp,
4066             "%u",
4067             presentation_queue
4068         );
4069     }
4070     fputs(")\n", _vdp_cap_data.fp);
4071 
4072     ret = _vdp_cap_data.vdp_presentation_queue_destroy(
4073         presentation_queue
4074     );
4075 
4076     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4077         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
4078     }
4079 
4080     return ret;
4081 }
4082 
_vdp_cap_presentation_queue_set_background_color(VdpPresentationQueue presentation_queue,VdpColor * const background_color)4083 static VdpStatus _vdp_cap_presentation_queue_set_background_color(
4084     VdpPresentationQueue presentation_queue,
4085     VdpColor * const     background_color
4086 )
4087 {
4088     VdpStatus ret;
4089 
4090     fputs("vdp_presentation_queue_set_background_color(", _vdp_cap_data.fp);
4091     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4092         fprintf(
4093             _vdp_cap_data.fp,
4094             "%u, ",
4095             presentation_queue
4096         );
4097         _vdp_cap_dump_color(background_color);
4098     }
4099     fputs(")\n", _vdp_cap_data.fp);
4100 
4101     ret = _vdp_cap_data.vdp_presentation_queue_set_background_color(
4102         presentation_queue,
4103         background_color
4104     );
4105 
4106     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4107         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
4108     }
4109 
4110     return ret;
4111 }
4112 
_vdp_cap_presentation_queue_get_background_color(VdpPresentationQueue presentation_queue,VdpColor * background_color)4113 static VdpStatus _vdp_cap_presentation_queue_get_background_color(
4114     VdpPresentationQueue presentation_queue,
4115     VdpColor *           background_color
4116 )
4117 {
4118     VdpStatus ret;
4119 
4120     fputs("vdp_presentation_queue_get_background_color(", _vdp_cap_data.fp);
4121     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4122         fprintf(
4123             _vdp_cap_data.fp,
4124             "%u, %s",
4125             presentation_queue,
4126             background_color ? "-" : "NULL"
4127         );
4128     }
4129     fputs(")\n", _vdp_cap_data.fp);
4130 
4131     ret = _vdp_cap_data.vdp_presentation_queue_get_background_color(
4132         presentation_queue,
4133         background_color
4134     );
4135 
4136     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4137         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
4138         if (ret == VDP_STATUS_OK) {
4139             fputs(", ", _vdp_cap_data.fp);
4140             _vdp_cap_dump_color(background_color);
4141         }
4142         fputs("\n", _vdp_cap_data.fp);
4143     }
4144 
4145     return ret;
4146 }
4147 
_vdp_cap_presentation_queue_get_time(VdpPresentationQueue presentation_queue,VdpTime * current_time)4148 static VdpStatus _vdp_cap_presentation_queue_get_time(
4149     VdpPresentationQueue presentation_queue,
4150     /* output parameters follow */
4151     VdpTime *            current_time
4152 )
4153 {
4154     VdpStatus ret;
4155 
4156     fputs("vdp_presentation_queue_get_time(", _vdp_cap_data.fp);
4157     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4158         fprintf(
4159             _vdp_cap_data.fp,
4160             "%u, %s",
4161             presentation_queue,
4162             current_time ? "-" : "NULL"
4163         );
4164     }
4165     fputs(")\n", _vdp_cap_data.fp);
4166 
4167     ret = _vdp_cap_data.vdp_presentation_queue_get_time(
4168         presentation_queue,
4169         current_time
4170     );
4171 
4172     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4173         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
4174         if (ret == VDP_STATUS_OK) {
4175             if (current_time) {
4176                 fprintf(_vdp_cap_data.fp, ", %" PRIu64, *current_time);
4177             }
4178             else {
4179                 fputs(", ???", _vdp_cap_data.fp);
4180             }
4181         }
4182         fputs("\n", _vdp_cap_data.fp);
4183     }
4184 
4185     return ret;
4186 }
4187 
_vdp_cap_presentation_queue_display(VdpPresentationQueue presentation_queue,VdpOutputSurface surface,uint32_t clip_width,uint32_t clip_height,VdpTime earliest_presentation_time)4188 static VdpStatus _vdp_cap_presentation_queue_display(
4189     VdpPresentationQueue presentation_queue,
4190     VdpOutputSurface     surface,
4191     uint32_t             clip_width,
4192     uint32_t             clip_height,
4193     VdpTime              earliest_presentation_time
4194 )
4195 {
4196     VdpStatus ret;
4197 
4198     fputs("vdp_presentation_queue_display(", _vdp_cap_data.fp);
4199     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4200         fprintf(
4201             _vdp_cap_data.fp,
4202             "%u, %u, %u, %u, %" PRIu64,
4203             presentation_queue,
4204             surface,
4205             clip_width,
4206             clip_height,
4207             earliest_presentation_time
4208         );
4209     }
4210     fputs(")\n", _vdp_cap_data.fp);
4211 
4212     ret = _vdp_cap_data.vdp_presentation_queue_display(
4213         presentation_queue,
4214         surface,
4215         clip_width,
4216         clip_height,
4217         earliest_presentation_time
4218     );
4219 
4220     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4221         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
4222     }
4223 
4224     return ret;
4225 }
4226 
_vdp_cap_presentation_queue_block_until_surface_idle(VdpPresentationQueue presentation_queue,VdpOutputSurface surface,VdpTime * first_presentation_time)4227 static VdpStatus _vdp_cap_presentation_queue_block_until_surface_idle(
4228     VdpPresentationQueue presentation_queue,
4229     VdpOutputSurface     surface,
4230     /* output parameters follow */
4231     VdpTime *            first_presentation_time
4232 )
4233 {
4234     VdpStatus ret;
4235 
4236     fputs("vdp_presentation_queue_block_until_surface_idle(", _vdp_cap_data.fp);
4237     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4238         fprintf(
4239             _vdp_cap_data.fp,
4240             "%u, %u, %s",
4241             presentation_queue,
4242             surface,
4243             first_presentation_time ? "-" : "NULL"
4244         );
4245     }
4246     fputs(")\n", _vdp_cap_data.fp);
4247 
4248     ret = _vdp_cap_data.vdp_presentation_queue_block_until_surface_idle(
4249         presentation_queue,
4250         surface,
4251         first_presentation_time
4252     );
4253 
4254     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4255         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
4256         if (ret == VDP_STATUS_OK) {
4257             if (first_presentation_time) {
4258                 fprintf(_vdp_cap_data.fp, ", %" PRIu64, *first_presentation_time);
4259             }
4260             else {
4261                 fputs(", ???", _vdp_cap_data.fp);
4262             }
4263         }
4264         fputs("\n", _vdp_cap_data.fp);
4265     }
4266 
4267     return ret;
4268 }
4269 
_vdp_cap_presentation_queue_query_surface_status(VdpPresentationQueue presentation_queue,VdpOutputSurface surface,VdpPresentationQueueStatus * status,VdpTime * first_presentation_time)4270 static VdpStatus _vdp_cap_presentation_queue_query_surface_status(
4271     VdpPresentationQueue         presentation_queue,
4272     VdpOutputSurface             surface,
4273     /* output parameters follow */
4274     VdpPresentationQueueStatus * status,
4275     VdpTime *                    first_presentation_time
4276 )
4277 {
4278     VdpStatus ret;
4279 
4280     fputs("vdp_presentation_queue_query_surface_status(", _vdp_cap_data.fp);
4281     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4282         fprintf(
4283             _vdp_cap_data.fp,
4284             "%u, %u, %s, %s",
4285             presentation_queue,
4286             surface,
4287             status ? "-" : "NULL",
4288             first_presentation_time ? "-" : "NULL"
4289         );
4290     }
4291     fputs(")\n", _vdp_cap_data.fp);
4292 
4293     ret = _vdp_cap_data.vdp_presentation_queue_query_surface_status(
4294         presentation_queue,
4295         surface,
4296         status,
4297         first_presentation_time
4298     );
4299 
4300     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4301         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
4302         if (ret == VDP_STATUS_OK) {
4303             if (status) {
4304                 fprintf(_vdp_cap_data.fp, ", %d", *status);
4305             }
4306             else {
4307                 fputs(", ???", _vdp_cap_data.fp);
4308             }
4309             if (first_presentation_time) {
4310                 fprintf(_vdp_cap_data.fp, ", %" PRIu64, *first_presentation_time);
4311             }
4312             else {
4313                 fputs(", ???", _vdp_cap_data.fp);
4314             }
4315         }
4316         fputs("\n", _vdp_cap_data.fp);
4317     }
4318 
4319     return ret;
4320 }
4321 
_vdp_cap_preemption_callback_register(VdpDevice device,VdpPreemptionCallback callback,void * context)4322 static VdpStatus _vdp_cap_preemption_callback_register(
4323     VdpDevice             device,
4324     VdpPreemptionCallback callback,
4325     void *                context
4326 )
4327 {
4328     VdpStatus ret;
4329 
4330     fputs("vdp_preemption_callback_register(", _vdp_cap_data.fp);
4331     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4332         fprintf(
4333             _vdp_cap_data.fp,
4334             "%u, %p, %p",
4335             device,
4336             callback,
4337             context
4338         );
4339     }
4340     fputs(")\n", _vdp_cap_data.fp);
4341 
4342     ret = _vdp_cap_data.vdp_preemption_callback_register(
4343         device,
4344         callback,
4345         context
4346     );
4347 
4348     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4349         fprintf(_vdp_cap_data.fp, "    -> %d\n", ret);
4350     }
4351 
4352     return ret;
4353 }
4354 
_vdp_cap_presentation_queue_target_create_x11(VdpDevice device,Drawable drawable,VdpPresentationQueueTarget * target)4355 static VdpStatus _vdp_cap_presentation_queue_target_create_x11(
4356     VdpDevice                    device,
4357     Drawable                     drawable,
4358     /* output parameters follow */
4359     VdpPresentationQueueTarget * target
4360 )
4361 {
4362     VdpStatus ret;
4363 
4364     fprintf(_vdp_cap_data.fp, "vdp_presentation_queue_target_create_x11(");
4365     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4366         fprintf(
4367             _vdp_cap_data.fp,
4368             "%u, %lu, %s",
4369             device,
4370             drawable,
4371             target ? "-" : "NULL"
4372         );
4373     }
4374     fputs(")\n", _vdp_cap_data.fp);
4375 
4376     ret = _vdp_cap_data.vdp_presentation_queue_target_create_x11(
4377         device,
4378         drawable,
4379         target
4380     );
4381 
4382     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4383         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
4384         if (ret == VDP_STATUS_OK) {
4385             if (target) {
4386                 fprintf(_vdp_cap_data.fp, ", %u", *target);
4387             }
4388             else {
4389                 fputs(", ???", _vdp_cap_data.fp);
4390             }
4391         }
4392         fputs("\n", _vdp_cap_data.fp);
4393     }
4394 
4395     return ret;
4396 }
4397 
_vdp_cap_get_proc_address(VdpDevice device,VdpFuncId function_id,void ** function_pointer)4398 static VdpStatus _vdp_cap_get_proc_address(
4399     VdpDevice device,
4400     VdpFuncId function_id,
4401     /* output parameters follow */
4402     void * *  function_pointer
4403 )
4404 {
4405     VdpStatus ret;
4406 
4407     fputs("vdp_get_proc_address(", _vdp_cap_data.fp);
4408     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4409         fprintf(
4410             _vdp_cap_data.fp,
4411             "%u, %u, %s",
4412             device,
4413             function_id,
4414             function_pointer ? "-" : "NULL"
4415         );
4416     }
4417     fputs(")\n", _vdp_cap_data.fp);
4418 
4419     if (device != _vdp_cap_data.vdp_device) {
4420         _VDP_TRACE_ERROR_BREAKPOINT();
4421         ret =  VDP_STATUS_ERROR;
4422     }
4423     else if (!function_pointer) {
4424         _VDP_TRACE_ERROR_BREAKPOINT();
4425         ret =  VDP_STATUS_ERROR;
4426     }
4427     else {
4428         ret = VDP_STATUS_OK;
4429         *function_pointer = 0;
4430 
4431         switch (function_id) {
4432         case VDP_FUNC_ID_GET_ERROR_STRING:
4433             if (_vdp_cap_data.vdp_get_error_string) {
4434                 *function_pointer = (void *)&_vdp_cap_get_error_string;
4435             }
4436             break;
4437         case VDP_FUNC_ID_GET_PROC_ADDRESS:
4438             if (_vdp_cap_data.vdp_get_proc_address) {
4439                 *function_pointer = (void *)&_vdp_cap_get_proc_address;
4440             }
4441             break;
4442         case VDP_FUNC_ID_GET_API_VERSION:
4443             if (_vdp_cap_data.vdp_get_api_version) {
4444                 *function_pointer = (void *)&_vdp_cap_get_api_version;
4445             }
4446             break;
4447         case VDP_FUNC_ID_GET_INFORMATION_STRING:
4448             if (_vdp_cap_data.vdp_get_information_string) {
4449                 *function_pointer = (void *)&_vdp_cap_get_information_string;
4450             }
4451             break;
4452         case VDP_FUNC_ID_DEVICE_DESTROY:
4453             if (_vdp_cap_data.vdp_device_destroy) {
4454                 *function_pointer = (void *)&_vdp_cap_device_destroy;
4455             }
4456             break;
4457         case VDP_FUNC_ID_GENERATE_CSC_MATRIX:
4458             if (_vdp_cap_data.vdp_generate_csc_matrix) {
4459                 *function_pointer = (void *)&_vdp_cap_generate_csc_matrix;
4460             }
4461             break;
4462         case VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES:
4463             if (_vdp_cap_data.vdp_video_surface_query_capabilities) {
4464                 *function_pointer = (void *)&_vdp_cap_video_surface_query_capabilities;
4465             }
4466             break;
4467         case VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES:
4468             if (_vdp_cap_data.vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities) {
4469                 *function_pointer = (void *)&_vdp_cap_video_surface_query_get_put_bits_y_cb_cr_capabilities;
4470             }
4471             break;
4472         case VDP_FUNC_ID_VIDEO_SURFACE_CREATE:
4473             if (_vdp_cap_data.vdp_video_surface_create) {
4474                 *function_pointer = (void *)&_vdp_cap_video_surface_create;
4475             }
4476             break;
4477         case VDP_FUNC_ID_VIDEO_SURFACE_DESTROY:
4478             if (_vdp_cap_data.vdp_video_surface_destroy) {
4479                 *function_pointer = (void *)&_vdp_cap_video_surface_destroy;
4480             }
4481             break;
4482         case VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS:
4483             if (_vdp_cap_data.vdp_video_surface_get_parameters) {
4484                 *function_pointer = (void *)&_vdp_cap_video_surface_get_parameters;
4485             }
4486             break;
4487         case VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR:
4488             if (_vdp_cap_data.vdp_video_surface_get_bits_y_cb_cr) {
4489                 *function_pointer = (void *)&_vdp_cap_video_surface_get_bits_y_cb_cr;
4490             }
4491             break;
4492         case VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR:
4493             if (_vdp_cap_data.vdp_video_surface_put_bits_y_cb_cr) {
4494                 *function_pointer = (void *)&_vdp_cap_video_surface_put_bits_y_cb_cr;
4495             }
4496             break;
4497         case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES:
4498             if (_vdp_cap_data.vdp_output_surface_query_capabilities) {
4499                 *function_pointer = (void *)&_vdp_cap_output_surface_query_capabilities;
4500             }
4501             break;
4502         case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES:
4503             if (_vdp_cap_data.vdp_output_surface_query_get_put_bits_native_capabilities) {
4504                 *function_pointer = (void *)&_vdp_cap_output_surface_query_get_put_bits_native_capabilities;
4505             }
4506             break;
4507         case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_INDEXED_CAPABILITIES:
4508             if (_vdp_cap_data.vdp_output_surface_query_put_bits_indexed_capabilities) {
4509                 *function_pointer = (void *)&_vdp_cap_output_surface_query_put_bits_indexed_capabilities;
4510             }
4511             break;
4512         case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES:
4513             if (_vdp_cap_data.vdp_output_surface_query_put_bits_y_cb_cr_capabilities) {
4514                 *function_pointer = (void *)&_vdp_cap_output_surface_query_put_bits_y_cb_cr_capabilities;
4515             }
4516             break;
4517         case VDP_FUNC_ID_OUTPUT_SURFACE_CREATE:
4518             if (_vdp_cap_data.vdp_output_surface_create) {
4519                 *function_pointer = (void *)&_vdp_cap_output_surface_create;
4520             }
4521             break;
4522         case VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY:
4523             if (_vdp_cap_data.vdp_output_surface_destroy) {
4524                 *function_pointer = (void *)&_vdp_cap_output_surface_destroy;
4525             }
4526             break;
4527         case VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS:
4528             if (_vdp_cap_data.vdp_output_surface_get_parameters) {
4529                 *function_pointer = (void *)&_vdp_cap_output_surface_get_parameters;
4530             }
4531             break;
4532         case VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE:
4533             if (_vdp_cap_data.vdp_output_surface_get_bits_native) {
4534                 *function_pointer = (void *)&_vdp_cap_output_surface_get_bits_native;
4535             }
4536             break;
4537         case VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE:
4538             if (_vdp_cap_data.vdp_output_surface_put_bits_native) {
4539                 *function_pointer = (void *)&_vdp_cap_output_surface_put_bits_native;
4540             }
4541             break;
4542         case VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED:
4543             if (_vdp_cap_data.vdp_output_surface_put_bits_indexed) {
4544                 *function_pointer = (void *)&_vdp_cap_output_surface_put_bits_indexed;
4545             }
4546             break;
4547         case VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR:
4548             if (_vdp_cap_data.vdp_output_surface_put_bits_y_cb_cr) {
4549                 *function_pointer = (void *)&_vdp_cap_output_surface_put_bits_y_cb_cr;
4550             }
4551             break;
4552         case VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES:
4553             if (_vdp_cap_data.vdp_bitmap_surface_query_capabilities) {
4554                 *function_pointer = (void *)&_vdp_cap_bitmap_surface_query_capabilities;
4555             }
4556             break;
4557         case VDP_FUNC_ID_BITMAP_SURFACE_CREATE:
4558             if (_vdp_cap_data.vdp_bitmap_surface_create) {
4559                 *function_pointer = (void *)&_vdp_cap_bitmap_surface_create;
4560             }
4561             break;
4562         case VDP_FUNC_ID_BITMAP_SURFACE_DESTROY:
4563             if (_vdp_cap_data.vdp_bitmap_surface_destroy) {
4564                 *function_pointer = (void *)&_vdp_cap_bitmap_surface_destroy;
4565             }
4566             break;
4567         case VDP_FUNC_ID_BITMAP_SURFACE_GET_PARAMETERS:
4568             if (_vdp_cap_data.vdp_bitmap_surface_get_parameters) {
4569                 *function_pointer = (void *)&_vdp_cap_bitmap_surface_get_parameters;
4570             }
4571             break;
4572         case VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE:
4573             if (_vdp_cap_data.vdp_bitmap_surface_put_bits_native) {
4574                 *function_pointer = (void *)&_vdp_cap_bitmap_surface_put_bits_native;
4575             }
4576             break;
4577         case VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE:
4578             if (_vdp_cap_data.vdp_output_surface_render_output_surface) {
4579                 *function_pointer = (void *)&_vdp_cap_output_surface_render_output_surface;
4580             }
4581             break;
4582         case VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE:
4583             if (_vdp_cap_data.vdp_output_surface_render_bitmap_surface) {
4584                 *function_pointer = (void *)&_vdp_cap_output_surface_render_bitmap_surface;
4585             }
4586             break;
4587         case VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES:
4588             if (_vdp_cap_data.vdp_decoder_query_capabilities) {
4589                 *function_pointer = (void *)&_vdp_cap_decoder_query_capabilities;
4590             }
4591             break;
4592         case VDP_FUNC_ID_DECODER_CREATE:
4593             if (_vdp_cap_data.vdp_decoder_create) {
4594                 *function_pointer = (void *)&_vdp_cap_decoder_create;
4595             }
4596             break;
4597         case VDP_FUNC_ID_DECODER_DESTROY:
4598             if (_vdp_cap_data.vdp_decoder_destroy) {
4599                 *function_pointer = (void *)&_vdp_cap_decoder_destroy;
4600             }
4601             break;
4602         case VDP_FUNC_ID_DECODER_GET_PARAMETERS:
4603             if (_vdp_cap_data.vdp_decoder_get_parameters) {
4604                 *function_pointer = (void *)&_vdp_cap_decoder_get_parameters;
4605             }
4606             break;
4607         case VDP_FUNC_ID_DECODER_RENDER:
4608             if (_vdp_cap_data.vdp_decoder_render) {
4609                 *function_pointer = (void *)&_vdp_cap_decoder_render;
4610             }
4611             break;
4612         case VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT:
4613             if (_vdp_cap_data.vdp_video_mixer_query_feature_support) {
4614                 *function_pointer = (void *)&_vdp_cap_video_mixer_query_feature_support;
4615             }
4616             break;
4617         case VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT:
4618             if (_vdp_cap_data.vdp_video_mixer_query_parameter_support) {
4619                 *function_pointer = (void *)&_vdp_cap_video_mixer_query_parameter_support;
4620             }
4621             break;
4622         case VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT:
4623             if (_vdp_cap_data.vdp_video_mixer_query_attribute_support) {
4624                 *function_pointer = (void *)&_vdp_cap_video_mixer_query_attribute_support;
4625             }
4626             break;
4627         case VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE:
4628             if (_vdp_cap_data.vdp_video_mixer_query_parameter_value_range) {
4629                 *function_pointer = (void *)&_vdp_cap_video_mixer_query_parameter_value_range;
4630             }
4631             break;
4632         case VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE:
4633             if (_vdp_cap_data.vdp_video_mixer_query_attribute_value_range) {
4634                 *function_pointer = (void *)&_vdp_cap_video_mixer_query_attribute_value_range;
4635             }
4636             break;
4637         case VDP_FUNC_ID_VIDEO_MIXER_CREATE:
4638             if (_vdp_cap_data.vdp_video_mixer_create) {
4639                 *function_pointer = (void *)&_vdp_cap_video_mixer_create;
4640             }
4641             break;
4642         case VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES:
4643             if (_vdp_cap_data.vdp_video_mixer_set_feature_enables) {
4644                 *function_pointer = (void *)&_vdp_cap_video_mixer_set_feature_enables;
4645             }
4646             break;
4647         case VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES:
4648             if (_vdp_cap_data.vdp_video_mixer_set_attribute_values) {
4649                 *function_pointer = (void *)&_vdp_cap_video_mixer_set_attribute_values;
4650             }
4651             break;
4652         case VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_SUPPORT:
4653             if (_vdp_cap_data.vdp_video_mixer_get_feature_support) {
4654                 *function_pointer = (void *)&_vdp_cap_video_mixer_get_feature_support;
4655             }
4656             break;
4657         case VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES:
4658             if (_vdp_cap_data.vdp_video_mixer_get_feature_enables) {
4659                 *function_pointer = (void *)&_vdp_cap_video_mixer_get_feature_enables;
4660             }
4661             break;
4662         case VDP_FUNC_ID_VIDEO_MIXER_GET_PARAMETER_VALUES:
4663             if (_vdp_cap_data.vdp_video_mixer_get_parameter_values) {
4664                 *function_pointer = (void *)&_vdp_cap_video_mixer_get_parameter_values;
4665             }
4666             break;
4667         case VDP_FUNC_ID_VIDEO_MIXER_GET_ATTRIBUTE_VALUES:
4668             if (_vdp_cap_data.vdp_video_mixer_get_attribute_values) {
4669                 *function_pointer = (void *)&_vdp_cap_video_mixer_get_attribute_values;
4670             }
4671             break;
4672         case VDP_FUNC_ID_VIDEO_MIXER_DESTROY:
4673             if (_vdp_cap_data.vdp_video_mixer_destroy) {
4674                 *function_pointer = (void *)&_vdp_cap_video_mixer_destroy;
4675             }
4676             break;
4677         case VDP_FUNC_ID_VIDEO_MIXER_RENDER:
4678             if (_vdp_cap_data.vdp_video_mixer_render) {
4679                 *function_pointer = (void *)&_vdp_cap_video_mixer_render;
4680             }
4681             break;
4682         case VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY:
4683             if (_vdp_cap_data.vdp_presentation_queue_target_destroy) {
4684                 *function_pointer = (void *)&_vdp_cap_presentation_queue_target_destroy;
4685             }
4686             break;
4687         case VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE:
4688             if (_vdp_cap_data.vdp_presentation_queue_create) {
4689                 *function_pointer = (void *)&_vdp_cap_presentation_queue_create;
4690             }
4691             break;
4692         case VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY:
4693             if (_vdp_cap_data.vdp_presentation_queue_destroy) {
4694                 *function_pointer = (void *)&_vdp_cap_presentation_queue_destroy;
4695             }
4696             break;
4697         case VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR:
4698             if (_vdp_cap_data.vdp_presentation_queue_set_background_color) {
4699                 *function_pointer = (void *)&_vdp_cap_presentation_queue_set_background_color;
4700             }
4701             break;
4702         case VDP_FUNC_ID_PRESENTATION_QUEUE_GET_BACKGROUND_COLOR:
4703             if (_vdp_cap_data.vdp_presentation_queue_get_background_color) {
4704                 *function_pointer = (void *)&_vdp_cap_presentation_queue_get_background_color;
4705             }
4706             break;
4707         case VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME:
4708             if (_vdp_cap_data.vdp_presentation_queue_get_time) {
4709                 *function_pointer = (void *)&_vdp_cap_presentation_queue_get_time;
4710             }
4711             break;
4712         case VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY:
4713             if (_vdp_cap_data.vdp_presentation_queue_display) {
4714                 *function_pointer = (void *)&_vdp_cap_presentation_queue_display;
4715             }
4716             break;
4717         case VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE:
4718             if (_vdp_cap_data.vdp_presentation_queue_block_until_surface_idle) {
4719                 *function_pointer = (void *)&_vdp_cap_presentation_queue_block_until_surface_idle;
4720             }
4721             break;
4722         case VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS:
4723             if (_vdp_cap_data.vdp_presentation_queue_query_surface_status) {
4724                 *function_pointer = (void *)&_vdp_cap_presentation_queue_query_surface_status;
4725             }
4726             break;
4727         case VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER:
4728             if (_vdp_cap_data.vdp_preemption_callback_register) {
4729                 *function_pointer = (void *)&_vdp_cap_preemption_callback_register;
4730             }
4731             break;
4732         case VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11:
4733             if (_vdp_cap_data.vdp_presentation_queue_target_create_x11) {
4734                 *function_pointer = (void *)&_vdp_cap_presentation_queue_target_create_x11;
4735             }
4736             break;
4737         default:
4738             fprintf(
4739                 _vdp_cap_data.fp,
4740                 "VDPAU capture: Not able to proxy function %d",
4741                 function_id
4742             );
4743             ret = _vdp_cap_data.vdp_get_proc_address(device, function_id, function_pointer);
4744             break;
4745         }
4746 
4747         if ((ret == VDP_STATUS_OK) && !*function_pointer) {
4748             ret = VDP_STATUS_INVALID_FUNC_ID;
4749         }
4750     }
4751 
4752     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4753         fprintf(_vdp_cap_data.fp, "    -> %d", ret);
4754         if (ret == VDP_STATUS_OK) {
4755             fprintf(
4756                 _vdp_cap_data.fp,
4757                 ", %p",
4758                 *function_pointer
4759             );
4760         }
4761         fputs("\n", _vdp_cap_data.fp);
4762     }
4763 
4764     return ret;
4765 }
4766 
vdp_trace_set_backend_handle(void * driver_dll_handle)4767 extern "C" void vdp_trace_set_backend_handle(
4768     void * driver_dll_handle
4769 )
4770 {
4771     _vdp_cap_data.dll = driver_dll_handle;
4772 }
4773 
4774 extern "C" VdpDeviceCreateX11 vdp_trace_device_create_x11;
4775 
vdp_trace_device_create_x11(Display * display,int screen,VdpDevice * device,VdpGetProcAddress ** get_proc_address)4776 VdpStatus vdp_trace_device_create_x11(
4777     Display *             display,
4778     int                   screen,
4779     /* output parameters follow */
4780     VdpDevice *           device,
4781     VdpGetProcAddress * * get_proc_address
4782 )
4783 {
4784     if (!device || !get_proc_address) {
4785         _VDP_TRACE_ERROR_BREAKPOINT();
4786         return VDP_STATUS_INVALID_POINTER;
4787     }
4788 
4789     // For now, the capture library only allows a single VdpDevice
4790     // This could probably be fixed by dynamically associating most of
4791     // _vdp_cap_data with a VdpDevice handle.
4792     if (_vdp_cap_data.fp) {
4793         fprintf(_vdp_cap_data.fp,
4794             "VDPAU trace: Multiple devices created; "
4795             "will return get_proc_address results from the latest only\n"
4796         );
4797     }
4798     else {
4799         _vdp_cap_data.level = 0;
4800         char const * vdpau_trace = secure_getenv("VDPAU_TRACE");
4801         if (vdpau_trace) {
4802             _vdp_cap_data.level = atoi(vdpau_trace);
4803         }
4804 
4805         _vdp_cap_data.fp = 0;
4806         char const * vdpau_trace_file = secure_getenv("VDPAU_TRACE_FILE");
4807         if (vdpau_trace_file && strlen(vdpau_trace_file)) {
4808             if (vdpau_trace_file[0] == '&') {
4809                 int fd = atoi(&vdpau_trace_file[1]);
4810                 _vdp_cap_data.fp = fdopen(fd, "wt");
4811             }
4812             else {
4813                 _vdp_cap_data.fp = fopen(vdpau_trace_file, "wt");
4814             }
4815             if (!_vdp_cap_data.fp) {
4816                 fprintf(
4817                     stderr,
4818                     "VDPAU capture: ERROR: Can't open '%s' for writing, defaulting to stderr\n",
4819                     vdpau_trace_file
4820                 );
4821             }
4822         }
4823         if (!_vdp_cap_data.fp) {
4824             _vdp_cap_data.fp = stderr;
4825         }
4826         fprintf(_vdp_cap_data.fp, "VDPAU capture: Enabled\n");
4827     }
4828 
4829     fprintf(_vdp_cap_data.fp, "vdp_imp_device_create_x11(");
4830     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4831         fprintf(
4832             _vdp_cap_data.fp,
4833             "%p, %d, -, -",
4834             display,
4835             screen
4836         );
4837     }
4838     fputs(")\n", _vdp_cap_data.fp);
4839 
4840     VdpStatus vdp_st = VDP_STATUS_ERROR;
4841 
4842     VdpDeviceCreateX11 * vdp_imp_device_create_x11;
4843     vdp_imp_device_create_x11 = (VdpDeviceCreateX11*)dlsym(
4844         _vdp_cap_data.dll,
4845          "vdp_imp_device_create_x11"
4846     );
4847     if (!vdp_imp_device_create_x11) {
4848         _VDP_TRACE_ERROR_BREAKPOINT();
4849         vdp_st = VDP_STATUS_NO_IMPLEMENTATION;
4850         goto done;
4851     }
4852 
4853     vdp_st = vdp_imp_device_create_x11(
4854         display,
4855         screen,
4856         &_vdp_cap_data.vdp_device,
4857         &_vdp_cap_data.vdp_get_proc_address
4858     );
4859     if (vdp_st != VDP_STATUS_OK) {
4860         _VDP_TRACE_ERROR_BREAKPOINT();
4861         goto done;
4862     }
4863 
4864     *device = _vdp_cap_data.vdp_device;
4865     *get_proc_address = _vdp_cap_get_proc_address;
4866 
4867 #define GET_POINTER(_id_, _var_) \
4868     vdp_st = _vdp_cap_data.vdp_get_proc_address( \
4869         _vdp_cap_data.vdp_device, \
4870         (_id_), \
4871         (void * *)&_vdp_cap_data._var_ \
4872     ); \
4873     if (vdp_st != VDP_STATUS_OK) { \
4874         _vdp_cap_data._var_ = 0; \
4875     }
4876 
4877     GET_POINTER(VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER,                          vdp_preemption_callback_register);
4878     GET_POINTER(VDP_FUNC_ID_GET_ERROR_STRING,                                      vdp_get_error_string);
4879     GET_POINTER(VDP_FUNC_ID_GET_API_VERSION,                                       vdp_get_api_version);
4880     GET_POINTER(VDP_FUNC_ID_GET_INFORMATION_STRING,                                vdp_get_information_string);
4881     GET_POINTER(VDP_FUNC_ID_DEVICE_DESTROY,                                        vdp_device_destroy);
4882     GET_POINTER(VDP_FUNC_ID_GENERATE_CSC_MATRIX,                                   vdp_generate_csc_matrix);
4883     GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES,                      vdp_video_surface_query_capabilities);
4884     GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities);
4885     GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_CREATE,                                  vdp_video_surface_create);
4886     GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY,                                 vdp_video_surface_destroy);
4887     GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS,                          vdp_video_surface_get_parameters);
4888     GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR,                        vdp_video_surface_get_bits_y_cb_cr);
4889     GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR,                        vdp_video_surface_put_bits_y_cb_cr);
4890     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES,                     vdp_output_surface_query_capabilities);
4891     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES, vdp_output_surface_query_get_put_bits_native_capabilities);
4892     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_INDEXED_CAPABILITIES,    vdp_output_surface_query_put_bits_indexed_capabilities);
4893     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES,    vdp_output_surface_query_put_bits_y_cb_cr_capabilities);
4894     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_CREATE,                                 vdp_output_surface_create);
4895     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY,                                vdp_output_surface_destroy);
4896     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS,                         vdp_output_surface_get_parameters);
4897     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE,                        vdp_output_surface_get_bits_native);
4898     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE,                        vdp_output_surface_put_bits_native);
4899     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED,                       vdp_output_surface_put_bits_indexed);
4900     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR,                       vdp_output_surface_put_bits_y_cb_cr);
4901     GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES,                     vdp_bitmap_surface_query_capabilities);
4902     GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_CREATE,                                 vdp_bitmap_surface_create);
4903     GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_DESTROY,                                vdp_bitmap_surface_destroy);
4904     GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_GET_PARAMETERS,                         vdp_bitmap_surface_get_parameters);
4905     GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE,                        vdp_bitmap_surface_put_bits_native);
4906     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE,                  vdp_output_surface_render_output_surface);
4907     GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE,                  vdp_output_surface_render_bitmap_surface);
4908     GET_POINTER(VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES,                            vdp_decoder_query_capabilities);
4909     GET_POINTER(VDP_FUNC_ID_DECODER_CREATE,                                        vdp_decoder_create);
4910     GET_POINTER(VDP_FUNC_ID_DECODER_DESTROY,                                       vdp_decoder_destroy);
4911     GET_POINTER(VDP_FUNC_ID_DECODER_GET_PARAMETERS,                                vdp_decoder_get_parameters);
4912     GET_POINTER(VDP_FUNC_ID_DECODER_RENDER,                                        vdp_decoder_render);
4913     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT,                     vdp_video_mixer_query_feature_support);
4914     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT,                   vdp_video_mixer_query_parameter_support);
4915     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT,                   vdp_video_mixer_query_attribute_support);
4916     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE,               vdp_video_mixer_query_parameter_value_range);
4917     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE,               vdp_video_mixer_query_attribute_value_range);
4918     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_CREATE,                                    vdp_video_mixer_create);
4919     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES,                       vdp_video_mixer_set_feature_enables);
4920     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES,                      vdp_video_mixer_set_attribute_values);
4921     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_SUPPORT,                       vdp_video_mixer_get_feature_support);
4922     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES,                       vdp_video_mixer_get_feature_enables);
4923     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_PARAMETER_VALUES,                      vdp_video_mixer_get_parameter_values);
4924     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_ATTRIBUTE_VALUES,                      vdp_video_mixer_get_attribute_values);
4925     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_DESTROY,                                   vdp_video_mixer_destroy);
4926     GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_RENDER,                                    vdp_video_mixer_render);
4927     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY,                     vdp_presentation_queue_target_destroy);
4928     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE,                             vdp_presentation_queue_create);
4929     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY,                            vdp_presentation_queue_destroy);
4930     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR,               vdp_presentation_queue_set_background_color);
4931     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_GET_BACKGROUND_COLOR,               vdp_presentation_queue_get_background_color);
4932     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME,                           vdp_presentation_queue_get_time);
4933     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY,                            vdp_presentation_queue_display);
4934     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE,           vdp_presentation_queue_block_until_surface_idle);
4935     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS,               vdp_presentation_queue_query_surface_status);
4936     GET_POINTER(VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER,                          vdp_preemption_callback_register);
4937     GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11,                  vdp_presentation_queue_target_create_x11);
4938 
4939     vdp_st = VDP_STATUS_OK;
4940 
4941 done:
4942     if (_vdp_cap_data.level >= LEVEL_PARAMS) {
4943         fprintf(_vdp_cap_data.fp, "    -> %d", vdp_st);
4944         if (vdp_st == VDP_STATUS_OK) {
4945             fprintf(
4946                 _vdp_cap_data.fp,
4947                 ", %x, %p",
4948                 _vdp_cap_data.vdp_device,
4949                 _vdp_cap_data.vdp_get_proc_address
4950             );
4951         }
4952         fputs("\n", _vdp_cap_data.fp);
4953     }
4954 
4955     return vdp_st;
4956 }
4957 
4958