[g3dvl] add support for different decoding entry points
[mesa.git] / src / gallium / auxiliary / vl / vl_context.c
1 /**************************************************************************
2 *
3 * Copyright 2009 Younes Manton.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <pipe/p_video_context.h>
29
30 #include <util/u_memory.h>
31 #include <util/u_rect.h>
32 #include <util/u_video.h>
33
34 #include "vl_context.h"
35 #include "vl_compositor.h"
36 #include "vl_mpeg12_decoder.h"
37
38 static void
39 vl_context_destroy(struct pipe_video_context *context)
40 {
41 struct vl_context *ctx = (struct vl_context*)context;
42
43 assert(context);
44
45 ctx->pipe->destroy(ctx->pipe);
46
47 FREE(ctx);
48 }
49
50 static int
51 vl_context_get_param(struct pipe_video_context *context, int param)
52 {
53 struct vl_context *ctx = (struct vl_context*)context;
54
55 assert(context);
56
57 if (param == PIPE_CAP_NPOT_TEXTURES)
58 return !ctx->pot_buffers;
59
60 debug_printf("vl_context: Unknown PIPE_CAP %d\n", param);
61 return 0;
62 }
63
64 static boolean
65 vl_context_is_format_supported(struct pipe_video_context *context,
66 enum pipe_format format,
67 unsigned usage)
68 {
69 struct vl_context *ctx = (struct vl_context*)context;
70
71 assert(context);
72
73 return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format,
74 PIPE_TEXTURE_2D,
75 0, usage);
76 }
77
78 static struct pipe_surface *
79 vl_context_create_surface(struct pipe_video_context *context,
80 struct pipe_resource *resource,
81 const struct pipe_surface *templ)
82 {
83 struct vl_context *ctx = (struct vl_context*)context;
84
85 assert(ctx);
86
87 return ctx->pipe->create_surface(ctx->pipe, resource, templ);
88 }
89
90 static struct pipe_sampler_view *
91 vl_context_create_sampler_view(struct pipe_video_context *context,
92 struct pipe_resource *resource,
93 const struct pipe_sampler_view *templ)
94 {
95 struct vl_context *ctx = (struct vl_context*)context;
96
97 assert(ctx);
98
99 return ctx->pipe->create_sampler_view(ctx->pipe, resource, templ);
100 }
101
102 static void
103 vl_context_upload_sampler(struct pipe_video_context *context,
104 struct pipe_sampler_view *dst,
105 const struct pipe_box *dst_box,
106 const void *src, unsigned src_stride,
107 unsigned src_x, unsigned src_y)
108 {
109 struct vl_context *ctx = (struct vl_context*)context;
110 struct pipe_transfer *transfer;
111 void *map;
112
113 assert(context);
114 assert(dst);
115 assert(dst_box);
116 assert(src);
117
118 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
119 if (!transfer)
120 return;
121
122 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
123 if (!transfer)
124 goto error_map;
125
126 util_copy_rect(map, dst->texture->format, transfer->stride, 0, 0,
127 dst_box->width, dst_box->height,
128 src, src_stride, src_x, src_y);
129
130 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
131
132 error_map:
133 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
134 }
135
136 static void
137 vl_context_clear_sampler(struct pipe_video_context *context,
138 struct pipe_sampler_view *dst,
139 const struct pipe_box *dst_box,
140 const float *rgba)
141 {
142 struct vl_context *ctx = (struct vl_context*)context;
143 struct pipe_transfer *transfer;
144 union util_color uc;
145 void *map;
146 unsigned i;
147
148 assert(context);
149 assert(dst);
150 assert(dst_box);
151 assert(rgba);
152
153 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
154 if (!transfer)
155 return;
156
157 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
158 if (!transfer)
159 goto error_map;
160
161 for ( i = 0; i < 4; ++i)
162 uc.f[i] = rgba[i];
163
164 util_fill_rect(map, dst->texture->format, transfer->stride, 0, 0,
165 dst_box->width, dst_box->height, &uc);
166
167 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
168
169 error_map:
170 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
171 }
172
173 static struct pipe_video_decoder *
174 vl_context_create_decoder(struct pipe_video_context *context,
175 enum pipe_video_profile profile,
176 enum pipe_video_entrypoint entrypoint,
177 enum pipe_video_chroma_format chroma_format,
178 unsigned width, unsigned height)
179 {
180 struct vl_context *ctx = (struct vl_context*)context;
181 unsigned buffer_width, buffer_height;
182
183 assert(context);
184 assert(width > 0 && height > 0);
185
186 buffer_width = ctx->pot_buffers ? util_next_power_of_two(width) : width;
187 buffer_height = ctx->pot_buffers ? util_next_power_of_two(height) : height;
188
189 switch (u_reduce_video_profile(profile)) {
190 case PIPE_VIDEO_CODEC_MPEG12:
191 return vl_create_mpeg12_decoder(context, ctx->pipe, profile, entrypoint,
192 chroma_format, buffer_width, buffer_height);
193 default:
194 return NULL;
195 }
196 return NULL;
197 }
198
199 static struct pipe_video_buffer *
200 vl_context_create_buffer(struct pipe_video_context *context,
201 enum pipe_format buffer_format,
202 enum pipe_video_chroma_format chroma_format,
203 unsigned width, unsigned height)
204 {
205 const enum pipe_format resource_formats[3] = {
206 PIPE_FORMAT_R8_SNORM,
207 PIPE_FORMAT_R8_SNORM,
208 PIPE_FORMAT_R8_SNORM
209 };
210
211 struct vl_context *ctx = (struct vl_context*)context;
212 struct pipe_video_buffer *result;
213 unsigned buffer_width, buffer_height;
214
215 assert(context);
216 assert(width > 0 && height > 0);
217 assert(buffer_format == PIPE_FORMAT_YV12);
218
219 buffer_width = ctx->pot_buffers ? util_next_power_of_two(width) : width;
220 buffer_height = ctx->pot_buffers ? util_next_power_of_two(height) : height;
221
222 result = vl_video_buffer_init(context, ctx->pipe,
223 buffer_width, buffer_height, 1,
224 chroma_format, 3,
225 resource_formats,
226 PIPE_USAGE_STATIC);
227 if (result) // TODO move format handling into vl_video_buffer
228 result->buffer_format = buffer_format;
229
230 return result;
231 }
232
233 static struct pipe_video_compositor *
234 vl_context_create_compositor(struct pipe_video_context *context)
235 {
236 struct vl_context *ctx = (struct vl_context*)context;
237
238 assert(context);
239
240 return vl_compositor_init(context, ctx->pipe);
241 }
242
243 struct pipe_video_context *
244 vl_create_context(struct pipe_context *pipe, bool pot_buffers)
245 {
246 struct vl_context *ctx;
247
248 ctx = CALLOC_STRUCT(vl_context);
249
250 if (!ctx)
251 return NULL;
252
253 ctx->base.screen = pipe->screen;
254
255 ctx->base.destroy = vl_context_destroy;
256 ctx->base.get_param = vl_context_get_param;
257 ctx->base.is_format_supported = vl_context_is_format_supported;
258 ctx->base.create_surface = vl_context_create_surface;
259 ctx->base.create_sampler_view = vl_context_create_sampler_view;
260 ctx->base.clear_sampler = vl_context_clear_sampler;
261 ctx->base.upload_sampler = vl_context_upload_sampler;
262 ctx->base.create_decoder = vl_context_create_decoder;
263 ctx->base.create_buffer = vl_context_create_buffer;
264 ctx->base.create_compositor = vl_context_create_compositor;
265
266 ctx->pipe = pipe;
267 ctx->pot_buffers = pot_buffers;
268
269 return &ctx->base;
270 }