Ilia Mirkin
2013-Jul-29 23:39 UTC
[Nouveau] [PATCH 1/2] nv30: hook up PMPEG support via nouveau_video, enables XvMC to work
It seems as though at least the NV44 expects the same format as VP2 does. But NV96 expects the format as currently done. Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> --- src/gallium/drivers/nouveau/nouveau_video.c | 43 +++++++++++++++++++++++++---- src/gallium/drivers/nouveau/nouveau_video.h | 2 ++ src/gallium/drivers/nv30/nv30_context.c | 2 ++ src/gallium/drivers/nv30/nv30_screen.c | 1 + 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c index 9357508..62cb8d5 100644 --- a/src/gallium/drivers/nouveau/nouveau_video.c +++ b/src/gallium/drivers/nouveau/nouveau_video.c @@ -101,7 +101,32 @@ nouveau_vpe_fini(struct nouveau_decoder *dec) { } static INLINE void -nouveau_vpe_mb_dct_blocks(struct nouveau_decoder *dec, const struct pipe_mpeg12_macroblock *mb) +nouveau_vpe_mb_dct_blocks_31(struct nouveau_decoder *dec, const struct pipe_mpeg12_macroblock *mb) +{ + int cbb; + unsigned cbp = mb->coded_block_pattern; + short *db = mb->blocks; + for (cbb = 0x20; cbb > 0; cbb >>= 1) { + if (cbb & cbp) { + int i, found = 0; + for (i = 0; i < 64; ++i) { + if (!db[i]) continue; + dec->data[dec->data_pos++] = (db[i] << 16) | (i * 2); + found = 1; + } + if (found) + dec->data[dec->data_pos - 1] |= 1; + else + dec->data[dec->data_pos++] = 1; + db += 64; + } else if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) { + dec->data[dec->data_pos++] = 1; + } + } +} + +static INLINE void +nouveau_vpe_mb_dct_blocks_84(struct nouveau_decoder *dec, const struct pipe_mpeg12_macroblock *mb) { int cbb; unsigned cbp = mb->coded_block_pattern; @@ -455,10 +480,14 @@ nouveau_decoder_decode_macroblock(struct pipe_video_decoder *decoder, nouveau_vpe_mb_mv_header(dec, mb, FALSE); nouveau_vpe_mb_dct_header(dec, mb, FALSE); } - if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) - nouveau_vpe_mb_dct_blocks(dec, mb); - else + if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { + if (dec->is8274) + nouveau_vpe_mb_dct_blocks_84(dec, mb); + else + nouveau_vpe_mb_dct_blocks_31(dec, mb); + } else { nouveau_vpe_mb_data_blocks(dec, mb); + } } } @@ -528,6 +557,8 @@ nouveau_create_decoder(struct pipe_context *context, goto vl; if (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0) goto vl; + if (screen->device->chipset < 0x31) + goto vl; dec = CALLOC_STRUCT(nouveau_decoder); if (!dec) @@ -577,6 +608,7 @@ nouveau_create_decoder(struct pipe_context *context, dec->base.end_frame = nouveau_decoder_end_frame; dec->base.flush = nouveau_decoder_flush; dec->screen = screen; + dec->is8274 = is8274; ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 1024 * 1024, NULL, &dec->cmd_bo); @@ -793,7 +825,8 @@ nouveau_video_buffer_create(struct pipe_context *pipe, * and it only supports the NV12 format */ if (templat->buffer_format != PIPE_FORMAT_NV12 || getenv("XVMC_VL") || - (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0)) + (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0) || + screen->device->chipset < 0x31) return vl_video_buffer_create(pipe, templat); assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); diff --git a/src/gallium/drivers/nouveau/nouveau_video.h b/src/gallium/drivers/nouveau/nouveau_video.h index 1d6ced0..6306ac3 100644 --- a/src/gallium/drivers/nouveau/nouveau_video.h +++ b/src/gallium/drivers/nouveau/nouveau_video.h @@ -26,6 +26,8 @@ struct nouveau_decoder { struct nouveau_object *mpeg; struct nouveau_bo *cmd_bo, *data_bo, *fence_bo; + bool is8274; + unsigned *fence_map; unsigned fence_seq; diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index bd05042..e872c02 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -257,5 +257,7 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv) return NULL; } + nouveau_context_init_vdec(&nv30->base); + return pipe; } diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 3d55d6f..40e8b5f 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -377,6 +377,7 @@ nv30_screen_create(struct nouveau_device *dev) pscreen->context_create = nv30_context_create; pscreen->is_format_supported = nv30_screen_is_format_supported; nv30_resource_screen_init(pscreen); + nouveau_screen_init_vdec(&screen->base); screen->base.fence.emit = nv30_screen_fence_emit; screen->base.fence.update = nv30_screen_fence_update; -- 1.8.1.5
Ilia Mirkin
2013-Jul-29 23:39 UTC
[Nouveau] [PATCH 2/2] nv50: allow forcing PMPEG use, for ease of testing
This also allows people who don't want to install the binary blobs required for VP2 to still get MPEG decoding. Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> --- src/gallium/drivers/nv50/nv50_context.c | 2 +- src/gallium/drivers/nv50/nv50_screen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 79a0473..3654a41 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -258,7 +258,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv) draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); #endif - if (screen->base.device->chipset < 0x84) { + if (screen->base.device->chipset < 0x84 || getenv("XVMC_PMPEG")) { /* PMPEG */ nouveau_context_init_vdec(&nv50->base); } else if (screen->base.device->chipset < 0x98 || diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 2951eb4..959366e 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -647,7 +647,7 @@ nv50_screen_create(struct nouveau_device *dev) nv50_screen_init_resource_functions(pscreen); - if (screen->base.device->chipset < 0x84) { + if (screen->base.device->chipset < 0x84 || getenv("XVMC_PMPEG")) { /* PMPEG */ nouveau_screen_init_vdec(&screen->base); } else if (screen->base.device->chipset < 0x98 || -- 1.8.1.5
Ilia Mirkin
2013-Jul-30 00:53 UTC
[Nouveau] [PATCHv2 2/2] nv50: allow forcing PMPEG use, for ease of testing
This also allows people who don't want to install the binary blobs required for VP2 to still get MPEG decoding. Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> --- v1 -> v2: - switched to using debug_get_bool_option and NOUVEAU prefix, for which there is some precedent src/gallium/drivers/nv50/nv50_context.c | 3 ++- src/gallium/drivers/nv50/nv50_screen.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 79a0473..185d241 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -258,7 +258,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv) draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); #endif - if (screen->base.device->chipset < 0x84) { + if (screen->base.device->chipset < 0x84 || + debug_get_bool_option("NOUVEAU_PMPEG", FALSE)) { /* PMPEG */ nouveau_context_init_vdec(&nv50->base); } else if (screen->base.device->chipset < 0x98 || diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 2951eb4..0cbee5d 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -647,7 +647,8 @@ nv50_screen_create(struct nouveau_device *dev) nv50_screen_init_resource_functions(pscreen); - if (screen->base.device->chipset < 0x84) { + if (screen->base.device->chipset < 0x84 || + debug_get_bool_option("NOUVEAU_PMPEG", FALSE)) { /* PMPEG */ nouveau_screen_init_vdec(&screen->base); } else if (screen->base.device->chipset < 0x98 || -- 1.8.1.5
Seemingly Similar Threads
- [PATCH 1/4] nouveau: fix number of surfaces in video buffer, use defines
- [PATCH 2/2] nv50: allow forcing PMPEG use, for ease of testing
- [RFC PATCH 0/8] nv50: expose global performance counters
- [PATCH 1/2] nv50: don't emit reloc markers after a referenced vtxbuf is mapped
- [PATCH 1/3] nv50: rework primid logic