Merge branch 'master' of 192.168.1.213:/usr/src/xf86-video-intel
This commit is contained in:
commit
7a371f6bef
|
|
@ -523,7 +523,7 @@ void backlight_disable(struct backlight *b)
|
|||
void backlight_close(struct backlight *b)
|
||||
{
|
||||
backlight_disable(b);
|
||||
if (b->pid)
|
||||
if (b->pid > 0)
|
||||
waitpid(b->pid, NULL, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -402,6 +402,34 @@ static inline void list_move_tail(struct list *list, struct list *head)
|
|||
#define container_of(ptr, type, member) \
|
||||
((type *)((char *)(ptr) - (char *) &((type *)0)->member))
|
||||
|
||||
static inline void __list_splice(const struct list *list,
|
||||
struct list *prev,
|
||||
struct list *next)
|
||||
{
|
||||
struct list *first = list->next;
|
||||
struct list *last = list->prev;
|
||||
|
||||
first->prev = prev;
|
||||
prev->next = first;
|
||||
|
||||
last->next = next;
|
||||
next->prev = last;
|
||||
}
|
||||
|
||||
static inline void list_splice(const struct list *list,
|
||||
struct list *head)
|
||||
{
|
||||
if (!list_is_empty(list))
|
||||
__list_splice(list, head, head->next);
|
||||
}
|
||||
|
||||
static inline void list_splice_tail(const struct list *list,
|
||||
struct list *head)
|
||||
{
|
||||
if (!list_is_empty(list))
|
||||
__list_splice(list, head->prev, head);
|
||||
}
|
||||
|
||||
static inline int list_is_singular(const struct list *list)
|
||||
{
|
||||
return list->next == list->prev;
|
||||
|
|
|
|||
|
|
@ -234,30 +234,36 @@ static const SymTabRec intel_chipsets[] = {
|
|||
{0x0157, "HD Graphics"},
|
||||
|
||||
/* Broadwell Marketing names */
|
||||
{0x1602, "HD graphics"},
|
||||
{0x1606, "HD graphics"},
|
||||
{0x160B, "HD graphics"},
|
||||
{0x160A, "HD graphics"},
|
||||
{0x160D, "HD graphics"},
|
||||
{0x160E, "HD graphics"},
|
||||
{0x1612, "HD graphics 5600"},
|
||||
{0x1616, "HD graphics 5500"},
|
||||
{0x161B, "HD graphics"},
|
||||
{0x161A, "HD graphics"},
|
||||
{0x161D, "HD graphics"},
|
||||
{0x161E, "HD graphics 5300"},
|
||||
{0x1622, "Iris Pro graphics 6200"},
|
||||
{0x1626, "HD graphics 6000"},
|
||||
{0x162B, "Iris graphics 6100"},
|
||||
{0x162A, "Iris Pro graphics P6300"},
|
||||
{0x162D, "HD graphics"},
|
||||
{0x162E, "HD graphics"},
|
||||
{0x1632, "HD graphics"},
|
||||
{0x1636, "HD graphics"},
|
||||
{0x163B, "HD graphics"},
|
||||
{0x163A, "HD graphics"},
|
||||
{0x163D, "HD graphics"},
|
||||
{0x163E, "HD graphics"},
|
||||
{0x1602, "HD Graphics"},
|
||||
{0x1606, "HD Graphics"},
|
||||
{0x160B, "HD Graphics"},
|
||||
{0x160A, "HD Graphics"},
|
||||
{0x160D, "HD Graphics"},
|
||||
{0x160E, "HD Graphics"},
|
||||
{0x1612, "HD Graphics 5600"},
|
||||
{0x1616, "HD Graphics 5500"},
|
||||
{0x161B, "HD Graphics"},
|
||||
{0x161A, "HD Graphics"},
|
||||
{0x161D, "HD Graphics"},
|
||||
{0x161E, "HD Graphics 5300"},
|
||||
{0x1622, "Iris Pro Graphics 6200"},
|
||||
{0x1626, "HD Graphics 6000"},
|
||||
{0x162B, "Iris Graphics 6100"},
|
||||
{0x162A, "Iris Pro Graphics P6300"},
|
||||
{0x162D, "HD Graphics"},
|
||||
{0x162E, "HD Graphics"},
|
||||
{0x1632, "HD Graphics"},
|
||||
{0x1636, "HD Graphics"},
|
||||
{0x163B, "HD Graphics"},
|
||||
{0x163A, "HD Graphics"},
|
||||
{0x163D, "HD Graphics"},
|
||||
{0x163E, "HD Graphics"},
|
||||
|
||||
/* Cherryview (Cherrytrail/Braswell) */
|
||||
{0x22b0, "HD Graphics"},
|
||||
{0x22b1, "HD Graphics"},
|
||||
{0x22b2, "HD Graphics"},
|
||||
{0x22b3, "HD Graphics"},
|
||||
|
||||
/* When adding new identifiers, also update:
|
||||
* 1. intel_identify()
|
||||
|
|
@ -508,6 +514,9 @@ static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
|
|||
if (hosted())
|
||||
return SNA;
|
||||
|
||||
if (xf86configptr == NULL) /* X -configure */
|
||||
return SNA;
|
||||
|
||||
dev = _xf86findDriver("intel", xf86configptr->conf_device_lst);
|
||||
if (dev && dev->dev_option_lst) {
|
||||
const char *s;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ const OptionInfoRec intel_options[] = {
|
|||
{OPTION_PREFER_OVERLAY, "XvPreferOverlay", OPTV_BOOLEAN, {0}, 0},
|
||||
{OPTION_HOTPLUG, "HotPlug", OPTV_BOOLEAN, {0}, 1},
|
||||
{OPTION_REPROBE, "ReprobeOutputs", OPTV_BOOLEAN, {0}, 0},
|
||||
{OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, 0},
|
||||
#ifdef INTEL_XVMC
|
||||
{OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, 1},
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ enum intel_options {
|
|||
OPTION_PREFER_OVERLAY,
|
||||
OPTION_HOTPLUG,
|
||||
OPTION_REPROBE,
|
||||
OPTION_DELETE_DP12,
|
||||
#if defined(XvMCExtension) && defined(ENABLE_XVMC)
|
||||
OPTION_XVMC,
|
||||
#define INTEL_XVMC 1
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 };
|
|||
/*
|
||||
* R = Y + Cr * 1.596
|
||||
*/
|
||||
mov (8) acc0<1>F Yn<8,8,1>F { compr align1 };
|
||||
mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 };
|
||||
mac.sat(8) src_sample_r_01<1>F Crn_01<8,8,1>F 1.596F { compr align1 };
|
||||
|
||||
mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 };
|
||||
|
|
@ -84,7 +84,7 @@ mac.sat(8) src_sample_r_23<1>F Crn_23<8,8,1>F 1.596F { compr align1 };
|
|||
/*
|
||||
* G = Crn * -0.813 + Cbn * -0.392 + Y
|
||||
*/
|
||||
mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 };
|
||||
mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 };
|
||||
mac (8) acc0<1>F Crn_01<8,8,1>F -0.813F { compr align1 };
|
||||
mac.sat(8) src_sample_g_01<1>F Cbn_01<8,8,1>F -0.392F { compr align1 };
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
{ 0x80600048, 0x21c03ae8, 0x3e8d02c0, 0x3fcc49ba },
|
||||
{ 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 },
|
||||
{ 0x80600048, 0x21e03ae8, 0x3e8d02e0, 0x3fcc49ba },
|
||||
{ 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 },
|
||||
{ 0x00600001, 0x24003ae0, 0x008d0300, 0x00000000 },
|
||||
{ 0x00600048, 0x24003ae0, 0x3e8d02c0, 0xbf5020c5 },
|
||||
{ 0x80600048, 0x22003ae8, 0x3e8d0340, 0xbec8b439 },
|
||||
{ 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 },
|
||||
|
|
|
|||
|
|
@ -976,7 +976,7 @@ memcpy_xor(const void *src, void *dst, int bpp,
|
|||
}
|
||||
|
||||
#define BILINEAR_INTERPOLATION_BITS 4
|
||||
static force_inline int
|
||||
static inline int
|
||||
bilinear_weight(pixman_fixed_t x)
|
||||
{
|
||||
return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) &
|
||||
|
|
@ -985,7 +985,7 @@ bilinear_weight(pixman_fixed_t x)
|
|||
|
||||
#if BILINEAR_INTERPOLATION_BITS <= 4
|
||||
/* Inspired by Filter_32_opaque from Skia */
|
||||
static force_inline uint32_t
|
||||
static inline uint32_t
|
||||
bilinear_interpolation(uint32_t tl, uint32_t tr,
|
||||
uint32_t bl, uint32_t br,
|
||||
int distx, int disty)
|
||||
|
|
@ -1018,7 +1018,7 @@ bilinear_interpolation(uint32_t tl, uint32_t tr,
|
|||
return ((lo >> 8) & 0xff00ff) | (hi & ~0xff00ff);
|
||||
}
|
||||
#elif SIZEOF_LONG > 4
|
||||
static force_inline uint32_t
|
||||
static inline uint32_t
|
||||
bilinear_interpolation(uint32_t tl, uint32_t tr,
|
||||
uint32_t bl, uint32_t br,
|
||||
int distx, int disty)
|
||||
|
|
@ -1063,7 +1063,7 @@ bilinear_interpolation(uint32_t tl, uint32_t tr,
|
|||
return (uint32_t)(r >> 16);
|
||||
}
|
||||
#else
|
||||
static force_inline uint32_t
|
||||
static inline uint32_t
|
||||
bilinear_interpolation(uint32_t tl, uint32_t tr,
|
||||
uint32_t bl, uint32_t br,
|
||||
int distx, int disty)
|
||||
|
|
|
|||
|
|
@ -63,20 +63,18 @@
|
|||
#define sse4_2 __attribute__((target("sse4.2,sse2,fpmath=sse")))
|
||||
#endif
|
||||
|
||||
#if HAS_GCC(4, 7)
|
||||
#define avx2 __attribute__((target("avx2,sse4.2,sse2,fpmath=sse")))
|
||||
#endif
|
||||
|
||||
#if HAS_GCC(4, 6) && defined(__OPTIMIZE__)
|
||||
#define fast __attribute__((optimize("Ofast")))
|
||||
#else
|
||||
#define fast
|
||||
#endif
|
||||
|
||||
#if HAS_GCC(4, 6) && defined(__OPTIMIZE__)
|
||||
#define fast_memcpy __attribute__((optimize("Ofast"))) __attribute__((target("inline-all-stringops")))
|
||||
#elif HAS_GCC(4, 5) && defined(__OPTIMIZE__)
|
||||
#define fast_memcpy __attribute__((target("inline-all-stringops")))
|
||||
#if HAS_GCC(4, 7)
|
||||
#define avx2 fast __attribute__((target("avx2,avx,sse4.2,sse2,fpmath=sse")))
|
||||
#endif
|
||||
|
||||
#if HAS_GCC(4, 5) && defined(__OPTIMIZE__)
|
||||
#define fast_memcpy fast __attribute__((target("inline-all-stringops")))
|
||||
#else
|
||||
#define fast_memcpy
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ inline static bool can_switch_to_blt(struct sna *sna,
|
|||
if (bo && RQ_IS_BLT(bo->rq))
|
||||
return true;
|
||||
|
||||
if (bo && bo->tiling == I915_TILING_Y)
|
||||
return false;
|
||||
|
||||
if (sna->render_state.gt < 2)
|
||||
return true;
|
||||
|
||||
|
|
@ -93,6 +96,9 @@ static int prefer_blt_bo(struct sna *sna,
|
|||
|
||||
if (src->rq)
|
||||
return RQ_IS_BLT(src->rq);
|
||||
|
||||
if (src->tiling == I915_TILING_Y)
|
||||
return false;
|
||||
} else {
|
||||
if (sna->render_state.gt > 2)
|
||||
return false;
|
||||
|
|
@ -104,7 +110,7 @@ static int prefer_blt_bo(struct sna *sna,
|
|||
return dst->tiling == I915_TILING_NONE || is_uncached(sna, dst);
|
||||
}
|
||||
|
||||
inline static bool force_blt_ring(struct sna *sna)
|
||||
inline static bool force_blt_ring(struct sna *sna, struct kgem_bo *bo)
|
||||
{
|
||||
if (sna->kgem.mode == KGEM_RENDER)
|
||||
return false;
|
||||
|
|
@ -112,6 +118,9 @@ inline static bool force_blt_ring(struct sna *sna)
|
|||
if (NO_RING_SWITCH(sna))
|
||||
return sna->kgem.ring == KGEM_BLT;
|
||||
|
||||
if (bo->tiling == I915_TILING_Y)
|
||||
return false;
|
||||
|
||||
if (sna->flags & SNA_POWERSAVE)
|
||||
return true;
|
||||
|
||||
|
|
@ -127,7 +136,7 @@ prefer_blt_ring(struct sna *sna, struct kgem_bo *bo, unsigned flags)
|
|||
if (PREFER_RENDER)
|
||||
return PREFER_RENDER < 0;
|
||||
|
||||
assert(!force_blt_ring(sna));
|
||||
assert(!force_blt_ring(sna, bo));
|
||||
assert(!kgem_bo_is_render(bo) || NO_RING_SWITCH(sna));
|
||||
|
||||
if (kgem_bo_is_blt(bo))
|
||||
|
|
@ -167,7 +176,7 @@ prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
|
|||
untiled_tlb_miss(tmp->src.bo))
|
||||
return true;
|
||||
|
||||
if (force_blt_ring(sna))
|
||||
if (force_blt_ring(sna, tmp->dst.bo))
|
||||
return true;
|
||||
|
||||
if (prefer_render_ring(sna, tmp->dst.bo))
|
||||
|
|
@ -188,7 +197,7 @@ prefer_blt_fill(struct sna *sna, struct kgem_bo *bo, unsigned flags)
|
|||
if (untiled_tlb_miss(bo))
|
||||
return true;
|
||||
|
||||
if (force_blt_ring(sna))
|
||||
if (force_blt_ring(sna, bo))
|
||||
return true;
|
||||
|
||||
if ((flags & (FILL_POINTS | FILL_SPANS)) == 0) {
|
||||
|
|
|
|||
|
|
@ -1965,54 +1965,77 @@ gen6_composite_set_target(struct sna *sna,
|
|||
|
||||
static bool
|
||||
try_blt(struct sna *sna,
|
||||
PicturePtr dst, PicturePtr src,
|
||||
int width, int height)
|
||||
uint8_t op,
|
||||
PicturePtr src,
|
||||
PicturePtr mask,
|
||||
PicturePtr dst,
|
||||
int16_t src_x, int16_t src_y,
|
||||
int16_t msk_x, int16_t msk_y,
|
||||
int16_t dst_x, int16_t dst_y,
|
||||
int16_t width, int16_t height,
|
||||
unsigned flags,
|
||||
struct sna_composite_op *tmp)
|
||||
{
|
||||
struct kgem_bo *bo;
|
||||
|
||||
if (sna->kgem.mode == KGEM_BLT) {
|
||||
DBG(("%s: already performing BLT\n", __FUNCTION__));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
if (too_large(width, height)) {
|
||||
DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
|
||||
__FUNCTION__, width, height));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
bo = __sna_drawable_peek_bo(dst->pDrawable);
|
||||
if (bo == NULL)
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (untiled_tlb_miss(bo))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (bo->rq)
|
||||
return RQ_IS_BLT(bo->rq);
|
||||
if (bo->rq) {
|
||||
if (RQ_IS_BLT(bo->rq))
|
||||
goto execute;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bo->tiling == I915_TILING_Y)
|
||||
goto upload;
|
||||
|
||||
if (src->pDrawable == dst->pDrawable &&
|
||||
can_switch_to_blt(sna, bo, 0))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (src->pDrawable) {
|
||||
struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable);
|
||||
if (s == NULL)
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (prefer_blt_bo(sna, s, bo))
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
if (sna->kgem.ring == KGEM_BLT) {
|
||||
DBG(("%s: already performing BLT\n", __FUNCTION__));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
return false;
|
||||
upload:
|
||||
flags |= COMPOSITE_UPLOAD;
|
||||
execute:
|
||||
return sna_blt_composite(sna, op,
|
||||
src, dst,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -2242,13 +2265,13 @@ gen6_render_composite(struct sna *sna,
|
|||
width, height, sna->kgem.ring));
|
||||
|
||||
if (mask == NULL &&
|
||||
try_blt(sna, dst, src, width, height) &&
|
||||
sna_blt_composite(sna, op,
|
||||
src, dst,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp))
|
||||
try_blt(sna, op,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
msk_x, msk_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp))
|
||||
return true;
|
||||
|
||||
if (gen6_composite_fallback(sna, src, mask, dst))
|
||||
|
|
@ -2695,7 +2718,7 @@ static inline bool prefer_blt_copy(struct sna *sna,
|
|||
untiled_tlb_miss(dst_bo))
|
||||
return true;
|
||||
|
||||
if (force_blt_ring(sna))
|
||||
if (force_blt_ring(sna, dst_bo))
|
||||
return true;
|
||||
|
||||
if (kgem_bo_is_render(dst_bo) ||
|
||||
|
|
|
|||
|
|
@ -2184,55 +2184,78 @@ gen7_composite_set_target(struct sna *sna,
|
|||
|
||||
static bool
|
||||
try_blt(struct sna *sna,
|
||||
PicturePtr dst, PicturePtr src,
|
||||
int width, int height)
|
||||
uint8_t op,
|
||||
PicturePtr src,
|
||||
PicturePtr mask,
|
||||
PicturePtr dst,
|
||||
int16_t src_x, int16_t src_y,
|
||||
int16_t msk_x, int16_t msk_y,
|
||||
int16_t dst_x, int16_t dst_y,
|
||||
int16_t width, int16_t height,
|
||||
unsigned flags,
|
||||
struct sna_composite_op *tmp)
|
||||
{
|
||||
struct kgem_bo *bo;
|
||||
|
||||
if (sna->kgem.mode == KGEM_BLT) {
|
||||
DBG(("%s: already performing BLT\n", __FUNCTION__));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
if (too_large(width, height)) {
|
||||
DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
|
||||
__FUNCTION__, width, height));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
bo = __sna_drawable_peek_bo(dst->pDrawable);
|
||||
if (bo == NULL)
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (untiled_tlb_miss(bo))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (bo->rq)
|
||||
return RQ_IS_BLT(bo->rq);
|
||||
if (bo->rq) {
|
||||
if (RQ_IS_BLT(bo->rq))
|
||||
goto execute;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bo->tiling == I915_TILING_Y)
|
||||
goto upload;
|
||||
|
||||
if (src->pDrawable == dst->pDrawable &&
|
||||
(sna->render_state.gt < 3 || width*height < 1024) &&
|
||||
can_switch_to_blt(sna, bo, 0))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (src->pDrawable) {
|
||||
struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable);
|
||||
if (s == NULL)
|
||||
return true;
|
||||
goto upload;
|
||||
|
||||
if (prefer_blt_bo(sna, s, bo))
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
if (sna->kgem.ring == KGEM_BLT) {
|
||||
DBG(("%s: already performing BLT\n", __FUNCTION__));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
return false;
|
||||
upload:
|
||||
flags |= COMPOSITE_UPLOAD;
|
||||
execute:
|
||||
return sna_blt_composite(sna, op,
|
||||
src, dst,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -2462,13 +2485,13 @@ gen7_render_composite(struct sna *sna,
|
|||
width, height, sna->kgem.mode, sna->kgem.ring));
|
||||
|
||||
if (mask == NULL &&
|
||||
try_blt(sna, dst, src, width, height) &&
|
||||
sna_blt_composite(sna, op,
|
||||
src, dst,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp))
|
||||
try_blt(sna, op,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
msk_x, msk_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp))
|
||||
return true;
|
||||
|
||||
if (gen7_composite_fallback(sna, src, mask, dst))
|
||||
|
|
@ -2893,7 +2916,7 @@ prefer_blt_copy(struct sna *sna,
|
|||
if (flags & COPY_DRI && !sna->kgem.has_semaphores)
|
||||
return false;
|
||||
|
||||
if (force_blt_ring(sna))
|
||||
if (force_blt_ring(sna, dst_bo))
|
||||
return true;
|
||||
|
||||
if ((flags & COPY_SMALL ||
|
||||
|
|
|
|||
|
|
@ -205,6 +205,33 @@ static const struct blendinfo {
|
|||
#define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y)
|
||||
#define OUT_VERTEX_F(v) vertex_emit(sna, v)
|
||||
|
||||
struct gt_info {
|
||||
const char *name;
|
||||
struct {
|
||||
int max_vs_entries;
|
||||
} urb;
|
||||
};
|
||||
|
||||
static const struct gt_info bdw_gt_info = {
|
||||
.name = "Broadwell (gen8)",
|
||||
.urb = { .max_vs_entries = 960 },
|
||||
};
|
||||
|
||||
static bool is_bdw(struct sna *sna)
|
||||
{
|
||||
return sna->kgem.gen == 0100;
|
||||
}
|
||||
|
||||
static const struct gt_info chv_gt_info = {
|
||||
.name = "Cherryview (gen8)",
|
||||
.urb = { .max_vs_entries = 640 },
|
||||
};
|
||||
|
||||
static bool is_chv(struct sna *sna)
|
||||
{
|
||||
return sna->kgem.gen == 0101;
|
||||
}
|
||||
|
||||
static inline bool too_large(int width, int height)
|
||||
{
|
||||
return width > GEN8_MAX_SIZE || height > GEN8_MAX_SIZE;
|
||||
|
|
@ -462,7 +489,7 @@ gen8_emit_urb(struct sna *sna)
|
|||
{
|
||||
/* num of VS entries must be divisible by 8 if size < 9 */
|
||||
OUT_BATCH(GEN8_3DSTATE_URB_VS | (2 - 2));
|
||||
OUT_BATCH(960 << URB_ENTRY_NUMBER_SHIFT |
|
||||
OUT_BATCH(sna->render_state.gen8.info->urb.max_vs_entries << URB_ENTRY_NUMBER_SHIFT |
|
||||
(2 - 1) << URB_ENTRY_SIZE_SHIFT |
|
||||
4 << URB_STARTING_ADDRESS_SHIFT);
|
||||
|
||||
|
|
@ -2002,55 +2029,78 @@ gen8_composite_set_target(struct sna *sna,
|
|||
|
||||
static bool
|
||||
try_blt(struct sna *sna,
|
||||
PicturePtr dst, PicturePtr src,
|
||||
int width, int height)
|
||||
uint8_t op,
|
||||
PicturePtr src,
|
||||
PicturePtr mask,
|
||||
PicturePtr dst,
|
||||
int16_t src_x, int16_t src_y,
|
||||
int16_t msk_x, int16_t msk_y,
|
||||
int16_t dst_x, int16_t dst_y,
|
||||
int16_t width, int16_t height,
|
||||
unsigned flags,
|
||||
struct sna_composite_op *tmp)
|
||||
{
|
||||
struct kgem_bo *bo;
|
||||
|
||||
if (sna->kgem.mode == KGEM_BLT) {
|
||||
DBG(("%s: already performing BLT\n", __FUNCTION__));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
if (too_large(width, height)) {
|
||||
DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
|
||||
__FUNCTION__, width, height));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
bo = __sna_drawable_peek_bo(dst->pDrawable);
|
||||
if (bo == NULL)
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (untiled_tlb_miss(bo))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (bo->rq)
|
||||
return RQ_IS_BLT(bo->rq);
|
||||
if (bo->rq) {
|
||||
if (RQ_IS_BLT(bo->rq))
|
||||
goto execute;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bo->tiling == I915_TILING_Y)
|
||||
goto upload;
|
||||
|
||||
if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (src->pDrawable == dst->pDrawable &&
|
||||
(sna->render_state.gt < 3 || width*height < 1024) &&
|
||||
can_switch_to_blt(sna, bo, 0))
|
||||
return true;
|
||||
goto execute;
|
||||
|
||||
if (src->pDrawable) {
|
||||
struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable);
|
||||
if (s == NULL)
|
||||
return true;
|
||||
goto upload;
|
||||
|
||||
if (prefer_blt_bo(sna, s, bo))
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
if (sna->kgem.ring == KGEM_BLT) {
|
||||
DBG(("%s: already performing BLT\n", __FUNCTION__));
|
||||
return true;
|
||||
goto execute;
|
||||
}
|
||||
|
||||
return false;
|
||||
upload:
|
||||
flags |= COMPOSITE_UPLOAD;
|
||||
execute:
|
||||
return sna_blt_composite(sna, op,
|
||||
src, dst,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -2280,13 +2330,13 @@ gen8_render_composite(struct sna *sna,
|
|||
width, height, sna->kgem.mode, sna->kgem.ring));
|
||||
|
||||
if (mask == NULL &&
|
||||
try_blt(sna, dst, src, width, height) &&
|
||||
sna_blt_composite(sna, op,
|
||||
src, dst,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp))
|
||||
try_blt(sna, op,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
msk_x, msk_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
flags, tmp))
|
||||
return true;
|
||||
|
||||
if (gen8_composite_fallback(sna, src, mask, dst))
|
||||
|
|
@ -2716,7 +2766,7 @@ prefer_blt_copy(struct sna *sna,
|
|||
if (flags & COPY_DRI && !sna->kgem.has_semaphores)
|
||||
return false;
|
||||
|
||||
if (force_blt_ring(sna))
|
||||
if (force_blt_ring(sna, dst_bo))
|
||||
return true;
|
||||
|
||||
if ((flags & COPY_SMALL ||
|
||||
|
|
@ -3915,6 +3965,13 @@ static bool gen8_render_setup(struct sna *sna)
|
|||
state->gt = ((devid >> 4) & 0xf) + 1;
|
||||
DBG(("%s: gt=%d\n", __FUNCTION__, state->gt));
|
||||
|
||||
if (is_bdw(sna))
|
||||
state->info = &bdw_gt_info;
|
||||
else if (is_chv(sna))
|
||||
state->info = &chv_gt_info;
|
||||
else
|
||||
return false;
|
||||
|
||||
sna_static_stream_init(&general);
|
||||
|
||||
/* Zero pad the start. If you see an offset of 0x0 in the batchbuffer
|
||||
|
|
@ -4026,5 +4083,5 @@ const char *gen8_render_init(struct sna *sna, const char *backend)
|
|||
|
||||
sna->render.max_3d_size = GEN8_MAX_SIZE;
|
||||
sna->render.max_3d_pitch = 1 << 18;
|
||||
return "Broadwell";
|
||||
return sna->render_state.gen8.info->name;
|
||||
}
|
||||
|
|
|
|||
614
src/sna/kgem.c
614
src/sna/kgem.c
File diff suppressed because it is too large
Load Diff
|
|
@ -158,6 +158,8 @@ struct kgem {
|
|||
int16_t count;
|
||||
} vma[NUM_MAP_TYPES];
|
||||
|
||||
uint32_t bcs_state;
|
||||
|
||||
uint32_t batch_flags;
|
||||
uint32_t batch_flags_base;
|
||||
#define I915_EXEC_SECURE (1<<9)
|
||||
|
|
@ -188,7 +190,9 @@ struct kgem {
|
|||
uint32_t has_handle_lut :1;
|
||||
uint32_t has_wc_mmap :1;
|
||||
|
||||
uint32_t can_fence :1;
|
||||
uint32_t can_blt_cpu :1;
|
||||
uint32_t can_blt_y :1;
|
||||
uint32_t can_render_y :1;
|
||||
uint32_t can_scanout_y :1;
|
||||
|
||||
|
|
@ -232,7 +236,7 @@ struct kgem {
|
|||
|
||||
#define KGEM_MAX_DEFERRED_VBO 16
|
||||
|
||||
#define KGEM_BATCH_RESERVED 1
|
||||
#define KGEM_BATCH_RESERVED 8 /* LRI(SWCTRL) + END */
|
||||
#define KGEM_RELOC_RESERVED (KGEM_MAX_DEFERRED_VBO)
|
||||
#define KGEM_EXEC_RESERVED (1+KGEM_MAX_DEFERRED_VBO)
|
||||
|
||||
|
|
@ -407,7 +411,7 @@ static inline void kgem_set_mode(struct kgem *kgem,
|
|||
enum kgem_mode mode,
|
||||
struct kgem_bo *bo)
|
||||
{
|
||||
assert(!kgem->wedged);
|
||||
warn_unless(!kgem->wedged);
|
||||
|
||||
#if DEBUG_FLUSH_BATCH
|
||||
kgem_submit(kgem);
|
||||
|
|
@ -429,7 +433,7 @@ static inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
|
|||
{
|
||||
assert(kgem->mode == KGEM_NONE);
|
||||
assert(kgem->nbatch == 0);
|
||||
assert(!kgem->wedged);
|
||||
warn_unless(!kgem->wedged);
|
||||
kgem->context_switch(kgem, mode);
|
||||
kgem->mode = mode;
|
||||
}
|
||||
|
|
@ -573,7 +577,7 @@ static inline bool kgem_bo_can_blt(struct kgem *kgem,
|
|||
{
|
||||
assert(bo->refcnt);
|
||||
|
||||
if (bo->tiling == I915_TILING_Y) {
|
||||
if (bo->tiling == I915_TILING_Y && !kgem->can_blt_y) {
|
||||
DBG(("%s: can not blt to handle=%d, tiling=Y\n",
|
||||
__FUNCTION__, bo->handle));
|
||||
return false;
|
||||
|
|
@ -588,6 +592,22 @@ static inline bool kgem_bo_can_blt(struct kgem *kgem,
|
|||
return kgem_bo_blt_pitch_is_ok(kgem, bo);
|
||||
}
|
||||
|
||||
void __kgem_bcs_set_tiling(struct kgem *kgem,
|
||||
struct kgem_bo *src,
|
||||
struct kgem_bo *dst);
|
||||
|
||||
inline static void kgem_bcs_set_tiling(struct kgem *kgem,
|
||||
struct kgem_bo *src,
|
||||
struct kgem_bo *dst)
|
||||
{
|
||||
assert(kgem->mode == KGEM_BLT);
|
||||
|
||||
if (!kgem->can_blt_y)
|
||||
return;
|
||||
|
||||
__kgem_bcs_set_tiling(kgem, src, dst);
|
||||
}
|
||||
|
||||
static inline bool kgem_bo_is_snoop(struct kgem_bo *bo)
|
||||
{
|
||||
assert(bo->refcnt);
|
||||
|
|
|
|||
|
|
@ -248,7 +248,6 @@ struct sna {
|
|||
#define SNA_FLUSH_GTT 0x400
|
||||
#define SNA_PERFORMANCE 0x1000
|
||||
#define SNA_POWERSAVE 0x2000
|
||||
#define SNA_REMOVE_OUTPUTS 0x4000
|
||||
#define SNA_HAS_FLIP 0x10000
|
||||
#define SNA_HAS_ASYNC_FLIP 0x20000
|
||||
#define SNA_LINEAR_FB 0x40000
|
||||
|
|
@ -323,7 +322,8 @@ struct sna {
|
|||
uint32_t fg, bg;
|
||||
int size;
|
||||
|
||||
int active;
|
||||
bool disable;
|
||||
bool active;
|
||||
int last_x;
|
||||
int last_y;
|
||||
|
||||
|
|
@ -591,13 +591,51 @@ static inline void sna_present_vblank_handler(struct drm_event_vblank *event) {
|
|||
#endif
|
||||
|
||||
extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation);
|
||||
extern int sna_crtc_to_pipe(xf86CrtcPtr crtc);
|
||||
extern int sna_crtc_to_pipe__safe(xf86CrtcPtr crtc);
|
||||
extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc);
|
||||
extern uint32_t sna_crtc_id(xf86CrtcPtr crtc);
|
||||
extern bool sna_crtc_is_on(xf86CrtcPtr crtc);
|
||||
extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc);
|
||||
|
||||
#define CRTC_VBLANK 0x3
|
||||
#define CRTC_ON 0x80000000
|
||||
|
||||
static inline unsigned long *sna_crtc_flags(xf86CrtcPtr crtc)
|
||||
{
|
||||
unsigned long *flags = crtc->driver_private;
|
||||
assert(flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline unsigned sna_crtc_pipe(xf86CrtcPtr crtc)
|
||||
{
|
||||
return *sna_crtc_flags(crtc) >> 8 & 0xff;
|
||||
}
|
||||
|
||||
static inline unsigned sna_crtc_id(xf86CrtcPtr crtc)
|
||||
{
|
||||
return *sna_crtc_flags(crtc) >> 16 & 0xff;
|
||||
}
|
||||
|
||||
static inline bool sna_crtc_is_on(xf86CrtcPtr crtc)
|
||||
{
|
||||
return *sna_crtc_flags(crtc) & CRTC_ON;
|
||||
}
|
||||
|
||||
static inline void sna_crtc_set_vblank(xf86CrtcPtr crtc)
|
||||
{
|
||||
assert((*sna_crtc_flags(crtc) & CRTC_VBLANK) < 2);
|
||||
++*sna_crtc_flags(crtc);
|
||||
}
|
||||
|
||||
static inline void sna_crtc_clear_vblank(xf86CrtcPtr crtc)
|
||||
{
|
||||
assert(*sna_crtc_flags(crtc) & CRTC_VBLANK);
|
||||
--*sna_crtc_flags(crtc);
|
||||
}
|
||||
|
||||
static inline bool sna_crtc_has_vblank(xf86CrtcPtr crtc)
|
||||
{
|
||||
return *sna_crtc_flags(crtc) & CRTC_VBLANK;
|
||||
}
|
||||
|
||||
CARD32 sna_format_for_depth(int depth);
|
||||
CARD32 sna_render_format_for_depth(int depth);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@
|
|||
#define FORCE_FLUSH 0
|
||||
#define FORCE_FULL_SYNC 0 /* https://bugs.freedesktop.org/show_bug.cgi?id=61628 */
|
||||
|
||||
#define DEFAULT_TILING I915_TILING_X
|
||||
#define DEFAULT_PIXMAP_TILING I915_TILING_X
|
||||
#define DEFAULT_SCANOUT_TILING I915_TILING_X
|
||||
|
||||
#define USE_INPLACE 1
|
||||
#define USE_SPANS 0 /* -1 force CPU, 1 force GPU */
|
||||
|
|
@ -613,9 +614,9 @@ static bool sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv, bool a
|
|||
|
||||
static inline uint32_t default_tiling(struct sna *sna, PixmapPtr pixmap)
|
||||
{
|
||||
#if DEFAULT_TILING == I915_TILING_NONE
|
||||
#if DEFAULT_PIXMAP_TILING == I915_TILING_NONE
|
||||
return I915_TILING_NONE;
|
||||
#elif DEFAULT_TILING == I915_TILING_X
|
||||
#elif DEFAULT_PIXMAP_TILING == I915_TILING_X
|
||||
return I915_TILING_X;
|
||||
#else
|
||||
/* Try to avoid hitting the Y-tiling GTT mapping bug on 855GM */
|
||||
|
|
@ -631,15 +632,6 @@ static inline uint32_t default_tiling(struct sna *sna, PixmapPtr pixmap)
|
|||
pixmap->drawable.height > sna->render.max_3d_size))
|
||||
return I915_TILING_X;
|
||||
|
||||
if (sna_damage_is_all(&sna_pixmap(pixmap)->cpu_damage,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height)) {
|
||||
DBG(("%s: entire source is damaged, using Y-tiling\n",
|
||||
__FUNCTION__));
|
||||
sna_damage_destroy(&sna_pixmap(priv)->gpu_damage);
|
||||
return I915_TILING_Y;
|
||||
}
|
||||
|
||||
return I915_TILING_Y;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -691,6 +683,12 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (bo->tiling == priv->gpu_bo->tiling) {
|
||||
DBG(("%s: tiling request failed\n", __FUNCTION__));
|
||||
kgem_bo_destroy(&sna->kgem, bo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
box.x1 = box.y1 = 0;
|
||||
box.x2 = pixmap->drawable.width;
|
||||
box.y2 = pixmap->drawable.height;
|
||||
|
|
@ -825,8 +823,8 @@ create_pixmap(struct sna *sna, ScreenPtr screen,
|
|||
datasize += adjust;
|
||||
}
|
||||
|
||||
DBG(("%s: allocating pixmap %dx%d, depth=%d, size=%ld\n",
|
||||
__FUNCTION__, width, height, depth, (long)datasize));
|
||||
DBG(("%s: allocating pixmap %dx%d, depth=%d/%d, size=%ld\n",
|
||||
__FUNCTION__, width, height, depth, bpp, (long)datasize));
|
||||
pixmap = AllocatePixmap(screen, datasize);
|
||||
if (!pixmap)
|
||||
return NullPixmap;
|
||||
|
|
@ -1648,7 +1646,7 @@ static bool sna_pixmap_alloc_gpu(struct sna *sna,
|
|||
if (pixmap->usage_hint == SNA_CREATE_FB && (sna->flags & SNA_LINEAR_FB) == 0) {
|
||||
flags |= CREATE_SCANOUT;
|
||||
tiling = kgem_choose_tiling(&sna->kgem,
|
||||
-I915_TILING_X,
|
||||
-DEFAULT_SCANOUT_TILING,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
pixmap->drawable.bitsPerPixel);
|
||||
|
|
@ -2373,21 +2371,26 @@ skip_inplace_map:
|
|||
assert(pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu));
|
||||
}
|
||||
|
||||
assert(pixmap->devKind);
|
||||
if (priv->clear_color == 0 ||
|
||||
pixmap->drawable.bitsPerPixel == 8 ||
|
||||
priv->clear_color == (1 << pixmap->drawable.depth) - 1) {
|
||||
memset(pixmap->devPrivate.ptr, priv->clear_color,
|
||||
(size_t)pixmap->devKind * pixmap->drawable.height);
|
||||
} else {
|
||||
pixman_fill(pixmap->devPrivate.ptr,
|
||||
pixmap->devKind/sizeof(uint32_t),
|
||||
pixmap->drawable.bitsPerPixel,
|
||||
0, 0,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
priv->clear_color);
|
||||
}
|
||||
if (sigtrap_get() == 0) {
|
||||
assert(pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
if (priv->clear_color == 0 ||
|
||||
pixmap->drawable.bitsPerPixel == 8 ||
|
||||
priv->clear_color == (1 << pixmap->drawable.depth) - 1) {
|
||||
memset(pixmap->devPrivate.ptr, priv->clear_color,
|
||||
(size_t)pixmap->devKind * pixmap->drawable.height);
|
||||
} else {
|
||||
pixman_fill(pixmap->devPrivate.ptr,
|
||||
pixmap->devKind/sizeof(uint32_t),
|
||||
pixmap->drawable.bitsPerPixel,
|
||||
0, 0,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
priv->clear_color);
|
||||
}
|
||||
sigtrap_put();
|
||||
} else
|
||||
return false;
|
||||
|
||||
clear_done:
|
||||
sna_damage_all(&priv->cpu_damage, pixmap);
|
||||
|
|
@ -2936,17 +2939,22 @@ move_to_cpu:
|
|||
assert(pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu));
|
||||
}
|
||||
|
||||
assert(pixmap->devKind);
|
||||
do {
|
||||
pixman_fill(pixmap->devPrivate.ptr,
|
||||
pixmap->devKind/sizeof(uint32_t),
|
||||
pixmap->drawable.bitsPerPixel,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
priv->clear_color);
|
||||
box++;
|
||||
} while (--n);
|
||||
if (sigtrap_get() == 0) {
|
||||
assert(pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
do {
|
||||
pixman_fill(pixmap->devPrivate.ptr,
|
||||
pixmap->devKind/sizeof(uint32_t),
|
||||
pixmap->drawable.bitsPerPixel,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
priv->clear_color);
|
||||
box++;
|
||||
} while (--n);
|
||||
sigtrap_put();
|
||||
} else
|
||||
return false;
|
||||
|
||||
clear_done:
|
||||
if (flags & MOVE_WRITE ||
|
||||
|
|
@ -4089,7 +4097,7 @@ sna_pixmap_create_upload(ScreenPtr screen,
|
|||
assert(width);
|
||||
assert(height);
|
||||
|
||||
if (depth == 1)
|
||||
if (depth < 8)
|
||||
return create_pixmap(sna, screen, width, height, depth,
|
||||
CREATE_PIXMAP_USAGE_SCRATCH);
|
||||
|
||||
|
|
@ -5297,6 +5305,7 @@ sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
|
|||
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
|
||||
assert(kgem_bo_can_blt(&sna->kgem, bo));
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
/* Region is pre-clipped and translated into pixmap space */
|
||||
box = region_rects(region);
|
||||
|
|
@ -5318,6 +5327,7 @@ sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -5461,6 +5471,7 @@ sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
|
|||
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
|
||||
assert(kgem_bo_can_blt(&sna->kgem, bo));
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
skip = h * BitmapBytePad(w + left);
|
||||
for (i = 1 << (gc->depth-1); i; i >>= 1, bits += skip) {
|
||||
|
|
@ -5488,6 +5499,7 @@ sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -6871,18 +6883,22 @@ fallback:
|
|||
return;
|
||||
}
|
||||
|
||||
assert(dst_pixmap->devPrivate.ptr);
|
||||
assert(dst_pixmap->devKind);
|
||||
do {
|
||||
pixman_fill(dst_pixmap->devPrivate.ptr,
|
||||
dst_pixmap->devKind/sizeof(uint32_t),
|
||||
dst_pixmap->drawable.bitsPerPixel,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
src_priv->clear_color);
|
||||
box++;
|
||||
} while (--n);
|
||||
if (sigtrap_get() == 0) {
|
||||
assert(dst_pixmap->devPrivate.ptr);
|
||||
assert(dst_pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
do {
|
||||
pixman_fill(dst_pixmap->devPrivate.ptr,
|
||||
dst_pixmap->devKind/sizeof(uint32_t),
|
||||
dst_pixmap->drawable.bitsPerPixel,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
src_priv->clear_color);
|
||||
box++;
|
||||
} while (--n);
|
||||
sigtrap_put();
|
||||
}
|
||||
} else if (!sna_copy_boxes__inplace(sna, region, alu,
|
||||
src_pixmap, src_priv,
|
||||
src_dx, src_dy,
|
||||
|
|
@ -6939,36 +6955,39 @@ fallback:
|
|||
((char *)src_pixmap->devPrivate.ptr +
|
||||
src_dy * src_stride + src_dx * bpp / 8);
|
||||
|
||||
do {
|
||||
DBG(("%s: memcpy_blt(box=(%d, %d), (%d, %d), src=(%d, %d), pitches=(%d, %d))\n",
|
||||
__FUNCTION__,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
src_dx, src_dy,
|
||||
src_stride, dst_stride));
|
||||
if (sigtrap_get() == 0) {
|
||||
do {
|
||||
DBG(("%s: memcpy_blt(box=(%d, %d), (%d, %d), src=(%d, %d), pitches=(%d, %d))\n",
|
||||
__FUNCTION__,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
src_dx, src_dy,
|
||||
src_stride, dst_stride));
|
||||
|
||||
assert(box->x1 >= 0);
|
||||
assert(box->y1 >= 0);
|
||||
assert(box->x2 <= dst_pixmap->drawable.width);
|
||||
assert(box->y2 <= dst_pixmap->drawable.height);
|
||||
assert(box->x1 >= 0);
|
||||
assert(box->y1 >= 0);
|
||||
assert(box->x2 <= dst_pixmap->drawable.width);
|
||||
assert(box->y2 <= dst_pixmap->drawable.height);
|
||||
|
||||
assert(box->x1 + src_dx >= 0);
|
||||
assert(box->y1 + src_dy >= 0);
|
||||
assert(box->x2 + src_dx <= src_pixmap->drawable.width);
|
||||
assert(box->y2 + src_dy <= src_pixmap->drawable.height);
|
||||
assert(has_coherent_ptr(sna, src_priv, MOVE_READ));
|
||||
assert(has_coherent_ptr(sna, dst_priv, MOVE_WRITE));
|
||||
assert(src_stride);
|
||||
assert(dst_stride);
|
||||
memcpy_blt(src_bits, dst_bits, bpp,
|
||||
src_stride, dst_stride,
|
||||
box->x1, box->y1,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1);
|
||||
box++;
|
||||
} while (--n);
|
||||
assert(box->x1 + src_dx >= 0);
|
||||
assert(box->y1 + src_dy >= 0);
|
||||
assert(box->x2 + src_dx <= src_pixmap->drawable.width);
|
||||
assert(box->y2 + src_dy <= src_pixmap->drawable.height);
|
||||
assert(has_coherent_ptr(sna, src_priv, MOVE_READ));
|
||||
assert(has_coherent_ptr(sna, dst_priv, MOVE_WRITE));
|
||||
assert(src_stride);
|
||||
assert(dst_stride);
|
||||
memcpy_blt(src_bits, dst_bits, bpp,
|
||||
src_stride, dst_stride,
|
||||
box->x1, box->y1,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1);
|
||||
box++;
|
||||
} while (--n);
|
||||
sigtrap_put();
|
||||
}
|
||||
} else {
|
||||
DBG(("%s: fallback -- miCopyRegion\n", __FUNCTION__));
|
||||
|
||||
|
|
@ -8341,6 +8360,7 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc,
|
|||
return; /* XXX fallback? */
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
if (sna->kgem.gen >= 0100) {
|
||||
|
|
@ -8408,6 +8428,7 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc,
|
|||
return; /* XXX fallback? */
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -8558,6 +8579,7 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
|
|||
return; /* XXX fallback? */
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -8674,6 +8696,8 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
|
|||
}
|
||||
}
|
||||
|
||||
kgem_bcs_set_tiling(&sna->kgem, upload, arg->bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
if (sna->kgem.gen >= 0100) {
|
||||
|
|
@ -12283,6 +12307,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
|
||||
|
||||
get_drawable_deltas(drawable, pixmap, &dx, &dy);
|
||||
assert(extents->x1 + dx >= 0);
|
||||
|
|
@ -12426,6 +12451,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
|
|||
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
|
||||
} while (1);
|
||||
} else {
|
||||
RegionRec clip;
|
||||
|
|
@ -12494,6 +12520,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
|
|||
if (!kgem_check_batch(&sna->kgem, 3)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
|
||||
|
||||
unwind_batch = sna->kgem.nbatch;
|
||||
unwind_reloc = sna->kgem.nreloc;
|
||||
|
|
@ -12590,6 +12617,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
|
|||
DBG(("%s: emitting split batch\n", __FUNCTION__));
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
|
||||
|
||||
unwind_batch = sna->kgem.nbatch;
|
||||
unwind_reloc = sna->kgem.nreloc;
|
||||
|
|
@ -13219,6 +13247,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
if (!clipped) {
|
||||
dx += drawable->x;
|
||||
|
|
@ -13331,6 +13360,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
|
|||
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
} while (1);
|
||||
} else {
|
||||
RegionRec clip;
|
||||
|
|
@ -13388,6 +13418,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
|
|||
if (!kgem_check_batch(&sna->kgem, 3)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
|
@ -13460,6 +13491,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
|
|||
if (!kgem_check_batch(&sna->kgem, 3)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
|
@ -13590,6 +13622,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
get_drawable_deltas(drawable, pixmap, &dx, &dy);
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
|
||||
assert(kgem_bo_can_blt(&sna->kgem, bo));
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
br00 = 3 << 20;
|
||||
br13 = bo->pitch;
|
||||
|
|
@ -13634,6 +13667,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
|
@ -13697,6 +13731,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -13827,6 +13862,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
|
@ -13888,6 +13924,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -14018,6 +14055,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
|
@ -14078,6 +14116,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -14217,6 +14256,7 @@ sna_poly_fill_rect_stippled_n_box__imm(struct sna *sna,
|
|||
return; /* XXX fallback? */
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
|
@ -14342,6 +14382,7 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
|
|||
return; /* XXX fallback? */
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
|
@ -14505,6 +14546,7 @@ sna_poly_fill_rect_stippled_n_blt__imm(DrawablePtr drawable,
|
|||
get_drawable_deltas(drawable, pixmap, &dx, &dy);
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
|
||||
assert(kgem_bo_can_blt(&sna->kgem, bo));
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
br00 = XY_MONO_SRC_COPY_IMM | 3 << 20;
|
||||
br13 = bo->pitch;
|
||||
|
|
@ -14650,6 +14692,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
|
|||
get_drawable_deltas(drawable, pixmap, &dx, &dy);
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
|
||||
assert(kgem_bo_can_blt(&sna->kgem, bo));
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
br00 = XY_MONO_SRC_COPY | 3 << 20;
|
||||
br13 = bo->pitch;
|
||||
|
|
@ -15372,6 +15415,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
|
|||
}
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n",
|
||||
__FUNCTION__,
|
||||
|
|
@ -15459,6 +15503,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
|
|||
if (!kgem_check_batch(&sna->kgem, 3+len)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
DBG(("%s: new batch, glyph clip box (%d, %d), (%d, %d)\n",
|
||||
__FUNCTION__,
|
||||
|
|
@ -16093,6 +16138,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
|
|||
}
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
unwind_batch = sna->kgem.nbatch;
|
||||
unwind_reloc = sna->kgem.nreloc;
|
||||
|
|
@ -16202,6 +16248,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
|
|||
if (!kgem_check_batch(&sna->kgem, 3+len)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
unwind_batch = sna->kgem.nbatch;
|
||||
unwind_reloc = sna->kgem.nreloc;
|
||||
|
|
@ -16541,6 +16588,7 @@ sna_push_pixels_solid_blt(GCPtr gc,
|
|||
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
|
||||
assert(kgem_bo_can_blt(&sna->kgem, bo));
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
/* Region is pre-clipped and translated into pixmap space */
|
||||
box = region_rects(region);
|
||||
|
|
@ -16562,6 +16610,7 @@ sna_push_pixels_solid_blt(GCPtr gc,
|
|||
return false;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem,
|
||||
bstride*bh,
|
||||
|
|
@ -17029,7 +17078,7 @@ sna_get_image__fast(PixmapPtr pixmap,
|
|||
if (priv == NULL || priv->gpu_damage == NULL)
|
||||
return false;
|
||||
|
||||
if (priv->clear) {
|
||||
if (priv->clear && sigtrap_get() == 0) {
|
||||
int w = region->extents.x2 - region->extents.x1;
|
||||
int h = region->extents.y2 - region->extents.y1;
|
||||
int pitch = PixmapBytePad(w, pixmap->drawable.depth);
|
||||
|
|
@ -17038,6 +17087,7 @@ sna_get_image__fast(PixmapPtr pixmap,
|
|||
__FUNCTION__, priv->clear_color));
|
||||
assert(DAMAGE_IS_ALL(priv->gpu_damage));
|
||||
assert(priv->cpu_damage == NULL);
|
||||
sigtrap_assert_active();
|
||||
|
||||
if (priv->clear_color == 0 ||
|
||||
pixmap->drawable.bitsPerPixel == 8 ||
|
||||
|
|
@ -17054,6 +17104,7 @@ sna_get_image__fast(PixmapPtr pixmap,
|
|||
priv->clear_color);
|
||||
}
|
||||
|
||||
sigtrap_put();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,11 @@ static const uint8_t fill_ROP[] = {
|
|||
ROP_1
|
||||
};
|
||||
|
||||
static void sig_done(struct sna *sna, const struct sna_composite_op *op)
|
||||
{
|
||||
sigtrap_put();
|
||||
}
|
||||
|
||||
static void nop_done(struct sna *sna, const struct sna_composite_op *op)
|
||||
{
|
||||
assert(sna->kgem.nbatch <= KGEM_BATCH_SIZE(&sna->kgem));
|
||||
|
|
@ -129,7 +134,6 @@ static bool sna_blt_fill_init(struct sna *sna,
|
|||
struct kgem *kgem = &sna->kgem;
|
||||
|
||||
assert(kgem_bo_can_blt (kgem, bo));
|
||||
assert(bo->tiling != I915_TILING_Y);
|
||||
blt->bo[0] = bo;
|
||||
|
||||
blt->br13 = bo->pitch;
|
||||
|
|
@ -183,6 +187,7 @@ static bool sna_blt_fill_init(struct sna *sna,
|
|||
return false;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = kgem->batch + kgem->nbatch;
|
||||
|
|
@ -243,6 +248,8 @@ noinline static void __sna_blt_fill_begin(struct sna *sna,
|
|||
struct kgem *kgem = &sna->kgem;
|
||||
uint32_t *b;
|
||||
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, blt->bo[0]);
|
||||
|
||||
assert(kgem->mode == KGEM_BLT);
|
||||
b = kgem->batch + kgem->nbatch;
|
||||
if (sna->kgem.gen >= 0100) {
|
||||
|
|
@ -295,6 +302,7 @@ inline static void sna_blt_fill_begin(struct sna *sna,
|
|||
if (kgem->nreloc) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(kgem, NULL, blt->bo[0]);
|
||||
assert(kgem->nbatch == 0);
|
||||
}
|
||||
|
||||
|
|
@ -338,8 +346,8 @@ static bool sna_blt_copy_init(struct sna *sna,
|
|||
{
|
||||
struct kgem *kgem = &sna->kgem;
|
||||
|
||||
assert(kgem_bo_can_blt (kgem, src));
|
||||
assert(kgem_bo_can_blt (kgem, dst));
|
||||
assert(kgem_bo_can_blt(kgem, src));
|
||||
assert(kgem_bo_can_blt(kgem, dst));
|
||||
|
||||
blt->bo[0] = src;
|
||||
blt->bo[1] = dst;
|
||||
|
|
@ -378,6 +386,7 @@ static bool sna_blt_copy_init(struct sna *sna,
|
|||
return false;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, src, dst);
|
||||
|
||||
sna->blt_state.fill_bo = 0;
|
||||
return true;
|
||||
|
|
@ -432,6 +441,7 @@ static bool sna_blt_alpha_fixup_init(struct sna *sna,
|
|||
return false;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, src, dst);
|
||||
|
||||
sna->blt_state.fill_bo = 0;
|
||||
return true;
|
||||
|
|
@ -462,6 +472,7 @@ static void sna_blt_alpha_fixup_one(struct sna *sna,
|
|||
!kgem_check_reloc(kgem, 2)) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, blt->bo[0], blt->bo[1]);
|
||||
}
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
|
|
@ -590,6 +601,7 @@ static void sna_blt_copy_one(struct sna *sna,
|
|||
!kgem_check_reloc(kgem, 2)) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, blt->bo[0], blt->bo[1]);
|
||||
}
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
|
|
@ -998,6 +1010,7 @@ static void blt_composite_fill__cpu(struct sna *sna,
|
|||
|
||||
assert(op->dst.pixmap->devPrivate.ptr);
|
||||
assert(op->dst.pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
pixman_fill(op->dst.pixmap->devPrivate.ptr,
|
||||
op->dst.pixmap->devKind / sizeof(uint32_t),
|
||||
op->dst.pixmap->drawable.bitsPerPixel,
|
||||
|
|
@ -1017,6 +1030,7 @@ blt_composite_fill_box_no_offset__cpu(struct sna *sna,
|
|||
|
||||
assert(op->dst.pixmap->devPrivate.ptr);
|
||||
assert(op->dst.pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
pixman_fill(op->dst.pixmap->devPrivate.ptr,
|
||||
op->dst.pixmap->devKind / sizeof(uint32_t),
|
||||
op->dst.pixmap->drawable.bitsPerPixel,
|
||||
|
|
@ -1037,6 +1051,7 @@ blt_composite_fill_boxes_no_offset__cpu(struct sna *sna,
|
|||
|
||||
assert(op->dst.pixmap->devPrivate.ptr);
|
||||
assert(op->dst.pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
pixman_fill(op->dst.pixmap->devPrivate.ptr,
|
||||
op->dst.pixmap->devKind / sizeof(uint32_t),
|
||||
op->dst.pixmap->drawable.bitsPerPixel,
|
||||
|
|
@ -1058,6 +1073,7 @@ blt_composite_fill_box__cpu(struct sna *sna,
|
|||
|
||||
assert(op->dst.pixmap->devPrivate.ptr);
|
||||
assert(op->dst.pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
pixman_fill(op->dst.pixmap->devPrivate.ptr,
|
||||
op->dst.pixmap->devKind / sizeof(uint32_t),
|
||||
op->dst.pixmap->drawable.bitsPerPixel,
|
||||
|
|
@ -1079,6 +1095,7 @@ blt_composite_fill_boxes__cpu(struct sna *sna,
|
|||
|
||||
assert(op->dst.pixmap->devPrivate.ptr);
|
||||
assert(op->dst.pixmap->devKind);
|
||||
sigtrap_assert_active();
|
||||
pixman_fill(op->dst.pixmap->devPrivate.ptr,
|
||||
op->dst.pixmap->devKind / sizeof(uint32_t),
|
||||
op->dst.pixmap->drawable.bitsPerPixel,
|
||||
|
|
@ -1431,6 +1448,7 @@ begin_blt(struct sna *sna,
|
|||
return false;
|
||||
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, op->dst.bo);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1456,6 +1474,7 @@ prepare_blt_clear(struct sna *sna,
|
|||
DBG(("%s\n", __FUNCTION__));
|
||||
|
||||
if (op->dst.bo == NULL) {
|
||||
op->u.blt.pixel = 0;
|
||||
op->blt = blt_composite_fill__cpu;
|
||||
if (op->dst.x|op->dst.y) {
|
||||
op->box = blt_composite_fill_box__cpu;
|
||||
|
|
@ -1466,9 +1485,8 @@ prepare_blt_clear(struct sna *sna,
|
|||
op->boxes = blt_composite_fill_boxes_no_offset__cpu;
|
||||
op->thread_boxes = blt_composite_fill_boxes_no_offset__cpu;
|
||||
}
|
||||
op->done = nop_done;
|
||||
op->u.blt.pixel = 0;
|
||||
return true;
|
||||
op->done = sig_done;
|
||||
return sigtrap_get() == 0;
|
||||
}
|
||||
|
||||
op->blt = blt_composite_fill;
|
||||
|
|
@ -1511,8 +1529,8 @@ prepare_blt_fill(struct sna *sna,
|
|||
op->boxes = blt_composite_fill_boxes_no_offset__cpu;
|
||||
op->thread_boxes = blt_composite_fill_boxes_no_offset__cpu;
|
||||
}
|
||||
op->done = nop_done;
|
||||
return true;
|
||||
op->done = sig_done;
|
||||
return sigtrap_get() == 0;
|
||||
}
|
||||
|
||||
op->blt = blt_composite_fill;
|
||||
|
|
@ -1695,6 +1713,7 @@ static void blt_composite_copy_boxes__thread(struct sna *sna,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
} else {
|
||||
do {
|
||||
|
|
@ -1751,6 +1770,7 @@ static void blt_composite_copy_boxes__thread(struct sna *sna,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
}
|
||||
sna_vertex_unlock(&sna->render);
|
||||
|
|
@ -1833,6 +1853,7 @@ static void blt_composite_copy_boxes__thread64(struct sna *sna,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
} else {
|
||||
do {
|
||||
|
|
@ -1891,6 +1912,7 @@ static void blt_composite_copy_boxes__thread64(struct sna *sna,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
}
|
||||
sna_vertex_unlock(&sna->render);
|
||||
|
|
@ -2000,6 +2022,7 @@ prepare_blt_copy(struct sna *sna,
|
|||
}
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, bo, op->dst.bo);
|
||||
|
||||
DBG(("%s\n", __FUNCTION__));
|
||||
|
||||
|
|
@ -2423,6 +2446,9 @@ prepare_blt_put(struct sna *sna,
|
|||
op->box = blt_put_composite_box;
|
||||
op->boxes = blt_put_composite_boxes;
|
||||
}
|
||||
|
||||
op->done = nop_done;
|
||||
return true;
|
||||
} else {
|
||||
if (alpha_fixup) {
|
||||
op->u.blt.pixel = alpha_fixup;
|
||||
|
|
@ -2434,10 +2460,10 @@ prepare_blt_put(struct sna *sna,
|
|||
op->box = blt_put_composite_box__cpu;
|
||||
op->boxes = blt_put_composite_boxes__cpu;
|
||||
}
|
||||
}
|
||||
op->done = nop_done;
|
||||
|
||||
return true;
|
||||
op->done = sig_done;
|
||||
return sigtrap_get() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -2594,6 +2620,8 @@ clear:
|
|||
}
|
||||
if (hint & REPLACES)
|
||||
kgem_bo_undo(&sna->kgem, tmp->dst.bo);
|
||||
if (flags & COMPOSITE_UPLOAD)
|
||||
return false;
|
||||
} else {
|
||||
RegionRec region;
|
||||
|
||||
|
|
@ -2680,6 +2708,8 @@ fill:
|
|||
}
|
||||
if (hint & REPLACES)
|
||||
kgem_bo_undo(&sna->kgem, tmp->dst.bo);
|
||||
if (flags & COMPOSITE_UPLOAD)
|
||||
return false;
|
||||
} else {
|
||||
RegionRec region;
|
||||
|
||||
|
|
@ -2818,7 +2848,7 @@ fill:
|
|||
if (src_pixmap->drawable.width <= sna->render.max_3d_size &&
|
||||
src_pixmap->drawable.height <= sna->render.max_3d_size &&
|
||||
bo->pitch <= sna->render.max_3d_pitch &&
|
||||
(flags & COMPOSITE_FALLBACK) == 0)
|
||||
(flags & (COMPOSITE_UPLOAD | COMPOSITE_FALLBACK)) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2869,7 +2899,7 @@ fallback:
|
|||
DBG(("%s: fallback -- unaccelerated upload\n",
|
||||
__FUNCTION__));
|
||||
goto fallback;
|
||||
} else {
|
||||
} else if ((flags & COMPOSITE_UPLOAD) == 0) {
|
||||
ret = prepare_blt_copy(sna, tmp, bo, alpha_fixup);
|
||||
if (!ret)
|
||||
goto fallback;
|
||||
|
|
@ -3046,6 +3076,7 @@ sna_blt_composite__convert(struct sna *sna,
|
|||
}
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, tmp->src.bo, tmp->dst.bo);
|
||||
|
||||
if (alpha_fixup) {
|
||||
tmp->blt = blt_composite_copy_with_alpha;
|
||||
|
|
@ -3387,6 +3418,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
|
|||
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(kgem_check_batch(kgem, 6));
|
||||
assert(kgem_check_reloc(kgem, 1));
|
||||
|
|
@ -3493,6 +3525,8 @@ bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
|
|||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = kgem->batch + kgem->nbatch;
|
||||
if (kgem->gen >= 0100) {
|
||||
|
|
@ -3581,6 +3615,7 @@ bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
b = kgem->batch + kgem->nbatch;
|
||||
|
|
@ -3727,6 +3762,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
|
|||
}
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
|
||||
if ((dst_dx | dst_dy) == 0) {
|
||||
if (kgem->gen >= 0100) {
|
||||
|
|
@ -3787,6 +3823,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
} else {
|
||||
uint64_t hdr = (uint64_t)br13 << 32 | cmd | 6;
|
||||
|
|
@ -3844,6 +3881,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -3905,6 +3943,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
} else {
|
||||
cmd |= 6;
|
||||
|
|
@ -3962,6 +4001,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
|
|||
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
} while (1);
|
||||
}
|
||||
}
|
||||
|
|
@ -4068,6 +4108,7 @@ bool sna_blt_copy_boxes__with_alpha(struct sna *sna, uint8_t alu,
|
|||
!kgem_check_reloc(kgem, 2)) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
|
||||
}
|
||||
|
||||
assert(sna->kgem.mode == KGEM_BLT);
|
||||
|
|
@ -4163,6 +4204,7 @@ bool sna_blt_copy_boxes_fallback(struct sna *sna, uint8_t alu,
|
|||
DBG(("%s: dst == src\n", __FUNCTION__));
|
||||
|
||||
if (src_bo->tiling == I915_TILING_Y &&
|
||||
!sna->kgem.can_blt_y &&
|
||||
kgem_bo_blt_pitch_is_ok(&sna->kgem, src_bo)) {
|
||||
struct kgem_bo *bo;
|
||||
|
||||
|
|
@ -4210,6 +4252,7 @@ bool sna_blt_copy_boxes_fallback(struct sna *sna, uint8_t alu,
|
|||
}
|
||||
} else {
|
||||
if (src_bo->tiling == I915_TILING_Y &&
|
||||
!sna->kgem.can_blt_y &&
|
||||
kgem_bo_blt_pitch_is_ok(&sna->kgem, src_bo)) {
|
||||
DBG(("%s: src is y-tiled\n", __FUNCTION__));
|
||||
if (src->type != DRAWABLE_PIXMAP)
|
||||
|
|
@ -4224,6 +4267,7 @@ bool sna_blt_copy_boxes_fallback(struct sna *sna, uint8_t alu,
|
|||
}
|
||||
|
||||
if (dst_bo->tiling == I915_TILING_Y &&
|
||||
!sna->kgem.can_blt_y &&
|
||||
kgem_bo_blt_pitch_is_ok(&sna->kgem, dst_bo)) {
|
||||
DBG(("%s: dst is y-tiled\n", __FUNCTION__));
|
||||
if (dst->type != DRAWABLE_PIXMAP)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -400,6 +400,9 @@ static uint32_t color_tiling(struct sna *sna, DrawablePtr draw)
|
|||
{
|
||||
uint32_t tiling;
|
||||
|
||||
if (!sna->kgem.can_fence)
|
||||
return I915_TILING_NONE;
|
||||
|
||||
if (COLOR_PREFER_TILING_Y &&
|
||||
(draw->width != sna->front->drawable.width ||
|
||||
draw->height != sna->front->drawable.height))
|
||||
|
|
@ -427,7 +430,6 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
|
|||
PixmapPtr pixmap)
|
||||
{
|
||||
struct sna_pixmap *priv;
|
||||
int tiling;
|
||||
|
||||
DBG(("%s: attaching DRI client to pixmap=%ld\n",
|
||||
__FUNCTION__, pixmap->drawable.serialNumber));
|
||||
|
|
@ -451,11 +453,18 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
|
|||
assert(priv->gpu_bo->proxy == NULL);
|
||||
assert(priv->gpu_bo->flush == false);
|
||||
|
||||
tiling = color_tiling(sna, &pixmap->drawable);
|
||||
if (tiling < 0)
|
||||
tiling = -tiling;
|
||||
if (priv->gpu_bo->tiling != tiling && !priv->gpu_bo->scanout)
|
||||
sna_pixmap_change_tiling(pixmap, tiling);
|
||||
if (!sna->kgem.can_fence) {
|
||||
if (!sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) {
|
||||
DBG(("%s: failed to discard tiling (%d) for DRI2 protocol\n", __FUNCTION__, priv->gpu_bo->tiling));
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
int tiling = color_tiling(sna, &pixmap->drawable);
|
||||
if (tiling < 0)
|
||||
tiling = -tiling;
|
||||
if (priv->gpu_bo->tiling < tiling && !priv->gpu_bo->scanout)
|
||||
sna_pixmap_change_tiling(pixmap, tiling);
|
||||
}
|
||||
|
||||
return priv->gpu_bo;
|
||||
}
|
||||
|
|
@ -870,6 +879,22 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define popcount(x) __builtin_popcount(x)
|
||||
#else
|
||||
static int popcount(unsigned int x)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (x) {
|
||||
count += x&1;
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kgem_bo *src, bool sync)
|
||||
{
|
||||
struct drm_i915_gem_busy busy;
|
||||
|
|
@ -940,9 +965,12 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
|
|||
* The ultimate question is whether preserving the ring outweighs
|
||||
* the cost of the query.
|
||||
*/
|
||||
mode = KGEM_RENDER;
|
||||
if (busy.busy & (0xfffe << 16))
|
||||
if (popcount(busy.busy >> 16) > 1)
|
||||
mode = busy.busy & 0xffff ? KGEM_BLT : KGEM_RENDER;
|
||||
else if (busy.busy & (0xfffe << 16))
|
||||
mode = KGEM_BLT;
|
||||
else
|
||||
mode = KGEM_RENDER;
|
||||
kgem_bo_mark_busy(&sna->kgem, busy.handle == src->handle ? src : dst, mode);
|
||||
_kgem_set_mode(&sna->kgem, mode);
|
||||
}
|
||||
|
|
@ -1312,8 +1340,8 @@ draw_current_msc(DrawablePtr draw, xf86CrtcPtr crtc, uint64_t msc)
|
|||
const struct ust_msc *this = sna_crtc_last_swap(crtc);
|
||||
DBG(("%s: Window transferring from pipe=%d [msc=%llu] to pipe=%d [msc=%llu], delta now %lld\n",
|
||||
__FUNCTION__,
|
||||
sna_crtc_to_pipe(priv->crtc), (long long)last->msc,
|
||||
sna_crtc_to_pipe(crtc), (long long)this->msc,
|
||||
sna_crtc_pipe(priv->crtc), (long long)last->msc,
|
||||
sna_crtc_pipe(crtc), (long long)this->msc,
|
||||
(long long)(priv->msc_delta + this->msc - last->msc)));
|
||||
priv->msc_delta += this->msc - last->msc;
|
||||
priv->crtc = crtc;
|
||||
|
|
@ -1491,7 +1519,7 @@ sna_dri2_add_event(struct sna *sna,
|
|||
info->sna = sna;
|
||||
info->draw = draw;
|
||||
info->crtc = crtc;
|
||||
info->pipe = sna_crtc_to_pipe(crtc);
|
||||
info->pipe = sna_crtc_pipe(crtc);
|
||||
|
||||
if (!add_event_to_client(info, sna, client)) {
|
||||
free(info);
|
||||
|
|
@ -1685,7 +1713,7 @@ can_flip(struct sna * sna,
|
|||
}
|
||||
|
||||
if (!sna_crtc_is_on(crtc)) {
|
||||
DBG(("%s: ref-pipe=%d is disabled\n", __FUNCTION__, sna_crtc_to_pipe(crtc)));
|
||||
DBG(("%s: ref-pipe=%d is disabled\n", __FUNCTION__, sna_crtc_pipe(crtc)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2137,7 +2165,7 @@ static void fake_swap_complete(struct sna *sna, ClientPtr client,
|
|||
|
||||
swap = sna_crtc_last_swap(crtc);
|
||||
DBG(("%s(type=%d): draw=%ld, pipe=%d, frame=%lld [msc %lld], tv=%d.%06d\n",
|
||||
__FUNCTION__, type, (long)draw->id, crtc ? sna_crtc_to_pipe(crtc) : -1,
|
||||
__FUNCTION__, type, (long)draw->id, crtc ? sna_crtc_pipe(crtc) : -1,
|
||||
(long long)swap->msc,
|
||||
(long long)draw_current_msc(draw, crtc, swap->msc),
|
||||
swap->tv_sec, swap->tv_usec));
|
||||
|
|
@ -2587,7 +2615,7 @@ get_current_msc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc)
|
|||
VG_CLEAR(vbl);
|
||||
vbl.request.type = _DRM_VBLANK_RELATIVE;
|
||||
vbl.request.sequence = 0;
|
||||
if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(crtc)) == 0)
|
||||
if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc)) == 0)
|
||||
ret = sna_crtc_record_vblank(crtc, &vbl);
|
||||
else
|
||||
ret = sna_crtc_last_swap(crtc)->msc;
|
||||
|
|
@ -2704,7 +2732,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
|
|||
if (immediate) {
|
||||
info = sna->dri2.flip_pending;
|
||||
DBG(("%s: performing immediate swap on pipe %d, pending? %d, mode: %d, continuation? %d\n",
|
||||
__FUNCTION__, sna_crtc_to_pipe(crtc),
|
||||
__FUNCTION__, sna_crtc_pipe(crtc),
|
||||
info != NULL, info ? info->flip_continue : 0,
|
||||
info && info->draw == draw));
|
||||
|
||||
|
|
@ -2844,7 +2872,7 @@ sna_dri2_schedule_xchg(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
|
|||
DBG(("%s: synchronous?=%d, send-event?=%d\n", __FUNCTION__, sync, event));
|
||||
if (!sync || event) {
|
||||
DBG(("%s: performing immediate xchg on pipe %d\n",
|
||||
__FUNCTION__, sna_crtc_to_pipe(crtc)));
|
||||
__FUNCTION__, sna_crtc_pipe(crtc)));
|
||||
sna_dri2_xchg(draw, front, back);
|
||||
}
|
||||
if (sync) {
|
||||
|
|
@ -2906,7 +2934,7 @@ sna_dri2_schedule_xchg_crtc(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc
|
|||
DBG(("%s: synchronous?=%d, send-event?=%d\n", __FUNCTION__, sync, event));
|
||||
if (!sync || event) {
|
||||
DBG(("%s: performing immediate xchg only on pipe %d\n",
|
||||
__FUNCTION__, sna_crtc_to_pipe(crtc)));
|
||||
__FUNCTION__, sna_crtc_pipe(crtc)));
|
||||
sna_dri2_xchg_crtc(sna, draw, crtc, front, back);
|
||||
}
|
||||
if (sync) {
|
||||
|
|
@ -3173,7 +3201,7 @@ sna_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
|
|||
const struct ust_msc *swap;
|
||||
|
||||
DBG(("%s(draw=%ld, pipe=%d)\n", __FUNCTION__, draw->id,
|
||||
crtc ? sna_crtc_to_pipe(crtc) : -1));
|
||||
crtc ? sna_crtc_pipe(crtc) : -1));
|
||||
|
||||
if (crtc != NULL) {
|
||||
union drm_wait_vblank vbl;
|
||||
|
|
@ -3181,7 +3209,7 @@ sna_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
|
|||
VG_CLEAR(vbl);
|
||||
vbl.request.type = _DRM_VBLANK_RELATIVE;
|
||||
vbl.request.sequence = 0;
|
||||
if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(crtc)) == 0)
|
||||
if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc)) == 0)
|
||||
sna_crtc_record_vblank(crtc, &vbl);
|
||||
} else
|
||||
/* Drawable not displayed, make up a *monotonic* value */
|
||||
|
|
@ -3215,7 +3243,7 @@ sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc
|
|||
|
||||
crtc = sna_dri2_get_crtc(draw);
|
||||
DBG(("%s(pipe=%d, target_msc=%llu, divisor=%llu, rem=%llu)\n",
|
||||
__FUNCTION__, crtc ? sna_crtc_to_pipe(crtc) : -1,
|
||||
__FUNCTION__, crtc ? sna_crtc_pipe(crtc) : -1,
|
||||
(long long)target_msc,
|
||||
(long long)divisor,
|
||||
(long long)remainder));
|
||||
|
|
@ -3224,7 +3252,7 @@ sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc
|
|||
if (crtc == NULL)
|
||||
goto out_complete;
|
||||
|
||||
pipe = sna_crtc_to_pipe(crtc);
|
||||
pipe = sna_crtc_pipe(crtc);
|
||||
|
||||
VG_CLEAR(vbl);
|
||||
|
||||
|
|
|
|||
|
|
@ -270,6 +270,8 @@ static PixmapPtr sna_dri3_pixmap_from_fd(ScreenPtr screen,
|
|||
priv->ptr = MAKE_STATIC_PTR(pixmap->devPrivate.ptr);
|
||||
} else {
|
||||
assert(priv->gpu_bo == bo);
|
||||
priv->create = kgem_can_create_2d(&sna->kgem,
|
||||
width, height, depth);
|
||||
priv->pinned |= PIN_DRI3;
|
||||
}
|
||||
list_add(&priv->cow_list, &sna->dri3.pixmaps);
|
||||
|
|
@ -325,6 +327,15 @@ static int sna_dri3_fd_from_pixmap(ScreenPtr screen,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (bo->tiling && !sna->kgem.can_fence) {
|
||||
if (!sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) {
|
||||
DBG(("%s: unable to discard GPU tiling (%d) for DRI3 protocol\n",
|
||||
__FUNCTION__, bo->tiling));
|
||||
return -1;
|
||||
}
|
||||
bo = priv->gpu_bo;
|
||||
}
|
||||
|
||||
fd = kgem_bo_export_to_prime(&sna->kgem, bo);
|
||||
if (fd == -1) {
|
||||
DBG(("%s: exporting handle=%d to fd failed\n", __FUNCTION__, bo->handle));
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ sna_set_fallback_mode(ScrnInfoPtr scrn)
|
|||
#endif
|
||||
}
|
||||
|
||||
static Bool sna_set_desired_mode(struct sna *sna)
|
||||
static void sna_set_desired_mode(struct sna *sna)
|
||||
{
|
||||
ScrnInfoPtr scrn = sna->scrn;
|
||||
|
||||
|
|
@ -212,7 +212,6 @@ static Bool sna_set_desired_mode(struct sna *sna)
|
|||
}
|
||||
|
||||
sna_mode_check(sna);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -282,7 +281,7 @@ static Bool sna_create_screen_resources(ScreenPtr screen)
|
|||
if (serverGeneration == 1 && (sna->flags & SNA_IS_HOSTED) == 0)
|
||||
sna_copy_fbcon(sna);
|
||||
|
||||
(void)sna_set_desired_mode(sna);
|
||||
sna_set_desired_mode(sna);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -620,9 +619,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int probe)
|
|||
|
||||
if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE))
|
||||
sna->flags |= SNA_LINEAR_FB;
|
||||
|
||||
if (xf86ReturnOptValBool(sna->Options, OPTION_DELETE_DP12, FALSE))
|
||||
sna->flags |= SNA_REMOVE_OUTPUTS;
|
||||
if (!sna->kgem.can_fence)
|
||||
sna->flags |= SNA_LINEAR_FB;
|
||||
|
||||
if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE))
|
||||
sna->flags |= SNA_NO_WAIT;
|
||||
|
|
@ -1220,13 +1218,8 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL)
|
|||
sna_mode_discover(sna);
|
||||
sna->flags &= ~SNA_REPROBE;
|
||||
}
|
||||
sna_mode_check(sna);
|
||||
|
||||
if (!sna_set_desired_mode(sna)) {
|
||||
sna_accel_leave(sna);
|
||||
intel_put_master(sna->dev);
|
||||
return FALSE;
|
||||
}
|
||||
sna_set_desired_mode(sna);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
#define NO_GLYPHS_VIA_MASK 0
|
||||
#define FORCE_SMALL_MASK 0 /* -1 = never, 1 = always */
|
||||
#define NO_GLYPHS_SLOW 0
|
||||
#define NO_DISCARD_MASK 0
|
||||
#define DISCARD_MASK 0 /* -1 = never, 1 = always */
|
||||
|
||||
#define CACHE_PICTURE_SIZE 1024
|
||||
#define GLYPH_MIN_SIZE 8
|
||||
|
|
@ -1094,6 +1094,9 @@ sna_glyph_get_image(GlyphPtr g, ScreenPtr s)
|
|||
|
||||
static inline bool use_small_mask(struct sna *sna, int16_t width, int16_t height, int depth)
|
||||
{
|
||||
if (depth < 8)
|
||||
return true;
|
||||
|
||||
if (FORCE_SMALL_MASK)
|
||||
return FORCE_SMALL_MASK > 0;
|
||||
|
||||
|
|
@ -1156,12 +1159,6 @@ glyphs_via_mask(struct sna *sna,
|
|||
src_x += box.x1 - list->xOff;
|
||||
src_y += box.y1 - list->yOff;
|
||||
|
||||
if (format->depth < 8) {
|
||||
format = PictureMatchFormat(screen, 8, PICT_a8);
|
||||
if (!format)
|
||||
return false;
|
||||
}
|
||||
|
||||
component_alpha = NeedsComponent(format->format);
|
||||
if (use_small_mask(sna, width, height, format->depth)) {
|
||||
pixman_image_t *mask_image;
|
||||
|
|
@ -1179,7 +1176,7 @@ use_small_mask:
|
|||
return false;
|
||||
|
||||
mask_image =
|
||||
pixman_image_create_bits(format->depth << 24 | format->format,
|
||||
pixman_image_create_bits(pixmap->drawable.bitsPerPixel << 24 | format->format,
|
||||
width, height,
|
||||
pixmap->devPrivate.ptr,
|
||||
pixmap->devKind);
|
||||
|
|
@ -1386,10 +1383,11 @@ next_image:
|
|||
DBG(("%s: atlas format=%08x, mask format=%08x\n",
|
||||
__FUNCTION__,
|
||||
(int)p->atlas->format,
|
||||
(int)(format->depth << 24 | format->format)));
|
||||
(int)mask->format));
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
if (p->atlas->format == (format->depth << 24 | format->format)) {
|
||||
if (p->atlas->format == mask->format ||
|
||||
alphaless(p->atlas->format) == mask->format) {
|
||||
ok = sna->render.composite(sna, PictOpAdd,
|
||||
p->atlas, NULL, mask,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
|
|
@ -1564,6 +1562,8 @@ skip_glyph:
|
|||
out:
|
||||
if (list_extents != stack_extents)
|
||||
free(list_extents);
|
||||
DBG(("%s: format=%08d, depth=%d\n",
|
||||
__FUNCTION__, format->format, format->depth));
|
||||
return format;
|
||||
}
|
||||
|
||||
|
|
@ -1573,24 +1573,34 @@ static bool can_discard_mask(uint8_t op, PicturePtr src, PictFormatPtr mask,
|
|||
PictFormatPtr g;
|
||||
uint32_t color;
|
||||
|
||||
if (NO_DISCARD_MASK)
|
||||
return false;
|
||||
if (DISCARD_MASK)
|
||||
return DISCARD_MASK > 0;
|
||||
|
||||
DBG(("%s: nlist=%d, mask=%08x, depth %d, op=%d (bounded? %d)\n",
|
||||
__FUNCTION__, nlist,
|
||||
mask ? (unsigned)mask->format : 0, mask ? mask->depth : 0,
|
||||
op, op_is_bounded(op)));
|
||||
|
||||
if (nlist == 1 && list->len == 1)
|
||||
return true;
|
||||
if (nlist == 1 && list->len == 1) {
|
||||
if (mask == list->format)
|
||||
return true;
|
||||
|
||||
if (!op_is_bounded(op))
|
||||
g = list->format;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (!op_is_bounded(op)) {
|
||||
DBG(("%s: unbounded op, not discarding\n", __FUNCTION__));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* No glyphs overlap and we are not performing a mask conversion. */
|
||||
g = glyphs_format(nlist, list, glyphs);
|
||||
if (mask == g)
|
||||
if (mask == g) {
|
||||
DBG(("%s: mask matches glyphs format, no conversion, so discard mask\n",
|
||||
__FUNCTION__));
|
||||
return true;
|
||||
}
|
||||
|
||||
DBG(("%s: preferred mask format %08x, depth %d\n",
|
||||
__FUNCTION__, g ? (unsigned)g->format : 0, g ? g->depth : 0));
|
||||
|
|
@ -1605,18 +1615,41 @@ static bool can_discard_mask(uint8_t op, PicturePtr src, PictFormatPtr mask,
|
|||
|
||||
list++;
|
||||
}
|
||||
|
||||
if (!sna_picture_is_solid(src, &color))
|
||||
return false;
|
||||
|
||||
return color >> 24 == 0xff;
|
||||
} else {
|
||||
if (PICT_FORMAT_A(mask->format) >= PICT_FORMAT_A(g->format))
|
||||
skip:
|
||||
if (mask->format == g->format)
|
||||
return true;
|
||||
|
||||
if (g->depth != 1)
|
||||
return false;
|
||||
}
|
||||
if (mask->format == alphaless(g->format))
|
||||
return true;
|
||||
|
||||
if (PICT_FORMAT_TYPE(g->format) == PICT_TYPE_A &&
|
||||
PICT_FORMAT_TYPE(mask->format) != PICT_TYPE_A)
|
||||
return true;
|
||||
|
||||
if (!sna_picture_is_solid(src, &color))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return color >> 24 == 0xff;
|
||||
static uint32_t pixman_format(PictFormatPtr short_format)
|
||||
{
|
||||
uint32_t bpp;
|
||||
|
||||
bpp = short_format->depth;
|
||||
if (bpp <= 1)
|
||||
bpp = 1;
|
||||
else if (bpp <= 8)
|
||||
bpp = 8;
|
||||
else if (bpp <= 16)
|
||||
bpp = 16;
|
||||
else
|
||||
bpp = 32;
|
||||
return bpp << 24 | short_format->format;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1756,7 +1789,7 @@ next:
|
|||
if (sigtrap_get() == 0) {
|
||||
if (mask_format) {
|
||||
pixman_composite_glyphs(op, src_image, dst_image,
|
||||
mask_format->format | (mask_format->depth << 24),
|
||||
pixman_format(mask_format),
|
||||
src_x + src_dx + region.extents.x1 - dst_x,
|
||||
src_y + src_dy + region.extents.y1 - dst_y,
|
||||
region.extents.x1, region.extents.y1,
|
||||
|
|
@ -1815,10 +1848,10 @@ out:
|
|||
x, y,
|
||||
mask_format->depth,
|
||||
(long)mask_format->format,
|
||||
(long)(mask_format->depth << 24 | mask_format->format),
|
||||
(long)pixman_format(mask_format),
|
||||
NeedsComponent(mask_format->format)));
|
||||
mask_image =
|
||||
pixman_image_create_bits(mask_format->depth << 24 | mask_format->format,
|
||||
pixman_image_create_bits(pixman_format(mask_format),
|
||||
region.extents.x2 - region.extents.x1,
|
||||
region.extents.y2 - region.extents.y1,
|
||||
NULL, 0);
|
||||
|
|
@ -2086,12 +2119,6 @@ glyphs_via_image(struct sna *sna,
|
|||
src_x += box.x1 - list->xOff;
|
||||
src_y += box.y1 - list->yOff;
|
||||
|
||||
if (format->depth < 8) {
|
||||
format = PictureMatchFormat(screen, 8, PICT_a8);
|
||||
if (!format)
|
||||
return false;
|
||||
}
|
||||
|
||||
DBG(("%s: small mask [format=%lx, depth=%d, size=%d], rendering glyphs to upload buffer\n",
|
||||
__FUNCTION__, (unsigned long)format->format,
|
||||
format->depth, (uint32_t)width*height*format->depth));
|
||||
|
|
@ -2104,7 +2131,7 @@ glyphs_via_image(struct sna *sna,
|
|||
return false;
|
||||
|
||||
mask_image =
|
||||
pixman_image_create_bits(format->depth << 24 | format->format,
|
||||
pixman_image_create_bits(pixmap->drawable.bitsPerPixel << 24 | format->format,
|
||||
width, height,
|
||||
pixmap->devPrivate.ptr,
|
||||
pixmap->devKind);
|
||||
|
|
|
|||
|
|
@ -105,8 +105,10 @@ read_boxes_inplace__cpu(struct kgem *kgem,
|
|||
if (!download_inplace__cpu(kgem, dst, bo, box, n))
|
||||
return false;
|
||||
|
||||
if (bo->tiling == I915_TILING_Y)
|
||||
return false;
|
||||
|
||||
assert(kgem_bo_can_map__cpu(kgem, bo, false));
|
||||
assert(bo->tiling != I915_TILING_Y);
|
||||
|
||||
src = kgem_bo_map__cpu(kgem, bo);
|
||||
if (src == NULL)
|
||||
|
|
@ -281,6 +283,9 @@ fallback:
|
|||
if (box[n].y2 > extents.y2)
|
||||
extents.y2 = box[n].y2;
|
||||
}
|
||||
if (!can_blt && sna->render.max_3d_size == 0)
|
||||
goto fallback;
|
||||
|
||||
if (kgem_bo_can_map(kgem, src_bo)) {
|
||||
/* Is it worth detiling? */
|
||||
if ((extents.y2 - extents.y1 - 1) * src_bo->pitch < 4096)
|
||||
|
|
@ -477,6 +482,7 @@ fallback:
|
|||
goto fallback;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL);
|
||||
|
||||
tmp_nbox = nbox;
|
||||
tmp_box = box;
|
||||
|
|
@ -539,6 +545,7 @@ fallback:
|
|||
break;
|
||||
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL);
|
||||
tmp_box += nbox_this_time;
|
||||
} while (1);
|
||||
} else {
|
||||
|
|
@ -597,6 +604,7 @@ fallback:
|
|||
break;
|
||||
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL);
|
||||
tmp_box += nbox_this_time;
|
||||
} while (1);
|
||||
}
|
||||
|
|
@ -666,8 +674,10 @@ write_boxes_inplace__tiled(struct kgem *kgem,
|
|||
{
|
||||
uint8_t *dst;
|
||||
|
||||
if (bo->tiling == I915_TILING_Y)
|
||||
return false;
|
||||
|
||||
assert(kgem->has_wc_mmap || kgem_bo_can_map__cpu(kgem, bo, true));
|
||||
assert(bo->tiling != I915_TILING_Y);
|
||||
|
||||
if (kgem_bo_can_map__cpu(kgem, bo, true)) {
|
||||
dst = kgem_bo_map__cpu(kgem, bo);
|
||||
|
|
@ -849,6 +859,8 @@ bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
|
|||
if (box[n].y2 > extents.y2)
|
||||
extents.y2 = box[n].y2;
|
||||
}
|
||||
if (!can_blt && sna->render.max_3d_size == 0)
|
||||
goto fallback;
|
||||
|
||||
/* Try to avoid switching rings... */
|
||||
if (!can_blt || kgem->ring == KGEM_RENDER ||
|
||||
|
|
@ -1038,6 +1050,7 @@ tile:
|
|||
goto fallback;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
|
||||
|
||||
if (kgem->gen >= 0100) {
|
||||
cmd |= 8;
|
||||
|
|
@ -1129,6 +1142,7 @@ tile:
|
|||
if (nbox) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
|
||||
}
|
||||
|
||||
kgem_bo_destroy(kgem, src_bo);
|
||||
|
|
@ -1224,6 +1238,7 @@ tile:
|
|||
if (nbox) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
|
||||
}
|
||||
|
||||
kgem_bo_destroy(kgem, src_bo);
|
||||
|
|
@ -1541,6 +1556,7 @@ tile:
|
|||
goto fallback;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
|
||||
|
||||
if (sna->kgem.gen >= 0100) {
|
||||
cmd |= 8;
|
||||
|
|
@ -1636,6 +1652,7 @@ tile:
|
|||
if (nbox) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
|
||||
}
|
||||
|
||||
kgem_bo_destroy(kgem, src_bo);
|
||||
|
|
@ -1732,6 +1749,7 @@ tile:
|
|||
if (nbox) {
|
||||
_kgem_submit(kgem);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
|
||||
}
|
||||
|
||||
kgem_bo_destroy(kgem, src_bo);
|
||||
|
|
|
|||
|
|
@ -56,9 +56,24 @@ to_present_event(uintptr_t data)
|
|||
|
||||
#define MARK_PRESENT(x) ((void *)((uintptr_t)(x) | 2))
|
||||
|
||||
static int pipe_from_crtc(RRCrtcPtr crtc)
|
||||
static inline xf86CrtcPtr unmask_crtc(xf86CrtcPtr crtc)
|
||||
{
|
||||
return crtc ? sna_crtc_to_pipe__safe(crtc->devPrivate) : -1;
|
||||
return (xf86CrtcPtr)((uintptr_t)crtc & ~1);
|
||||
}
|
||||
|
||||
static inline xf86CrtcPtr mark_crtc(xf86CrtcPtr crtc)
|
||||
{
|
||||
return (xf86CrtcPtr)((uintptr_t)crtc | 1);
|
||||
}
|
||||
|
||||
static inline bool has_vblank(xf86CrtcPtr crtc)
|
||||
{
|
||||
return (uintptr_t)crtc & 1;
|
||||
}
|
||||
|
||||
static inline int pipe_from_crtc(RRCrtcPtr crtc)
|
||||
{
|
||||
return crtc ? sna_crtc_pipe(crtc->devPrivate) : -1;
|
||||
}
|
||||
|
||||
static uint32_t pipe_select(int pipe)
|
||||
|
|
@ -98,7 +113,7 @@ static void vblank_complete(struct sna_present_event *info,
|
|||
DBG(("%s: %d events complete\n", __FUNCTION__, info->n_event_id));
|
||||
for (n = 0; n < info->n_event_id; n++) {
|
||||
DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete%s\n", __FUNCTION__,
|
||||
sna_crtc_to_pipe(info->crtc),
|
||||
sna_crtc_pipe(unmask_crtc(info->crtc)),
|
||||
(int)(ust / 1000000), (int)(ust % 1000000),
|
||||
(long long)msc, (long long)info->target_msc,
|
||||
(long long)info->event_id[n],
|
||||
|
|
@ -142,7 +157,7 @@ static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data)
|
|||
VG_CLEAR(vbl);
|
||||
vbl.request.type = DRM_VBLANK_RELATIVE;
|
||||
vbl.request.sequence = 0;
|
||||
if (sna_wait_vblank(info->sna, &vbl, sna_crtc_to_pipe(info->crtc)) == 0) {
|
||||
if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) {
|
||||
ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec);
|
||||
msc = sna_crtc_record_vblank(info->crtc, &vbl);
|
||||
DBG(("%s: event=%lld, target msc=%lld, now %lld\n",
|
||||
|
|
@ -155,7 +170,7 @@ static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data)
|
|||
vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
|
||||
vbl.request.sequence = info->target_msc;
|
||||
vbl.request.signal = (uintptr_t)MARK_PRESENT(info);
|
||||
if (sna_wait_vblank(info->sna, &vbl, sna_crtc_to_pipe(info->crtc)) == 0) {
|
||||
if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) {
|
||||
DBG(("%s: scheduled new vblank event for %lld\n", __FUNCTION__, (long long)info->target_msc));
|
||||
free(timer);
|
||||
return 0;
|
||||
|
|
@ -173,7 +188,7 @@ static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data)
|
|||
DBG(("%s: blocking wait!\n", __FUNCTION__));
|
||||
vbl.request.type = DRM_VBLANK_ABSOLUTE;
|
||||
vbl.request.sequence = info->target_msc;
|
||||
(void)sna_wait_vblank(info->sna, &vbl, sna_crtc_to_pipe(info->crtc));
|
||||
(void)sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc));
|
||||
}
|
||||
} else {
|
||||
const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
|
||||
|
|
@ -241,24 +256,31 @@ static int
|
|||
sna_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
|
||||
{
|
||||
struct sna *sna = to_sna_from_screen(crtc->pScreen);
|
||||
int pipe = pipe_from_crtc(crtc);
|
||||
union drm_wait_vblank vbl;
|
||||
|
||||
DBG(("%s(pipe=%d)\n", __FUNCTION__, pipe));
|
||||
DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc->devPrivate)));
|
||||
if (sna_crtc_has_vblank(crtc->devPrivate)) {
|
||||
DBG(("%s: vblank active, reusing last swap msc/ust\n",
|
||||
__FUNCTION__));
|
||||
goto last;
|
||||
}
|
||||
|
||||
VG_CLEAR(vbl);
|
||||
vbl.request.type = DRM_VBLANK_RELATIVE;
|
||||
vbl.request.sequence = 0;
|
||||
if (sna_wait_vblank(sna, &vbl, pipe) == 0) {
|
||||
if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc->devPrivate)) == 0) {
|
||||
*ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec);
|
||||
*msc = sna_crtc_record_vblank(crtc->devPrivate, &vbl);
|
||||
} else {
|
||||
const struct ust_msc *swap = sna_crtc_last_swap(crtc->devPrivate);
|
||||
const struct ust_msc *swap;
|
||||
last:
|
||||
swap = sna_crtc_last_swap(crtc->devPrivate);
|
||||
*ust = swap_ust(swap);
|
||||
*msc = swap->msc;
|
||||
}
|
||||
|
||||
DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld\n", __FUNCTION__, pipe,
|
||||
DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld\n", __FUNCTION__,
|
||||
sna_crtc_pipe(crtc->devPrivate),
|
||||
(int)(*ust / 1000000), (int)(*ust % 1000000),
|
||||
(long long)*msc));
|
||||
|
||||
|
|
@ -269,10 +291,13 @@ void
|
|||
sna_present_vblank_handler(struct drm_event_vblank *event)
|
||||
{
|
||||
struct sna_present_event *info = to_present_event(event->user_data);
|
||||
xf86CrtcPtr crtc = info->crtc;
|
||||
|
||||
vblank_complete(info,
|
||||
ust64(event->tv_sec, event->tv_usec),
|
||||
sna_crtc_record_event(info->crtc, event));
|
||||
sna_crtc_record_event(unmask_crtc(crtc), event));
|
||||
if (has_vblank(crtc))
|
||||
sna_crtc_clear_vblank(unmask_crtc(crtc));
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -284,14 +309,14 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
|
|||
union drm_wait_vblank vbl;
|
||||
|
||||
DBG(("%s(pipe=%d, event=%lld, msc=%lld)\n",
|
||||
__FUNCTION__, pipe_from_crtc(crtc),
|
||||
__FUNCTION__, sna_crtc_pipe(crtc->devPrivate),
|
||||
(long long)event_id, (long long)msc));
|
||||
|
||||
swap = sna_crtc_last_swap(crtc->devPrivate);
|
||||
assert((int64_t)(msc - swap->msc) >= 0);
|
||||
if ((int64_t)(msc - swap->msc) <= 0) {
|
||||
DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
|
||||
pipe_from_crtc(crtc),
|
||||
sna_crtc_pipe(crtc->devPrivate),
|
||||
swap->tv_sec, swap->tv_usec,
|
||||
(long long)swap->msc, (long long)msc,
|
||||
(long long)event_id));
|
||||
|
|
@ -300,13 +325,14 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
|
|||
}
|
||||
|
||||
list_for_each_entry(tmp, &sna->present.vblank_queue, link) {
|
||||
if (tmp->target_msc == msc && tmp->crtc == crtc->devPrivate) {
|
||||
if (tmp->target_msc == msc &&
|
||||
unmask_crtc(tmp->crtc) == crtc->devPrivate) {
|
||||
uint64_t *events = tmp->event_id;
|
||||
|
||||
if (is_power_of_two(tmp->n_event_id)) {
|
||||
events = malloc(2*sizeof(uint64_t)*tmp->n_event_id);
|
||||
if (events == NULL)
|
||||
goto fail;
|
||||
return BadAlloc;
|
||||
|
||||
memcpy(events,
|
||||
tmp->event_id,
|
||||
|
|
@ -321,11 +347,13 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
|
|||
events[tmp->n_event_id++] = event_id;
|
||||
return Success;
|
||||
}
|
||||
if ((int64_t)(tmp->target_msc - msc) > 0)
|
||||
if ((int64_t)(tmp->target_msc - msc) > 0) {
|
||||
DBG(("%s: previous target_msc=%lld invalid for coalescing\n",
|
||||
__FUNCTION__, (long long)tmp->target_msc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
info = malloc(sizeof(struct sna_present_event) + sizeof(uint64_t));
|
||||
if (info == NULL)
|
||||
return BadAlloc;
|
||||
|
|
@ -342,13 +370,18 @@ fail:
|
|||
vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
|
||||
vbl.request.sequence = msc;
|
||||
vbl.request.signal = (uintptr_t)MARK_PRESENT(info);
|
||||
if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(info->crtc))) {
|
||||
if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(info->crtc))) {
|
||||
DBG(("%s: vblank enqueue failed\n", __FUNCTION__));
|
||||
if (!sna_fake_vblank(info)) {
|
||||
list_del(&info->link);
|
||||
free(info);
|
||||
return BadAlloc;
|
||||
}
|
||||
} else {
|
||||
if (msc - swap->msc == 1) {
|
||||
sna_crtc_set_vblank(info->crtc);
|
||||
info->crtc = mark_crtc(info->crtc);
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
|
|
@ -444,6 +477,24 @@ sna_present_check_flip(RRCrtcPtr crtc,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (flip->pinned) {
|
||||
assert(flip->gpu_bo);
|
||||
if (sna->flags & SNA_LINEAR_FB) {
|
||||
if (flip->gpu_bo->tiling != I915_TILING_NONE) {
|
||||
DBG(("%s: pined bo, tilng=%d needs NONE\n",
|
||||
__FUNCTION__, flip->gpu_bo->tiling));
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (!sna->kgem.can_scanout_y &&
|
||||
flip->gpu_bo->tiling == I915_TILING_Y) {
|
||||
DBG(("%s: pined bo, tilng=%d and can't scanout Y\n",
|
||||
__FUNCTION__, flip->gpu_bo->tiling));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -492,12 +543,14 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
|
|||
swap = *sna_crtc_last_swap(info->crtc);
|
||||
|
||||
DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld (target %lld), event=%lld complete%s\n", __FUNCTION__,
|
||||
info->crtc ? sna_crtc_to_pipe(info->crtc) : -1,
|
||||
info->crtc ? sna_crtc_pipe(info->crtc) : -1,
|
||||
swap.tv_sec, swap.tv_usec, (long long)swap.msc,
|
||||
(long long)info->target_msc,
|
||||
(long long)info->event_id[0],
|
||||
info->target_msc && info->target_msc == swap.msc ? "" : ": MISS"));
|
||||
present_event_notify(info->event_id[0], swap_ust(&swap), swap.msc);
|
||||
if (info->crtc)
|
||||
sna_crtc_clear_vblank(info->crtc);
|
||||
|
||||
if (info->sna->present.unflip) {
|
||||
DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, (long long)info->sna->present.unflip));
|
||||
|
|
@ -540,6 +593,8 @@ flip(struct sna *sna,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (info->crtc)
|
||||
sna_crtc_set_vblank(info->crtc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -560,7 +615,7 @@ get_flip_bo(PixmapPtr pixmap)
|
|||
if (priv->gpu_bo->scanout)
|
||||
return priv->gpu_bo;
|
||||
|
||||
if (sna->kgem.has_llc && !wedged(sna)) {
|
||||
if (sna->kgem.has_llc && !wedged(sna) && !priv->pinned) {
|
||||
struct kgem_bo *bo;
|
||||
uint32_t tiling;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ sna_format_for_depth(int depth)
|
|||
{
|
||||
switch (depth) {
|
||||
case 1: return PICT_a1;
|
||||
case 4: return PICT_a4;
|
||||
case 4: return PICT_x4a4;
|
||||
case 8: return PICT_a8;
|
||||
case 15: return PICT_x1r5g5b5;
|
||||
case 16: return PICT_r5g6b5;
|
||||
|
|
@ -271,18 +271,6 @@ no_render_context_switch(struct kgem *kgem,
|
|||
(void)new_mode;
|
||||
}
|
||||
|
||||
static void
|
||||
no_render_retire(struct kgem *kgem)
|
||||
{
|
||||
(void)kgem;
|
||||
}
|
||||
|
||||
static void
|
||||
no_render_expire(struct kgem *kgem)
|
||||
{
|
||||
(void)kgem;
|
||||
}
|
||||
|
||||
static void
|
||||
no_render_fini(struct sna *sna)
|
||||
{
|
||||
|
|
@ -316,8 +304,6 @@ const char *no_render_init(struct sna *sna)
|
|||
render->fini = no_render_fini;
|
||||
|
||||
sna->kgem.context_switch = no_render_context_switch;
|
||||
sna->kgem.retire = no_render_retire;
|
||||
sna->kgem.expire = no_render_expire;
|
||||
if (sna->kgem.has_blt)
|
||||
sna->kgem.ring = KGEM_BLT;
|
||||
|
||||
|
|
|
|||
|
|
@ -238,8 +238,9 @@ struct sna_render {
|
|||
int16_t w, int16_t h,
|
||||
unsigned flags,
|
||||
struct sna_composite_op *tmp);
|
||||
#define COMPOSITE_PARTIAL 0x1
|
||||
#define COMPOSITE_FALLBACK 0x80000000
|
||||
#define COMPOSITE_PARTIAL 0x1
|
||||
#define COMPOSITE_UPLOAD 0x40000000
|
||||
#define COMPOSITE_FALLBACK 0x80000000
|
||||
|
||||
bool (*check_composite_spans)(struct sna *sna, uint8_t op,
|
||||
PicturePtr dst, PicturePtr src,
|
||||
|
|
@ -540,7 +541,7 @@ enum {
|
|||
|
||||
struct gen8_render_state {
|
||||
unsigned gt;
|
||||
|
||||
const struct gt_info *info;
|
||||
struct kgem_bo *general_bo;
|
||||
|
||||
uint32_t vs_state;
|
||||
|
|
|
|||
|
|
@ -592,6 +592,8 @@ lerp32_opacity(PixmapPtr scratch,
|
|||
uint32_t *ptr;
|
||||
int stride, i;
|
||||
|
||||
sigtrap_assert_active();
|
||||
|
||||
ptr = (uint32_t*)((uint8_t *)scratch->devPrivate.ptr + scratch->devKind * y);
|
||||
ptr += x;
|
||||
stride = scratch->devKind / 4;
|
||||
|
|
|
|||
|
|
@ -1707,8 +1707,7 @@ static void span_thread_add_box(struct sna *sna, void *data,
|
|||
{
|
||||
struct span_thread_boxes *b = data;
|
||||
|
||||
__DBG(("%s: adding %d boxes with alpha=%f\n",
|
||||
__FUNCTION__, count, alpha));
|
||||
__DBG(("%s: adding box with alpha=%f\n", __FUNCTION__, alpha));
|
||||
|
||||
if (unlikely(b->num_boxes == SPAN_THREAD_MAX_BOXES)) {
|
||||
DBG(("%s: flushing %d boxes\n", __FUNCTION__, b->num_boxes));
|
||||
|
|
@ -2370,6 +2369,7 @@ tor_blt_lerp32(struct sna *sna,
|
|||
if (coverage == 0)
|
||||
return;
|
||||
|
||||
sigtrap_assert_active();
|
||||
ptr += box->y1 * stride + box->x1;
|
||||
|
||||
h = box->y2 - box->y1;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ struct mono {
|
|||
struct mono_polygon polygon;
|
||||
};
|
||||
|
||||
#define I(x) pixman_fixed_to_int ((x) + pixman_fixed_1_minus_e/2)
|
||||
#define I(x) pixman_fixed_to_int((x) + pixman_fixed_1_minus_e/2)
|
||||
|
||||
static struct quorem
|
||||
floored_muldivrem(int32_t x, int32_t a, int32_t b)
|
||||
|
|
@ -250,22 +250,22 @@ mono_add_line(struct mono *mono,
|
|||
|
||||
e->dxdy = floored_muldivrem(dx, pixman_fixed_1, dy);
|
||||
|
||||
e->x = floored_muldivrem((ytop - dst_y) * pixman_fixed_1 + pixman_fixed_1_minus_e/2 - p1->y,
|
||||
e->x = floored_muldivrem((ytop - dst_y) * pixman_fixed_1 + pixman_fixed_1/2 - p1->y,
|
||||
dx, dy);
|
||||
e->x.quo += p1->x;
|
||||
e->x.rem -= dy;
|
||||
|
||||
e->dy = dy;
|
||||
|
||||
__DBG(("%s: initial x=%d [%d.%d/%d] + dxdy=%d.%d/%d\n",
|
||||
__FUNCTION__,
|
||||
I(e->x.quo), e->x.quo, e->x.rem, e->dy,
|
||||
e->dxdy.quo, e->dxdy.rem, e->dy));
|
||||
}
|
||||
e->x.quo += dst_x*pixman_fixed_1;
|
||||
__DBG(("%s: initial x=%d [%d.%d/%d] + dxdy=%d.%d/%d\n",
|
||||
__FUNCTION__,
|
||||
I(e->x.quo), e->x.quo, e->x.rem, e->dy,
|
||||
e->dxdy.quo, e->dxdy.rem, e->dy));
|
||||
|
||||
{
|
||||
struct mono_edge **ptail = &polygon->y_buckets[ytop - mono->clip.extents.y1];
|
||||
assert(ytop - mono->clip.extents.y1 < mono->clip.extents.y2 - mono->clip.extents.y1);
|
||||
if (*ptail)
|
||||
(*ptail)->prev = e;
|
||||
e->next = *ptail;
|
||||
|
|
@ -369,6 +369,10 @@ static struct mono_edge *mono_filter(struct mono_edge *edges)
|
|||
e->x.rem == n->x.rem &&
|
||||
e->dxdy.quo == n->dxdy.quo &&
|
||||
e->dxdy.rem == n->dxdy.rem) {
|
||||
assert(e->dy == n->dy);
|
||||
__DBG(("%s: discarding cancellation pair (%d.%d) + (%d.%d)\n",
|
||||
__FUNCTION__, e->x.quo, e->x.rem, e->dxdy.quo, e->dxdy.rem));
|
||||
|
||||
if (e->prev)
|
||||
e->prev->next = n->next;
|
||||
else
|
||||
|
|
@ -379,8 +383,11 @@ static struct mono_edge *mono_filter(struct mono_edge *edges)
|
|||
break;
|
||||
|
||||
e = n->next;
|
||||
} else
|
||||
} else {
|
||||
__DBG(("%s: adding edge (%d.%d) + (%d.%d)/%d, height=%d\n",
|
||||
__FUNCTION__, n->x.quo, n->x.rem, n->dxdy.quo, n->dxdy.rem, n->dy, n->height_left));
|
||||
e = n;
|
||||
}
|
||||
}
|
||||
|
||||
return edges;
|
||||
|
|
@ -571,6 +578,8 @@ mono_row(struct mono *c, int16_t y, int16_t h)
|
|||
int winding = 0;
|
||||
BoxRec box;
|
||||
|
||||
__DBG(("%s: y=%d, h=%d\n", __FUNCTION__, y, h));
|
||||
|
||||
DBG_MONO_EDGES(edge);
|
||||
VALIDATE_MONO_EDGES(&c->head);
|
||||
|
||||
|
|
@ -581,6 +590,8 @@ mono_row(struct mono *c, int16_t y, int16_t h)
|
|||
struct mono_edge *next = edge->next;
|
||||
int16_t xend = I(edge->x.quo);
|
||||
|
||||
__DBG(("%s: adding edge dir=%d [winding=%d], x=%d [%d]\n",
|
||||
__FUNCTION__, edge->dir, winding + edge->dir, xend, edge->x.quo));
|
||||
if (--edge->height_left) {
|
||||
if (edge->dy) {
|
||||
edge->x.quo += edge->dxdy.quo;
|
||||
|
|
@ -589,6 +600,8 @@ mono_row(struct mono *c, int16_t y, int16_t h)
|
|||
++edge->x.quo;
|
||||
edge->x.rem -= edge->dy;
|
||||
}
|
||||
__DBG(("%s: stepped edge (%d.%d) + (%d.%d)/%d, height=%d, prev_x=%d\n",
|
||||
__FUNCTION__, edge->x.quo, edge->x.rem, edge->dxdy.quo, edge->dxdy.rem, edge->dy, edge->height_left, edge->x.quo));
|
||||
}
|
||||
|
||||
if (edge->x.quo < prev_x) {
|
||||
|
|
@ -612,17 +625,22 @@ mono_row(struct mono *c, int16_t y, int16_t h)
|
|||
winding += edge->dir;
|
||||
if (winding == 0) {
|
||||
assert(I(next->x.quo) >= xend);
|
||||
if (I(next->x.quo) > xend + 1) {
|
||||
if (I(next->x.quo) > xend) {
|
||||
__DBG(("%s: end span: %d\n", __FUNCTION__, xend));
|
||||
if (xstart < c->clip.extents.x1)
|
||||
xstart = c->clip.extents.x1;
|
||||
if (xend > c->clip.extents.x2)
|
||||
xend = c->clip.extents.x2;
|
||||
if (xend > xstart)
|
||||
if (xend > xstart) {
|
||||
__DBG(("%s: emit span [%d, %d]\n", __FUNCTION__, xstart, xend));
|
||||
c->span(c, xstart, xend, &box);
|
||||
}
|
||||
xstart = INT16_MIN;
|
||||
}
|
||||
} else if (xstart == INT16_MIN)
|
||||
} else if (xstart == INT16_MIN) {
|
||||
__DBG(("%s: starting new span: %d\n", __FUNCTION__, xend));
|
||||
xstart = xend;
|
||||
}
|
||||
|
||||
edge = next;
|
||||
}
|
||||
|
|
@ -684,9 +702,14 @@ mono_render(struct mono *mono)
|
|||
for (i = 0; i < h; i = j) {
|
||||
j = i + 1;
|
||||
|
||||
__DBG(("%s: row=%d, new edges? %d\n", __FUNCTION__,
|
||||
i, polygon->y_buckets[i] != NULL));
|
||||
|
||||
if (polygon->y_buckets[i])
|
||||
mono_merge_edges(mono, polygon->y_buckets[i]);
|
||||
|
||||
__DBG(("%s: row=%d, vertical? %d\n", __FUNCTION__,
|
||||
i, mono->is_vertical));
|
||||
if (mono->is_vertical) {
|
||||
struct mono_edge *e = mono->head.next;
|
||||
int min_height = h - i;
|
||||
|
|
@ -701,6 +724,7 @@ mono_render(struct mono *mono)
|
|||
j++;
|
||||
if (j != i + 1)
|
||||
mono_step_edges(mono, j - (i + 1));
|
||||
__DBG(("%s: %d vertical rows\n", __FUNCTION__, j-i));
|
||||
}
|
||||
|
||||
mono_row(mono, i, j-i);
|
||||
|
|
@ -1013,6 +1037,7 @@ mono_inplace_fill_box(struct sna *sna,
|
|||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
fill->color));
|
||||
sigtrap_assert_active();
|
||||
pixman_fill(fill->data, fill->stride, fill->bpp,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
|
|
@ -1034,6 +1059,7 @@ mono_inplace_fill_boxes(struct sna *sna,
|
|||
box->x2 - box->x1,
|
||||
box->y2 - box->y1,
|
||||
fill->color));
|
||||
sigtrap_assert_active();
|
||||
pixman_fill(fill->data, fill->stride, fill->bpp,
|
||||
box->x1, box->y1,
|
||||
box->x2 - box->x1,
|
||||
|
|
@ -1421,10 +1447,13 @@ mono_triangles_span_converter(struct sna *sna,
|
|||
mono_render(&mono);
|
||||
mono.op.done(mono.sna, &mono.op);
|
||||
}
|
||||
mono_fini(&mono);
|
||||
|
||||
if (!was_clear && !operator_is_bounded(op)) {
|
||||
xPointFixed p1, p2;
|
||||
|
||||
DBG(("%s: performing unbounded clear\n", __FUNCTION__));
|
||||
|
||||
if (!mono_init(&mono, 2+3*count))
|
||||
return false;
|
||||
|
||||
|
|
@ -1470,7 +1499,6 @@ mono_triangles_span_converter(struct sna *sna,
|
|||
mono_fini(&mono);
|
||||
}
|
||||
|
||||
mono_fini(&mono);
|
||||
REGION_UNINIT(NULL, &mono.clip);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1655,8 +1655,7 @@ static void span_thread_add_box(struct sna *sna, void *data,
|
|||
{
|
||||
struct span_thread_boxes *b = data;
|
||||
|
||||
__DBG(("%s: adding %d boxes with alpha=%f\n",
|
||||
__FUNCTION__, count, alpha));
|
||||
__DBG(("%s: adding box with alpha=%f\n", __FUNCTION__, alpha));
|
||||
|
||||
if (unlikely(b->num_boxes == SPAN_THREAD_MAX_BOXES)) {
|
||||
DBG(("%s: flushing %d boxes\n", __FUNCTION__, b->num_boxes));
|
||||
|
|
@ -2386,6 +2385,7 @@ tor_blt_lerp32(struct sna *sna,
|
|||
if (coverage == 0)
|
||||
return;
|
||||
|
||||
sigtrap_assert_active();
|
||||
ptr += box->y1 * stride + box->x1;
|
||||
|
||||
h = box->y2 - box->y1;
|
||||
|
|
|
|||
|
|
@ -81,14 +81,11 @@ static int sna_video_sprite_stop(ddStopVideo_ARGS)
|
|||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(video->sna->scrn);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < config->num_crtc; i++) {
|
||||
for (i = 0; i < video->sna->mode.num_real_crtc; i++) {
|
||||
xf86CrtcPtr crtc = config->crtc[i];
|
||||
int pipe;
|
||||
|
||||
if (sna_crtc_id(crtc) == 0)
|
||||
break;
|
||||
|
||||
pipe = sna_crtc_to_pipe(crtc);
|
||||
pipe = sna_crtc_pipe(crtc);
|
||||
if (video->bo[pipe] == NULL)
|
||||
continue;
|
||||
|
||||
|
|
@ -221,7 +218,7 @@ sna_video_sprite_show(struct sna *sna,
|
|||
BoxPtr dstBox)
|
||||
{
|
||||
struct local_mode_set_plane s;
|
||||
int pipe = sna_crtc_to_pipe(crtc);
|
||||
int pipe = sna_crtc_pipe(crtc);
|
||||
|
||||
/* XXX handle video spanning multiple CRTC */
|
||||
|
||||
|
|
@ -402,7 +399,7 @@ static int sna_video_sprite_put_image(ddPutImage_ARGS)
|
|||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < config->num_crtc; i++) {
|
||||
for (i = 0; i < video->sna->mode.num_real_crtc; i++) {
|
||||
xf86CrtcPtr crtc = config->crtc[i];
|
||||
struct sna_video_frame frame;
|
||||
int pipe;
|
||||
|
|
@ -411,10 +408,7 @@ static int sna_video_sprite_put_image(ddPutImage_ARGS)
|
|||
RegionRec reg;
|
||||
Rotation rotation;
|
||||
|
||||
if (sna_crtc_id(crtc) == 0)
|
||||
break;
|
||||
|
||||
pipe = sna_crtc_to_pipe(crtc);
|
||||
pipe = sna_crtc_pipe(crtc);
|
||||
|
||||
sna_video_frame_init(video, format->id, width, height, &frame);
|
||||
|
||||
|
|
@ -611,7 +605,7 @@ static bool sna_video_has_sprites(struct sna *sna)
|
|||
|
||||
for (i = 0; i < sna->mode.num_real_crtc; i++) {
|
||||
if (!sna_crtc_to_sprite(config->crtc[i])) {
|
||||
DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_to_pipe(config->crtc[i])));
|
||||
DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i])));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,8 +94,6 @@ struct intel_mode {
|
|||
intel_pageflip_abort_proc abort;
|
||||
void *data;
|
||||
} pageflip;
|
||||
|
||||
Bool delete_dp_12_displays;
|
||||
};
|
||||
|
||||
struct intel_pageflip {
|
||||
|
|
@ -2248,10 +2246,6 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
|
|||
intel->use_pageflipping = TRUE;
|
||||
}
|
||||
|
||||
if (xf86ReturnOptValBool(intel->Options, OPTION_DELETE_DP12, FALSE)) {
|
||||
mode->delete_dp_12_displays = TRUE;
|
||||
}
|
||||
|
||||
intel->modes = mode;
|
||||
drmModeFreeResources(mode_res);
|
||||
return TRUE;
|
||||
|
|
@ -2515,12 +2509,11 @@ intel_mode_hotplug(struct intel_screen_private *intel)
|
|||
int i, j;
|
||||
Bool found;
|
||||
Bool changed = FALSE;
|
||||
struct intel_mode *mode = intel->modes;
|
||||
|
||||
mode_res = drmModeGetResources(intel->drmSubFD);
|
||||
if (!mode_res)
|
||||
goto out;
|
||||
|
||||
restart_destroy:
|
||||
for (i = 0; i < config->num_output; i++) {
|
||||
xf86OutputPtr output = config->output[i];
|
||||
struct intel_output *intel_output;
|
||||
|
|
@ -2542,11 +2535,6 @@ restart_destroy:
|
|||
RROutputChanged(output->randr_output, TRUE);
|
||||
|
||||
changed = TRUE;
|
||||
if (mode->delete_dp_12_displays) {
|
||||
RROutputDestroy(output->randr_output);
|
||||
xf86OutputDestroy(output);
|
||||
goto restart_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
/* find new output ids we don't have outputs for */
|
||||
|
|
|
|||
|
|
@ -766,7 +766,7 @@ I830HandleUEvents(int fd, void *closure)
|
|||
udev_device_unref(dev);
|
||||
}
|
||||
|
||||
static bool has_randr(void)
|
||||
static int has_randr(void)
|
||||
{
|
||||
#if HAS_DIXREGISTERPRIVATEKEY
|
||||
return dixPrivateKeyRegistered(rrPrivKey);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ cursor-test
|
|||
render-fill
|
||||
render-trapezoid
|
||||
render-trapezoid-image
|
||||
render-triangle
|
||||
render-fill-copy
|
||||
render-composite-solid
|
||||
render-composite-solid-mask
|
||||
|
|
@ -18,6 +19,7 @@ render-copyarea
|
|||
render-copyarea-mask
|
||||
render-copyarea-size
|
||||
render-copy-alphaless
|
||||
render-glyphs
|
||||
mixed-stress
|
||||
lowlevel-blt-bench
|
||||
vsync.avi
|
||||
|
|
|
|||
|
|
@ -12,8 +12,10 @@ stress_TESTS = \
|
|||
DrawSegments \
|
||||
cursor-test \
|
||||
render-fill \
|
||||
render-glyphs \
|
||||
render-trapezoid \
|
||||
render-trapezoid-image \
|
||||
render-triangle \
|
||||
render-fill-copy \
|
||||
render-composite-solid \
|
||||
render-composite-solid-mask \
|
||||
|
|
|
|||
34
test/dri3.c
34
test/dri3.c
|
|
@ -29,6 +29,7 @@
|
|||
#include <xcb/dri3.h>
|
||||
#include <xcb/sync.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dri3.h"
|
||||
|
||||
|
|
@ -109,12 +110,45 @@ void dri3_fence_free(Display *dpy, struct dri3_fence *fence)
|
|||
xcb_sync_destroy_fence(c, fence->xid);
|
||||
}
|
||||
|
||||
static void dri3_query_version(xcb_connection_t *c, int *major, int *minor)
|
||||
{
|
||||
xcb_dri3_query_version_reply_t *reply;
|
||||
|
||||
reply = xcb_dri3_query_version_reply(c,
|
||||
xcb_dri3_query_version(c,
|
||||
XCB_DRI3_MAJOR_VERSION,
|
||||
XCB_DRI3_MINOR_VERSION),
|
||||
NULL);
|
||||
if (reply != NULL) {
|
||||
*major = reply->major_version;
|
||||
*minor = reply->minor_version;
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
|
||||
static int dri3_exists(xcb_connection_t *c)
|
||||
{
|
||||
const xcb_query_extension_reply_t *ext;
|
||||
int major, minor;
|
||||
|
||||
major = minor = -1;
|
||||
|
||||
ext = xcb_get_extension_data(c, &xcb_dri3_id);
|
||||
if (ext != NULL && ext->present)
|
||||
dri3_query_version(c, &major, &minor);
|
||||
|
||||
return major >= 0;
|
||||
}
|
||||
|
||||
int dri3_open__full(Display *dpy, Window root, unsigned provider)
|
||||
{
|
||||
xcb_connection_t *c = XGetXCBConnection(dpy);
|
||||
xcb_dri3_open_cookie_t cookie;
|
||||
xcb_dri3_open_reply_t *reply;
|
||||
|
||||
if (!dri3_exists(c))
|
||||
return -1;
|
||||
|
||||
cookie = xcb_dri3_open(c, root, provider);
|
||||
reply = xcb_dri3_open_reply(c, cookie, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -249,7 +249,6 @@ static void run(Display *dpy, Window win, const char *name, unsigned options)
|
|||
free(ev);
|
||||
} while ((ev = (xcb_present_generic_event_t *)xcb_poll_for_special_event(c, Q)));
|
||||
}
|
||||
assert(p);
|
||||
|
||||
b->busy = (options & NOCOPY) == 0;
|
||||
if (b->fence.xid) {
|
||||
|
|
|
|||
|
|
@ -1564,6 +1564,7 @@ static int test_dri3_tiling(Display *dpy)
|
|||
unsigned int width, height;
|
||||
unsigned border, depth, bpp;
|
||||
unsigned stride, size;
|
||||
void *Q;
|
||||
int x, y;
|
||||
int device;
|
||||
int line = -1;
|
||||
|
|
@ -1594,8 +1595,10 @@ static int test_dri3_tiling(Display *dpy)
|
|||
width, height, stride, size);
|
||||
|
||||
_x_error_occurred = 0;
|
||||
Q = setup_msc(dpy, root);
|
||||
|
||||
for (t = 0; t < sizeof(tiling)/sizeof(tiling[0]); t++) {
|
||||
uint64_t msc;
|
||||
uint32_t src;
|
||||
int src_fd;
|
||||
Pixmap src_pix;
|
||||
|
|
@ -1618,6 +1621,8 @@ static int test_dri3_tiling(Display *dpy)
|
|||
width, height, depth,
|
||||
src_fd, bpp, stride, size);
|
||||
|
||||
msc = wait_vblank(dpy, root, Q);
|
||||
|
||||
xcb_present_pixmap(XGetXCBConnection(dpy),
|
||||
win, src_pix,
|
||||
0, /* sbc */
|
||||
|
|
@ -1629,10 +1634,27 @@ static int test_dri3_tiling(Display *dpy)
|
|||
None, /* wait fence */
|
||||
None,
|
||||
XCB_PRESENT_OPTION_NONE,
|
||||
0, /* target msc */
|
||||
0, /* divisor */
|
||||
msc + 2, /* target msc */
|
||||
1, /* divisor */
|
||||
0, /* remainder */
|
||||
0, NULL);
|
||||
|
||||
xcb_present_pixmap(XGetXCBConnection(dpy),
|
||||
win, src_pix,
|
||||
0, /* sbc */
|
||||
0, /* valid */
|
||||
0, /* update */
|
||||
0, /* x_off */
|
||||
0, /* y_off */
|
||||
None,
|
||||
None, /* wait fence */
|
||||
None,
|
||||
XCB_PRESENT_OPTION_NONE,
|
||||
msc + 3, /* target msc */
|
||||
1, /* divisor */
|
||||
0, /* remainder */
|
||||
0, NULL);
|
||||
|
||||
XSync(dpy, True);
|
||||
if (_x_error_occurred) {
|
||||
line = __LINE__;
|
||||
|
|
@ -1645,10 +1667,12 @@ static int test_dri3_tiling(Display *dpy)
|
|||
gem_close(device, src);
|
||||
}
|
||||
|
||||
teardown_msc(dpy, Q);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
printf("%s failed with tiling %d, line %d\n", __func__, tiling[t], line);
|
||||
teardown_msc(dpy, Q);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,441 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/Xutil.h> /* for XDestroyImage */
|
||||
#include <pixman.h> /* for pixman blt functions */
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static const XRenderColor colors[] = {
|
||||
/* red, green, blue, alpha */
|
||||
{ 0 },
|
||||
{ 0, 0, 0, 0xffff },
|
||||
{ 0xffff, 0, 0, 0xffff },
|
||||
{ 0, 0xffff, 0, 0xffff },
|
||||
{ 0, 0, 0xffff, 0xffff },
|
||||
{ 0xffff, 0xffff, 0xffff, 0xffff },
|
||||
};
|
||||
|
||||
static struct clip {
|
||||
void *func;
|
||||
} clips[] = {
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static int _x_error_occurred;
|
||||
|
||||
static int
|
||||
_check_error_handler(Display *display,
|
||||
XErrorEvent *event)
|
||||
{
|
||||
_x_error_occurred = 1;
|
||||
return False; /* ignored */
|
||||
}
|
||||
|
||||
static void clear(struct test_display *dpy,
|
||||
struct test_target *tt,
|
||||
const XRenderColor *c)
|
||||
{
|
||||
XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, c,
|
||||
0, 0, tt->width, tt->height);
|
||||
}
|
||||
|
||||
static bool check_op(struct test_display *dpy, int op, struct test_target *tt)
|
||||
{
|
||||
XRenderColor render_color = {0};
|
||||
|
||||
XSync(dpy->dpy, True);
|
||||
_x_error_occurred = 0;
|
||||
|
||||
XRenderFillRectangle(dpy->dpy, op,
|
||||
tt->picture, &render_color,
|
||||
0, 0, 0, 0);
|
||||
|
||||
XSync(dpy->dpy, True);
|
||||
return _x_error_occurred == 0;
|
||||
}
|
||||
|
||||
struct glyph_iter {
|
||||
enum {
|
||||
GLYPHS, OP, DST, SRC, MASK, CLIP,
|
||||
} stage;
|
||||
|
||||
int glyph_format;
|
||||
int op;
|
||||
int dst_color;
|
||||
int src_color;
|
||||
int mask_format;
|
||||
int clip;
|
||||
|
||||
struct {
|
||||
struct test_display *dpy;
|
||||
struct test_target tt;
|
||||
GlyphSet glyphset;
|
||||
Picture src;
|
||||
XRenderPictFormat *mask_format;
|
||||
} ref, out;
|
||||
};
|
||||
|
||||
static void glyph_iter_init(struct glyph_iter *gi,
|
||||
struct test *t, enum target target)
|
||||
{
|
||||
memset(gi, 0, sizeof(*gi));
|
||||
|
||||
gi->out.dpy = &t->out;
|
||||
test_target_create_render(&t->out, target, &gi->out.tt);
|
||||
|
||||
gi->ref.dpy = &t->ref;
|
||||
test_target_create_render(&t->ref, target, &gi->ref.tt);
|
||||
|
||||
gi->stage = GLYPHS;
|
||||
gi->glyph_format = -1;
|
||||
gi->op = -1;
|
||||
gi->dst_color = -1;
|
||||
gi->src_color = -1;
|
||||
gi->mask_format = -1;
|
||||
gi->clip = -1;
|
||||
}
|
||||
|
||||
static void render_clear(char *image, int image_size, int bpp)
|
||||
{
|
||||
memset(image, 0, image_size);
|
||||
}
|
||||
|
||||
static void render_black(char *image, int image_size, int bpp)
|
||||
{
|
||||
if (bpp == 4) {
|
||||
uint32_t *p = (uint32_t *)image;
|
||||
image_size /= 4;
|
||||
while (image_size--)
|
||||
*p++ = 0x000000ff;
|
||||
} else
|
||||
memset(image, 0x55, image_size);
|
||||
}
|
||||
|
||||
static void render_green(char *image, int image_size, int bpp)
|
||||
{
|
||||
if (bpp == 4) {
|
||||
uint32_t *p = (uint32_t *)image;
|
||||
image_size /= 4;
|
||||
while (image_size--)
|
||||
*p++ = 0xffff0000;
|
||||
} else
|
||||
memset(image, 0xaa, image_size);
|
||||
}
|
||||
|
||||
static void render_white(char *image, int image_size, int bpp)
|
||||
{
|
||||
memset(image, 0xff, image_size);
|
||||
}
|
||||
|
||||
static GlyphSet create_glyphs(Display *dpy, int format_id)
|
||||
{
|
||||
#define N_GLYPHS 4
|
||||
XRenderPictFormat *format;
|
||||
XGlyphInfo glyph = { 8, 8, 0, 0, 8, 0 };
|
||||
char image[4*8*8];
|
||||
GlyphSet glyphset;
|
||||
Glyph gid;
|
||||
int image_size;
|
||||
int bpp;
|
||||
int n;
|
||||
|
||||
format = XRenderFindStandardFormat(dpy, format_id);
|
||||
if (format == NULL)
|
||||
return 0;
|
||||
|
||||
switch (format_id) {
|
||||
case PictStandardARGB32:
|
||||
case PictStandardRGB24:
|
||||
image_size = 4 * 8 * 8;
|
||||
bpp = 4;
|
||||
break;
|
||||
case PictStandardA8:
|
||||
case PictStandardA4:
|
||||
image_size = 8 * 8;
|
||||
bpp = 1;
|
||||
break;
|
||||
case PictStandardA1:
|
||||
image_size = 8;
|
||||
bpp = 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphset = XRenderCreateGlyphSet(dpy, format);
|
||||
for (n = 0; n < N_GLYPHS; n++) {
|
||||
gid = n;
|
||||
|
||||
switch (n) {
|
||||
case 0: render_clear(image, image_size, bpp); break;
|
||||
case 1: render_black(image, image_size, bpp); break;
|
||||
case 2: render_green(image, image_size, bpp); break;
|
||||
case 3: render_white(image, image_size, bpp); break;
|
||||
}
|
||||
|
||||
XRenderAddGlyphs(dpy, glyphset,
|
||||
&gid, &glyph, 1, image, image_size);
|
||||
}
|
||||
|
||||
return glyphset;
|
||||
}
|
||||
|
||||
static const char *glyph_name(int n)
|
||||
{
|
||||
switch (n) {
|
||||
case 0: return "clear";
|
||||
case 1: return "black";
|
||||
case 2: return "green";
|
||||
case 3: return "white";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static bool glyph_iter_next(struct glyph_iter *gi)
|
||||
{
|
||||
restart:
|
||||
if (gi->stage == GLYPHS) {
|
||||
if (++gi->glyph_format == PictStandardNUM)
|
||||
return false;
|
||||
|
||||
if (gi->out.glyphset)
|
||||
XRenderFreeGlyphSet(gi->out.dpy->dpy,
|
||||
gi->out.glyphset);
|
||||
gi->out.glyphset = create_glyphs(gi->out.dpy->dpy,
|
||||
gi->glyph_format);
|
||||
|
||||
if (gi->ref.glyphset)
|
||||
XRenderFreeGlyphSet(gi->ref.dpy->dpy,
|
||||
gi->ref.glyphset);
|
||||
gi->ref.glyphset = create_glyphs(gi->ref.dpy->dpy,
|
||||
gi->glyph_format);
|
||||
|
||||
gi->stage++;
|
||||
}
|
||||
|
||||
if (gi->stage == OP) {
|
||||
do {
|
||||
if (++gi->op == 255)
|
||||
goto reset_op;
|
||||
} while (!check_op(gi->out.dpy, gi->op, &gi->out.tt) ||
|
||||
!check_op(gi->ref.dpy, gi->op, &gi->ref.tt));
|
||||
|
||||
gi->stage++;
|
||||
}
|
||||
|
||||
if (gi->stage == DST) {
|
||||
if (++gi->dst_color == ARRAY_SIZE(colors))
|
||||
goto reset_dst;
|
||||
|
||||
gi->stage++;
|
||||
}
|
||||
|
||||
if (gi->stage == SRC) {
|
||||
if (++gi->src_color == ARRAY_SIZE(colors))
|
||||
goto reset_src;
|
||||
|
||||
if (gi->ref.src)
|
||||
XRenderFreePicture(gi->ref.dpy->dpy, gi->ref.src);
|
||||
gi->ref.src = XRenderCreateSolidFill(gi->ref.dpy->dpy,
|
||||
&colors[gi->src_color]);
|
||||
|
||||
if (gi->out.src)
|
||||
XRenderFreePicture(gi->out.dpy->dpy, gi->out.src);
|
||||
gi->out.src = XRenderCreateSolidFill(gi->out.dpy->dpy,
|
||||
&colors[gi->src_color]);
|
||||
|
||||
gi->stage++;
|
||||
}
|
||||
|
||||
if (gi->stage == MASK) {
|
||||
if (++gi->mask_format > PictStandardNUM)
|
||||
goto reset_mask;
|
||||
|
||||
if (gi->mask_format == PictStandardRGB24)
|
||||
gi->mask_format++;
|
||||
|
||||
if (gi->mask_format < PictStandardNUM) {
|
||||
gi->out.mask_format = XRenderFindStandardFormat(gi->out.dpy->dpy,
|
||||
gi->mask_format);
|
||||
gi->ref.mask_format = XRenderFindStandardFormat(gi->ref.dpy->dpy,
|
||||
gi->mask_format);
|
||||
} else {
|
||||
gi->out.mask_format = NULL;
|
||||
gi->ref.mask_format = NULL;
|
||||
}
|
||||
|
||||
gi->stage++;
|
||||
}
|
||||
|
||||
if (gi->stage == CLIP) {
|
||||
if (++gi->clip == ARRAY_SIZE(clips))
|
||||
goto reset_clip;
|
||||
|
||||
gi->stage++;
|
||||
}
|
||||
|
||||
gi->stage--;
|
||||
return true;
|
||||
|
||||
reset_op:
|
||||
gi->op = -1;
|
||||
reset_dst:
|
||||
gi->dst_color = -1;
|
||||
reset_src:
|
||||
gi->src_color = -1;
|
||||
reset_mask:
|
||||
gi->mask_format = -1;
|
||||
reset_clip:
|
||||
gi->clip = -1;
|
||||
gi->stage--;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
static void glyph_iter_fini(struct glyph_iter *gi)
|
||||
{
|
||||
if (gi->out.glyphset)
|
||||
XRenderFreeGlyphSet (gi->out.dpy->dpy, gi->out.glyphset);
|
||||
if (gi->ref.glyphset)
|
||||
XRenderFreeGlyphSet (gi->ref.dpy->dpy, gi->ref.glyphset);
|
||||
|
||||
test_target_destroy_render(gi->out.dpy, &gi->out.tt);
|
||||
test_target_destroy_render(gi->ref.dpy, &gi->ref.tt);
|
||||
}
|
||||
|
||||
static const char *stdformat_to_str(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case PictStandardARGB32: return "ARGB32";
|
||||
case PictStandardRGB24: return "RGB24";
|
||||
case PictStandardA8: return "A8";
|
||||
case PictStandardA4: return "A4";
|
||||
case PictStandardA1: return "A1";
|
||||
default: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
static char *glyph_iter_to_string(struct glyph_iter *gi,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
static char buf[100];
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
len = sprintf(buf, "glyphs=%s, op=%d, dst=%08x, src=%08x, mask=%s",
|
||||
stdformat_to_str(gi->glyph_format), gi->op,
|
||||
xrender_color(&colors[gi->dst_color]),
|
||||
xrender_color(&colors[gi->src_color]),
|
||||
stdformat_to_str(gi->mask_format));
|
||||
|
||||
if (format) {
|
||||
buf[len++] = ' ';
|
||||
va_start(ap, format);
|
||||
vsprintf(buf+len, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void single(struct test *t, enum target target)
|
||||
{
|
||||
struct glyph_iter gi;
|
||||
int n;
|
||||
|
||||
printf("Testing single glyph (%s): ", test_target_name(target));
|
||||
fflush(stdout);
|
||||
|
||||
glyph_iter_init(&gi, t, target);
|
||||
while (glyph_iter_next(&gi)) {
|
||||
XGlyphElt8 elt;
|
||||
char id[N_GLYPHS];
|
||||
|
||||
for (n = 0; n < N_GLYPHS; n++) {
|
||||
id[n] = n;
|
||||
|
||||
elt.chars = &id[n];
|
||||
elt.nchars = 1;
|
||||
elt.xOff = 0;
|
||||
elt.yOff = 0;
|
||||
|
||||
clear(gi.out.dpy, &gi.out.tt, &colors[gi.dst_color]);
|
||||
elt.glyphset = gi.out.glyphset;
|
||||
XRenderCompositeText8 (gi.out.dpy->dpy, gi.op,
|
||||
gi.out.src,
|
||||
gi.out.tt.picture,
|
||||
gi.out.mask_format,
|
||||
0, 0,
|
||||
0, 8,
|
||||
&elt, 1);
|
||||
|
||||
clear(gi.ref.dpy, &gi.ref.tt, &colors[gi.dst_color]);
|
||||
elt.glyphset = gi.ref.glyphset;
|
||||
XRenderCompositeText8 (gi.ref.dpy->dpy, gi.op,
|
||||
gi.ref.src,
|
||||
gi.ref.tt.picture,
|
||||
gi.ref.mask_format,
|
||||
0, 0,
|
||||
0, 8,
|
||||
&elt, 1);
|
||||
test_compare(t,
|
||||
gi.out.tt.draw, gi.out.tt.format,
|
||||
gi.ref.tt.draw, gi.ref.tt.format,
|
||||
0, 0, gi.out.tt.width, gi.out.tt.height,
|
||||
glyph_iter_to_string(&gi,
|
||||
"glyph=%s",
|
||||
glyph_name(n)));
|
||||
}
|
||||
|
||||
elt.chars = &id[0];
|
||||
elt.nchars = n;
|
||||
clear(gi.out.dpy, &gi.out.tt, &colors[gi.dst_color]);
|
||||
elt.glyphset = gi.out.glyphset;
|
||||
XRenderCompositeText8 (gi.out.dpy->dpy, gi.op,
|
||||
gi.out.src,
|
||||
gi.out.tt.picture,
|
||||
gi.out.mask_format,
|
||||
0, 0,
|
||||
0, 8,
|
||||
&elt, 1);
|
||||
|
||||
clear(gi.ref.dpy, &gi.ref.tt, &colors[gi.dst_color]);
|
||||
elt.glyphset = gi.ref.glyphset;
|
||||
XRenderCompositeText8 (gi.ref.dpy->dpy, gi.op,
|
||||
gi.ref.src,
|
||||
gi.ref.tt.picture,
|
||||
gi.ref.mask_format,
|
||||
0, 0,
|
||||
0, 8,
|
||||
&elt, 1);
|
||||
test_compare(t,
|
||||
gi.out.tt.draw, gi.out.tt.format,
|
||||
gi.ref.tt.draw, gi.ref.tt.format,
|
||||
0, 0, gi.out.tt.width, gi.out.tt.height,
|
||||
glyph_iter_to_string(&gi, "all"));
|
||||
}
|
||||
glyph_iter_fini(&gi);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct test test;
|
||||
int t;
|
||||
|
||||
test_init(&test, argc, argv);
|
||||
XSetErrorHandler(_check_error_handler);
|
||||
|
||||
for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
|
||||
single(&test, t);
|
||||
//overlapping(&test, t);
|
||||
//gap(&test, t);
|
||||
//mixed(&test, t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -403,16 +403,141 @@ static void trap_tests(struct test *t,
|
|||
free(traps);
|
||||
}
|
||||
|
||||
enum edge {
|
||||
EDGE_SHARP = PolyEdgeSharp,
|
||||
EDGE_SMOOTH,
|
||||
};
|
||||
|
||||
static const char *edge_name(enum edge edge)
|
||||
{
|
||||
switch (edge) {
|
||||
default:
|
||||
case EDGE_SHARP: return "sharp";
|
||||
case EDGE_SMOOTH: return "smooth";
|
||||
}
|
||||
}
|
||||
|
||||
static void set_edge(Display *dpy, Picture p, enum edge edge)
|
||||
{
|
||||
XRenderPictureAttributes a;
|
||||
|
||||
a.poly_edge = edge;
|
||||
XRenderChangePicture(dpy, p, CPPolyEdge, &a);
|
||||
}
|
||||
|
||||
static void edge_test(struct test *t,
|
||||
enum mask mask,
|
||||
enum edge edge,
|
||||
enum target target)
|
||||
{
|
||||
struct test_target out, ref;
|
||||
XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
|
||||
Picture src_ref, src_out;
|
||||
XTrapezoid trap;
|
||||
int left_or_right, p;
|
||||
|
||||
test_target_create_render(&t->out, target, &out);
|
||||
set_edge(t->out.dpy, out.picture, edge);
|
||||
src_out = XRenderCreateSolidFill(t->out.dpy, &white);
|
||||
|
||||
test_target_create_render(&t->ref, target, &ref);
|
||||
set_edge(t->ref.dpy, ref.picture, edge);
|
||||
src_ref = XRenderCreateSolidFill(t->ref.dpy, &white);
|
||||
|
||||
printf("Testing edges (with mask %s and %s edges) (%s): ",
|
||||
mask_name(mask),
|
||||
edge_name(edge),
|
||||
test_target_name(target));
|
||||
fflush(stdout);
|
||||
|
||||
for (left_or_right = 0; left_or_right <= 1; left_or_right++) {
|
||||
for (p = -64; p <= out.width + 64; p++) {
|
||||
char buf[80];
|
||||
|
||||
if (left_or_right) {
|
||||
trap.left.p1.x = 0;
|
||||
trap.left.p1.y = 0;
|
||||
trap.left.p2.x = 0;
|
||||
trap.left.p2.y = out.height << 16;
|
||||
|
||||
trap.right.p1.x = p << 16;
|
||||
trap.right.p1.y = 0;
|
||||
trap.right.p2.x = out.width << 16;
|
||||
trap.right.p2.y = out.height << 16;
|
||||
} else {
|
||||
trap.right.p1.x = out.width << 16;
|
||||
trap.right.p1.y = 0;
|
||||
trap.right.p2.x = out.width << 16;
|
||||
trap.right.p2.y = out.height << 16;
|
||||
|
||||
trap.left.p1.x = 0;
|
||||
trap.left.p1.y = 0;
|
||||
trap.left.p2.x = p << 16;
|
||||
trap.left.p2.y = out.height << 16;
|
||||
}
|
||||
|
||||
trap.top = 0;
|
||||
trap.bottom = out.height << 16;
|
||||
|
||||
sprintf(buf,
|
||||
"trap=((%d, %d), (%d, %d)), ((%d, %d), (%d, %d))\n",
|
||||
trap.left.p1.x >> 16, trap.left.p1.y >> 16,
|
||||
trap.left.p2.x >> 16, trap.left.p2.y >> 16,
|
||||
trap.right.p1.x >> 16, trap.right.p1.y >> 16,
|
||||
trap.right.p2.x >> 16, trap.right.p2.y >> 16);
|
||||
|
||||
clear(&t->out, &out);
|
||||
XRenderCompositeTrapezoids(t->out.dpy,
|
||||
PictOpSrc,
|
||||
src_out,
|
||||
out.picture,
|
||||
mask_format(t->out.dpy, mask),
|
||||
0, 0,
|
||||
&trap, 1);
|
||||
|
||||
clear(&t->ref, &ref);
|
||||
XRenderCompositeTrapezoids(t->ref.dpy,
|
||||
PictOpSrc,
|
||||
src_ref,
|
||||
ref.picture,
|
||||
mask_format(t->ref.dpy, mask),
|
||||
0, 0,
|
||||
&trap, 1);
|
||||
|
||||
test_compare(t,
|
||||
out.draw, out.format,
|
||||
ref.draw, ref.format,
|
||||
0, 0, out.width, out.height,
|
||||
buf);
|
||||
}
|
||||
}
|
||||
|
||||
XRenderFreePicture(t->out.dpy, src_out);
|
||||
test_target_destroy_render(&t->out, &out);
|
||||
|
||||
XRenderFreePicture(t->ref.dpy, src_ref);
|
||||
test_target_destroy_render(&t->ref, &ref);
|
||||
|
||||
printf("pass\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct test test;
|
||||
int i, dx, dy;
|
||||
enum target target;
|
||||
enum mask mask;
|
||||
enum edge edge;
|
||||
enum trapezoid trapezoid;
|
||||
|
||||
test_init(&test, argc, argv);
|
||||
|
||||
for (target = TARGET_FIRST; target <= TARGET_LAST; target++) {
|
||||
for (mask = MASK_NONE; mask <= MASK_A8; mask++)
|
||||
for (edge = EDGE_SHARP; edge <= EDGE_SMOOTH; edge++)
|
||||
edge_test(&test, mask, edge, target);
|
||||
}
|
||||
|
||||
for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
|
||||
int reps = REPS(i), sets = SETS(i);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,180 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
enum edge {
|
||||
EDGE_SHARP = PolyEdgeSharp,
|
||||
EDGE_SMOOTH,
|
||||
};
|
||||
|
||||
static void set_edge(Display *dpy, Picture p, enum edge edge)
|
||||
{
|
||||
XRenderPictureAttributes a;
|
||||
|
||||
a.poly_edge = edge;
|
||||
XRenderChangePicture(dpy, p, CPPolyEdge, &a);
|
||||
}
|
||||
|
||||
static XRenderPictFormat *mask_format(Display *dpy, enum mask mask)
|
||||
{
|
||||
switch (mask) {
|
||||
default:
|
||||
case MASK_NONE: return NULL;
|
||||
case MASK_A1: return XRenderFindStandardFormat(dpy, PictStandardA1);
|
||||
case MASK_A8: return XRenderFindStandardFormat(dpy, PictStandardA8);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *mask_name(enum mask mask)
|
||||
{
|
||||
switch (mask) {
|
||||
default:
|
||||
case MASK_NONE: return "none";
|
||||
case MASK_A1: return "a1";
|
||||
case MASK_A8: return "a8";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *edge_name(enum edge edge)
|
||||
{
|
||||
switch (edge) {
|
||||
default:
|
||||
case EDGE_SHARP: return "sharp";
|
||||
case EDGE_SMOOTH: return "smooth";
|
||||
}
|
||||
}
|
||||
|
||||
static void clear(struct test_display *dpy, struct test_target *tt)
|
||||
{
|
||||
XRenderColor render_color = {0};
|
||||
XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
|
||||
0, 0, tt->width, tt->height);
|
||||
}
|
||||
|
||||
static void step_to_point(int step, int width, int height, XPointFixed *p)
|
||||
{
|
||||
do {
|
||||
p->x = (step - 64) << 16;
|
||||
p->y = -64 << 16;
|
||||
|
||||
step -= width - 128;
|
||||
if (step <= 0)
|
||||
return;
|
||||
|
||||
p->x = (width + 64) << 16;
|
||||
p->y = (step - 64) << 16;
|
||||
step -= height - 128;
|
||||
|
||||
if (step <= 0)
|
||||
return;
|
||||
|
||||
p->x = (width + 64 - step) << 16;
|
||||
p->y = (height + 64) << 16;
|
||||
step -= width - 128;
|
||||
|
||||
if (step <= 0)
|
||||
return;
|
||||
|
||||
p->x = -64 << 16;
|
||||
p->y = (height + 64 - step) << 16;
|
||||
step -= height - 128;
|
||||
} while (step > 0);
|
||||
}
|
||||
|
||||
static void edge_test(struct test *t,
|
||||
enum mask mask,
|
||||
enum edge edge,
|
||||
enum target target)
|
||||
{
|
||||
struct test_target out, ref;
|
||||
XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
|
||||
Picture src_ref, src_out;
|
||||
XTriangle tri;
|
||||
unsigned step, max;
|
||||
|
||||
test_target_create_render(&t->out, target, &out);
|
||||
set_edge(t->out.dpy, out.picture, edge);
|
||||
src_out = XRenderCreateSolidFill(t->out.dpy, &white);
|
||||
|
||||
test_target_create_render(&t->ref, target, &ref);
|
||||
set_edge(t->ref.dpy, ref.picture, edge);
|
||||
src_ref = XRenderCreateSolidFill(t->ref.dpy, &white);
|
||||
|
||||
printf("Testing edges (with mask %s and %s edges) (%s): ",
|
||||
mask_name(mask),
|
||||
edge_name(edge),
|
||||
test_target_name(target));
|
||||
fflush(stdout);
|
||||
|
||||
max = 2*(out.width + 128 + out.height+128);
|
||||
step = 0;
|
||||
for (step = 0; step <= max; step++) {
|
||||
char buf[80];
|
||||
|
||||
step_to_point(step, out.width, out.height, &tri.p1);
|
||||
step_to_point(step + out.width + 128,
|
||||
out.width, out.height,
|
||||
&tri.p2);
|
||||
step_to_point(step + out.height + 128 + 2*(out.width + 128),
|
||||
out.width, out.height,
|
||||
&tri.p3);
|
||||
|
||||
sprintf(buf,
|
||||
"tri=((%d, %d), (%d, %d), (%d, %d))\n",
|
||||
tri.p1.x >> 16, tri.p1.y >> 16,
|
||||
tri.p2.x >> 16, tri.p2.y >> 16,
|
||||
tri.p3.x >> 16, tri.p3.y >> 16);
|
||||
|
||||
clear(&t->out, &out);
|
||||
XRenderCompositeTriangles(t->out.dpy,
|
||||
PictOpSrc,
|
||||
src_out,
|
||||
out.picture,
|
||||
mask_format(t->out.dpy, mask),
|
||||
0, 0,
|
||||
&tri, 1);
|
||||
|
||||
clear(&t->ref, &ref);
|
||||
XRenderCompositeTriangles(t->ref.dpy,
|
||||
PictOpSrc,
|
||||
src_ref,
|
||||
ref.picture,
|
||||
mask_format(t->ref.dpy, mask),
|
||||
0, 0,
|
||||
&tri, 1);
|
||||
|
||||
test_compare(t,
|
||||
out.draw, out.format,
|
||||
ref.draw, ref.format,
|
||||
0, 0, out.width, out.height,
|
||||
buf);
|
||||
}
|
||||
|
||||
XRenderFreePicture(t->out.dpy, src_out);
|
||||
test_target_destroy_render(&t->out, &out);
|
||||
|
||||
XRenderFreePicture(t->ref.dpy, src_ref);
|
||||
test_target_destroy_render(&t->ref, &ref);
|
||||
|
||||
printf("pass\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct test test;
|
||||
enum target target;
|
||||
enum mask mask;
|
||||
enum edge edge;
|
||||
|
||||
test_init(&test, argc, argv);
|
||||
|
||||
for (target = TARGET_FIRST; target <= TARGET_LAST; target++) {
|
||||
for (mask = MASK_NONE; mask <= MASK_A8; mask++)
|
||||
for (edge = EDGE_SHARP; edge <= EDGE_SMOOTH; edge++)
|
||||
edge_test(&test, mask, edge, target);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -107,6 +107,15 @@ static inline uint32_t color(uint8_t red, uint8_t green, uint8_t blue, uint8_t a
|
|||
return alpha << 24 | ra >> 8 << 16 | ga >> 8 << 8 | ba >> 8;
|
||||
}
|
||||
|
||||
static inline uint32_t xrender_color(const XRenderColor *c)
|
||||
{
|
||||
uint32_t ra = c->red * c->alpha;
|
||||
uint32_t ga = c->green * c->alpha;
|
||||
uint32_t ba = c->blue * c->alpha;
|
||||
|
||||
return c->alpha >> 8 << 24 | ra >> 24 << 16 | ga >> 24 << 8 | ba >> 24;
|
||||
}
|
||||
|
||||
void test_timer_start(struct test_display *t, struct timespec *tv);
|
||||
double test_timer_stop(struct test_display *t, struct timespec *tv);
|
||||
|
||||
|
|
|
|||
|
|
@ -197,13 +197,10 @@ void test_compare(struct test *t,
|
|||
const char *info)
|
||||
{
|
||||
XImage out_image, ref_image;
|
||||
Pixmap tmp;
|
||||
char *out, *ref;
|
||||
uint32_t *out, *ref;
|
||||
char buf[600];
|
||||
uint32_t mask;
|
||||
int i, j;
|
||||
XGCValues gcv;
|
||||
GC gc;
|
||||
|
||||
if (w * h * 4 > t->out.max_shm_size)
|
||||
return test_compare_fallback(t,
|
||||
|
|
@ -214,37 +211,24 @@ void test_compare(struct test *t,
|
|||
test_init_image(&out_image, &t->out.shm, out_format, w, h);
|
||||
test_init_image(&ref_image, &t->ref.shm, ref_format, w, h);
|
||||
|
||||
gcv.graphics_exposures = 0;
|
||||
|
||||
die_unless(out_image.depth == ref_image.depth);
|
||||
die_unless(out_image.bits_per_pixel == ref_image.bits_per_pixel);
|
||||
die_unless(out_image.bits_per_pixel == 32);
|
||||
|
||||
mask = depth_mask(out_image.depth);
|
||||
XShmGetImage(t->out.dpy, out_draw, &out_image, x, y, AllPlanes);
|
||||
out = (uint32_t *)out_image.data;
|
||||
|
||||
tmp = XCreatePixmap(t->out.dpy, out_draw, w, h, out_image.depth);
|
||||
gc = XCreateGC(t->out.dpy, tmp, GCGraphicsExposures, &gcv);
|
||||
XCopyArea(t->out.dpy, out_draw, tmp, gc, x, y, w, h, 0, 0);
|
||||
XShmGetImage(t->out.dpy, tmp, &out_image, 0, 0, AllPlanes);
|
||||
XFreeGC(t->out.dpy, gc);
|
||||
XFreePixmap(t->out.dpy, tmp);
|
||||
out = out_image.data;
|
||||
|
||||
tmp = XCreatePixmap(t->ref.dpy, ref_draw, w, h, ref_image.depth);
|
||||
gc = XCreateGC(t->ref.dpy, tmp, GCGraphicsExposures, &gcv);
|
||||
XCopyArea(t->ref.dpy, ref_draw, tmp, gc, x, y, w, h, 0, 0);
|
||||
XShmGetImage(t->ref.dpy, tmp, &ref_image, 0, 0, AllPlanes);
|
||||
XFreeGC(t->ref.dpy, gc);
|
||||
XFreePixmap(t->ref.dpy, tmp);
|
||||
ref = ref_image.data;
|
||||
XShmGetImage(t->ref.dpy, ref_draw, &ref_image, x, y, AllPlanes);
|
||||
ref = (uint32_t *)ref_image.data;
|
||||
|
||||
/* Start with an exact comparison. However, one quicky desires
|
||||
* a fuzzy comparator to hide hardware inaccuracies...
|
||||
*/
|
||||
mask = depth_mask(out_image.depth);
|
||||
for (j = 0; j < h; j++) {
|
||||
for (i = 0; i < w; i++) {
|
||||
uint32_t a = ((uint32_t *)out)[i] & mask;
|
||||
uint32_t b = ((uint32_t *)ref)[i] & mask;
|
||||
uint32_t a = out[i] & mask;
|
||||
uint32_t b = ref[i] & mask;
|
||||
if (a != b && pixel_difference(a, b) > MAX_DELTA) {
|
||||
show_pixels(buf,
|
||||
&out_image, &ref_image,
|
||||
|
|
@ -255,8 +239,8 @@ void test_compare(struct test *t,
|
|||
x,i, y,j, a, b, pixel_difference(a, b), buf, info);
|
||||
}
|
||||
}
|
||||
out += out_image.bytes_per_line;
|
||||
ref += ref_image.bytes_per_line;
|
||||
out = (uint32_t *)((char *)out + out_image.bytes_per_line);
|
||||
ref = (uint32_t *)((char *)ref + ref_image.bytes_per_line);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* To compile standalone: gcc -o dri3info dri3info.c `pkg-config --cflags --libs xcb-dri3 x11-xcb xrandr xxf86vm libdrm`
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ struct display {
|
|||
Cursor invisible_cursor;
|
||||
Cursor visible_cursor;
|
||||
|
||||
XcursorImage cursor_image;
|
||||
XcursorImage cursor_image; /* first only */
|
||||
int cursor_serial;
|
||||
int cursor_x;
|
||||
int cursor_y;
|
||||
|
|
@ -1614,14 +1614,17 @@ static Cursor display_load_invisible_cursor(struct display *display)
|
|||
|
||||
static Cursor display_get_visible_cursor(struct display *display)
|
||||
{
|
||||
if (display->cursor_serial != display->cursor_image.size) {
|
||||
DBG(CURSOR, ("%s updating cursor\n", DisplayString(display->dpy)));
|
||||
struct display *first = display->ctx->display;
|
||||
|
||||
if (display->cursor_serial != first->cursor_serial) {
|
||||
DBG(CURSOR, ("%s updating cursor %dx%d, serial %d\n",
|
||||
DisplayString(display->dpy), first->cursor_image.width, first->cursor_image.height, first->cursor_serial));
|
||||
|
||||
if (display->visible_cursor)
|
||||
XFreeCursor(display->dpy, display->visible_cursor);
|
||||
|
||||
display->visible_cursor = XcursorImageLoadCursor(display->dpy, &display->cursor_image);
|
||||
display->cursor_serial = display->cursor_image.size;
|
||||
display->visible_cursor = XcursorImageLoadCursor(display->dpy, &first->cursor_image);
|
||||
display->cursor_serial = first->cursor_serial;
|
||||
}
|
||||
|
||||
return display->visible_cursor;
|
||||
|
|
@ -1644,7 +1647,7 @@ static void display_load_visible_cursor(struct display *display, XFixesCursorIma
|
|||
display->cursor_image.height = cur->height;
|
||||
display->cursor_image.xhot = cur->xhot;
|
||||
display->cursor_image.yhot = cur->yhot;
|
||||
display->cursor_image.size++;
|
||||
display->cursor_serial++;
|
||||
|
||||
n = cur->width*cur->height;
|
||||
src = cur->pixels;
|
||||
|
|
@ -1652,11 +1655,24 @@ static void display_load_visible_cursor(struct display *display, XFixesCursorIma
|
|||
while (n--)
|
||||
*dst++ = *src++;
|
||||
|
||||
DBG(CURSOR, ("%s marking cursor changed\n", DisplayString(display->dpy)));
|
||||
display->cursor_moved++;
|
||||
if (display->cursor != display->invisible_cursor) {
|
||||
display->cursor_visible++;
|
||||
context_enable_timer(display->ctx);
|
||||
if (verbose & CURSOR) {
|
||||
int x, y;
|
||||
|
||||
printf("%s cursor image %dx%d, serial %d:\n",
|
||||
DisplayString(display->dpy),
|
||||
cur->width, cur->height,
|
||||
display->cursor_serial);
|
||||
dst = display->cursor_image.pixels;
|
||||
for (y = 0; y < cur->height; y++) {
|
||||
for (x = 0; x < cur->width; x++) {
|
||||
if (x == cur->xhot && y == cur->yhot)
|
||||
printf("+");
|
||||
else
|
||||
printf("%c", *dst ? *dst >> 24 >= 127 ? 'x' : '.' : ' ');
|
||||
dst++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1700,6 +1716,8 @@ static void display_flush_cursor(struct display *display)
|
|||
if (cursor == None)
|
||||
cursor = display->invisible_cursor;
|
||||
if (cursor != display->cursor) {
|
||||
DBG(CURSOR, ("%s setting cursor shape %lx\n",
|
||||
DisplayString(display->dpy), (long)cursor));
|
||||
XDefineCursor(display->dpy, display->root, cursor);
|
||||
display->cursor = cursor;
|
||||
}
|
||||
|
|
@ -3405,8 +3423,17 @@ int main(int argc, char **argv)
|
|||
if (cur == NULL)
|
||||
continue;
|
||||
|
||||
for (i = 1; i < ctx.ndisplay; i++)
|
||||
display_load_visible_cursor(&ctx.display[i], cur);
|
||||
display_load_visible_cursor(&ctx.display[0], cur);
|
||||
for (i = 1; i < ctx.ndisplay; i++) {
|
||||
struct display *display = &ctx.display[i];
|
||||
|
||||
DBG(CURSOR, ("%s marking cursor changed\n", DisplayString(display->dpy)));
|
||||
display->cursor_moved++;
|
||||
if (display->cursor != display->invisible_cursor) {
|
||||
display->cursor_visible++;
|
||||
context_enable_timer(display->ctx);
|
||||
}
|
||||
}
|
||||
|
||||
XFree(cur);
|
||||
} else if (e.type == ctx.display->rr_event + RRScreenChangeNotify) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue