r300: Zero-initialize register for NV_vertex_program
[mesa.git] / src / xvmc / context.c
1 #include <assert.h>
2 #include <X11/Xlib.h>
3 #include <X11/extensions/XvMClib.h>
4 #include <pipe/p_context.h>
5 #include <vl_display.h>
6 #include <vl_screen.h>
7 #include <vl_context.h>
8 #include <vl_winsys.h>
9
10 static Status Validate
11 (
12 Display *display,
13 XvPortID port,
14 int surface_type_id,
15 unsigned int width,
16 unsigned int height,
17 int flags,
18 int *found_port,
19 int *chroma_format,
20 int *mc_type
21 )
22 {
23 unsigned int found_surface = 0;
24 XvAdaptorInfo *adaptor_info;
25 unsigned int num_adaptors;
26 int num_types;
27 unsigned int max_width, max_height;
28 Status ret;
29 unsigned int i, j, k;
30
31 assert(display && chroma_format);
32
33 *found_port = 0;
34
35 ret = XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info);
36 if (ret != Success)
37 return ret;
38
39 /* Scan through all adaptors looking for this port and surface */
40 for (i = 0; i < num_adaptors && !*found_port; ++i)
41 {
42 /* Scan through all ports of this adaptor looking for our port */
43 for (j = 0; j < adaptor_info[i].num_ports && !*found_port; ++j)
44 {
45 /* If this is our port, scan through all its surfaces looking for our surface */
46 if (adaptor_info[i].base_id + j == port)
47 {
48 XvMCSurfaceInfo *surface_info;
49
50 *found_port = 1;
51 surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types);
52
53 if (surface_info)
54 {
55 for (k = 0; k < num_types && !found_surface; ++k)
56 {
57 if (surface_info[k].surface_type_id == surface_type_id)
58 {
59 found_surface = 1;
60 max_width = surface_info[k].max_width;
61 max_height = surface_info[k].max_height;
62 *chroma_format = surface_info[k].chroma_format;
63 *mc_type = surface_info[k].mc_type;
64 }
65 }
66
67 XFree(surface_info);
68 }
69 else
70 {
71 XvFreeAdaptorInfo(adaptor_info);
72 return BadAlloc;
73 }
74 }
75 }
76 }
77
78 XvFreeAdaptorInfo(adaptor_info);
79
80 if (!*found_port)
81 return XvBadPort;
82 if (!found_surface)
83 return BadMatch;
84 if (width > max_width || height > max_height)
85 return BadValue;
86 if (flags != XVMC_DIRECT && flags != 0)
87 return BadValue;
88
89 return Success;
90 }
91
92 static enum vlProfile ProfileToVL(int xvmc_profile)
93 {
94 if (xvmc_profile & XVMC_MPEG_1)
95 assert(0);
96 else if (xvmc_profile & XVMC_MPEG_2)
97 return vlProfileMpeg2Main;
98 else if (xvmc_profile & XVMC_H263)
99 assert(0);
100 else if (xvmc_profile & XVMC_MPEG_4)
101 assert(0);
102 else
103 assert(0);
104
105 return -1;
106 }
107
108 static enum vlEntryPoint EntryToVL(int xvmc_entry)
109 {
110 return xvmc_entry & XVMC_IDCT ? vlEntryPointIDCT : vlEntryPointMC;
111 }
112
113 static enum vlFormat FormatToVL(int xvmc_format)
114 {
115 switch (xvmc_format)
116 {
117 case XVMC_CHROMA_FORMAT_420:
118 return vlFormatYCbCr420;
119 case XVMC_CHROMA_FORMAT_422:
120 return vlFormatYCbCr422;
121 case XVMC_CHROMA_FORMAT_444:
122 return vlFormatYCbCr444;
123 default:
124 assert(0);
125 }
126
127 return -1;
128 }
129
130 Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context)
131 {
132 int found_port;
133 int chroma_format;
134 int mc_type;
135 Status ret;
136 struct vlDisplay *vl_dpy;
137 struct vlScreen *vl_scrn;
138 struct vlContext *vl_ctx;
139 struct pipe_context *pipe;
140
141 assert(display);
142
143 if (!context)
144 return XvMCBadContext;
145
146 ret = Validate(display, port, surface_type_id, width, height, flags, &found_port, &chroma_format, &mc_type);
147
148 /* XXX: Success and XvBadPort have the same value */
149 if (ret != Success || !found_port)
150 return ret;
151
152 /* XXX: Assumes default screen, should check which screen port is on */
153 pipe = create_pipe_context(display, XDefaultScreen(display));
154
155 assert(pipe);
156
157 vlCreateDisplay(display, &vl_dpy);
158 vlCreateScreen(vl_dpy, XDefaultScreen(display), pipe->screen, &vl_scrn);
159 vlCreateContext
160 (
161 vl_scrn,
162 pipe,
163 width,
164 height,
165 FormatToVL(chroma_format),
166 ProfileToVL(mc_type),
167 EntryToVL(mc_type),
168 &vl_ctx
169 );
170
171 context->context_id = XAllocID(display);
172 context->surface_type_id = surface_type_id;
173 context->width = width;
174 context->height = height;
175 context->flags = flags;
176 context->port = port;
177 context->privData = vl_ctx;
178
179 return Success;
180 }
181
182 Status XvMCDestroyContext(Display *display, XvMCContext *context)
183 {
184 struct vlContext *vl_ctx;
185 struct vlScreen *vl_screen;
186 struct vlDisplay *vl_dpy;
187 struct pipe_context *pipe;
188
189 assert(display);
190
191 if (!context)
192 return XvMCBadContext;
193
194 vl_ctx = context->privData;
195
196 assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
197
198 pipe = vlGetPipeContext(vl_ctx);
199 vl_screen = vlContextGetScreen(vl_ctx);
200 vl_dpy = vlGetDisplay(vl_screen);
201 vlDestroyContext(vl_ctx);
202 vlDestroyScreen(vl_screen);
203 vlDestroyDisplay(vl_dpy);
204 destroy_pipe_context(pipe);
205
206 return Success;
207 }