diff options
author | Ilia Mirkin <[email protected]> | 2013-08-10 16:43:06 -0400 |
---|---|---|
committer | Maarten Lankhorst <[email protected]> | 2013-08-15 15:19:48 +0200 |
commit | 73f4499a02db0cdad31f7881d718daadd712c40f (patch) | |
tree | 4c3a26c6f26bdf762fbca544577415a8f20615dc | |
parent | e1cd987bb641eef88a9b856aaccff8bb526f6311 (diff) |
nvc0: move vp param filling logic into nouveau
Signed-off-by: Ilia Mirkin <[email protected]>
-rw-r--r-- | src/gallium/drivers/nouveau/Makefile.sources | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_vp3_video.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c | 485 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_video.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_video_bsp.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_video_vp.c | 472 |
6 files changed, 499 insertions, 476 deletions
diff --git a/src/gallium/drivers/nouveau/Makefile.sources b/src/gallium/drivers/nouveau/Makefile.sources index ca3320721ca..7912f6703e3 100644 --- a/src/gallium/drivers/nouveau/Makefile.sources +++ b/src/gallium/drivers/nouveau/Makefile.sources @@ -6,4 +6,5 @@ C_SOURCES := \ nouveau_heap.c \ nouveau_video.c \ nouveau_vp3_video.c \ - nouveau_vp3_video_bsp.c + nouveau_vp3_video_bsp.c \ + nouveau_vp3_video_vp.c diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.h b/src/gallium/drivers/nouveau/nouveau_vp3_video.h index 2558d57917b..8d3548abd9a 100644 --- a/src/gallium/drivers/nouveau/nouveau_vp3_video.h +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.h @@ -202,3 +202,9 @@ nouveau_vp3_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, struct nouveau_vp3_video_buffer *target, unsigned comm_seq, unsigned num_buffers, const void *const *data, const unsigned *num_bytes); + +void +nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc, + struct nouveau_vp3_video_buffer *target, unsigned comm_seq, + unsigned *caps, unsigned *is_ref, + struct nouveau_vp3_video_buffer *refs[16]); diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c b/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c new file mode 100644 index 00000000000..c9b1b996bd0 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video_vp.c @@ -0,0 +1,485 @@ +/* + * Copyright 2011-2013 Maarten Lankhorst + * + * 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, sublicense, + * 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: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "nouveau_vp3_video.h" + +struct mpeg12_picparm_vp { + uint16_t width; // 00 in mb units + uint16_t height; // 02 in mb units + + uint32_t unk04; // 04 stride for Y? + uint32_t unk08; // 08 stride for CbCr? + + uint32_t ofs[6]; // 1c..20 ofs + uint32_t bucket_size; // 24 + uint32_t inter_ring_data_size; // 28 + uint16_t unk2c; // 2c + uint16_t alternate_scan; // 2e + uint16_t unk30; // 30 not seen set yet + uint16_t picture_structure; // 32 + uint16_t pad2[3]; + uint16_t unk3a; // 3a set on I frame? + + uint32_t f_code[4]; // 3c + uint32_t picture_coding_type; // 4c + uint32_t intra_dc_precision; // 50 + uint32_t q_scale_type; // 54 + uint32_t top_field_first; // 58 + uint32_t full_pel_forward_vector; // 5c + uint32_t full_pel_backward_vector; // 60 + uint8_t intra_quantizer_matrix[0x40]; // 64 + uint8_t non_intra_quantizer_matrix[0x40]; // a4 +}; + +struct mpeg4_picparm_vp { + uint32_t width; // 00 in normal units + uint32_t height; // 04 in normal units + uint32_t unk08; // stride 1 + uint32_t unk0c; // stride 2 + uint32_t ofs[6]; // 10..24 ofs + uint32_t bucket_size; // 28 + uint32_t pad1; // 2c, pad + uint32_t pad2; // 30 + uint32_t inter_ring_data_size; // 34 + + uint32_t trd[2]; // 38, 3c + uint32_t trb[2]; // 40, 44 + uint32_t u48; // XXX codec selection? Should test with different values of VdpDecoderProfile + uint16_t f_code_fw; // 4c + uint16_t f_code_bw; // 4e + uint8_t interlaced; // 50 + + uint8_t quant_type; // bool, written to 528 + uint8_t quarter_sample; // bool, written to 548 + uint8_t short_video_header; // bool, negated written to 528 shifted by 1 + uint8_t u54; // bool, written to 0x740 + uint8_t vop_coding_type; // 55 + uint8_t rounding_control; // 56 + uint8_t alternate_vertical_scan_flag; // 57 bool + uint8_t top_field_first; // bool, written to vuc + + uint8_t pad4[3]; // 59, 5a, 5b, contains garbage on blob + uint32_t pad5[0x10]; // 5c...9c non-inclusive, but WHY? + + uint32_t intra[0x10]; // 9c + uint32_t non_intra[0x10]; // bc + // udc..uff pad? +}; + +// Full version, with data pumped from BSP +struct vc1_picparm_vp { + uint32_t bucket_size; // 00 + uint32_t pad; // 04 + + uint32_t inter_ring_data_size; // 08 + uint32_t unk0c; // stride 1 + uint32_t unk10; // stride 2 + uint32_t ofs[6]; // 14..28 ofs + + uint16_t width; // 2c + uint16_t height; // 2e + + uint8_t profile; // 30 0 = simple, 1 = main, 2 = advanced + uint8_t loopfilter; // 31 written into vuc + uint8_t fastuvmc; // 32, written into vuc + uint8_t dquant; // 33 + + uint8_t overlap; // 34 + uint8_t quantizer; // 35 + uint8_t u36; // 36, bool + uint8_t pad2; // 37, to align to 0x38 +}; + +struct h264_picparm_vp { // 700..a00 + uint16_t width, height; + uint32_t stride1, stride2; // 04 08 + uint32_t ofs[6]; // 0c..24 in-image offset + + uint32_t u24; // nfi ac8 ? + uint32_t bucket_size; // 28 bucket size + uint32_t inter_ring_data_size; // 2c + + unsigned f0 : 1; // 0 0x01: into 640 shifted by 3, 540 shifted by 5, half size something? + unsigned f1 : 1; // 1 0x02: into vuc ofs 56 + unsigned weighted_pred_flag : 1; // 2 0x04 + unsigned f3 : 1; // 3 0x08: into vuc ofs 68 + unsigned is_reference : 1; // 4 + unsigned interlace : 1; // 5 field_pic_flag + unsigned bottom_field_flag : 1; // 6 + unsigned f7 : 1; // 7 0x80: nfi yet + + signed log2_max_frame_num_minus4 : 4; // 31 0..3 + unsigned u31_45 : 2; // 31 4..5 + unsigned pic_order_cnt_type : 2; // 31 6..7 + signed pic_init_qp_minus26 : 6; // 32 0..5 + signed chroma_qp_index_offset : 5; // 32 6..10 + signed second_chroma_qp_index_offset : 5; // 32 11..15 + + unsigned weighted_bipred_idc : 2; // 34 0..1 + unsigned fifo_dec_index : 7; // 34 2..8 + unsigned tmp_idx : 5; // 34 9..13 + unsigned frame_number : 16; // 34 14..29 + unsigned u34_3030 : 1; // 34 30..30 pp.u34[30:30] + unsigned u34_3131 : 1; // 34 31..31 pad? + + uint32_t field_order_cnt[2]; // 38, 3c + + struct { // 40 + // 0x00223102 + // nfi (needs: top_is_reference, bottom_is_reference, is_long_term, maybe some other state that was saved.. + unsigned fifo_idx : 7; // 00 0..6 + unsigned tmp_idx : 5; // 00 7..11 + unsigned unk12 : 1; // 00 12 not seen yet, but set, maybe top_is_reference + unsigned unk13 : 1; // 00 13 not seen yet, but set, maybe bottom_is_reference? + unsigned unk14 : 1; // 00 14 skipped? + unsigned notseenyet : 1; // 00 15 pad? + unsigned unk16 : 1; // 00 16 + unsigned unk17 : 4; // 00 17..20 + unsigned unk21 : 4; // 00 21..24 + unsigned pad : 7; // 00 d25..31 + + uint32_t field_order_cnt[2]; // 04,08 + uint32_t frame_idx; // 0c + } refs[0x10]; + + uint8_t m4x4[6][16]; // 140 + uint8_t m8x8[2][64]; // 1a0 + uint32_t u220; // 220 number of extra reorder_list to append? + uint8_t u224[0x20]; // 224..244 reorder_list append ? + uint8_t nfi244[0xb0]; // add some pad to make sure nulls are read +}; + +static void +nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *refs[16], unsigned seq, struct nouveau_vp3_video_buffer *target) +{ + unsigned h264 = u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_CODEC_MPEG4_AVC; + unsigned i, idx, empty_spot = dec->base.max_references + 1; + for (i = 0; i < dec->base.max_references; ++i) { + if (!refs[i]) + continue; + + idx = refs[i]->valid_ref; + //debug_printf("ref[%i] %p in slot %i\n", i, refs[i], idx); + assert(target != refs[i] || + (h264 && empty_spot && + (!dec->refs[idx].decoded_bottom || !dec->refs[idx].decoded_top))); + if (target == refs[i]) + empty_spot = 0; + + if (dec->refs[idx].vidbuf != refs[i]) { + debug_printf("%p is not a real ref\n", refs[i]); + // FIXME: Maybe do m2mf copy here if a application really depends on it? + continue; + } + + assert(dec->refs[idx].vidbuf == refs[i]); + dec->refs[idx].last_used = seq; + } + if (!empty_spot) + return; + + /* Try to find a real empty spot first, there should be one.. + */ + for (i = 0; i < dec->base.max_references + 1; ++i) { + if (dec->refs[i].last_used < seq) { + if (!dec->refs[i].vidbuf) { + empty_spot = i; + break; + } + if (empty_spot < dec->base.max_references+1 && + dec->refs[empty_spot].last_used < dec->refs[i].last_used) + continue; + empty_spot = i; + } + } + assert(empty_spot < dec->base.max_references+1); + dec->refs[empty_spot].last_used = seq; +// debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, i); + dec->refs[empty_spot].vidbuf = target; + dec->refs[empty_spot].decoded_bottom = dec->refs[empty_spot].decoded_top = 0; + target->valid_ref = empty_spot; +} + +static uint32_t +nouveau_vp3_fill_picparm_mpeg12_vp(struct nouveau_vp3_decoder *dec, + struct pipe_mpeg12_picture_desc *desc, + struct nouveau_vp3_video_buffer *refs[16], + unsigned *is_ref, + char *map) +{ + struct mpeg12_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub; + uint32_t i, ret = 0x01010, ring; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk; + assert(!(dec->base.width & 0xf)); + *is_ref = desc->picture_coding_type <= 2; + + if (dec->base.profile == PIPE_VIDEO_PROFILE_MPEG1) + pic_vp->picture_structure = 3; + else + pic_vp->picture_structure = desc->picture_structure; + + assert(desc->picture_structure != 4); + if (desc->picture_structure == 4) // Untested, but should work + ret |= 0x100; + pic_vp->width = mb(dec->base.width); + pic_vp->height = mb(dec->base.height); + pic_vp->unk08 = pic_vp->unk04 = (dec->base.width+0xf)&~0xf; // Stride + + nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]); + pic_vp->ofs[5] = pic_vp->ofs[3]; + pic_vp->ofs[0] = pic_vp->ofs[2] = 0; + nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size); + + pic_vp->alternate_scan = desc->alternate_scan; + pic_vp->pad2[0] = pic_vp->pad2[1] = pic_vp->pad2[2] = 0; + pic_vp->unk30 = desc->picture_structure < 3 && (desc->picture_structure == 2 - desc->top_field_first); + pic_vp->unk3a = (desc->picture_coding_type == 1); + for (i = 0; i < 4; ++i) + pic_vp->f_code[i] = desc->f_code[i/2][i%2] + 1; // FU + pic_vp->picture_coding_type = desc->picture_coding_type; + pic_vp->intra_dc_precision = desc->intra_dc_precision; + pic_vp->q_scale_type = desc->q_scale_type; + pic_vp->top_field_first = desc->top_field_first; + pic_vp->full_pel_forward_vector = desc->full_pel_forward_vector; + pic_vp->full_pel_backward_vector = desc->full_pel_backward_vector; + memcpy(pic_vp->intra_quantizer_matrix, desc->intra_matrix, 0x40); + memcpy(pic_vp->non_intra_quantizer_matrix, desc->non_intra_matrix, 0x40); + memcpy(map, pic_vp, sizeof(*pic_vp)); + refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0]; + refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1]; + return ret | (dec->base.profile != PIPE_VIDEO_PROFILE_MPEG1); +} + +static uint32_t +nouveau_vp3_fill_picparm_mpeg4_vp(struct nouveau_vp3_decoder *dec, + struct pipe_mpeg4_picture_desc *desc, + struct nouveau_vp3_video_buffer *refs[16], + unsigned *is_ref, + char *map) +{ + struct mpeg4_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub; + uint32_t ring, ret = 0x01014; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk; + assert(!(dec->base.width & 0xf)); + *is_ref = desc->vop_coding_type <= 1; + + pic_vp->width = dec->base.width; + pic_vp->height = mb(dec->base.height)<<4; + pic_vp->unk0c = pic_vp->unk08 = mb(dec->base.width)<<4; // Stride + + nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]); + pic_vp->ofs[5] = pic_vp->ofs[3]; + pic_vp->ofs[0] = pic_vp->ofs[2] = 0; + pic_vp->pad1 = pic_vp->pad2 = 0; + nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size); + + pic_vp->trd[0] = desc->trd[0]; + pic_vp->trd[1] = desc->trd[1]; + pic_vp->trb[0] = desc->trb[0]; + pic_vp->trb[1] = desc->trb[1]; + pic_vp->u48 = 0; // Codec? + pic_vp->pad1 = pic_vp->pad2 = 0; + pic_vp->f_code_fw = desc->vop_fcode_forward; + pic_vp->f_code_bw = desc->vop_fcode_backward; + pic_vp->interlaced = desc->interlaced; + pic_vp->quant_type = desc->quant_type; + pic_vp->quarter_sample = desc->quarter_sample; + pic_vp->short_video_header = desc->short_video_header; + pic_vp->u54 = 0; + pic_vp->vop_coding_type = desc->vop_coding_type; + pic_vp->rounding_control = desc->rounding_control; + pic_vp->alternate_vertical_scan_flag = desc->alternate_vertical_scan_flag; + pic_vp->top_field_first = desc->top_field_first; + + memcpy(pic_vp->intra, desc->intra_matrix, 0x40); + memcpy(pic_vp->non_intra, desc->non_intra_matrix, 0x40); + memcpy(map, pic_vp, sizeof(*pic_vp)); + refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0]; + refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1]; + return ret; +} + +static uint32_t +nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec, + const struct pipe_h264_picture_desc *d, + struct nouveau_vp3_video_buffer *refs[16], + unsigned *is_ref, + char *map) +{ + struct h264_picparm_vp stub_h = {}, *h = &stub_h; + unsigned ring, i, j = 0; + assert(offsetof(struct h264_picparm_vp, u224) == 0x224); + *is_ref = d->is_reference; + dec->last_frame_num = d->frame_num; + + h->width = mb(dec->base.width); + h->height = mb(dec->base.height); + h->stride1 = h->stride2 = mb(dec->base.width)*16; + nouveau_vp3_ycbcr_offsets(dec, &h->ofs[1], &h->ofs[3], &h->ofs[4]); + h->ofs[5] = h->ofs[3]; + h->ofs[0] = h->ofs[2] = 0; + h->u24 = dec->tmp_stride >> 8; + assert(h->u24); + nouveau_vp3_inter_sizes(dec, 1, &ring, &h->bucket_size, &h->inter_ring_data_size); + + h->u220 = 0; + h->f0 = d->mb_adaptive_frame_field_flag; + h->f1 = d->direct_8x8_inference_flag; + h->weighted_pred_flag = d->weighted_pred_flag; + h->f3 = d->constrained_intra_pred_flag; + h->is_reference = d->is_reference; + h->interlace = d->field_pic_flag; + h->bottom_field_flag = d->bottom_field_flag; + h->f7 = 0; // TODO: figure out when set.. + h->log2_max_frame_num_minus4 = d->log2_max_frame_num_minus4; + h->u31_45 = 1; + + h->pic_order_cnt_type = d->pic_order_cnt_type; + h->pic_init_qp_minus26 = d->pic_init_qp_minus26; + h->chroma_qp_index_offset = d->chroma_qp_index_offset; + h->second_chroma_qp_index_offset = d->second_chroma_qp_index_offset; + h->weighted_bipred_idc = d->weighted_bipred_idc; + h->tmp_idx = 0; // set in h264_vp_refs below + h->fifo_dec_index = 0; // always set to 0 to be fifo compatible with other codecs + h->frame_number = d->frame_num; + h->u34_3030 = h->u34_3131 = 0; + h->field_order_cnt[0] = d->field_order_cnt[0]; + h->field_order_cnt[1] = d->field_order_cnt[1]; + memset(h->refs, 0, sizeof(h->refs)); + memcpy(h->m4x4, d->scaling_lists_4x4, sizeof(h->m4x4) + sizeof(h->m8x8)); + h->u220 = 0; + for (i = 0; i < d->num_ref_frames; ++i) { + if (!d->ref[i]) + break; + refs[j] = (struct nouveau_vp3_video_buffer *)d->ref[i]; + h->refs[j].fifo_idx = j + 1; + h->refs[j].tmp_idx = refs[j]->valid_ref; + h->refs[j].field_order_cnt[0] = d->field_order_cnt_list[i][0]; + h->refs[j].field_order_cnt[1] = d->field_order_cnt_list[i][1]; + h->refs[j].frame_idx = d->frame_num_list[i]; + if (!dec->refs[refs[j]->valid_ref].field_pic_flag) { + h->refs[j].unk12 = d->top_is_reference[i]; + h->refs[j].unk13 = d->bottom_is_reference[i]; + } + h->refs[j].unk14 = 0; + h->refs[j].notseenyet = 0; + h->refs[j].unk16 = dec->refs[refs[j]->valid_ref].field_pic_flag; + h->refs[j].unk17 = dec->refs[refs[j]->valid_ref].decoded_top && + d->top_is_reference[i]; + h->refs[j].unk21 = dec->refs[refs[j]->valid_ref].decoded_bottom && + d->bottom_is_reference[i]; + h->refs[j].pad = 0; + assert(!d->is_long_term[i]); + j++; + } + for (; i < 16; ++i) + assert(!d->ref[i]); + assert(d->num_ref_frames <= dec->base.max_references); + + for (; i < d->num_ref_frames; ++i) + h->refs[j].unk16 = d->field_pic_flag; + *(struct h264_picparm_vp *)map = *h; + + return 0x1113; +} + +static void +nouveau_vp3_fill_picparm_h264_vp_refs(struct nouveau_vp3_decoder *dec, + struct pipe_h264_picture_desc *d, + struct nouveau_vp3_video_buffer *refs[16], + struct nouveau_vp3_video_buffer *target, + char *map) +{ + struct h264_picparm_vp *h = (struct h264_picparm_vp *)map; + assert(dec->refs[target->valid_ref].vidbuf == target); +// debug_printf("Target: %p\n", target); + + h->tmp_idx = target->valid_ref; + dec->refs[target->valid_ref].field_pic_flag = d->field_pic_flag; + if (!d->field_pic_flag || d->bottom_field_flag) + dec->refs[target->valid_ref].decoded_bottom = 1; + if (!d->field_pic_flag || !d->bottom_field_flag) + dec->refs[target->valid_ref].decoded_top = 1; +} + +static uint32_t +nouveau_vp3_fill_picparm_vc1_vp(struct nouveau_vp3_decoder *dec, + struct pipe_vc1_picture_desc *d, + struct nouveau_vp3_video_buffer *refs[16], + unsigned *is_ref, + char *map) +{ + struct vc1_picparm_vp *vc = (struct vc1_picparm_vp *)map; + unsigned ring; + assert(dec->base.profile != PIPE_VIDEO_PROFILE_VC1_SIMPLE); + *is_ref = d->picture_type <= 1; + + nouveau_vp3_ycbcr_offsets(dec, &vc->ofs[1], &vc->ofs[3], &vc->ofs[4]); + vc->ofs[5] = vc->ofs[3]; + vc->ofs[0] = vc->ofs[2] = 0; + vc->width = dec->base.width; + vc->height = mb(dec->base.height)<<4; + vc->unk0c = vc->unk10 = mb(dec->base.width)<<4; // Stride + vc->pad = vc->pad2 = 0; + nouveau_vp3_inter_sizes(dec, 1, &ring, &vc->bucket_size, &vc->inter_ring_data_size); + vc->profile = dec->base.profile - PIPE_VIDEO_PROFILE_VC1_SIMPLE; + vc->loopfilter = d->loopfilter; + vc->fastuvmc = d->fastuvmc; + vc->dquant = d->dquant; + vc->overlap = d->overlap; + vc->quantizer = d->quantizer; + vc->u36 = 0; // ? No idea what this one is.. + refs[0] = (struct nouveau_vp3_video_buffer *)d->ref[0]; + refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)d->ref[1]; + return 0x12; +} + +void nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc, + struct nouveau_vp3_video_buffer *target, unsigned comm_seq, + unsigned *caps, unsigned *is_ref, + struct nouveau_vp3_video_buffer *refs[16]) +{ + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; + enum pipe_video_codec codec = u_reduce_video_profile(dec->base.profile); + char *vp = bsp_bo->map + VP_OFFSET; + + switch (codec){ + case PIPE_VIDEO_CODEC_MPEG12: + *caps = nouveau_vp3_fill_picparm_mpeg12_vp(dec, desc.mpeg12, refs, is_ref, vp); + nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target); + return; + case PIPE_VIDEO_CODEC_MPEG4: + *caps = nouveau_vp3_fill_picparm_mpeg4_vp(dec, desc.mpeg4, refs, is_ref, vp); + nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target); + return; + case PIPE_VIDEO_CODEC_VC1: { + *caps = nouveau_vp3_fill_picparm_vc1_vp(dec, desc.vc1, refs, is_ref, vp); + nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target); + return; + } + case PIPE_VIDEO_CODEC_MPEG4_AVC: { + *caps = nouveau_vp3_fill_picparm_h264_vp(dec, desc.h264, refs, is_ref, vp); + nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target); + nouveau_vp3_fill_picparm_h264_vp_refs(dec, desc.h264, refs, target, vp); + return; + } + default: assert(0); return; + } +} diff --git a/src/gallium/drivers/nvc0/nvc0_video.h b/src/gallium/drivers/nvc0/nvc0_video.h index 1ceb6ebe56c..5cd79f6fac4 100644 --- a/src/gallium/drivers/nvc0/nvc0_video.h +++ b/src/gallium/drivers/nvc0/nvc0_video.h @@ -37,13 +37,6 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, unsigned *vp_caps, unsigned *is_ref, struct nouveau_vp3_video_buffer *refs[16]); -extern void nvc0_decoder_vp_caps(struct nouveau_vp3_decoder *dec, - union pipe_desc desc, - struct nouveau_vp3_video_buffer *target, - unsigned comm_seq, - unsigned *caps, unsigned *is_ref, - struct nouveau_vp3_video_buffer *refs[16]); - extern void nvc0_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, struct nouveau_vp3_video_buffer *target, unsigned comm_seq, diff --git a/src/gallium/drivers/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nvc0/nvc0_video_bsp.c index 06c85e60c38..2ce551995a8 100644 --- a/src/gallium/drivers/nvc0/nvc0_video_bsp.c +++ b/src/gallium/drivers/nvc0/nvc0_video_bsp.c @@ -74,7 +74,7 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, caps = nouveau_vp3_bsp(dec, desc, target, comm_seq, num_buffers, data, num_bytes); - nvc0_decoder_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs); + nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs); nouveau_pushbuf_space(push, 6 + (codec == PIPE_VIDEO_CODEC_MPEG4_AVC ? 9 : 7) + fence_extra + 2, num_refs, 0); nouveau_pushbuf_refn(push, bo_refs, num_refs); diff --git a/src/gallium/drivers/nvc0/nvc0_video_vp.c b/src/gallium/drivers/nvc0/nvc0_video_vp.c index e3c00b9c710..eb4f1a9f415 100644 --- a/src/gallium/drivers/nvc0/nvc0_video_vp.c +++ b/src/gallium/drivers/nvc0/nvc0_video_vp.c @@ -23,443 +23,6 @@ #include "nvc0_video.h" #include <sys/mman.h> -struct mpeg12_picparm_vp { - uint16_t width; // 00 in mb units - uint16_t height; // 02 in mb units - - uint32_t unk04; // 04 stride for Y? - uint32_t unk08; // 08 stride for CbCr? - - uint32_t ofs[6]; // 1c..20 ofs - uint32_t bucket_size; // 24 - uint32_t inter_ring_data_size; // 28 - uint16_t unk2c; // 2c - uint16_t alternate_scan; // 2e - uint16_t unk30; // 30 not seen set yet - uint16_t picture_structure; // 32 - uint16_t pad2[3]; - uint16_t unk3a; // 3a set on I frame? - - uint32_t f_code[4]; // 3c - uint32_t picture_coding_type; // 4c - uint32_t intra_dc_precision; // 50 - uint32_t q_scale_type; // 54 - uint32_t top_field_first; // 58 - uint32_t full_pel_forward_vector; // 5c - uint32_t full_pel_backward_vector; // 60 - uint8_t intra_quantizer_matrix[0x40]; // 64 - uint8_t non_intra_quantizer_matrix[0x40]; // a4 -}; - -struct mpeg4_picparm_vp { - uint32_t width; // 00 in normal units - uint32_t height; // 04 in normal units - uint32_t unk08; // stride 1 - uint32_t unk0c; // stride 2 - uint32_t ofs[6]; // 10..24 ofs - uint32_t bucket_size; // 28 - uint32_t pad1; // 2c, pad - uint32_t pad2; // 30 - uint32_t inter_ring_data_size; // 34 - - uint32_t trd[2]; // 38, 3c - uint32_t trb[2]; // 40, 44 - uint32_t u48; // XXX codec selection? Should test with different values of VdpDecoderProfile - uint16_t f_code_fw; // 4c - uint16_t f_code_bw; // 4e - uint8_t interlaced; // 50 - - uint8_t quant_type; // bool, written to 528 - uint8_t quarter_sample; // bool, written to 548 - uint8_t short_video_header; // bool, negated written to 528 shifted by 1 - uint8_t u54; // bool, written to 0x740 - uint8_t vop_coding_type; // 55 - uint8_t rounding_control; // 56 - uint8_t alternate_vertical_scan_flag; // 57 bool - uint8_t top_field_first; // bool, written to vuc - - uint8_t pad4[3]; // 59, 5a, 5b, contains garbage on blob - uint32_t pad5[0x10]; // 5c...9c non-inclusive, but WHY? - - uint32_t intra[0x10]; // 9c - uint32_t non_intra[0x10]; // bc - // udc..uff pad? -}; - -// Full version, with data pumped from BSP -struct vc1_picparm_vp { - uint32_t bucket_size; // 00 - uint32_t pad; // 04 - - uint32_t inter_ring_data_size; // 08 - uint32_t unk0c; // stride 1 - uint32_t unk10; // stride 2 - uint32_t ofs[6]; // 14..28 ofs - - uint16_t width; // 2c - uint16_t height; // 2e - - uint8_t profile; // 30 0 = simple, 1 = main, 2 = advanced - uint8_t loopfilter; // 31 written into vuc - uint8_t fastuvmc; // 32, written into vuc - uint8_t dquant; // 33 - - uint8_t overlap; // 34 - uint8_t quantizer; // 35 - uint8_t u36; // 36, bool - uint8_t pad2; // 37, to align to 0x38 -}; - -struct h264_picparm_vp { // 700..a00 - uint16_t width, height; - uint32_t stride1, stride2; // 04 08 - uint32_t ofs[6]; // 0c..24 in-image offset - - uint32_t u24; // nfi ac8 ? - uint32_t bucket_size; // 28 bucket size - uint32_t inter_ring_data_size; // 2c - - unsigned f0 : 1; // 0 0x01: into 640 shifted by 3, 540 shifted by 5, half size something? - unsigned f1 : 1; // 1 0x02: into vuc ofs 56 - unsigned weighted_pred_flag : 1; // 2 0x04 - unsigned f3 : 1; // 3 0x08: into vuc ofs 68 - unsigned is_reference : 1; // 4 - unsigned interlace : 1; // 5 field_pic_flag - unsigned bottom_field_flag : 1; // 6 - unsigned f7 : 1; // 7 0x80: nfi yet - - signed log2_max_frame_num_minus4 : 4; // 31 0..3 - unsigned u31_45 : 2; // 31 4..5 - unsigned pic_order_cnt_type : 2; // 31 6..7 - signed pic_init_qp_minus26 : 6; // 32 0..5 - signed chroma_qp_index_offset : 5; // 32 6..10 - signed second_chroma_qp_index_offset : 5; // 32 11..15 - - unsigned weighted_bipred_idc : 2; // 34 0..1 - unsigned fifo_dec_index : 7; // 34 2..8 - unsigned tmp_idx : 5; // 34 9..13 - unsigned frame_number : 16; // 34 14..29 - unsigned u34_3030 : 1; // 34 30..30 pp.u34[30:30] - unsigned u34_3131 : 1; // 34 31..31 pad? - - uint32_t field_order_cnt[2]; // 38, 3c - - struct { // 40 - // 0x00223102 - // nfi (needs: top_is_reference, bottom_is_reference, is_long_term, maybe some other state that was saved.. - unsigned fifo_idx : 7; // 00 0..6 - unsigned tmp_idx : 5; // 00 7..11 - unsigned unk12 : 1; // 00 12 not seen yet, but set, maybe top_is_reference - unsigned unk13 : 1; // 00 13 not seen yet, but set, maybe bottom_is_reference? - unsigned unk14 : 1; // 00 14 skipped? - unsigned notseenyet : 1; // 00 15 pad? - unsigned unk16 : 1; // 00 16 - unsigned unk17 : 4; // 00 17..20 - unsigned unk21 : 4; // 00 21..24 - unsigned pad : 7; // 00 d25..31 - - uint32_t field_order_cnt[2]; // 04,08 - uint32_t frame_idx; // 0c - } refs[0x10]; - - uint8_t m4x4[6][16]; // 140 - uint8_t m8x8[2][64]; // 1a0 - uint32_t u220; // 220 number of extra reorder_list to append? - uint8_t u224[0x20]; // 224..244 reorder_list append ? - uint8_t nfi244[0xb0]; // add some pad to make sure nulls are read -}; - -static void -nvc0_decoder_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *refs[16], unsigned seq, struct nouveau_vp3_video_buffer *target) -{ - unsigned h264 = u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_CODEC_MPEG4_AVC; - unsigned i, idx, empty_spot = dec->base.max_references + 1; - for (i = 0; i < dec->base.max_references; ++i) { - if (!refs[i]) - continue; - - idx = refs[i]->valid_ref; - //debug_printf("ref[%i] %p in slot %i\n", i, refs[i], idx); - assert(target != refs[i] || - (h264 && empty_spot && - (!dec->refs[idx].decoded_bottom || !dec->refs[idx].decoded_top))); - if (target == refs[i]) - empty_spot = 0; - - if (dec->refs[idx].vidbuf != refs[i]) { - debug_printf("%p is not a real ref\n", refs[i]); - // FIXME: Maybe do m2mf copy here if a application really depends on it? - continue; - } - - assert(dec->refs[idx].vidbuf == refs[i]); - dec->refs[idx].last_used = seq; - } - if (!empty_spot) - return; - - /* Try to find a real empty spot first, there should be one.. - */ - for (i = 0; i < dec->base.max_references + 1; ++i) { - if (dec->refs[i].last_used < seq) { - if (!dec->refs[i].vidbuf) { - empty_spot = i; - break; - } - if (empty_spot < dec->base.max_references+1 && - dec->refs[empty_spot].last_used < dec->refs[i].last_used) - continue; - empty_spot = i; - } - } - assert(empty_spot < dec->base.max_references+1); - dec->refs[empty_spot].last_used = seq; -// debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, i); - dec->refs[empty_spot].vidbuf = target; - dec->refs[empty_spot].decoded_bottom = dec->refs[empty_spot].decoded_top = 0; - target->valid_ref = empty_spot; -} - -static void -nvc0_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target) -{ - dec->refs[target->valid_ref].vidbuf = NULL; - dec->refs[target->valid_ref].last_used = 0; -// debug_printf("Unreffed %p\n", target); -} - -static uint32_t -nvc0_decoder_fill_picparm_mpeg12_vp(struct nouveau_vp3_decoder *dec, - struct pipe_mpeg12_picture_desc *desc, - struct nouveau_vp3_video_buffer *refs[16], - unsigned *is_ref, - char *map) -{ - struct mpeg12_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub; - uint32_t i, ret = 0x01010, ring; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk; - assert(!(dec->base.width & 0xf)); - *is_ref = desc->picture_coding_type <= 2; - - if (dec->base.profile == PIPE_VIDEO_PROFILE_MPEG1) - pic_vp->picture_structure = 3; - else - pic_vp->picture_structure = desc->picture_structure; - - assert(desc->picture_structure != 4); - if (desc->picture_structure == 4) // Untested, but should work - ret |= 0x100; - pic_vp->width = mb(dec->base.width); - pic_vp->height = mb(dec->base.height); - pic_vp->unk08 = pic_vp->unk04 = (dec->base.width+0xf)&~0xf; // Stride - - nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]); - pic_vp->ofs[5] = pic_vp->ofs[3]; - pic_vp->ofs[0] = pic_vp->ofs[2] = 0; - nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size); - - pic_vp->alternate_scan = desc->alternate_scan; - pic_vp->pad2[0] = pic_vp->pad2[1] = pic_vp->pad2[2] = 0; - pic_vp->unk30 = desc->picture_structure < 3 && (desc->picture_structure == 2 - desc->top_field_first); - pic_vp->unk3a = (desc->picture_coding_type == 1); - for (i = 0; i < 4; ++i) - pic_vp->f_code[i] = desc->f_code[i/2][i%2] + 1; // FU - pic_vp->picture_coding_type = desc->picture_coding_type; - pic_vp->intra_dc_precision = desc->intra_dc_precision; - pic_vp->q_scale_type = desc->q_scale_type; - pic_vp->top_field_first = desc->top_field_first; - pic_vp->full_pel_forward_vector = desc->full_pel_forward_vector; - pic_vp->full_pel_backward_vector = desc->full_pel_backward_vector; - memcpy(pic_vp->intra_quantizer_matrix, desc->intra_matrix, 0x40); - memcpy(pic_vp->non_intra_quantizer_matrix, desc->non_intra_matrix, 0x40); - memcpy(map, pic_vp, sizeof(*pic_vp)); - refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0]; - refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1]; - return ret | (dec->base.profile != PIPE_VIDEO_PROFILE_MPEG1); -} - -static uint32_t -nvc0_decoder_fill_picparm_mpeg4_vp(struct nouveau_vp3_decoder *dec, - struct pipe_mpeg4_picture_desc *desc, - struct nouveau_vp3_video_buffer *refs[16], - unsigned *is_ref, - char *map) -{ - struct mpeg4_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub; - uint32_t ring, ret = 0x01014; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk; - assert(!(dec->base.width & 0xf)); - *is_ref = desc->vop_coding_type <= 1; - - pic_vp->width = dec->base.width; - pic_vp->height = mb(dec->base.height)<<4; - pic_vp->unk0c = pic_vp->unk08 = mb(dec->base.width)<<4; // Stride - - nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]); - pic_vp->ofs[5] = pic_vp->ofs[3]; - pic_vp->ofs[0] = pic_vp->ofs[2] = 0; - pic_vp->pad1 = pic_vp->pad2 = 0; - nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size); - - pic_vp->trd[0] = desc->trd[0]; - pic_vp->trd[1] = desc->trd[1]; - pic_vp->trb[0] = desc->trb[0]; - pic_vp->trb[1] = desc->trb[1]; - pic_vp->u48 = 0; // Codec? - pic_vp->pad1 = pic_vp->pad2 = 0; - pic_vp->f_code_fw = desc->vop_fcode_forward; - pic_vp->f_code_bw = desc->vop_fcode_backward; - pic_vp->interlaced = desc->interlaced; - pic_vp->quant_type = desc->quant_type; - pic_vp->quarter_sample = desc->quarter_sample; - pic_vp->short_video_header = desc->short_video_header; - pic_vp->u54 = 0; - pic_vp->vop_coding_type = desc->vop_coding_type; - pic_vp->rounding_control = desc->rounding_control; - pic_vp->alternate_vertical_scan_flag = desc->alternate_vertical_scan_flag; - pic_vp->top_field_first = desc->top_field_first; - - memcpy(pic_vp->intra, desc->intra_matrix, 0x40); - memcpy(pic_vp->non_intra, desc->non_intra_matrix, 0x40); - memcpy(map, pic_vp, sizeof(*pic_vp)); - refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0]; - refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1]; - return ret; -} - -static uint32_t -nvc0_decoder_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec, - const struct pipe_h264_picture_desc *d, - struct nouveau_vp3_video_buffer *refs[16], - unsigned *is_ref, - char *map) -{ - struct h264_picparm_vp stub_h = {}, *h = &stub_h; - unsigned ring, i, j = 0; - assert(offsetof(struct h264_picparm_vp, u224) == 0x224); - *is_ref = d->is_reference; - dec->last_frame_num = d->frame_num; - - h->width = mb(dec->base.width); - h->height = mb(dec->base.height); - h->stride1 = h->stride2 = mb(dec->base.width)*16; - nouveau_vp3_ycbcr_offsets(dec, &h->ofs[1], &h->ofs[3], &h->ofs[4]); - h->ofs[5] = h->ofs[3]; - h->ofs[0] = h->ofs[2] = 0; - h->u24 = dec->tmp_stride >> 8; - assert(h->u24); - nouveau_vp3_inter_sizes(dec, 1, &ring, &h->bucket_size, &h->inter_ring_data_size); - - h->u220 = 0; - h->f0 = d->mb_adaptive_frame_field_flag; - h->f1 = d->direct_8x8_inference_flag; - h->weighted_pred_flag = d->weighted_pred_flag; - h->f3 = d->constrained_intra_pred_flag; - h->is_reference = d->is_reference; - h->interlace = d->field_pic_flag; - h->bottom_field_flag = d->bottom_field_flag; - h->f7 = 0; // TODO: figure out when set.. - h->log2_max_frame_num_minus4 = d->log2_max_frame_num_minus4; - h->u31_45 = 1; - - h->pic_order_cnt_type = d->pic_order_cnt_type; - h->pic_init_qp_minus26 = d->pic_init_qp_minus26; - h->chroma_qp_index_offset = d->chroma_qp_index_offset; - h->second_chroma_qp_index_offset = d->second_chroma_qp_index_offset; - h->weighted_bipred_idc = d->weighted_bipred_idc; - h->tmp_idx = 0; // set in h264_vp_refs below - h->fifo_dec_index = 0; // always set to 0 to be fifo compatible with other codecs - h->frame_number = d->frame_num; - h->u34_3030 = h->u34_3131 = 0; - h->field_order_cnt[0] = d->field_order_cnt[0]; - h->field_order_cnt[1] = d->field_order_cnt[1]; - memset(h->refs, 0, sizeof(h->refs)); - memcpy(h->m4x4, d->scaling_lists_4x4, sizeof(h->m4x4) + sizeof(h->m8x8)); - h->u220 = 0; - for (i = 0; i < d->num_ref_frames; ++i) { - if (!d->ref[i]) - break; - refs[j] = (struct nouveau_vp3_video_buffer *)d->ref[i]; - h->refs[j].fifo_idx = j + 1; - h->refs[j].tmp_idx = refs[j]->valid_ref; - h->refs[j].field_order_cnt[0] = d->field_order_cnt_list[i][0]; - h->refs[j].field_order_cnt[1] = d->field_order_cnt_list[i][1]; - h->refs[j].frame_idx = d->frame_num_list[i]; - if (!dec->refs[refs[j]->valid_ref].field_pic_flag) { - h->refs[j].unk12 = d->top_is_reference[i]; - h->refs[j].unk13 = d->bottom_is_reference[i]; - } - h->refs[j].unk14 = 0; - h->refs[j].notseenyet = 0; - h->refs[j].unk16 = dec->refs[refs[j]->valid_ref].field_pic_flag; - h->refs[j].unk17 = dec->refs[refs[j]->valid_ref].decoded_top && - d->top_is_reference[i]; - h->refs[j].unk21 = dec->refs[refs[j]->valid_ref].decoded_bottom && - d->bottom_is_reference[i]; - h->refs[j].pad = 0; - assert(!d->is_long_term[i]); - j++; - } - for (; i < 16; ++i) - assert(!d->ref[i]); - assert(d->num_ref_frames <= dec->base.max_references); - - for (; i < d->num_ref_frames; ++i) - h->refs[j].unk16 = d->field_pic_flag; - *(struct h264_picparm_vp *)map = *h; - - return 0x1113; -} - -static void -nvc0_decoder_fill_picparm_h264_vp_refs(struct nouveau_vp3_decoder *dec, - struct pipe_h264_picture_desc *d, - struct nouveau_vp3_video_buffer *refs[16], - struct nouveau_vp3_video_buffer *target, - char *map) -{ - struct h264_picparm_vp *h = (struct h264_picparm_vp *)map; - assert(dec->refs[target->valid_ref].vidbuf == target); -// debug_printf("Target: %p\n", target); - - h->tmp_idx = target->valid_ref; - dec->refs[target->valid_ref].field_pic_flag = d->field_pic_flag; - if (!d->field_pic_flag || d->bottom_field_flag) - dec->refs[target->valid_ref].decoded_bottom = 1; - if (!d->field_pic_flag || !d->bottom_field_flag) - dec->refs[target->valid_ref].decoded_top = 1; -} - -static uint32_t -nvc0_decoder_fill_picparm_vc1_vp(struct nouveau_vp3_decoder *dec, - struct pipe_vc1_picture_desc *d, - struct nouveau_vp3_video_buffer *refs[16], - unsigned *is_ref, - char *map) -{ - struct vc1_picparm_vp *vc = (struct vc1_picparm_vp *)map; - unsigned ring; - assert(dec->base.profile != PIPE_VIDEO_PROFILE_VC1_SIMPLE); - *is_ref = d->picture_type <= 1; - - nouveau_vp3_ycbcr_offsets(dec, &vc->ofs[1], &vc->ofs[3], &vc->ofs[4]); - vc->ofs[5] = vc->ofs[3]; - vc->ofs[0] = vc->ofs[2] = 0; - vc->width = dec->base.width; - vc->height = mb(dec->base.height)<<4; - vc->unk0c = vc->unk10 = mb(dec->base.width)<<4; // Stride - vc->pad = vc->pad2 = 0; - nouveau_vp3_inter_sizes(dec, 1, &ring, &vc->bucket_size, &vc->inter_ring_data_size); - vc->profile = dec->base.profile - PIPE_VIDEO_PROFILE_VC1_SIMPLE; - vc->loopfilter = d->loopfilter; - vc->fastuvmc = d->fastuvmc; - vc->dquant = d->dquant; - vc->overlap = d->overlap; - vc->quantizer = d->quantizer; - vc->u36 = 0; // ? No idea what this one is.. - refs[0] = (struct nouveau_vp3_video_buffer *)d->ref[0]; - refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)d->ref[1]; - return 0x12; -} - #if NOUVEAU_VP3_DEBUG_FENCE static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32 comm_seq, struct nouveau_bo *inter_bo, unsigned slice_size) @@ -493,37 +56,12 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32 } #endif -void nvc0_decoder_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc, - struct nouveau_vp3_video_buffer *target, unsigned comm_seq, - unsigned *caps, unsigned *is_ref, - struct nouveau_vp3_video_buffer *refs[16]) +static void +nvc0_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target) { - struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; - enum pipe_video_codec codec = u_reduce_video_profile(dec->base.profile); - char *vp = bsp_bo->map + VP_OFFSET; - - switch (codec){ - case PIPE_VIDEO_CODEC_MPEG12: - *caps = nvc0_decoder_fill_picparm_mpeg12_vp(dec, desc.mpeg12, refs, is_ref, vp); - nvc0_decoder_handle_references(dec, refs, dec->fence_seq, target); - return; - case PIPE_VIDEO_CODEC_MPEG4: - *caps = nvc0_decoder_fill_picparm_mpeg4_vp(dec, desc.mpeg4, refs, is_ref, vp); - nvc0_decoder_handle_references(dec, refs, dec->fence_seq, target); - return; - case PIPE_VIDEO_CODEC_VC1: { - *caps = nvc0_decoder_fill_picparm_vc1_vp(dec, desc.vc1, refs, is_ref, vp); - nvc0_decoder_handle_references(dec, refs, dec->fence_seq, target); - return; - } - case PIPE_VIDEO_CODEC_MPEG4_AVC: { - *caps = nvc0_decoder_fill_picparm_h264_vp(dec, desc.h264, refs, is_ref, vp); - nvc0_decoder_handle_references(dec, refs, dec->fence_seq, target); - nvc0_decoder_fill_picparm_h264_vp_refs(dec, desc.h264, refs, target, vp); - return; - } - default: assert(0); return; - } + dec->refs[target->valid_ref].vidbuf = NULL; + dec->refs[target->valid_ref].last_used = 0; +// debug_printf("Unreffed %p\n", target); } void |