diff options
author | Austin Yuan <shengquan.yuan@gmail.com> | 2010-07-09 17:15:25 +0800 |
---|---|---|
committer | Austin Yuan <shengquan.yuan@gmail.com> | 2010-07-09 17:15:25 +0800 |
commit | 3c3088a5d713e7a92bc7cf2a0635f4fcda0e52c3 (patch) | |
tree | 7e6e6b7256e9bb738f7e76e82ff78e9f1aa55778 | |
parent | 4ff4b0db9706d6205e9d16f2f1b04dac9c75ed72 (diff) | |
parent | 4916645f3d29804a085994ccfb352525708d1ae3 (diff) |
Merge branch 'fdva-master'
-rw-r--r-- | i965_drv_video/i965_avc_bsd.c | 88 | ||||
-rw-r--r-- | i965_drv_video/i965_media_h264.c | 13 | ||||
-rw-r--r-- | i965_drv_video/i965_media_h264.h | 1 | ||||
-rw-r--r-- | i965_drv_video/intel_batchbuffer.c | 6 | ||||
-rw-r--r-- | i965_drv_video/shaders/h264/mc/avc_mc.g4b | 6 | ||||
-rw-r--r-- | i965_drv_video/shaders/h264/mc/avc_mc.g4b.gen5 | 6 | ||||
-rw-r--r-- | i965_drv_video/shaders/h264/mc/intra_Pred_8x8_Y.asm | 4 | ||||
-rw-r--r-- | va/glx/va_glx_impl.c | 39 | ||||
-rw-r--r-- | va/glx/va_glx_private.h | 10 | ||||
-rw-r--r-- | va/va.c | 2 | ||||
-rw-r--r-- | va/x11/dri2_util.c | 6 | ||||
-rw-r--r-- | va/x11/va_dricommon.c | 38 | ||||
-rw-r--r-- | va/x11/va_dricommon.h | 1 |
13 files changed, 157 insertions, 63 deletions
diff --git a/i965_drv_video/i965_avc_bsd.c b/i965_drv_video/i965_avc_bsd.c index 1334f26..0976439 100644 --- a/i965_drv_video/i965_avc_bsd.c +++ b/i965_drv_video/i965_avc_bsd.c @@ -177,8 +177,8 @@ i965_avc_bsd_img_state(VADriverContextP ctx, struct decode_state *decode_state) (height_in_mbs << 16) | (width_in_mbs << 0)); OUT_BCS_BATCH(ctx, - (pic_param->second_chroma_qp_index_offset << 24) | - (pic_param->chroma_qp_index_offset << 16) | + ((pic_param->second_chroma_qp_index_offset & 0x1f) << 24) | + ((pic_param->chroma_qp_index_offset & 0x1f) << 16) | (SCAN_RASTER_ORDER << 15) | /* AVC ILDB Data */ (SCAN_SPECIAL_ORDER << 14) | /* AVC IT Command */ (SCAN_RASTER_ORDER << 13) | /* AVC IT Data */ @@ -566,11 +566,41 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx, ADVANCE_BCS_BATCH(ctx); } +/* + * Return the bit offset to the first bit of the slice data + * + * VASliceParameterBufferH264.slice_data_bit_offset will point into the part + * of slice header if there are some escaped bytes in the slice header. The offset + * to slice data is needed for BSD unit so that BSD unit can fetch right slice data + * for processing. This fixes conformance case BASQP1_Sony_C.jsv + */ +static int +i965_avc_bsd_get_slice_bit_offset(uint8_t *buf, int mode_flag, int in_slice_data_bit_offset) +{ + int out_slice_data_bit_offset; + int slice_header_size = in_slice_data_bit_offset / 8; + int i, j; + + for (i = 0, j = 0; i < slice_header_size; i++, j++) { + if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3) { + i++, j += 2; + } + } + + out_slice_data_bit_offset = 8 * j + in_slice_data_bit_offset % 8; + + if (mode_flag == ENTROPY_CABAC) + out_slice_data_bit_offset = ALIGN(out_slice_data_bit_offset, 0x8); + + return out_slice_data_bit_offset; +} + static void g4x_avc_bsd_object(VADriverContextP ctx, struct decode_state *decode_state, VAPictureParameterBufferH264 *pic_param, - VASliceParameterBufferH264 *slice_param) + VASliceParameterBufferH264 *slice_param, + int slice_index) { int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1; int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */ @@ -585,6 +615,7 @@ g4x_avc_bsd_object(VADriverContextP ctx, int weighted_pred_idc = 0; int first_mb_in_slice = 0; int slice_type; + uint8_t *slice_data = NULL; encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */ @@ -594,10 +625,12 @@ g4x_avc_bsd_object(VADriverContextP ctx, } else cmd_len = 8; - slice_data_bit_offset = slice_param->slice_data_bit_offset; - - if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC) - slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8); + dri_bo_map(decode_state->slice_datas[slice_index]->bo, 0); + slice_data = (uint8_t *)(decode_state->slice_datas[slice_index]->bo->virtual + slice_param->slice_data_offset); + slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data, + pic_param->pic_fields.bits.entropy_coding_mode_flag, + slice_param->slice_data_bit_offset); + dri_bo_unmap(decode_state->slice_datas[slice_index]->bo); if (slice_param->slice_type == SLICE_TYPE_I || slice_param->slice_type == SLICE_TYPE_SI) @@ -629,11 +662,9 @@ g4x_avc_bsd_object(VADriverContextP ctx, else if (slice_type == SLICE_TYPE_B) weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc; - first_mb_in_slice = slice_param->first_mb_in_slice; + first_mb_in_slice = slice_param->first_mb_in_slice << mbaff_picture; slice_hor_pos = first_mb_in_slice % width_in_mbs; slice_ver_pos = first_mb_in_slice / width_in_mbs; - first_mb_in_slice = (slice_ver_pos << mbaff_picture) * width_in_mbs + slice_hor_pos; - slice_hor_pos <<= mbaff_picture; BEGIN_BCS_BATCH(ctx, cmd_len); OUT_BCS_BATCH(ctx, CMD_AVC_BSD_OBJECT | (cmd_len - 2)); @@ -695,7 +726,8 @@ static void ironlake_avc_bsd_object(VADriverContextP ctx, struct decode_state *decode_state, VAPictureParameterBufferH264 *pic_param, - VASliceParameterBufferH264 *slice_param) + VASliceParameterBufferH264 *slice_param, + int slice_index) { int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1; int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */ @@ -713,6 +745,8 @@ ironlake_avc_bsd_object(VADriverContextP ctx, int weighted_pred_idc = 0; int first_mb_in_slice; int slice_type; + uint8_t *slice_data = NULL; + encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */ if (encrypted) { @@ -720,10 +754,12 @@ ironlake_avc_bsd_object(VADriverContextP ctx, } else counter_value = 0; - slice_data_bit_offset = slice_param->slice_data_bit_offset; - - if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC) - slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8); + dri_bo_map(decode_state->slice_datas[slice_index]->bo, 0); + slice_data = (uint8_t *)(decode_state->slice_datas[slice_index]->bo->virtual + slice_param->slice_data_offset); + slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data, + pic_param->pic_fields.bits.entropy_coding_mode_flag, + slice_param->slice_data_bit_offset); + dri_bo_unmap(decode_state->slice_datas[slice_index]->bo); if (slice_param->slice_type == SLICE_TYPE_I || slice_param->slice_type == SLICE_TYPE_SI) @@ -755,11 +791,9 @@ ironlake_avc_bsd_object(VADriverContextP ctx, else if (slice_type == SLICE_TYPE_B) weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc; - first_mb_in_slice = slice_param->first_mb_in_slice; + first_mb_in_slice = slice_param->first_mb_in_slice << mbaff_picture; slice_hor_pos = first_mb_in_slice % width_in_mbs; slice_ver_pos = first_mb_in_slice / width_in_mbs; - first_mb_in_slice = (slice_ver_pos << mbaff_picture) * width_in_mbs + slice_hor_pos; - slice_hor_pos <<= mbaff_picture; BEGIN_BCS_BATCH(ctx, 16); OUT_BCS_BATCH(ctx, CMD_AVC_BSD_OBJECT | (16 - 2)); @@ -837,14 +871,15 @@ static void i965_avc_bsd_object(VADriverContextP ctx, struct decode_state *decode_state, VAPictureParameterBufferH264 *pic_param, - VASliceParameterBufferH264 *slice_param) + VASliceParameterBufferH264 *slice_param, + int slice_index) { struct i965_driver_data *i965 = i965_driver_data(ctx); if (IS_IRONLAKE(i965->intel.device_id)) - ironlake_avc_bsd_object(ctx, decode_state, pic_param, slice_param); + ironlake_avc_bsd_object(ctx, decode_state, pic_param, slice_param, slice_index); else - g4x_avc_bsd_object(ctx, decode_state, pic_param, slice_param); + g4x_avc_bsd_object(ctx, decode_state, pic_param, slice_param, slice_index); } static void @@ -852,7 +887,7 @@ i965_avc_bsd_phantom_slice(VADriverContextP ctx, struct decode_state *decode_state, VAPictureParameterBufferH264 *pic_param) { - i965_avc_bsd_object(ctx, decode_state, pic_param, NULL); + i965_avc_bsd_object(ctx, decode_state, pic_param, NULL, 0); } static void @@ -993,6 +1028,8 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state) i965_avc_bsd_frame_store_index(ctx, pic_param); i965_h264_context->enable_avc_ildb = 0; + i965_h264_context->picture.i_flag = 1; + for (j = 0; j < decode_state->num_slice_params && i965_h264_context->enable_avc_ildb == 0; j++) { assert(decode_state->slice_params && decode_state->slice_params[j]->buffer); slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j]->buffer; @@ -1035,9 +1072,14 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state) (slice_param->slice_type == SLICE_TYPE_SP) || (slice_param->slice_type == SLICE_TYPE_B)); + if (i965_h264_context->picture.i_flag && + (slice_param->slice_type != SLICE_TYPE_I || + slice_param->slice_type != SLICE_TYPE_SI)) + i965_h264_context->picture.i_flag = 0; + i965_avc_bsd_slice_state(ctx, pic_param, slice_param); i965_avc_bsd_buf_base_state(ctx, pic_param, slice_param); - i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param); + i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param, j); slice_param++; } } diff --git a/i965_drv_video/i965_media_h264.c b/i965_drv_video/i965_media_h264.c index 95efa3f..add774f 100644 --- a/i965_drv_video/i965_media_h264.c +++ b/i965_drv_video/i965_media_h264.c @@ -523,7 +523,6 @@ i965_media_h264_vfe_state_extension(VADriverContextP ctx, struct i965_h264_context *i965_h264_context; struct i965_vfe_state_ex *vfe_state_ex; VAPictureParameterBufferH264 *pic_param; - VASliceParameterBufferH264 *slice_param; int mbaff_frame_flag; assert(media_state->private_context); @@ -531,10 +530,6 @@ i965_media_h264_vfe_state_extension(VADriverContextP ctx, assert(decode_state->pic_param && decode_state->pic_param->buffer); pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer; - - assert(decode_state->slice_params[0] && decode_state->slice_params[0]->buffer); - slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[0]->buffer; - mbaff_frame_flag = (pic_param->seq_fields.bits.mb_adaptive_frame_field_flag && !pic_param->pic_fields.bits.field_pic_flag); @@ -556,16 +551,12 @@ i965_media_h264_vfe_state_extension(VADriverContextP ctx, vfe_state_ex->vfex1.avc.residual_data_fix_offset_flag = !!RESIDUAL_DATA_OFFSET; vfe_state_ex->vfex1.avc.residual_data_offset = RESIDUAL_DATA_OFFSET; - if (slice_param->slice_type == SLICE_TYPE_I || - slice_param->slice_type == SLICE_TYPE_SI) + if (i965_h264_context->picture.i_flag) { vfe_state_ex->vfex1.avc.sub_field_present_flag = PRESENT_NOMV; /* NoMV */ - else - vfe_state_ex->vfex1.avc.sub_field_present_flag = PRESENT_MV_WO; /* Both MV and W/O */ - - if (vfe_state_ex->vfex1.avc.sub_field_present_flag == 0) { vfe_state_ex->vfex1.avc.weight_grf_offset = 0; vfe_state_ex->vfex1.avc.residual_grf_offset = 0; } else { + vfe_state_ex->vfex1.avc.sub_field_present_flag = PRESENT_MV_WO; /* Both MV and W/O */ vfe_state_ex->vfex1.avc.weight_grf_offset = 4; vfe_state_ex->vfex1.avc.residual_grf_offset = 6; } diff --git a/i965_drv_video/i965_media_h264.h b/i965_drv_video/i965_media_h264.h index 5a10e73..d1b6214 100644 --- a/i965_drv_video/i965_media_h264.h +++ b/i965_drv_video/i965_media_h264.h @@ -37,6 +37,7 @@ struct i965_h264_context unsigned int width_in_mbs; unsigned int height_in_mbs; int mbaff_frame_flag; + int i_flag; } picture; int enable_avc_ildb; diff --git a/i965_drv_video/intel_batchbuffer.c b/i965_drv_video/intel_batchbuffer.c index 02f66d3..abe548e 100644 --- a/i965_drv_video/intel_batchbuffer.c +++ b/i965_drv_video/intel_batchbuffer.c @@ -37,6 +37,7 @@ static void intel_batchbuffer_reset(struct intel_batchbuffer *batch) { struct intel_driver_data *intel = batch->intel; + int batch_size = batch->flag == I915_EXEC_RENDER ? BATCH_SIZE : (BATCH_SIZE * 8); assert(batch->flag == I915_EXEC_RENDER || batch->flag == I915_EXEC_BSD); @@ -44,12 +45,13 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) dri_bo_unreference(batch->buffer); batch->buffer = dri_bo_alloc(intel->bufmgr, batch->flag == I915_EXEC_RENDER ? "render batch buffer" : "bsd batch buffer", - BATCH_SIZE, 0x1000); + batch_size, + 0x1000); assert(batch->buffer); dri_bo_map(batch->buffer, 1); assert(batch->buffer->virtual); batch->map = batch->buffer->virtual; - batch->size = BATCH_SIZE; + batch->size = batch_size; batch->ptr = batch->map; batch->atomic = 0; } diff --git a/i965_drv_video/shaders/h264/mc/avc_mc.g4b b/i965_drv_video/shaders/h264/mc/avc_mc.g4b index f627326..cdee6ac 100644 --- a/i965_drv_video/shaders/h264/mc/avc_mc.g4b +++ b/i965_drv_video/shaders/h264/mc/avc_mc.g4b @@ -344,7 +344,7 @@ { 0x80800040, 0xd04045b1, 0x00b18840, 0x002c0744 }, { 0x80800040, 0xd06045b1, 0x00b18860, 0x002c0746 }, { 0x00000001, 0x34000020, 0x000007e0, 0x00000000 }, - { 0x02800005, 0x20003da0, 0x00000708, 0x00020002 }, + { 0x02802005, 0x20003da0, 0x00000708, 0x00020002 }, { 0x02600005, 0x20003da0, 0x02000708, 0x00010001 }, { 0x009a0001, 0x27200169, 0x00000000, 0x80808080 }, { 0x00780001, 0x27400231, 0x028d0724, 0x00000000 }, @@ -423,7 +423,7 @@ { 0x00800040, 0x24003e2c, 0x00b10726, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10725, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10724, 0x00010001 }, - { 0x00800008, 0x25e03d89, 0x00240400, 0x00020002 }, + { 0x00800008, 0x25e03d89, 0x002d0400, 0x00020002 }, { 0x80800040, 0xd0003531, 0x00ad05c0, 0x00b18800 }, { 0x80800040, 0xd0203531, 0x00ad05c2, 0x00b18820 }, { 0x80800040, 0xd0403531, 0x00ad05c4, 0x00b18840 }, @@ -434,7 +434,7 @@ { 0x00800040, 0x24003e2c, 0x00b10742, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10741, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10740, 0x00010001 }, - { 0x00800008, 0x25e03d89, 0x00240400, 0x00020002 }, + { 0x00800008, 0x25e03d89, 0x002d0400, 0x00020002 }, { 0x00800001, 0x45c10231, 0x00d205e0, 0x00000000 }, { 0x80800040, 0xd0003631, 0x004d05c0, 0x00b18800 }, { 0x80800040, 0xd0203631, 0x004d05c4, 0x00b18820 }, diff --git a/i965_drv_video/shaders/h264/mc/avc_mc.g4b.gen5 b/i965_drv_video/shaders/h264/mc/avc_mc.g4b.gen5 index f627326..cdee6ac 100644 --- a/i965_drv_video/shaders/h264/mc/avc_mc.g4b.gen5 +++ b/i965_drv_video/shaders/h264/mc/avc_mc.g4b.gen5 @@ -344,7 +344,7 @@ { 0x80800040, 0xd04045b1, 0x00b18840, 0x002c0744 }, { 0x80800040, 0xd06045b1, 0x00b18860, 0x002c0746 }, { 0x00000001, 0x34000020, 0x000007e0, 0x00000000 }, - { 0x02800005, 0x20003da0, 0x00000708, 0x00020002 }, + { 0x02802005, 0x20003da0, 0x00000708, 0x00020002 }, { 0x02600005, 0x20003da0, 0x02000708, 0x00010001 }, { 0x009a0001, 0x27200169, 0x00000000, 0x80808080 }, { 0x00780001, 0x27400231, 0x028d0724, 0x00000000 }, @@ -423,7 +423,7 @@ { 0x00800040, 0x24003e2c, 0x00b10726, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10725, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10724, 0x00010001 }, - { 0x00800008, 0x25e03d89, 0x00240400, 0x00020002 }, + { 0x00800008, 0x25e03d89, 0x002d0400, 0x00020002 }, { 0x80800040, 0xd0003531, 0x00ad05c0, 0x00b18800 }, { 0x80800040, 0xd0203531, 0x00ad05c2, 0x00b18820 }, { 0x80800040, 0xd0403531, 0x00ad05c4, 0x00b18840 }, @@ -434,7 +434,7 @@ { 0x00800040, 0x24003e2c, 0x00b10742, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10741, 0x00020002 }, { 0x00800048, 0x24003e2c, 0x00b10740, 0x00010001 }, - { 0x00800008, 0x25e03d89, 0x00240400, 0x00020002 }, + { 0x00800008, 0x25e03d89, 0x002d0400, 0x00020002 }, { 0x00800001, 0x45c10231, 0x00d205e0, 0x00000000 }, { 0x80800040, 0xd0003631, 0x004d05c0, 0x00b18800 }, { 0x80800040, 0xd0203631, 0x004d05c4, 0x00b18820 }, diff --git a/i965_drv_video/shaders/h264/mc/intra_Pred_8x8_Y.asm b/i965_drv_video/shaders/h264/mc/intra_Pred_8x8_Y.asm index ce77771..c4f245e 100644 --- a/i965_drv_video/shaders/h264/mc/intra_Pred_8x8_Y.asm +++ b/i965_drv_video/shaders/h264/mc/intra_Pred_8x8_Y.asm @@ -210,7 +210,7 @@ INTRA_8X8_VERT_LEFT: add (16) acc0<1>:w REF_TOP(0,2)REGION(16,1) 2:w // p[x+2]+2
mac (16) acc0<1>:w REF_TOP(0,1)REGION(16,1) 2:w // 2*p[x+1]+p[x+2]+2
mac (16) acc0<1>:w REF_TOP(0)REGION(16,1) 1:w // p[x]+2*p[x+1]+p[x+2]+2
- shr (16) PRED_YW(15)<1> acc0<1>:w 2:w // (p[x]+2*p[x+1]+p[x+2]+2)>>2
+ shr (16) PRED_YW(15)<1> acc0<1;8,1>:w 2:w // (p[x]+2*p[x+1]+p[x+2]+2)>>2
// Add error block
$for(0,0; <4; 1,32) {
@@ -229,7 +229,7 @@ INTRA_8X8_HOR_UP: add (16) acc0<1>:w REF_LEFT(0,2)REGION(16,1) 2:w // p[y+2]+2
mac (16) acc0<1>:w REF_LEFT(0,1)REGION(16,1) 2:w // 2*p[y+1]+p[y+2]+2
mac (16) acc0<1>:w REF_LEFT(0)REGION(16,1) 1:w // p[y]+2*p[y+1]+p[y+2]+2
- shr (16) PRED_YW(15)<1> acc0<1>:w 2:w // (p[y]+2*p[y+1]+p[y+2]+2)>>2
+ shr (16) PRED_YW(15)<1> acc0<1;8,1>:w 2:w // (p[y]+2*p[y+1]+p[y+2]+2)>>2
// Merge even/odd pixels
// The predicted data need to be stored in byte type (22 bytes are required)
diff --git a/va/glx/va_glx_impl.c b/va/glx/va_glx_impl.c index 497b64e..f5bbe91 100644 --- a/va/glx/va_glx_impl.c +++ b/va/glx/va_glx_impl.c @@ -222,6 +222,14 @@ static int load_tfp_extensions(VADriverContextP ctx) { VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); + pOpenGLVTable->glx_create_pixmap = (PFNGLXCREATEPIXMAPPROC) + get_proc_address("glXCreatePixmap"); + if (!pOpenGLVTable->glx_create_pixmap) + return 0; + pOpenGLVTable->glx_destroy_pixmap = (PFNGLXDESTROYPIXMAPPROC) + get_proc_address("glXDestroyPixmap"); + if (!pOpenGLVTable->glx_destroy_pixmap) + return 0; pOpenGLVTable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC) get_proc_address("glXBindTexImageEXT"); if (!pOpenGLVTable->glx_bind_tex_image) @@ -451,15 +459,16 @@ struct VASurfaceGLX { // Create Pixmaps for GLX texture-from-pixmap extension static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) { - const unsigned int width = pSurfaceGLX->width; - const unsigned int height = pSurfaceGLX->height; - Pixmap pixmap = None; - GLXFBConfig *fbconfig = NULL; - GLXPixmap glx_pixmap = None; - Window root_window; - XWindowAttributes wattr; - int *attrib; - int n_fbconfig_attrs; + VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx); + const unsigned int width = pSurfaceGLX->width; + const unsigned int height = pSurfaceGLX->height; + Pixmap pixmap = None; + GLXFBConfig *fbconfig = NULL; + GLXPixmap glx_pixmap = None; + Window root_window; + XWindowAttributes wattr; + int *attrib; + int n_fbconfig_attrs; root_window = RootWindow((Display *)ctx->native_dpy, ctx->x11_screen); XGetWindowAttributes((Display *)ctx->native_dpy, root_window, &wattr); @@ -523,7 +532,7 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) *attrib++ = GL_NONE; x11_trap_errors(); - glx_pixmap = glXCreatePixmap( + glx_pixmap = pOpenGLVTable->glx_create_pixmap( (Display *)ctx->native_dpy, fbconfig[0], pixmap, @@ -544,13 +553,15 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) // Destroy Pixmaps used for TFP static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) { + VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx); + if (pSurfaceGLX->pix_texture) { glDeleteTextures(1, &pSurfaceGLX->pix_texture); pSurfaceGLX->pix_texture = 0; } if (pSurfaceGLX->glx_pixmap) { - glXDestroyPixmap((Display *)ctx->native_dpy, pSurfaceGLX->glx_pixmap); + pOpenGLVTable->glx_destroy_pixmap((Display *)ctx->native_dpy, pSurfaceGLX->glx_pixmap); pSurfaceGLX->glx_pixmap = None; } @@ -1059,12 +1070,6 @@ VAStatus va_glx_init_context(VADriverContextP ctx) if (!glXQueryVersion((Display *)ctx->native_dpy, &glx_major, &glx_minor)) return VA_STATUS_ERROR_UNIMPLEMENTED; - if (glx_major < 1 || (glx_major == 1 && glx_minor < 3)) { /* GLX 1.3 */ - va_glx_error_message("GLX version 1.3 expected but only " - "version %d.%d is available\n", - glx_major, glx_minor); - return VA_STATUS_ERROR_UNIMPLEMENTED; - } if (!check_tfp_extensions(ctx) || !load_tfp_extensions(ctx)) return VA_STATUS_ERROR_UNIMPLEMENTED; diff --git a/va/glx/va_glx_private.h b/va/glx/va_glx_private.h index 6667de9..eb1185c 100644 --- a/va/glx/va_glx_private.h +++ b/va/glx/va_glx_private.h @@ -31,15 +31,25 @@ #include "va_x11.h" #include "va_glx.h" #include "va_backend_glx.h" +#include <GL/glxext.h> #if GLX_GLXEXT_VERSION < 18 typedef void (*PFNGLXBINDTEXIMAGEEXTPROC)(Display *, GLXDrawable, int, const int *); typedef void (*PFNGLXRELEASETEXIMAGEEXTPROC)(Display *, GLXDrawable, int); #endif +#if GLX_GLXEXT_VERSION < 27 +/* XXX: this is not exactly that version but this is the only means to + make sure we have the correct <GL/glx.h> with those signatures */ +typedef GLXPixmap (*PFNGLXCREATEPIXMAPPROC)(Display *, GLXFBConfig, Pixmap, const int *); +typedef void (*PFNGLXDESTROYPIXMAPPROC)(Display *, GLXPixmap); +#endif + typedef struct VAOpenGLVTable *VAOpenGLVTableP; struct VAOpenGLVTable { + PFNGLXCREATEPIXMAPPROC glx_create_pixmap; + PFNGLXDESTROYPIXMAPPROC glx_destroy_pixmap; PFNGLXBINDTEXIMAGEEXTPROC glx_bind_tex_image; PFNGLXRELEASETEXIMAGEEXTPROC glx_release_tex_image; PFNGLGENFRAMEBUFFERSEXTPROC gl_gen_framebuffers; @@ -319,6 +319,8 @@ const char *vaErrorStr(VAStatus error_status) return "the requested function is not implemented"; case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING: return "surface is in displaying (may by overlay)" ; + case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT: + return "invalid VAImageFormat"; case VA_STATUS_ERROR_UNKNOWN: return "unknown libva error"; } diff --git a/va/x11/dri2_util.c b/va/x11/dri2_util.c index 63db330..0309c0f 100644 --- a/va/x11/dri2_util.c +++ b/va/x11/dri2_util.c @@ -98,7 +98,11 @@ dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) VA_DRI2Buffer *buffers; i = 0; - attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (dri_drawable->is_window) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + else + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + buffers = VA_DRI2GetBuffers(ctx->native_dpy, dri_drawable->x_drawable, &dri2_drawable->width, &dri2_drawable->height, attachments, i, &count); diff --git a/va/x11/va_dricommon.c b/va/x11/va_dricommon.c index f9c3dfd..71f9705 100644 --- a/va/x11/va_dricommon.c +++ b/va/x11/va_dricommon.c @@ -1,6 +1,41 @@ #include "va_dricommon.h" -static struct dri_drawable * +// X error trap +static int x11_error_code = 0; +static int (*old_error_handler)(Display *, XErrorEvent *); + +static int +error_handler(Display *dpy, XErrorEvent *error) +{ + x11_error_code = error->error_code; + return 0; +} + +static void +x11_trap_errors(void) +{ + x11_error_code = 0; + old_error_handler = XSetErrorHandler(error_handler); +} + +static int +x11_untrap_errors(void) +{ + XSetErrorHandler(old_error_handler); + return x11_error_code; +} + +static int +is_window(Display *dpy, Drawable drawable) +{ + XWindowAttributes wattr; + + x11_trap_errors(); + XGetWindowAttributes(dpy, drawable, &wattr); + return x11_untrap_errors() == 0; +} + +static struct dri_drawable * do_drawable_hash(VADriverContextP ctx, XID drawable) { struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; @@ -15,6 +50,7 @@ do_drawable_hash(VADriverContextP ctx, XID drawable) dri_drawable = dri_state->createDrawable(ctx, drawable); dri_drawable->x_drawable = drawable; + dri_drawable->is_window = is_window((Display *)ctx->native_dpy, drawable); dri_drawable->next = dri_state->drawable_hash[index]; dri_state->drawable_hash[index] = dri_drawable; diff --git a/va/x11/va_dricommon.h b/va/x11/va_dricommon.h index ae364e7..0f8a1db 100644 --- a/va/x11/va_dricommon.h +++ b/va/x11/va_dricommon.h @@ -40,6 +40,7 @@ union dri_buffer struct dri_drawable { XID x_drawable; + int is_window; int x; int y; unsigned int width; |