sp_video_context.c 14.3 KB
Newer Older
Younes Manton's avatar
Younes Manton committed
1
/**************************************************************************
Younes Manton's avatar
Younes Manton committed
2
 *
Younes Manton's avatar
Younes Manton committed
3 4
 * Copyright 2009 Younes Manton.
 * All Rights Reserved.
Younes Manton's avatar
Younes Manton committed
5
 *
Younes Manton's avatar
Younes Manton committed
6 7 8 9 10 11 12
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
Younes Manton's avatar
Younes Manton committed
13
 *
Younes Manton's avatar
Younes Manton committed
14 15 16
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
Younes Manton's avatar
Younes Manton committed
17
 *
Younes Manton's avatar
Younes Manton committed
18 19 20 21 22 23 24
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Younes Manton's avatar
Younes Manton committed
25
 *
Younes Manton's avatar
Younes Manton committed
26 27
 **************************************************************************/

Brian Paul's avatar
Brian Paul committed
28 29 30
#include "util/u_inlines.h"
#include "util/u_memory.h"

31
#include "sp_video_context.h"
32
#include <util/u_inlines.h>
33
#include <util/u_memory.h>
Younes Manton's avatar
Younes Manton committed
34
#include <util/u_rect.h>
35
#include <util/u_video.h>
36
#include "sp_public.h"
37
#include "sp_texture.h"
38 39 40 41

static void
sp_mpeg12_destroy(struct pipe_video_context *vpipe)
{
42
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
43

44
   assert(vpipe);
45

46 47 48
   /* Asserted in softpipe_delete_fs_state() for some reason */
   ctx->pipe->bind_vs_state(ctx->pipe, NULL);
   ctx->pipe->bind_fs_state(ctx->pipe, NULL);
49

50 51 52
   ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
   ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
   ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
53

54
   pipe_surface_reference(&ctx->decode_target, NULL);
55 56 57
   vl_compositor_cleanup(&ctx->compositor);
   vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
   ctx->pipe->destroy(ctx->pipe);
58

59
   FREE(ctx);
60 61
}

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
static int
sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
{
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;

   assert(vpipe);

   switch (param) {
      case PIPE_CAP_NPOT_TEXTURES:
         /* XXX: Temporary; not all paths are NPOT-tested */
#if 0
         return ctx->pipe->screen->get_param(ctx->pipe->screen, param);
#endif
         return FALSE;
      case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT:
         return PIPE_FORMAT_AYUV;
      default:
      {
         debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param);
         return 0;
      }
   }
}

static boolean
sp_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
                              enum pipe_format format,
                              unsigned usage,
                              unsigned geom)
{
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;

   assert(vpipe);

   /* XXX: Temporary; not all paths are NPOT-tested */
   if (geom & PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)
      return FALSE;

   return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, PIPE_TEXTURE_2D,
                                                 format, usage, geom);
}

104 105
static void
sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
106 107
                             struct pipe_surface *past,
                             struct pipe_surface *future,
108 109 110 111
                             unsigned num_macroblocks,
                             struct pipe_macroblock *macroblocks,
                             struct pipe_fence_handle **fence)
{
112 113
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
   struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
114

115 116 117 118 119
   assert(vpipe);
   assert(num_macroblocks);
   assert(macroblocks);
   assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
   assert(ctx->decode_target);
120

121
   vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
122 123 124
                                            ctx->decode_target,
                                            past, future, num_macroblocks,
                                            mpeg12_macroblocks, fence);
125 126 127
}

static void
Younes Manton's avatar
Younes Manton committed
128 129 130 131 132
sp_mpeg12_surface_fill(struct pipe_video_context *vpipe,
                       struct pipe_surface *dst,
                       unsigned dstx, unsigned dsty,
                       unsigned width, unsigned height,
                       unsigned value)
133
{
134
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
135

136
   assert(vpipe);
Younes Manton's avatar
Younes Manton committed
137
   assert(dst);
138

Younes Manton's avatar
Younes Manton committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
   if (ctx->pipe->surface_fill)
      ctx->pipe->surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
   else
      util_surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
}

static void
sp_mpeg12_surface_copy(struct pipe_video_context *vpipe,
                       struct pipe_surface *dst,
                       unsigned dstx, unsigned dsty,
                       struct pipe_surface *src,
                       unsigned srcx, unsigned srcy,
                       unsigned width, unsigned height)
{
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;

   assert(vpipe);
   assert(dst);

   if (ctx->pipe->surface_copy)
      ctx->pipe->surface_copy(ctx->pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
   else
      util_surface_copy(ctx->pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, width, height);
162 163 164 165
}

static void
sp_mpeg12_render_picture(struct pipe_video_context     *vpipe,
166
                         struct pipe_surface           *src_surface,
167 168
                         enum pipe_mpeg12_picture_type picture_type,
                         /*unsigned                    num_past_surfaces,
169
                         struct pipe_surface           *past_surfaces,
170
                         unsigned                      num_future_surfaces,
171
                         struct pipe_surface           *future_surfaces,*/
172 173 174 175 176
                         struct pipe_video_rect        *src_area,
                         struct pipe_surface           *dst_surface,
                         struct pipe_video_rect        *dst_area,
                         struct pipe_fence_handle      **fence)
{
177
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
178

179 180 181 182 183
   assert(vpipe);
   assert(src_surface);
   assert(src_area);
   assert(dst_surface);
   assert(dst_area);
184

185 186
   vl_compositor_render(&ctx->compositor, src_surface,
                        picture_type, src_area, dst_surface, dst_area, fence);
187 188
}

189 190
static void
sp_mpeg12_set_picture_background(struct pipe_video_context *vpipe,
191
                                  struct pipe_surface *bg,
192 193 194 195 196 197 198 199 200 201 202 203 204
                                  struct pipe_video_rect *bg_src_rect)
{
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;

   assert(vpipe);
   assert(bg);
   assert(bg_src_rect);

   vl_compositor_set_background(&ctx->compositor, bg, bg_src_rect);
}

static void
sp_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
205
                             struct pipe_surface *layers[],
206 207 208 209 210 211 212 213 214 215 216 217 218
                             struct pipe_video_rect *src_rects[],
                             struct pipe_video_rect *dst_rects[],
                             unsigned num_layers)
{
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;

   assert(vpipe);
   assert((layers && src_rects && dst_rects) ||
          (!layers && !src_rects && !dst_rects));

   vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers);
}

219 220
static void
sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
221
                            struct pipe_surface *dt)
222
{
223
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
224

225 226
   assert(vpipe);
   assert(dt);
227

228
   pipe_surface_reference(&ctx->decode_target, dt);
229 230
}

Younes Manton's avatar
Younes Manton committed
231 232
static void
sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
233 234 235 236 237 238 239 240
{
   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;

   assert(vpipe);

   vl_compositor_set_csc_matrix(&ctx->compositor, mat);
}

241 242 243
static bool
init_pipe_state(struct sp_mpeg12_context *ctx)
{
244 245 246
   struct pipe_rasterizer_state rast;
   struct pipe_blend_state blend;
   struct pipe_depth_stencil_alpha_state dsa;
Jose Fonseca's avatar
Jose Fonseca committed
247
   unsigned i;
248

249
   assert(ctx);
250

251 252 253 254 255 256 257 258 259 260 261 262
   rast.flatshade = 1;
   rast.flatshade_first = 0;
   rast.light_twoside = 0;
   rast.front_winding = PIPE_WINDING_CCW;
   rast.cull_mode = PIPE_WINDING_CW;
   rast.fill_cw = PIPE_POLYGON_MODE_FILL;
   rast.fill_ccw = PIPE_POLYGON_MODE_FILL;
   rast.offset_cw = 0;
   rast.offset_ccw = 0;
   rast.scissor = 0;
   rast.poly_smooth = 0;
   rast.poly_stipple_enable = 0;
263
   rast.sprite_coord_enable = 0;
264 265 266 267 268 269 270 271 272
   rast.point_size_per_vertex = 0;
   rast.multisample = 0;
   rast.line_smooth = 0;
   rast.line_stipple_enable = 0;
   rast.line_stipple_factor = 0;
   rast.line_stipple_pattern = 0;
   rast.line_last_pixel = 0;
   rast.line_width = 1;
   rast.point_smooth = 0;
273
   rast.point_quad_rasterization = 0;
274 275 276
   rast.point_size = 1;
   rast.offset_units = 1;
   rast.offset_scale = 1;
Younes Manton's avatar
Younes Manton committed
277
   rast.gl_rasterization_rules = 1;
278 279
   ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
   ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
280

281 282 283 284 285 286 287 288
   blend.independent_blend_enable = 0;
   blend.rt[0].blend_enable = 0;
   blend.rt[0].rgb_func = PIPE_BLEND_ADD;
   blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
   blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
   blend.rt[0].alpha_func = PIPE_BLEND_ADD;
   blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
   blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
289 290 291
   blend.logicop_enable = 0;
   blend.logicop_func = PIPE_LOGICOP_CLEAR;
   /* Needed to allow color writes to FB, even if blending disabled */
292
   blend.rt[0].colormask = PIPE_MASK_RGBA;
293 294 295
   blend.dither = 0;
   ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
   ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
296

297 298 299
   dsa.depth.enabled = 0;
   dsa.depth.writemask = 0;
   dsa.depth.func = PIPE_FUNC_ALWAYS;
Jose Fonseca's avatar
Jose Fonseca committed
300
   for (i = 0; i < 2; ++i) {
301 302 303 304 305 306 307 308 309 310 311 312 313
      dsa.stencil[i].enabled = 0;
      dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
      dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
      dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
      dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
      dsa.stencil[i].valuemask = 0;
      dsa.stencil[i].writemask = 0;
   }
   dsa.alpha.enabled = 0;
   dsa.alpha.func = PIPE_FUNC_ALWAYS;
   dsa.alpha.ref_value = 0;
   ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
   ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
314

315
   return true;
316 317 318
}

static struct pipe_video_context *
Younes Manton's avatar
Younes Manton committed
319
sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
320
                 enum pipe_video_chroma_format chroma_format,
Younes Manton's avatar
Younes Manton committed
321 322 323 324
                 unsigned width, unsigned height,
                 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
                 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
                 bool pot_buffers)
325
{
326
   struct sp_mpeg12_context *ctx;
327

328
   assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
329

330
   ctx = CALLOC_STRUCT(sp_mpeg12_context);
331

332 333
   if (!ctx)
      return NULL;
334

335 336 337 338
   ctx->base.profile = profile;
   ctx->base.chroma_format = chroma_format;
   ctx->base.width = width;
   ctx->base.height = height;
339

Younes Manton's avatar
Younes Manton committed
340
   ctx->base.screen = pipe->screen;
341
   ctx->base.destroy = sp_mpeg12_destroy;
342 343
   ctx->base.get_param = sp_mpeg12_get_param;
   ctx->base.is_format_supported = sp_mpeg12_is_format_supported;
344 345
   ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
   ctx->base.render_picture = sp_mpeg12_render_picture;
Younes Manton's avatar
Younes Manton committed
346 347
   ctx->base.surface_fill = sp_mpeg12_surface_fill;
   ctx->base.surface_copy = sp_mpeg12_surface_copy;
348 349
   ctx->base.set_picture_background = sp_mpeg12_set_picture_background;
   ctx->base.set_picture_layers = sp_mpeg12_set_picture_layers;
350
   ctx->base.set_decode_target = sp_mpeg12_set_decode_target;
351
   ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix;
352

Younes Manton's avatar
Younes Manton committed
353
   ctx->pipe = pipe;
354

355 356
   if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
                                   width, height, chroma_format,
Younes Manton's avatar
Younes Manton committed
357
                                   bufmode, eb_handling, pot_buffers)) {
358 359 360 361
      ctx->pipe->destroy(ctx->pipe);
      FREE(ctx);
      return NULL;
   }
362

363 364 365 366 367 368
   if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
      vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
      ctx->pipe->destroy(ctx->pipe);
      FREE(ctx);
      return NULL;
   }
369

370 371 372 373 374 375 376
   if (!init_pipe_state(ctx)) {
      vl_compositor_cleanup(&ctx->compositor);
      vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
      ctx->pipe->destroy(ctx->pipe);
      FREE(ctx);
      return NULL;
   }
377

378
   return &ctx->base;
379 380 381 382 383 384
}

struct pipe_video_context *
sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
                enum pipe_video_chroma_format chroma_format,
                unsigned width, unsigned height)
Younes Manton's avatar
Younes Manton committed
385 386 387 388 389 390
{
   struct pipe_context *pipe;

   assert(screen);
   assert(width && height);

391
   pipe = screen->context_create(screen, NULL);
Younes Manton's avatar
Younes Manton committed
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
   if (!pipe)
      return NULL;

   /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
   /* TODO: Use XFER_NONE when implemented */
   return sp_video_create_ex(pipe, profile,
                             chroma_format,
                             width, height,
                             VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
                             VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
                             true);
}

struct pipe_video_context *
sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
                   enum pipe_video_chroma_format chroma_format,
                   unsigned width, unsigned height,
                   enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
                   enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
                   bool pot_buffers)
412
{
Younes Manton's avatar
Younes Manton committed
413
   assert(pipe);
414
   assert(width && height);
415

416 417
   switch (u_reduce_video_profile(profile)) {
      case PIPE_VIDEO_CODEC_MPEG12:
Younes Manton's avatar
Younes Manton committed
418
         return sp_mpeg12_create(pipe, profile,
419
                                 chroma_format,
Younes Manton's avatar
Younes Manton committed
420 421 422
                                 width, height,
                                 bufmode, eb_handling,
                                 pot_buffers);
423 424 425
      default:
         return NULL;
   }
426
}