summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Yuan <shengquan.yuan@gmail.com>2010-07-09 17:15:25 +0800
committerAustin Yuan <shengquan.yuan@gmail.com>2010-07-09 17:15:25 +0800
commit3c3088a5d713e7a92bc7cf2a0635f4fcda0e52c3 (patch)
tree7e6e6b7256e9bb738f7e76e82ff78e9f1aa55778
parent4ff4b0db9706d6205e9d16f2f1b04dac9c75ed72 (diff)
parent4916645f3d29804a085994ccfb352525708d1ae3 (diff)
Merge branch 'fdva-master'
-rw-r--r--i965_drv_video/i965_avc_bsd.c88
-rw-r--r--i965_drv_video/i965_media_h264.c13
-rw-r--r--i965_drv_video/i965_media_h264.h1
-rw-r--r--i965_drv_video/intel_batchbuffer.c6
-rw-r--r--i965_drv_video/shaders/h264/mc/avc_mc.g4b6
-rw-r--r--i965_drv_video/shaders/h264/mc/avc_mc.g4b.gen56
-rw-r--r--i965_drv_video/shaders/h264/mc/intra_Pred_8x8_Y.asm4
-rw-r--r--va/glx/va_glx_impl.c39
-rw-r--r--va/glx/va_glx_private.h10
-rw-r--r--va/va.c2
-rw-r--r--va/x11/dri2_util.c6
-rw-r--r--va/x11/va_dricommon.c38
-rw-r--r--va/x11/va_dricommon.h1
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;
diff --git a/va/va.c b/va/va.c
index 00a96cf..e143c7b 100644
--- a/va/va.c
+++ b/va/va.c
@@ -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;