xf86-video-intel: 4 commits - src/sna/gen3_render.c src/sna/kgem.c src/sna/sna_video.c src/sna/sna_video.h src/sna/sna_video_overlay.c src/sna/sna_video_textured.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Nov 9 07:30:17 PST 2011


 src/sna/gen3_render.c        |  206 ++++++++++++++++++++++++++-----------------
 src/sna/kgem.c               |    1 
 src/sna/sna_video.c          |   41 +++-----
 src/sna/sna_video.h          |   11 +-
 src/sna/sna_video_overlay.c  |    9 +
 src/sna/sna_video_textured.c |   33 +++---
 6 files changed, 176 insertions(+), 125 deletions(-)

New commits:
commit 3252b46e115e6cc46abbcc4f502feeb9edc31ad6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 9 15:16:04 2011 +0000

    sna/gen3: Pack video frames
    
    If you're going to benchmark, you may as well do so favourably.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index c8ad209..83ac23a 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2959,36 +2959,36 @@ gen3_emit_video_state(struct sna *sna,
 		      struct kgem_bo *dst_bo,
 		      int width, int height)
 {
-	uint32_t shader_offset;
-	uint32_t ms3;
+	struct gen3_render_state *state = &sna->render_state.gen3;
+	uint32_t id, ms3, rewind;
 
 	gen3_emit_target(sna, dst_bo, width, height,
 			 sna_format_for_depth(pixmap->drawable.depth));
 
 	/* XXX share with composite? Is it worth the effort? */
-	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
-		  I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) |
-		  2);
-	OUT_BATCH((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT));
-	OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
-		  S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
-		  S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
-		  S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
-		  S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
-		  S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
-		  S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
-		  S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
-	OUT_BATCH((2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
-		  (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) |
-		  S6_COLOR_WRITE_ENABLE);
-
-	sna->render_state.gen3.last_blend = 0;
-	sna->render_state.gen3.last_sampler = 0;
-	sna->render_state.gen3.floats_per_vertex = 4;
-	sna->render_state.gen3.last_shader = -1;
-	sna->render_state.gen3.last_constants = 0;
+	if ((state->last_shader & (1<<31)) == 0) {
+		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+			  I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) |
+			  2);
+		OUT_BATCH((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT));
+		OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
+			  S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
+			  S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
+			  S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
+			  S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
+			  S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
+			  S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
+			  S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
+		OUT_BATCH((2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+			  (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) |
+			  S6_COLOR_WRITE_ENABLE);
+
+		state->last_blend = 0;
+		state->floats_per_vertex = 4;
+	}
 
 	if (!is_planar_fourcc(frame->id)) {
+		rewind = sna->kgem.nbatch;
 		OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | 4);
 		OUT_BATCH(0x0000001);	/* constant 0 */
 		/* constant 0: brightness/contrast */
@@ -2996,7 +2996,15 @@ gen3_emit_video_state(struct sna *sna,
 		OUT_BATCH_F(video->contrast / 255.0);
 		OUT_BATCH_F(0.0);
 		OUT_BATCH_F(0.0);
+		if (state->last_constants &&
+		    memcmp(&sna->kgem.batch[state->last_constants],
+			   &sna->kgem.batch[rewind],
+			   6*sizeof(uint32_t)) == 0)
+			sna->kgem.nbatch = rewind;
+		else
+			state->last_constants = rewind;
 
+		rewind = sna->kgem.nbatch;
 		OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3);
 		OUT_BATCH(0x00000001);
 		OUT_BATCH(SS2_COLORSPACE_CONVERSION |
@@ -3009,6 +3017,13 @@ gen3_emit_video_state(struct sna *sna,
 			  (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
 			  SS3_NORMALIZED_COORDS);
 		OUT_BATCH(0x00000000);
+		if (state->last_sampler &&
+		    memcmp(&sna->kgem.batch[state->last_sampler],
+			   &sna->kgem.batch[rewind],
+			   5*sizeof(uint32_t)) == 0)
+			sna->kgem.nbatch = rewind;
+		else
+			state->last_sampler = rewind;
 
 		OUT_BATCH(_3DSTATE_MAP_STATE | 3);
 		OUT_BATCH(0x00000001);	/* texture map #1 */
@@ -3031,15 +3046,23 @@ gen3_emit_video_state(struct sna *sna,
 		OUT_BATCH(ms3);
 		OUT_BATCH(((frame->pitch[0] / 4) - 1) << MS4_PITCH_SHIFT);
 
-		shader_offset = sna->kgem.nbatch++;
+		id = 1<<31 | 1<<1 | !!video->brightness;
+		if (state->last_shader != id) {
+			state->last_shader = id;
+			id = sna->kgem.nbatch++;
+
+			gen3_fs_dcl(FS_S0);
+			gen3_fs_dcl(FS_T0);
+			gen3_fs_texld(FS_OC, FS_S0, FS_T0);
+			if (video->brightness != 0) {
+				gen3_fs_add(FS_OC,
+					    gen3_fs_operand_reg(FS_OC),
+					    gen3_fs_operand(FS_C0, X, X, X, ZERO));
+			}
 
-		gen3_fs_dcl(FS_S0);
-		gen3_fs_dcl(FS_T0);
-		gen3_fs_texld(FS_OC, FS_S0, FS_T0);
-		if (video->brightness != 0) {
-			gen3_fs_add(FS_OC,
-				    gen3_fs_operand_reg(FS_OC),
-				    gen3_fs_operand(FS_C0, X, X, X, ZERO));
+			sna->kgem.batch[id] =
+				_3DSTATE_PIXEL_SHADER_PROGRAM |
+				(sna->kgem.nbatch - id - 2);
 		}
 	} else {
 		/* For the planar formats, we set up three samplers --
@@ -3062,6 +3085,7 @@ gen3_emit_video_state(struct sna *sna,
 		 * r3 = (v,v,v,v)
 		 * OC = (r,g,b,1)
 		 */
+		rewind = sna->kgem.nbatch;
 		OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | (22 - 2));
 		OUT_BATCH(0x000001f);	/* constants 0-4 */
 		/* constant 0: normalization offsets */
@@ -3089,7 +3113,15 @@ gen3_emit_video_state(struct sna *sna,
 		OUT_BATCH_F(video->contrast / 255.0);
 		OUT_BATCH_F(0.0);
 		OUT_BATCH_F(0.0);
+		if (state->last_constants &&
+		    memcmp(&sna->kgem.batch[state->last_constants],
+			   &sna->kgem.batch[rewind],
+			   22*sizeof(uint32_t)) == 0)
+			sna->kgem.nbatch = rewind;
+		else
+			state->last_constants = rewind;
 
+		rewind = sna->kgem.nbatch;
 		OUT_BATCH(_3DSTATE_SAMPLER_STATE | 9);
 		OUT_BATCH(0x00000007);
 		/* sampler 0 */
@@ -3122,6 +3154,13 @@ gen3_emit_video_state(struct sna *sna,
 			  (2 << SS3_TEXTUREMAP_INDEX_SHIFT) |
 			  SS3_NORMALIZED_COORDS);
 		OUT_BATCH(0x00000000);
+		if (state->last_sampler &&
+		    memcmp(&sna->kgem.batch[state->last_sampler],
+			   &sna->kgem.batch[rewind],
+			   11*sizeof(uint32_t)) == 0)
+			sna->kgem.nbatch = rewind;
+		else
+			state->last_sampler = rewind;
 
 		OUT_BATCH(_3DSTATE_MAP_STATE | 9);
 		OUT_BATCH(0x00000007);
@@ -3166,63 +3205,68 @@ gen3_emit_video_state(struct sna *sna,
 		OUT_BATCH(ms3);
 		OUT_BATCH(((frame->pitch[0] / 4) - 1) << MS4_PITCH_SHIFT);
 
-		shader_offset = sna->kgem.nbatch++;
+		id = 1<<31 | 2<<1 | !!video->brightness;
+		if (state->last_shader != id) {
+			state->last_shader = id;
+			id = sna->kgem.nbatch++;
 
-		/* Declare samplers */
-		gen3_fs_dcl(FS_S0);	/* Y */
-		gen3_fs_dcl(FS_S1);	/* U */
-		gen3_fs_dcl(FS_S2);	/* V */
-		gen3_fs_dcl(FS_T0);	/* normalized coords */
+			/* Declare samplers */
+			gen3_fs_dcl(FS_S0);	/* Y */
+			gen3_fs_dcl(FS_S1);	/* U */
+			gen3_fs_dcl(FS_S2);	/* V */
+			gen3_fs_dcl(FS_T0);	/* normalized coords */
 
-		/* Load samplers to temporaries. */
-		gen3_fs_texld(FS_R1, FS_S0, FS_T0);
-		gen3_fs_texld(FS_R2, FS_S1, FS_T0);
-		gen3_fs_texld(FS_R3, FS_S2, FS_T0);
+			/* Load samplers to temporaries. */
+			gen3_fs_texld(FS_R1, FS_S0, FS_T0);
+			gen3_fs_texld(FS_R2, FS_S1, FS_T0);
+			gen3_fs_texld(FS_R3, FS_S2, FS_T0);
 
-		/* Move the sampled YUV data in R[123] to the first
-		 * 3 channels of R0.
-		 */
-		gen3_fs_mov_masked(FS_R0, MASK_X,
-				   gen3_fs_operand_reg(FS_R1));
-		gen3_fs_mov_masked(FS_R0, MASK_Y,
-				   gen3_fs_operand_reg(FS_R2));
-		gen3_fs_mov_masked(FS_R0, MASK_Z,
-				   gen3_fs_operand_reg(FS_R3));
-
-		/* Normalize the YUV data */
-		gen3_fs_add(FS_R0, gen3_fs_operand_reg(FS_R0),
-			    gen3_fs_operand_reg(FS_C0));
-		/* dot-product the YUV data in R0 by the vectors of
-		 * coefficients for calculating R, G, and B, storing
-		 * the results in the R, G, or B channels of the output
-		 * color.  The OC results are implicitly clamped
-		 * at the end of the program.
-		 */
-		gen3_fs_dp3(FS_OC, MASK_X,
-			    gen3_fs_operand_reg(FS_R0),
-			    gen3_fs_operand_reg(FS_C1));
-		gen3_fs_dp3(FS_OC, MASK_Y,
-			    gen3_fs_operand_reg(FS_R0),
-			    gen3_fs_operand_reg(FS_C2));
-		gen3_fs_dp3(FS_OC, MASK_Z,
-			    gen3_fs_operand_reg(FS_R0),
-			    gen3_fs_operand_reg(FS_C3));
-		/* Set alpha of the output to 1.0, by wiring W to 1
-		 * and not actually using the source.
-		 */
-		gen3_fs_mov_masked(FS_OC, MASK_W,
-				   gen3_fs_operand_one());
+			/* Move the sampled YUV data in R[123] to the first
+			 * 3 channels of R0.
+			 */
+			gen3_fs_mov_masked(FS_R0, MASK_X,
+					   gen3_fs_operand_reg(FS_R1));
+			gen3_fs_mov_masked(FS_R0, MASK_Y,
+					   gen3_fs_operand_reg(FS_R2));
+			gen3_fs_mov_masked(FS_R0, MASK_Z,
+					   gen3_fs_operand_reg(FS_R3));
+
+			/* Normalize the YUV data */
+			gen3_fs_add(FS_R0, gen3_fs_operand_reg(FS_R0),
+				    gen3_fs_operand_reg(FS_C0));
+			/* dot-product the YUV data in R0 by the vectors of
+			 * coefficients for calculating R, G, and B, storing
+			 * the results in the R, G, or B channels of the output
+			 * color.  The OC results are implicitly clamped
+			 * at the end of the program.
+			 */
+			gen3_fs_dp3(FS_OC, MASK_X,
+				    gen3_fs_operand_reg(FS_R0),
+				    gen3_fs_operand_reg(FS_C1));
+			gen3_fs_dp3(FS_OC, MASK_Y,
+				    gen3_fs_operand_reg(FS_R0),
+				    gen3_fs_operand_reg(FS_C2));
+			gen3_fs_dp3(FS_OC, MASK_Z,
+				    gen3_fs_operand_reg(FS_R0),
+				    gen3_fs_operand_reg(FS_C3));
+			/* Set alpha of the output to 1.0, by wiring W to 1
+			 * and not actually using the source.
+			 */
+			gen3_fs_mov_masked(FS_OC, MASK_W,
+					   gen3_fs_operand_one());
+
+			if (video->brightness != 0) {
+				gen3_fs_add(FS_OC,
+					    gen3_fs_operand_reg(FS_OC),
+					    gen3_fs_operand(FS_C4, X, X, X, ZERO));
+			}
 
-		if (video->brightness != 0) {
-			gen3_fs_add(FS_OC,
-				    gen3_fs_operand_reg(FS_OC),
-				    gen3_fs_operand(FS_C4, X, X, X, ZERO));
+			sna->kgem.batch[id] =
+				_3DSTATE_PIXEL_SHADER_PROGRAM |
+				(sna->kgem.nbatch - id - 2);
 		}
 	}
 
-	sna->kgem.batch[shader_offset] =
-		_3DSTATE_PIXEL_SHADER_PROGRAM |
-		(sna->kgem.nbatch - shader_offset - 2);
 }
 
 static void
commit 8e926759528a12076bd7565672acd82a37aa3eb1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 9 14:44:54 2011 +0000

    sna/video: Pass texture video limits to the client
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index dadf8b9..88a7368 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -48,16 +48,6 @@
 
 static Atom xvBrightness, xvContrast, xvSyncToVblank;
 
-/* client libraries expect an encoding */
-static const XF86VideoEncodingRec DummyEncoding[1] = {
-	{
-		0,
-		"XV_IMAGE",
-		8192, 8192,
-		{1, 1}
-	}
-};
-
 #define NUM_FORMATS 3
 
 static XF86VideoFormatRec Formats[NUM_FORMATS] = {
@@ -65,11 +55,11 @@ static XF86VideoFormatRec Formats[NUM_FORMATS] = {
 };
 
 //#define NUM_TEXTURED_ATTRIBUTES 3
-#define NUM_TEXTURED_ATTRIBUTES 0
+#define NUM_TEXTURED_ATTRIBUTES 1
 static XF86AttributeRec TexturedAttributes[] = {
+	{XvSettable | XvGettable, -1, 1, "XV_SYNC_TO_VBLANK"},
 	{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
 	{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
-	{XvSettable | XvGettable, -1, 1, "XV_SYNC_TO_VBLANK"},
 };
 
 #ifdef SNA_XVMC
@@ -408,8 +398,13 @@ XF86VideoAdaptorPtr sna_video_textured_setup(struct sna *sna,
 	adaptor->flags = 0;
 	adaptor->name = "Intel(R) Textured Video";
 	adaptor->nEncodings = 1;
-	adaptor->pEncodings = xnfalloc(sizeof(DummyEncoding));
-	memcpy(adaptor->pEncodings, DummyEncoding, sizeof(DummyEncoding));
+	adaptor->pEncodings = xnfalloc(sizeof(XF86VideoEncodingRec));
+	adaptor->pEncodings[0].id = 0;
+	adaptor->pEncodings[0].name = "XV_IMAGE";
+	adaptor->pEncodings[0].width = sna->render.max_3d_size;
+	adaptor->pEncodings[0].height = sna->render.max_3d_size;
+	adaptor->pEncodings[0].rate.numerator = 1;
+	adaptor->pEncodings[0].rate.denominator = 1;
 	adaptor->nFormats = NUM_FORMATS;
 	adaptor->pFormats = Formats;
 	adaptor->nPorts = nports;
commit bca58ff6f02b20ccf88937df8e2688f18cabac80
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 9 14:18:57 2011 +0000

    sna: Clear kgem->busy when all requests have been processed
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index a55086a..8d2295a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -737,6 +737,7 @@ bool kgem_retire(struct kgem *kgem)
 	kgem->need_retire = !list_is_empty(&kgem->requests);
 	if (!kgem->need_retire && kgem->ring)
 		kgem->ring = kgem->mode;
+	kgem->busy &= kgem->need_retire;
 
 	return retired;
 }
commit 8fdbd01c94c0f6f56247feed8f225901ba39e18e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 9 13:14:04 2011 +0000

    sna/video: Use the normal bo cache for texture video streams
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index fd5f3f1..d3788fd 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -94,16 +94,25 @@ void sna_video_free_buffers(struct sna *sna, struct sna_video *video)
 	}
 }
 
-void sna_video_frame_fini(struct sna *sna,
-			  struct sna_video *video,
-			  struct sna_video_frame *frame)
+struct kgem_bo *
+sna_video_buffer(struct sna *sna,
+		 struct sna_video *video,
+		 struct sna_video_frame *frame)
 {
-	struct kgem_bo *bo;
+	/* Free the current buffer if we're going to have to reallocate */
+	if (video->buf && video->buf->size < frame->size)
+		sna_video_free_buffers(sna, video);
 
-	if (!frame->bo->reusable) {
-		kgem_bo_destroy(&sna->kgem, frame->bo);
-		return;
-	}
+	if (video->buf == NULL)
+		video->buf = kgem_create_linear(&sna->kgem, frame->size);
+
+	return video->buf;
+}
+
+void sna_video_buffer_fini(struct sna *sna,
+			   struct sna_video *video)
+{
+	struct kgem_bo *bo;
 
 	bo = video->old_buf[1];
 	video->old_buf[1] = video->old_buf[0];
@@ -245,21 +254,6 @@ sna_video_frame_init(struct sna *sna,
 	}
 }
 
-static struct kgem_bo *
-sna_video_buffer(struct sna *sna,
-		 struct sna_video *video,
-		 struct sna_video_frame *frame)
-{
-	/* Free the current buffer if we're going to have to reallocate */
-	if (video->buf && video->buf->size < frame->size)
-		sna_video_free_buffers(sna, video);
-
-	if (video->buf == NULL)
-		video->buf = kgem_create_linear(&sna->kgem, frame->size);
-
-	return video->buf;
-}
-
 static void sna_memcpy_plane(uint8_t *dst, const uint8_t *src,
 			     int height, int width,
 			     int dstPitch, int srcPitch,
@@ -442,7 +436,6 @@ sna_video_copy_data(struct sna *sna,
 {
 	uint8_t *dst;
 
-	frame->bo = sna_video_buffer(sna, video, frame);
 	if (frame->bo == NULL)
 		return FALSE;
 
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index ab8289b..47ddab0 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -117,15 +117,20 @@ sna_video_frame_init(struct sna *sna,
 		     int id, short width, short height,
 		     struct sna_video_frame *frame);
 
+struct kgem_bo *
+sna_video_buffer(struct sna *sna,
+		 struct sna_video *video,
+		 struct sna_video_frame *frame);
+
 Bool
 sna_video_copy_data(struct sna *sna,
 		    struct sna_video *video,
 		    struct sna_video_frame *frame,
 		    const uint8_t *buf);
 
-void sna_video_frame_fini(struct sna *sna,
-			  struct sna_video *video,
-			  struct sna_video_frame *frame);
+void sna_video_buffer_fini(struct sna *sna,
+			   struct sna_video *video);
+
 void sna_video_free_buffers(struct sna *sna, struct sna_video *video);
 
 #endif /* SNA_VIDEO_H */
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index 491baa8..9ba78ef 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -504,6 +504,13 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn,
 
 	/* overlay can't handle rotation natively, store it for the copy func */
 	video->rotation = crtc->rotation;
+
+	frame.bo = sna_video_buffer(sna, video, &frame);
+	if (frame.bo == NULL) {
+		DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
+		return BadAlloc;
+	}
+
 	if (!sna_video_copy_data(sna, video, &frame, buf)) {
 		DBG(("%s: failed to copy video data\n", __FUNCTION__));
 		return BadAlloc;
@@ -515,7 +522,7 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn,
 		return BadAlloc;
 	}
 
-	sna_video_frame_fini(sna, video, &frame);
+	sna_video_buffer_fini(sna, video);
 
 	/* update cliplist */
 	if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) {
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index 3461dc5..dadf8b9 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -262,8 +262,14 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 		if (frame.bo == NULL)
 			return BadAlloc;
 	} else {
-		if (!sna_video_copy_data(sna, video, &frame, buf))
+		frame.bo = kgem_create_linear(&sna->kgem, frame.size);
+		if (frame.bo == NULL)
+			return BadAlloc;
+
+		if (!sna_video_copy_data(sna, video, &frame, buf)) {
+			kgem_bo_destroy(&sna->kgem, frame.bo);
 			return BadAlloc;
+		}
 	}
 
 	if (crtc && video->SyncToVblank != 0)
@@ -275,7 +281,7 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 			  drw_w, drw_h,
 			  pixmap);
 
-	sna_video_frame_fini(sna, video, &frame);
+	kgem_bo_destroy(&sna->kgem, frame.bo);
 
 	DamageDamageRegion(drawable, clip);
 


More information about the xorg-commit mailing list