summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeon/radeon_vce.c13
-rw-r--r--src/gallium/drivers/radeon/radeon_vce.h3
-rw-r--r--src/gallium/drivers/radeon/radeon_vce_50.c19
3 files changed, 30 insertions, 5 deletions
diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c
index 0b667fd489b..bc8f36db355 100644
--- a/src/gallium/drivers/radeon/radeon_vce.c
+++ b/src/gallium/drivers/radeon/radeon_vce.c
@@ -57,6 +57,7 @@ static void flush(struct rvce_encoder *enc)
{
enc->ws->cs_flush(enc->cs, RADEON_FLUSH_ASYNC, NULL, 0);
enc->task_info_idx = 0;
+ enc->bs_idx = 0;
}
#if 0
@@ -310,7 +311,8 @@ static void rvce_encode_bitstream(struct pipe_video_codec *encoder,
RVID_ERR("Can't create feedback buffer.\n");
return;
}
- enc->session(enc);
+ if (!enc->cs->cdw)
+ enc->session(enc);
enc->encode(enc);
enc->feedback(enc);
}
@@ -323,7 +325,8 @@ static void rvce_end_frame(struct pipe_video_codec *encoder,
struct rvce_cpb_slot *slot = LIST_ENTRY(
struct rvce_cpb_slot, enc->cpb_slots.prev, list);
- flush(enc);
+ if (!enc->dual_inst || enc->bs_idx > 1)
+ flush(enc);
/* update the CPB backtrack with the just encoded frame */
slot->picture_type = enc->pic.picture_type;
@@ -362,6 +365,9 @@ static void rvce_get_feedback(struct pipe_video_codec *encoder,
*/
static void rvce_flush(struct pipe_video_codec *encoder)
{
+ struct rvce_encoder *enc = (struct rvce_encoder*)encoder;
+
+ flush(enc);
}
static void rvce_cs_flush(void *ctx, unsigned flags,
@@ -401,6 +407,9 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context,
enc->use_vui = true;
if (rscreen->info.family >= CHIP_TONGA)
enc->dual_pipe = true;
+ /* TODO enable B frame with dual instance */
+ if ((rscreen->info.family >= CHIP_TONGA) && (templ->max_references == 1))
+ enc->dual_inst = true;
enc->base = *templ;
enc->base.context = context;
diff --git a/src/gallium/drivers/radeon/radeon_vce.h b/src/gallium/drivers/radeon/radeon_vce.h
index 06e9868ca96..624bda479f8 100644
--- a/src/gallium/drivers/radeon/radeon_vce.h
+++ b/src/gallium/drivers/radeon/radeon_vce.h
@@ -106,11 +106,14 @@ struct rvce_encoder {
struct rvid_buffer *fb;
struct rvid_buffer cpb;
struct pipe_h264_enc_picture_desc pic;
+
unsigned task_info_idx;
+ unsigned bs_idx;
bool use_vm;
bool use_vui;
bool dual_pipe;
+ bool dual_inst;
};
/* CPB handling functions */
diff --git a/src/gallium/drivers/radeon/radeon_vce_50.c b/src/gallium/drivers/radeon/radeon_vce_50.c
index 5bf22194418..afdab18c0d3 100644
--- a/src/gallium/drivers/radeon/radeon_vce_50.c
+++ b/src/gallium/drivers/radeon/radeon_vce_50.c
@@ -78,17 +78,30 @@ static void rate_control(struct rvce_encoder *enc)
static void encode(struct rvce_encoder *enc)
{
- signed luma_offset, chroma_offset;
+ signed luma_offset, chroma_offset, bs_offset;
+ unsigned dep, bs_idx = enc->bs_idx++;
int i;
- enc->task_info(enc, 0x00000003, 0, 0, 0);
+ if (enc->dual_inst) {
+ if (bs_idx == 0)
+ dep = 1;
+ else if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR)
+ dep = 0;
+ else
+ dep = 2;
+ } else
+ dep = 0;
+
+ enc->task_info(enc, 0x00000003, dep, 0, bs_idx);
RVCE_BEGIN(0x05000001); // context buffer
RVCE_READWRITE(enc->cpb.res->cs_buf, enc->cpb.res->domains, 0); // encodeContextAddressHi/Lo
RVCE_END();
+ bs_offset = -(signed)(bs_idx * enc->bs_size);
+
RVCE_BEGIN(0x05000004); // video bitstream buffer
- RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, 0); // videoBitstreamRingAddressHi/Lo
+ RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, bs_offset); // videoBitstreamRingAddressHi/Lo
RVCE_CS(enc->bs_size); // videoBitstreamRingSize
RVCE_END();