summaryrefslogtreecommitdiff
path: root/src/sna/gen8_render.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-03-31 19:43:07 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2016-03-31 20:41:26 +0100
commit2c4890001db18cc0534dd4a1f8d09c5df72c9404 (patch)
tree9a836dfbf28cd2b6eaec9d4bf0b0e01c3d156341 /src/sna/gen8_render.c
parent3fafabe56241c7180a8b7d1896b1c6d7e4999ba2 (diff)
sna/video: Use the GPU to prescale overlay sprites
Since Haswell, we lost the ability to use hardware scalers on the overlay planes. Allow Xv clients to pass in unscaled data and use the 3D pipe to prescale the images before display. (I doubt I have the rotations corrected!...) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/gen8_render.c')
-rw-r--r--src/sna/gen8_render.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/src/sna/gen8_render.c b/src/sna/gen8_render.c
index 0631e0a3..0947576c 100644
--- a/src/sna/gen8_render.c
+++ b/src/sna/gen8_render.c
@@ -106,6 +106,12 @@ static const uint32_t ps_kernel_planar[][4] = {
#include "exa_wm_yuv_rgb.g8b"
#include "exa_wm_write.g8b"
};
+
+static const uint32_t ps_kernel_rgb[][4] = {
+#include "exa_wm_src_affine.g8b"
+#include "exa_wm_src_sample_argb.g8b"
+#include "exa_wm_write.g8b"
+};
#endif
#define SURFACE_DW (64 / sizeof(uint32_t));
@@ -119,7 +125,7 @@ static const struct wm_kernel_info {
const void *data;
unsigned int size;
int num_surfaces;
-} wm_kernels[] = {
+} wm_kernels[GEN8_WM_KERNEL_COUNT] = {
NOKERNEL(NOMASK, gen8_wm_kernel__affine, 2),
NOKERNEL(NOMASK_P, gen8_wm_kernel__projective, 2),
@@ -138,6 +144,7 @@ static const struct wm_kernel_info {
#if !NO_VIDEO
KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7),
KERNEL(VIDEO_PACKED, ps_kernel_packed, 2),
+ KERNEL(VIDEO_RGB, ps_kernel_rgb, 2),
#endif
};
#undef KERNEL
@@ -3733,7 +3740,9 @@ static void gen8_emit_video_state(struct sna *sna,
frame->pitch[0];
n_src = 6;
} else {
- if (frame->id == FOURCC_UYVY)
+ if (frame->id == FOURCC_RGB888)
+ src_surf_format = SURFACEFORMAT_B8G8R8X8_UNORM;
+ else if (frame->id == FOURCC_UYVY)
src_surf_format = SURFACEFORMAT_YCRCB_SWAPY;
else
src_surf_format = SURFACEFORMAT_YCRCB_NORMAL;
@@ -3765,6 +3774,23 @@ static void gen8_emit_video_state(struct sna *sna,
gen8_emit_state(sna, op, offset);
}
+static unsigned select_video_kernel(const struct sna_video_frame *frame)
+{
+ switch (frame->id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ case FOURCC_XVMC:
+ return GEN8_WM_KERNEL_VIDEO_PLANAR;
+
+ case FOURCC_RGB888:
+ case FOURCC_RGB565:
+ return GEN8_WM_KERNEL_VIDEO_RGB;
+
+ default:
+ return GEN8_WM_KERNEL_VIDEO_PACKED;
+ }
+}
+
static bool
gen8_render_video(struct sna *sna,
struct sna_video *video,
@@ -3811,6 +3837,11 @@ gen8_render_video(struct sna *sna,
tmp.floats_per_vertex = 3;
tmp.floats_per_rect = 9;
+ DBG(("%s: scaling?=%d, planar?=%d [%x]\n",
+ __FUNCTION__,
+ src_width != dst_width || src_height != dst_height,
+ is_planar_fourcc(frame->id), frame->id));
+
if (src_width == dst_width && src_height == dst_height)
filter = SAMPLER_FILTER_NEAREST;
else
@@ -3820,9 +3851,7 @@ gen8_render_video(struct sna *sna,
GEN8_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD,
SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE),
NO_BLEND,
- is_planar_fourcc(frame->id) ?
- GEN8_WM_KERNEL_VIDEO_PLANAR :
- GEN8_WM_KERNEL_VIDEO_PACKED,
+ select_video_kernel(frame),
2);
tmp.priv = frame;