[PATCH] present: Send GLX_BufferSwapComplete events from present extension

2013-11-25 Thread Keith Packard
Eric Anholt  writes:

> There's a minor behavior change that the event now gets sent to the
> drawable owner rather than the caller of DRI2SwapBuffers.

Yeah, probably not ideal, especially when the GLX drawable is created
using the window XID (as is the case for some older GLX clients). I
don't have the original client at the time the event is generated, but I
think I can go back and stick it in; will require tracking when the
client exits, of course.

> I don't expect it to matter in practice (I expect that the
> swap-requesting client using this GLX extension is also the
> drawable-creating one), and either choice seems wrong compared to "send
> the event to everyone listening for the event on this drawable".  That
> would be a separate change, anyway.

I think the original behaviour, sending the event to the client who sent
the PresentPixmap request is the only sane plan, and only a bit more
complicated than sending it to the drawable owner.

I'll cook up an alternate patch and send that along; we can then compare
the two approaches at least.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH] dri3: Support GLX_INTEL_swap_event

2013-11-25 Thread Keith Packard
Eric Anholt  writes:

> I'd prefer to see sbc stay with its current name, since that's its name
> in the specs we're trying to implement (GLX_OML_sync_control,
> GLX_INTEL_swap_event).  If you drop the rename from the patch,
>
> Reviewed-by: Eric Anholt 

Sounds good.

> I read that as "SBC is incremented when the PresentComplete comes in"
> not "SBC is incremented when we generate the Present request".
> Otherwise glXWaitForSbcOML doesn't make much sense. (in the "e.g." I'm
> assuming they're talking a hardware register for pageflipping that
> immediately starts scanning out the new stuff, not our fancy new
> automatically double buffered ones that you have to push hard on to get
> an immediate pageflip mode)

Oh, that's almost sensible. And nicely eliminates the silly sleep(1)
loop. New patches coming shortly.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH] intel: Track known prime buffers for re-use

2013-11-25 Thread Keith Packard
If the application sends us a file descriptor pointing at a prime
buffer that we've already got, we have to re-use the same bo_gem
structure or chaos will result.

Track the set of all known prime objects and look to see if the kernel
has returned one of those for a new file descriptor.

Also checks for prime buffers in the flink case.

Signed-off-by: Keith Packard 
---
 intel/intel_bufmgr_gem.c | 50 +---
 1 file changed, 43 insertions(+), 7 deletions(-)

diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index df6fcec..2b7fe07 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -149,6 +149,8 @@ struct _drm_intel_bo_gem {

/**
 * Kenel-assigned global name for this object
+ *
+ * List contains both flink named and prime fd'd objects
 */
unsigned int global_name;
drmMMListHead name_list;
@@ -862,10 +864,6 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
}
}

-   bo_gem = calloc(1, sizeof(*bo_gem));
-   if (!bo_gem)
-   return NULL;
-
VG_CLEAR(open_arg);
open_arg.name = handle;
ret = drmIoctl(bufmgr_gem->fd,
@@ -874,9 +872,26 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
if (ret != 0) {
DBG("Couldn't reference %s handle 0x%08x: %s\n",
name, handle, strerror(errno));
-   free(bo_gem);
return NULL;
}
+/* Now see if someone has used a prime handle to get this
+ * object from the kernel before by looking through the list
+ * again for a matching gem_handle
+ */
+   for (list = bufmgr_gem->named.next;
+list != _gem->named;
+list = list->next) {
+   bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
+   if (bo_gem->gem_handle == open_arg.handle) {
+   drm_intel_gem_bo_reference(_gem->bo);
+   return _gem->bo;
+   }
+   }
+
+   bo_gem = calloc(1, sizeof(*bo_gem));
+   if (!bo_gem)
+   return NULL;
+
bo_gem->bo.size = open_arg.size;
bo_gem->bo.offset = 0;
bo_gem->bo.virtual = NULL;
@@ -2451,8 +2466,25 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr 
*bufmgr, int prime_fd, int s
uint32_t handle;
drm_intel_bo_gem *bo_gem;
struct drm_i915_gem_get_tiling get_tiling;
+   drmMMListHead *list;

ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, );
+
+   /*
+* See if the kernel has already returned this buffer to us. Just as
+* for named buffers, we must not create two bo's pointing at the same
+* kernel object
+*/
+   for (list = bufmgr_gem->named.next;
+list != _gem->named;
+list = list->next) {
+   bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
+   if (bo_gem->gem_handle == handle) {
+   drm_intel_gem_bo_reference(_gem->bo);
+   return _gem->bo;
+   }
+   }
+
if (ret) {
  fprintf(stderr,"ret is %d %d\n", ret, errno);
return NULL;
@@ -2487,8 +2519,8 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr 
*bufmgr, int prime_fd, int s
bo_gem->has_error = false;
bo_gem->reusable = false;

-   DRMINITLISTHEAD(_gem->name_list);
DRMINITLISTHEAD(_gem->vma_list);
+   DRMLISTADDTAIL(_gem->name_list, _gem->named);

VG_CLEAR(get_tiling);
get_tiling.handle = bo_gem->gem_handle;
@@ -2513,6 +2545,9 @@ drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int 
*prime_fd)
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;

+if (DRMLISTEMPTY(_gem->name_list))
+DRMLISTADDTAIL(_gem->name_list, _gem->named);
+
if (drmPrimeHandleToFD(bufmgr_gem->fd, bo_gem->gem_handle,
   DRM_CLOEXEC, prime_fd) != 0)
return -errno;
@@ -2542,7 +2577,8 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
bo_gem->global_name = flink.name;
bo_gem->reusable = false;

-   DRMLISTADDTAIL(_gem->name_list, _gem->named);
+if (DRMLISTEMPTY(_gem->name_list))
+DRMLISTADDTAIL(_gem->name_list, _gem->named);
}

*name = bo_gem->global_name;
-- 
1.8.4.4



[Mesa-dev] [PATCH] intel: Track known prime buffers for re-use

2013-11-25 Thread Keith Packard
Daniel Vetter  writes:

> Yeah, it unfortunately took a few rounds of kernel fixes and other
> haggling to get the semantics right on this one. The kernel atm promises
> to userspace (minus one big in a racy corner case no one should care
> about, still need to fix that one) that it'll return the same gem handle
> if userspace already has one for the underlying object.

That's definitely something we want it to do -- returning different
handles to the same object would result in madness. We just need to deal with 
the
userspace consequences.

> We need that to make sure userspace doesn't submit the same bo in execbuf
> multiple times and then upsets the kernel - we'll reject such batches as
> userspace bugs.

Oh, I'm well aware of that; you can imagine the adventures I had trying
to debug this...

>> -DRMINITLISTHEAD(_gem->name_list);
>>  DRMINITLISTHEAD(_gem->vma_list);
>> +DRMLISTADDTAIL(_gem->name_list, _gem->prime);
>
> Won't this result in us having fun when a buffer is both imported from a
> prime buffer and then also used with legacy flink? Or is this something
> the X server won't support?

Well, the whole point of prime-based FD buffer passing is to *not* use
flink, of course. However, you could use both DRI2 and DRI3 on
the same pixmap (presumably through different APIs).

Ok, I just tried to create a completely separate prime list for this,
and I think that's wrong. If the question is whether the kernel might
return the same object from two calls, then we'd best actually keep a
single list and look things up for both APIs there. *and*, I think we
need to do the flink->gem handle conversion and then look in the list
again to see if that gem handle was already returned from another flink
or prime fd.

> The second one is about exporting: With flink names we also add the name
> to the lookup list in drm_intel_gem_bo_flink. I think we should do the
> same for exported prime buffers just as a precaution - the kernel will
> return the (existing) gem name also for a prime buffer that has been
> exported by yourself. I guess that would imply insane userspace, but
> better safe than sorry.

yeah, that would seem like crazy user-space behaviour, but user space
often seems insane.

Thanks for your review; replacement patch to follow shortly.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[Intel-gfx] [Mesa-dev] [PATCH] dri3, i915, i965: Add __DRI_IMAGE_FOURCC_SARGB8888

2013-11-22 Thread Keith Packard
Ville Syrj?l?  writes:

> What is this format anyway? -ENODOCS

Same as MESA_FORMAT_SARGB8 and __DRI_IMAGE_FORMAT_SARGB8 :-)

> If its just an srgb version of ARGB, then I wouldn't really want it
> in drm_fourcc.h. I expect colorspacy stuff will be handled by various
> crtc/plane properties in the kernel so we don't need to encode that
> stuff into the fb format.

It's not any different from splitting YUV codes from RGB codes; a
different color encoding with the same bitfields. And, for mesa, it's
necessary to differentiate between ARGB and SARGB within the same format
code given how the API is structured. So, we have choices:

 1) Let Mesa define it's own fourcc codes and risk future accidental
collisions

 2) Rewrite piles of mesa code to split out the color encoding from the
bitfield information and pass it separately.

 3) Add "reasonable" format codes like this to the kernel fourcc list.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[Intel-gfx] [Mesa-dev] [PATCH] dri3, i915, i965: Add __DRI_IMAGE_FOURCC_SARGB8888

2013-11-22 Thread Keith Packard
Kristian H?gsberg  writes:

> I already explained to Keith why we use different sets of format codes
> in the DRI interface, but it's always fun to slam other peoples code.

As we discussed, my complaint isn't so much about __DRI_IMAGE_FOURCC,
but the fact that the __DRIimage interfaces use *both*
__DRI_IMAGE_FOURCC and __DRI_IMAGE_FORMAT at different times.

Ok, here's a fine thing we can actually fix -- the pattern that mesa
uses all over the place in converting formats looks like this (not to
pick on anyone, it's repeated everywhere, this is just the first one I
found in gbm_dri.c):

static uint32_t
gbm_dri_to_gbm_format(uint32_t dri_format)
{
   uint32_t ret = 0;

   switch (dri_format) {
   case __DRI_IMAGE_FORMAT_RGB565:
  ret = GBM_FORMAT_RGB565;
  break;
   case __DRI_IMAGE_FORMAT_XRGB:
  ret = GBM_FORMAT_XRGB;
  break;
   case __DRI_IMAGE_FORMAT_ARGB:
  ret = GBM_FORMAT_ARGB;
  break;
   case __DRI_IMAGE_FORMAT_ABGR:
  ret = GBM_FORMAT_ABGR;
  break;
   default:
  ret = 0;
  break;
   }

   return ret;
}

The problem here is that any unknown incoming formats get translated to
garbage (0) outgoing. With fourcc codes, there is the slight advantage
that 0 is never a legal value, but it sure would be nice to print a
warning or even abort if you get a format code you don't understand as
there's no way 0 is ever going to do what you want.

Anyone have a preference? Abort? Print an error? Silently continue to do
the wrong thing?

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 2/2] i965: Set fast color clear mcs_state on newly allocated image miptrees

2013-11-22 Thread Keith Packard
Just copying code from the dri2 path to set up the fast color clear state.

This also removes a couple of bogus intel_region_reference calls.

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c 
b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 884ddef..ca78f32 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -762,7 +762,13 @@ intel_miptree_create_for_image_buffer(struct brw_context 
*intel,
if (!singlesample_mt)
   return NULL;

-   intel_region_reference(_mt->region, region);
+   /* If this miptree is capable of supporting fast color clears, set
+* mcs_state appropriately to ensure that fast clears will occur.
+* Allocation of the MCS miptree will be deferred until the first fast
+* clear actually occurs.
+*/
+   if (intel_is_non_msrt_mcs_buffer_supported(intel, singlesample_mt))
+  singlesample_mt->mcs_state = INTEL_MCS_STATE_RESOLVED;

if (num_samples == 0)
   return singlesample_mt;
@@ -780,8 +786,6 @@ intel_miptree_create_for_image_buffer(struct brw_context 
*intel,
multisample_mt->singlesample_mt = singlesample_mt;
multisample_mt->need_downsample = false;

-   intel_region_reference(_mt->region, region);
-
if (intel->is_front_buffer_rendering && buffer_type == 
__DRI_IMAGE_BUFFER_FRONT) {
   intel_miptree_upsample(intel, multisample_mt);
}
-- 
1.8.4.3



[PATCH 1/2] i965: Correct check for re-bound buffer in intel_update_image_buffer

2013-11-22 Thread Keith Packard
The buffer-object is the persistent thing passed through the loader, so when
updating an image buffer, check to see if it is already bound to the provided
bo. The region, on the other hand, is allocated separately for the miptree,
and so will never be the same as that passed back from the loader.

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/i965/brw_context.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c 
b/src/mesa/drivers/dri/i965/brw_context.c
index bee98e3..64ff855 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -1339,10 +1339,21 @@ intel_update_image_buffer(struct brw_context *intel,

unsigned num_samples = rb->Base.Base.NumSamples;

-   if (rb->mt &&
-   rb->mt->region &&
-   rb->mt->region == region)
-  return;
+   /* Check and see if we're already bound to the right
+* buffer object
+*/
+   if (num_samples == 0) {
+   if (rb->mt &&
+   rb->mt->region &&
+   rb->mt->region->bo == region->bo)
+  return;
+   } else {
+   if (rb->mt &&
+   rb->mt->singlesample_mt &&
+   rb->mt->singlesample_mt->region &&
+   rb->mt->singlesample_mt->region->bo == region->bo)
+  return;
+   }

intel_miptree_release(>mt);
rb->mt = intel_miptree_create_for_image_buffer(intel,
-- 
1.8.4.3



[PATCH 0/2] Minor __DRIimage fixes for i965

2013-11-22 Thread Keith Packard
While debugging the libdrm duplicate buffer object adventure, I managed to
temporarily understand object lifetimes in the __DRIimage getBuffers path, and
also to compare that to the DRI2 getBuffers path. Here are a couple of small
fixes.

I haven't looked at the i915 code, but I suspect the first one, and parts of
the second one would apply.

 [PATCH 1/2] i965: Correct check for re-bound buffer in

The code was attempting to avoid re-creating the miptree when the loader
handed back the same bufffer we already had, but it was confused about how to
tell -- turns out the object actually shared between the loader and the driver
is the BO, not the region. And so, we compare BO pointers to see if the image
buffer needs to have a new miptree.

 [PATCH 2/2] i965: Set fast color clear mcs_state on newly allocated

Here's a chunk of code that was just missing from the __DRIimage path as a
result of rebasing across some new driver additions.

Both of these fixes are candidates for 10.0 as they affect the __DRIimage
paths now used by Wayland.

-keith


[PATCH] intel: Track known prime buffers for re-use

2013-11-22 Thread Keith Packard
If the application sends us a file descriptor pointing at a prime
buffer that we've already got, we have to re-use the same bo_gem
structure or chaos will result.

Track the set of all known prime objects and look to see if the kernel
has returned one of those for a new file descriptor.

Signed-off-by: Keith Packard 
---

This one took a while to find -- multiple bo_gem structs pointing at
the same gem handle would either cause the object to be destroyed
before we were done using it, or we'd end up sending the same
gem_handle for multiple buffers.

This looks a lot like the named object handling stuff, as one would
expect.

 intel/intel_bufmgr_gem.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index df6fcec..2897bb2 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -112,6 +112,7 @@ typedef struct _drm_intel_bufmgr_gem {

drmMMListHead named;
drmMMListHead vma_cache;
+drmMMListHead prime;
int vma_count, vma_open, vma_max;

uint64_t gtt_size;
@@ -2451,8 +2452,25 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr 
*bufmgr, int prime_fd, int s
uint32_t handle;
drm_intel_bo_gem *bo_gem;
struct drm_i915_gem_get_tiling get_tiling;
+   drmMMListHead *list;

ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, );
+
+   /*
+* See if the kernel has already returned this buffer to us. Just as
+* for named buffers, we must not create two bo's pointing at the same
+* kernel object
+*/
+   for (list = bufmgr_gem->prime.next;
+list != _gem->prime;
+list = list->next) {
+   bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
+   if (bo_gem->gem_handle == handle) {
+   drm_intel_gem_bo_reference(_gem->bo);
+   return _gem->bo;
+   }
+   }
+
if (ret) {
  fprintf(stderr,"ret is %d %d\n", ret, errno);
return NULL;
@@ -2487,8 +2505,8 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr 
*bufmgr, int prime_fd, int s
bo_gem->has_error = false;
bo_gem->reusable = false;

-   DRMINITLISTHEAD(_gem->name_list);
DRMINITLISTHEAD(_gem->vma_list);
+   DRMLISTADDTAIL(_gem->name_list, _gem->prime);

VG_CLEAR(get_tiling);
get_tiling.handle = bo_gem->gem_handle;
@@ -3301,5 +3319,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
DRMINITLISTHEAD(_gem->vma_cache);
bufmgr_gem->vma_max = -1; /* unlimited by default */

+   DRMINITLISTHEAD(_gem->prime);
+
return _gem->bufmgr;
 }
-- 
1.8.4.3



[Mesa-dev] [PATCH] dri3, i915, i965: Add __DRI_IMAGE_FOURCC_SARGB8888

2013-11-22 Thread Keith Packard
Daniel Vetter  writes:

> Hm, where do we have the canonical source for all these fourcc codes? I'm
> asking since we have our own copy in the kernel as drm_fourcc.h, and that
> one is part of the userspace ABI since we use it to pass around
> framebuffer formats and format lists.

I think it's the kernel? I really don't know, as the whole notion of
fourcc codes seems crazy to me...

Feel free to steal this code and stick it in the kernel if you like.

> Just afraid to create long-term maintainance madness here with the
> kernel's iron thou-shalt-not-break-userspace-ever rule ... Not likely
> we'll ever accept srgb for framebuffers though.

Would suck to collide with something we do want though.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH] dri3: Support GLX_INTEL_swap_event

2013-11-21 Thread Keith Packard
The easy part is turning on the extension, now that the X server has a patch
to send the events.

The only trick was making sure the Present extension reliably provided the
right 'sbc' count back in the event, and that's done by making sure the sbc
count is always the same as the sequence number that we send in the
PresentPixmap requests, and that's done by using the same variable for both
roles.

Signed-off-by: Keith Packard 
---

This passes the piglet glx-swap-event test.

 src/glx/dri3_glx.c  | 27 ++-
 src/glx/dri3_priv.h |  3 +--
 2 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 669f0bb..a7bf318 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -423,7 +423,7 @@ dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t 
target_msc, int64_t divisor,

*ust = priv->ust;
*msc = priv->msc;
-   *sbc = priv->sbc;
+   *sbc = priv->present_count;

return 1;
 }
@@ -450,7 +450,7 @@ dri3_wait_for_sbc(__GLXDRIdrawable *pdraw, int64_t 
target_sbc, int64_t *ust,
 {
struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;

-   while (priv->sbc < target_sbc) {
+   while (priv->present_count < target_sbc) {
   sleep(1);
}
return dri3_wait_for_msc(pdraw, 0, 0, 0, ust, msc, sbc);
@@ -1282,7 +1282,8 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t 
target_msc, int64_t divisor,
   /* Compute when we want the frame shown by taking the last known 
successful
* MSC and adding in a swap interval for each outstanding swap request
*/
-  ++priv->present_request_serial;
+  ++priv->present_count;
+  priv->present_request_serial = (uint32_t) priv->present_count;
   if (target_msc == 0)
  target_msc = priv->msc + priv->swap_interval * 
(priv->present_request_serial - priv->present_event_serial);

@@ -1302,7 +1303,7 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t 
target_msc, int64_t divisor,
  target_msc,
  divisor,
  remainder, 0, NULL);
-  ret = ++priv->sbc;
+  ret = priv->present_count;

   /* If there's a fake front, then copy the source back buffer
* to the fake front to keep it up to date. This needs
@@ -1494,23 +1495,7 @@ dri3_bind_extensions(struct dri3_screen *psc, struct 
glx_display * priv,
__glXEnableDirectExtension(>base, "GLX_SGI_swap_control");
__glXEnableDirectExtension(>base, "GLX_MESA_swap_control");
__glXEnableDirectExtension(>base, "GLX_SGI_make_current_read");
-
-   /*
-* GLX_INTEL_swap_event is broken on the server side, where it's
-* currently unconditionally enabled. This completely breaks
-* systems running on drivers which don't support that extension.
-* There's no way to test for its presence on this side, so instead
-* of disabling it unconditionally, just disable it for drivers
-* which are known to not support it, or for DDX drivers supporting
-* only an older (pre-ScheduleSwap) version of DRI2.
-*
-* This is a hack which is required until:
-* http://lists.x.org/archives/xorg-devel/2013-February/035449.html
-* is merged and updated xserver makes it's way into distros:
-*/
-//   if (pdp->swapAvailable && strcmp(driverName, "vmwgfx") != 0) {
-//  __glXEnableDirectExtension(>base, "GLX_INTEL_swap_event");
-//   }
+   __glXEnableDirectExtension(>base, "GLX_INTEL_swap_event");

mask = psc->image_driver->getAPIMask(psc->driScreen);

diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index 05f66cf..cdf986d 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -183,11 +183,10 @@ struct dri3_drawable {
uint8_t have_fake_front;
uint8_t is_pixmap;

+   uint64_t present_count;
uint32_t present_request_serial;
uint32_t present_event_serial;

-   uint64_t sbc;
-
uint64_t ust, msc;

/* For WaitMSC */
-- 
1.8.4.2



[PATCH] present: Send GLX_BufferSwapComplete events from present extension

2013-11-21 Thread Keith Packard
This allows GL to support the GLX_INTEL_swap_event extension

Signed-off-by: Keith Packard 
---

This is the X server side; the mesa patch will be sent shortly (it's tiny)

 glx/Makefile.am |  3 ++-
 glx/glxcmds.c   | 69 +
 glx/glxdri2.c   | 26 +--
 glx/glxext.c|  3 +++
 glx/glxserver.h |  9 +++
 present/present.h   |  9 +++
 present/present_event.c | 10 +++
 7 files changed, 109 insertions(+), 20 deletions(-)

diff --git a/glx/Makefile.am b/glx/Makefile.am
index 5f28e87..44d3a7d 100644
--- a/glx/Makefile.am
+++ b/glx/Makefile.am
@@ -20,7 +20,8 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/hw/xfree86/os-support/bus \
-I$(top_srcdir)/hw/xfree86/common \
-I$(top_srcdir)/hw/xfree86/dri \
-   -I$(top_srcdir)/mi
+   -I$(top_srcdir)/mi \
+   -I$(top_srcdir)/present

 if DRI2_AIGLX
 AM_CPPFLAGS += -I$(top_srcdir)/hw/xfree86/dri2
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index efa4aec..2c5de70 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2468,3 +2468,72 @@ __glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc)

 return Success;
 }
+
+#include 
+
+void
+__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust,
+   CARD64 msc, CARD32 sbc)
+{
+ClientPtr client = clients[CLIENT_ID(drawable->drawId)];
+
+xGLXBufferSwapComplete2 wire =  {
+.type = __glXEventBase + GLX_BufferSwapComplete
+};
+
+if (!client)
+return;
+
+if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
+return;
+
+wire.event_type = type;
+wire.drawable = drawable->drawId;
+wire.ust_hi = ust >> 32;
+wire.ust_lo = ust & 0x;
+wire.msc_hi = msc >> 32;
+wire.msc_lo = msc & 0x;
+wire.sbc = sbc;
+
+WriteEventsToClient(client, 1, (xEvent *) );
+}
+
+#if PRESENT
+static void
+__glXpresentCompleteNotify(WindowPtr window, CARD8 present_mode, CARD32 serial,
+   uint64_t ust, uint64_t msc)
+{
+__GLXdrawable *drawable;
+int error;
+int glx_type;
+int rc;
+
+rc = dixLookupResourceByType((pointer *) , window->drawable.id,
+ __glXDrawableRes, serverClient, 
DixGetAttrAccess);
+
+if (rc != Success)
+return;
+
+switch(present_mode) {
+case PresentCompleteModeFlip:
+glx_type = GLX_FLIP_COMPLETE_INTEL;
+break;
+case PresentCompleteModeCopy:
+glx_type = GLX_BLIT_COMPLETE_INTEL;
+break;
+default:
+glx_type = 0;
+break;
+}
+
+__glXsendSwapEvent(drawable, glx_type, ust, msc, serial);
+}
+
+#include 
+
+void
+__glXregisterPresentCompleteNotify(void)
+{
+present_register_complete_notify(__glXpresentCompleteNotify);
+}
+#endif
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 1d74c8f..9d3f3c3 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -177,36 +177,24 @@ __glXdriSwapEvent(ClientPtr client, void *data, int type, 
CARD64 ust,
   CARD64 msc, CARD32 sbc)
 {
 __GLXdrawable *drawable = data;
-xGLXBufferSwapComplete2 wire =  {
-.type = __glXEventBase + GLX_BufferSwapComplete
-};
-
-if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
-return;
-
+int glx_type;
 switch (type) {
 case DRI2_EXCHANGE_COMPLETE:
-wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL;
+glx_type = GLX_EXCHANGE_COMPLETE_INTEL;
 break;
 case DRI2_BLIT_COMPLETE:
-wire.event_type = GLX_BLIT_COMPLETE_INTEL;
+glx_type = GLX_BLIT_COMPLETE_INTEL;
 break;
 case DRI2_FLIP_COMPLETE:
-wire.event_type = GLX_FLIP_COMPLETE_INTEL;
+glx_type = GLX_FLIP_COMPLETE_INTEL;
 break;
 default:
 /* unknown swap completion type */
-wire.event_type = 0;
+glx_type = 0;
 break;
 }
-wire.drawable = drawable->drawId;
-wire.ust_hi = ust >> 32;
-wire.ust_lo = ust & 0x;
-wire.msc_hi = msc >> 32;
-wire.msc_lo = msc & 0x;
-wire.sbc = sbc;
-
-WriteEventsToClient(client, 1, (xEvent *) );
+
+__glXsendSwapEvent(drawable, glx_type, ust, msc, sbc);
 }

 /*
diff --git a/glx/glxext.c b/glx/glxext.c
index 3a7de28..601d08a 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -399,6 +399,9 @@ GlxExtensionInit(void)

 __glXErrorBase = extEntry->errorBase;
 __glXEventBase = extEntry->eventBase;
+#if PRESENT
+__glXregisterPresentCompleteNotify();
+#endif
 }

 //
diff --git a/glx/glxserver.h b/glx/glxserver.h
index 5e29abb..f862b63 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -120,6 +120,15 @@ void glxResumeClients(void);
 void __glXsetGetProcAddress(void (*(*get_proc_address) (const char *)) (void));
 void *__

[PATCH] v2: dri3: Free resources when drawable is destroyed.

2013-11-21 Thread Keith Packard
Always nice to clean up after ourselves.

Signed-off-by: Keith Packard 
---

v2: Include changes to dri3_priv.h as well

 src/glx/dri3_glx.c  | 17 -
 src/glx/dri3_priv.h |  5 -
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 239d58b..669f0bb 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -266,13 +266,25 @@ dri3_create_context(struct glx_screen *base,
 }

 static void
+dri3_free_render_buffer(struct dri3_drawable *pdraw, struct dri3_buffer 
*buffer);
+
+static void
 dri3_destroy_drawable(__GLXDRIdrawable *base)
 {
struct dri3_screen *psc = (struct dri3_screen *) base->psc;
struct dri3_drawable *pdraw = (struct dri3_drawable *) base;
+   xcb_connection_t *c = XGetXCBConnection(pdraw->base.psc->dpy);
+   int i;

(*psc->core->destroyDrawable) (pdraw->driDrawable);

+   for (i = 0; i < DRI3_NUM_BUFFERS; i++) {
+  if (pdraw->buffers[i])
+ dri3_free_render_buffer(pdraw, pdraw->buffers[i]);
+   }
+
+   if (pdraw->special_event)
+  xcb_unregister_for_special_event(c, pdraw->special_event);
free(pdraw);
 }

@@ -736,6 +748,7 @@ dri3_alloc_render_buffer(struct glx_screen *glx_screen, 
Drawable draw,
   fence_fd);

buffer->pixmap = pixmap;
+   buffer->own_pixmap = true;
buffer->sync_fence = sync_fence;
buffer->shm_fence = shm_fence;
buffer->width = width;
@@ -769,7 +782,8 @@ dri3_free_render_buffer(struct dri3_drawable *pdraw, struct 
dri3_buffer *buffer)
struct dri3_screen   *psc = (struct dri3_screen *) pdraw->base.psc;
xcb_connection_t *c = XGetXCBConnection(pdraw->base.psc->dpy);

-   xcb_free_pixmap(c, buffer->pixmap);
+   if (buffer->own_pixmap)
+  xcb_free_pixmap(c, buffer->pixmap);
xcb_sync_destroy_fence(c, buffer->sync_fence);
xshmfence_unmap_shm(buffer->shm_fence);
(*psc->image->destroyImage)(buffer->image);
@@ -988,6 +1002,7 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable,
   goto no_image;

buffer->pixmap = pixmap;
+   buffer->own_pixmap = false;
buffer->width = bp_reply->width;
buffer->height = bp_reply->height;
buffer->buffer_type = buffer_type;
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index 0d21e67..05f66cf 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -89,6 +89,7 @@ struct dri3_buffer {
uint32_t sync_fence; /* XID of X SyncFence object */
void *shm_fence; /* pointer to xshmfence object */
GLbooleanbusy;   /* Set on swap, cleared on IdleNotify */
+   GLbooleanown_pixmap; /* We allocated the pixmap ID, free on destroy 
*/
void *driverPrivate;

uint32_t size;
@@ -171,6 +172,8 @@ dri3_pixmap_buf_id(enum dri3_buffer_type buffer_type)
   return DRI3_FRONT_ID;
 }

+#define DRI3_NUM_BUFFERS(1 + DRI3_MAX_BACK)
+
 struct dri3_drawable {
__GLXDRIdrawable base;
__DRIdrawable *driDrawable;
@@ -194,7 +197,7 @@ struct dri3_drawable {
uint64_t previous_time;
unsigned frames;

-   struct dri3_buffer *buffers[1 + DRI3_MAX_BACK];
+   struct dri3_buffer *buffers[DRI3_NUM_BUFFERS];
int cur_back;
int depth;

-- 
1.8.4.2



[PATCH] dri3: Free resources when drawable is destroyed.

2013-11-21 Thread Keith Packard
Always nice to clean up after ourselves.

Signed-off-by: Keith Packard 
---

Ok, so not having this in the dri3 code led to a bit of extra memory
usage in apps and the X server.

 src/glx/dri3_glx.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 239d58b..669f0bb 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -266,13 +266,25 @@ dri3_create_context(struct glx_screen *base,
 }

 static void
+dri3_free_render_buffer(struct dri3_drawable *pdraw, struct dri3_buffer 
*buffer);
+
+static void
 dri3_destroy_drawable(__GLXDRIdrawable *base)
 {
struct dri3_screen *psc = (struct dri3_screen *) base->psc;
struct dri3_drawable *pdraw = (struct dri3_drawable *) base;
+   xcb_connection_t *c = XGetXCBConnection(pdraw->base.psc->dpy);
+   int i;

(*psc->core->destroyDrawable) (pdraw->driDrawable);

+   for (i = 0; i < DRI3_NUM_BUFFERS; i++) {
+  if (pdraw->buffers[i])
+ dri3_free_render_buffer(pdraw, pdraw->buffers[i]);
+   }
+
+   if (pdraw->special_event)
+  xcb_unregister_for_special_event(c, pdraw->special_event);
free(pdraw);
 }

@@ -736,6 +748,7 @@ dri3_alloc_render_buffer(struct glx_screen *glx_screen, 
Drawable draw,
   fence_fd);

buffer->pixmap = pixmap;
+   buffer->own_pixmap = true;
buffer->sync_fence = sync_fence;
buffer->shm_fence = shm_fence;
buffer->width = width;
@@ -769,7 +782,8 @@ dri3_free_render_buffer(struct dri3_drawable *pdraw, struct 
dri3_buffer *buffer)
struct dri3_screen   *psc = (struct dri3_screen *) pdraw->base.psc;
xcb_connection_t *c = XGetXCBConnection(pdraw->base.psc->dpy);

-   xcb_free_pixmap(c, buffer->pixmap);
+   if (buffer->own_pixmap)
+  xcb_free_pixmap(c, buffer->pixmap);
xcb_sync_destroy_fence(c, buffer->sync_fence);
xshmfence_unmap_shm(buffer->shm_fence);
(*psc->image->destroyImage)(buffer->image);
@@ -988,6 +1002,7 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable,
   goto no_image;

buffer->pixmap = pixmap;
+   buffer->own_pixmap = false;
buffer->width = bp_reply->width;
buffer->height = bp_reply->height;
buffer->buffer_type = buffer_type;
-- 
1.8.4.2



[PATCH] dri3: Prepare for API change in libxshmfence

2013-11-21 Thread Keith Packard
libxshmfence foolishly advertises the type of a fence as 'int32_t *', which
works when the fence is a linux futex. However, that library is going to
change the exported datatype to 'struct xshmfence *', which will provide some
nice typechecking. Anticipate the change by just using 'void *' in mesa, which
works with both the int32_t* and struct xshmfence* versions.

Signed-off-by: Keith Packard 
---

libxshmfence will also be providing a HAVE_STRUCT_XSHMFENCE define, so
we could actually check for that and use struct xshmfence when
available. Just using 'void *' avoids a bunch of clutter, but if
people think they'd rather have extra type checking, I can do the
other version instead.

 src/glx/dri3_glx.c  | 4 ++--
 src/glx/dri3_priv.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 5861317..239d58b 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -676,7 +676,7 @@ dri3_alloc_render_buffer(struct glx_screen *glx_screen, 
Drawable draw,
xcb_connection_t *c = XGetXCBConnection(dpy);
xcb_pixmap_t pixmap;
xcb_sync_fence_t sync_fence;
-   int32_t *shm_fence;
+   void *shm_fence;
int buffer_fd, fence_fd;
int stride;

@@ -922,7 +922,7 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable,
struct dri3_screen   *psc;
xcb_connection_t *c;
xcb_sync_fence_t sync_fence;
-   int32_t  *shm_fence;
+   void *shm_fence;
int  fence_fd;
__DRIimage   *image_planar;
int  stride, offset;
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index c892800..0d21e67 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -87,7 +87,7 @@ struct dri3_buffer {
 */

uint32_t sync_fence; /* XID of X SyncFence object */
-   int32_t  *shm_fence; /* pointer to xshmfence object */
+   void *shm_fence; /* pointer to xshmfence object */
GLbooleanbusy;   /* Set on swap, cleared on IdleNotify */
void *driverPrivate;

-- 
1.8.4.2



[PATCH] gallium: Use base.stamp for all drawable invalidation checks.

2013-11-21 Thread Keith Packard
Upper levels of the stack use base.stamp to tell when a drawable needs to be
revalidated, but the dri state tracker was using dPriv->lastStamp. Those two,
along with dri2.stamp, all get simultaneously incremented when a dri2
invalidate event was delivered, and so end up containing precisely the same
value.

This patch doesn't change the fact that there are three variables, rather it
switches all of the tests to use only base.stamp, which is functionally
equivalent to the previous code.

Then, it passes base.stamp to the image loader getBuffers function so that the
one which is checked will get updated by the XCB special event queue used by 
DRI3.

Signed-off-by: Keith Packard 
---

This patch makes sure that drawables get invalidated when the window
changes size or when SwapBuffers is called; dri3 has only a single
location to smite when things change, so we need to make sure the
upper levels all share that location.

This should permit the elimination of the dri2.stamp and lastStamp
variables, which would be a nice further cleanup.

 src/gallium/state_trackers/dri/common/dri_drawable.c | 4 ++--
 src/gallium/state_trackers/dri/drm/dri2.c| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c 
b/src/gallium/state_trackers/dri/common/dri_drawable.c
index f255108..734bca2 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -73,7 +73,7 @@ dri_st_framebuffer_validate(struct st_context_iface *stctx,
 * checked.
 */
do {
-  lastStamp = drawable->dPriv->lastStamp;
+  lastStamp = drawable->base.stamp;
   new_stamp = (drawable->texture_stamp != lastStamp);

   if (new_stamp || new_mask || screen->broken_invalidate) {
@@ -91,7 +91,7 @@ dri_st_framebuffer_validate(struct st_context_iface *stctx,
  drawable->texture_stamp = lastStamp;
  drawable->texture_mask = statt_mask;
   }
-   } while (lastStamp != drawable->dPriv->lastStamp);
+   } while (lastStamp != drawable->base.stamp);

if (!out)
   return TRUE;
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c 
b/src/gallium/state_trackers/dri/drm/dri2.c
index 6a56cd4..c7e4151 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -545,7 +545,7 @@ dri_image_allocate_textures(struct dri_context *ctx,

(*sPriv->image.loader->getBuffers) (dPriv,
image_format,
-   >dri2.stamp,
+   (uint32_t *) >base.stamp,
dPriv->loaderPrivate,
buffer_mask,
);
-- 
1.8.4.2



[PATCH] dri3, i915, i965: Add __DRI_IMAGE_FOURCC_SARGB8888

2013-11-21 Thread Keith Packard
The __DRIimage createImageFromFds function takes a fourcc code, but there was
no fourcc code that match __DRI_IMAGE_FORMAT_SARGB8. This adds a define for
that format, adds a translation in DRI3 from __DRI_IMAGE_FORMAT_SARGB8 to
__DRI_IMAGE_FOURCC_SARGB and then adds translations *back* to
__IMAGE_FORMAT_SARGB8 in both the i915 and i965 drivers.

I'll refrain from comments on whether I think having two separate sets of
format defines in dri_interface.h is a good idea or not...

Signed-off-by: Keith Packard 
---

This gets iceweasel running with the GL compositor enabled.

 include/GL/internal/dri_interface.h  | 1 +
 src/glx/dri3_glx.c   | 1 +
 src/mesa/drivers/dri/i915/intel_screen.c | 3 +++
 src/mesa/drivers/dri/i965/intel_screen.c | 3 +++
 4 files changed, 8 insertions(+)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index b012570..a4387c4 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1034,6 +1034,7 @@ struct __DRIdri2ExtensionRec {
 #define __DRI_IMAGE_FOURCC_XRGB0x34325258
 #define __DRI_IMAGE_FOURCC_ABGR0x34324241
 #define __DRI_IMAGE_FOURCC_XBGR0x34324258
+#define __DRI_IMAGE_FOURCC_SARGB0x83324258
 #define __DRI_IMAGE_FOURCC_YUV410  0x39565559
 #define __DRI_IMAGE_FOURCC_YUV411  0x31315559
 #define __DRI_IMAGE_FOURCC_YUV420  0x32315559
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index b047cc8..5861317 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -890,6 +890,7 @@ image_format_to_fourcc(int format)

/* Convert from __DRI_IMAGE_FORMAT to __DRI_IMAGE_FOURCC (sigh) */
switch (format) {
+   case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB;
case __DRI_IMAGE_FORMAT_RGB565: return __DRI_IMAGE_FOURCC_RGB565;
case __DRI_IMAGE_FORMAT_XRGB: return __DRI_IMAGE_FOURCC_XRGB;
case __DRI_IMAGE_FORMAT_ARGB: return __DRI_IMAGE_FOURCC_ARGB;
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c 
b/src/mesa/drivers/dri/i915/intel_screen.c
index 7f1fc6b..2dd2bc7 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -184,6 +184,9 @@ static struct intel_image_format intel_image_formats[] = {
{ __DRI_IMAGE_FOURCC_ARGB, __DRI_IMAGE_COMPONENTS_RGBA, 1,
  { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB, 4 } } },

+   { __DRI_IMAGE_FOURCC_SARGB, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8, 4 } } },
+
{ __DRI_IMAGE_FOURCC_XRGB, __DRI_IMAGE_COMPONENTS_RGB, 1,
  { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB, 4 }, } },

diff --git a/src/mesa/drivers/dri/i965/intel_screen.c 
b/src/mesa/drivers/dri/i965/intel_screen.c
index e44d0f6..cf8c3e2 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -220,6 +220,9 @@ static struct intel_image_format intel_image_formats[] = {
{ __DRI_IMAGE_FOURCC_ARGB, __DRI_IMAGE_COMPONENTS_RGBA, 1,
  { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB, 4 } } },

+   { __DRI_IMAGE_FOURCC_SARGB, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8, 4 } } },
+
{ __DRI_IMAGE_FOURCC_XRGB, __DRI_IMAGE_COMPONENTS_RGB, 1,
  { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB, 4 }, } },

-- 
1.8.4.2



[Mesa-dev] [PATCH] Don't use libudev for glx/dri3

2013-11-19 Thread Keith Packard
Eric Anholt  writes:

> Keith Packard  writes:
>
>> libudev doesn't have a stable API/ABI, and if the application wants to use 
>> one
>> version, we'd best not load another into libGL.
>>
>> Signed-off-by: Keith Packard 
>
> This looks so simple it's definitely worth dropping udev, but I'd like
> to see the udev code actually dropped instead of #if 0ed.

It's either that or make it a config option, in case libudev is useful
on some other system someday?

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20131119/2939f32d/attachment.pgp>


[Mesa-dev] [PATCH] Don't use libudev for glx/dri3

2013-11-18 Thread Keith Packard
Emil Velikov  writes:

> On 18/11/13 01:08, Keith Packard wrote:
>> libudev doesn't have a stable API/ABI, and if the application wants to use 
>> one
>> version, we'd best not load another into libGL.
>> 
>> Signed-off-by: Keith Packard 
>> ---
>> 
> Hi Keith,
>
> Did you had the chance to look at src/gallium/targets/egl-static/egl.c?
> It has a different implementation of drm_fd_get_pci_id, whenever udev is
> not available.

Yeah, it's ugly in a different way from the udev technique...

> AFAICS it goes back to the kernel via the relevant ioctl to retrieve the
> deviceid/chipid. Currently all but nouveau provide such information. I'm
> thinking that this approach might be more reasonable for those concerned
> with portability of the udev bits (think on *BSD).

I'd encourage some kind of standard IOCTL from DRM that returns the
PCI-ID of the underlying device, rather than relying on the level of
kludge present in either the udev (or my fake udev) method or the
non-udev path in the egl code...

> I'm not nitpicking, just thought you might find this interesting.

Definitely interesting; it's almost what we want -- the kernel knows the
information, there just isn't a clean way of getting it (and no way at
all for some devices).

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20131118/bed4ee40/attachment-0001.pgp>


[Mesa-dev] [PATCH] Don't use libudev for glx/dri3

2013-11-17 Thread Keith Packard
Kenneth Graunke  writes:

> For non-API facing stuff, you can just use stdbool.h's
> bool/true/false.

tnx. I pushed that to my dri3 branch. Btw, that branch also has some
gallium support for __DRIimageDriverExtension. I don't have any hardware
to test with, so it's surely broken in some major ways, but it might
show where the hooks need to be.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[Mesa-dev] [PATCH] Don't use libudev for glx/dri3

2013-11-17 Thread Keith Packard
Emil Velikov  writes:

> On 18/11/13 01:08, Keith Packard wrote:
>> libudev doesn't have a stable API/ABI, and if the application wants to use 
>> one
>> version, we'd best not load another into libGL.
>> 
>> Signed-off-by: Keith Packard 
>> ---
>> 
> Hi Keith,
>
> Firstly, I would like to apologise for the rather daft questions.
>
> With that said, looking through your patch I've noticed that (most of)
> your int functions are returning 0 or failure and 1 on success. Were
> those functions meant to return boolean/bool?

Sure, but I was too lazy to figure out which kind of bool belongs in
that part of mesa...

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20131117/83478e60/attachment.pgp>


[PATCH] Don't use libudev for glx/dri3

2013-11-17 Thread Keith Packard
libudev doesn't have a stable API/ABI, and if the application wants to use one
version, we'd best not load another into libGL.

Signed-off-by: Keith Packard 
---

Sorry for the patch spam; I hadn't rebased in a while and there was a
configure.ac conflict. Here's a version which should apply cleanly to master.

 configure.ac  |   8 
 src/glx/dri3_common.c | 104 +++---
 2 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/configure.ac b/configure.ac
index fb16338..656d9d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -821,9 +821,6 @@ xyesno)
 PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED"
 if test x"$enable_dri3" = xyes; then
-if test x"$have_libudev" != xyes; then
-  AC_MSG_ERROR([DRI3 requires libudev >= $LIBUDEV_REQUIRED])
-fi
 PKG_CHECK_MODULES([DRI3PROTO], [dri3proto >= $DRI3PROTO_REQUIRED])
 PKG_CHECK_MODULES([PRESENTPROTO], [presentproto >= 
$PRESENTPROTO_REQUIRED])
 fi
@@ -847,11 +844,6 @@ xyesno)
 X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS"
 GL_LIB_DEPS="$DRIGL_LIBS"

-if test x"$enable_dri3$have_libudev" = xyesyes; then
-X11_INCLUDES="$X11_INCLUDES $LIBUDEV_CFLAGS"
-GL_LIB_DEPS="$GL_LIB_DEPS $LIBUDEV_LIBS"
-fi
-
 # need DRM libs, $PTHREAD_LIBS, etc.
 GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm $PTHREAD_LIBS $DLOPEN_LIBS"
 GL_PC_LIB_PRIV="-lm $PTHREAD_LIBS $DLOPEN_LIBS"
diff --git a/src/glx/dri3_common.c b/src/glx/dri3_common.c
index c758f96..7330d79 100644
--- a/src/glx/dri3_common.c
+++ b/src/glx/dri3_common.c
@@ -72,22 +72,41 @@
 #include "dri3_priv.h"

 #define DRIVER_MAP_DRI3_ONLY
+
 #include "pci_ids/pci_id_driver_map.h"

+static dev_t
+dri3_rdev_from_fd(int fd)
+{
+   struct stat buf;
+
+   if (fstat(fd, ) < 0) {
+  ErrorMessageF("DRI3: failed to stat fd %d", fd);
+  return 0;
+   }
+   return buf.st_rdev;
+}
+
+/*
+ * There are multiple udev library versions, and they aren't polite about
+ * symbols, so just avoid using it until some glorious future when the udev
+ * developers figure out how to not break things
+ */
+
+#define USE_UDEV 0
+#if USE_UDEV
 #include 

 static struct udev_device *
 dri3_udev_device_new_from_fd(struct udev *udev, int fd)
 {
struct udev_device *device;
-   struct stat buf;
+   dev_t rdev = dri3_rdev_from_fd(fd);

-   if (fstat(fd, ) < 0) {
-  ErrorMessageF("DRI3: failed to stat fd %d", fd);
+   if (rdev == 0)
   return NULL;
-   }

-   device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+   device = udev_device_new_from_devnum(udev, 'c', rdev);
if (device == NULL) {
   ErrorMessageF("DRI3: could not create udev device for fd %d", fd);
   return NULL;
@@ -96,19 +115,20 @@ dri3_udev_device_new_from_fd(struct udev *udev, int fd)
return device;
 }

-char *
-dri3_get_driver_for_fd(int fd)
+static int
+dri3_get_pci_id_from_fd(int fd, int *vendorp, int *chipp)
 {
struct udev *udev;
struct udev_device *device, *parent;
const char *pci_id;
-   char *driver = NULL;
-   int vendor_id, chip_id, i, j;
+   int ret = 0;

udev = udev_new();
+   if (!udev)
+  goto no_udev;
device = dri3_udev_device_new_from_fd(udev, fd);
if (device == NULL)
-  return NULL;
+  goto no_dev;

parent = udev_device_get_parent(device);
if (parent == NULL) {
@@ -118,10 +138,69 @@ dri3_get_driver_for_fd(int fd)

pci_id = udev_device_get_property_value(parent, "PCI_ID");
if (pci_id == NULL ||
-   sscanf(pci_id, "%x:%x", _id, _id) != 2) {
+   sscanf(pci_id, "%x:%x", vendorp, chipp) != 2) {
   ErrorMessageF("DRI3: malformed or no PCI ID");
   goto out;
}
+   ret = 1;
+
+out:
+   udev_device_unref(device);
+no_dev:
+   udev_unref(udev);
+no_udev:
+   return ret;
+}
+#else
+
+#define SYS_PATH_MAX256
+
+static int
+dri3_read_hex(dev_t rdev, char *entry, int *value)
+{
+   char path[SYS_PATH_MAX];
+   FILE *f;
+   int  r;
+
+   snprintf(path, sizeof (path), "/sys/dev/char/%u:%u/device/%s",
+major(rdev), minor(rdev), entry);
+
+   f = fopen(path,"r");
+   if (f == NULL)
+  return 0;
+
+   r = fscanf(f, "0x%x\n", value);
+   fclose(f);
+   if (r != 1)
+  return 0;
+   return 1;
+}
+
+static int
+dri3_get_pci_id_from_fd(int fd, int *vendorp, int *chipp)
+{
+   dev_trdev = dri3_rdev_from_fd(fd);
+   
+   if (!rdev)
+  return 0;
+
+   if (!dri3_read_hex(rdev, "vendor", vendorp))
+  return 0;
+   if (!dri3_read_hex(rdev, "device", chipp))
+  return 0;
+   return 1;
+}
+
+#endif
+
+char *
+dri3_g

[PATCH] Don't use libudev for glx/dri3

2013-11-17 Thread Keith Packard
libudev doesn't have a stable API/ABI, and if the application wants to use one
version, we'd best not load another into libGL.

Signed-off-by: Keith Packard 
---
 configure.ac  |   5 +--
 src/glx/dri3_common.c | 106 +++---
 2 files changed, 94 insertions(+), 17 deletions(-)

diff --git a/configure.ac b/configure.ac
index 63c2973..10e9e0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -821,7 +821,6 @@ xyesno)
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED"
 PKG_CHECK_MODULES([DRI3PROTO], [dri3proto >= $DRI3PROTO_REQUIRED])
 PKG_CHECK_MODULES([PRESENTPROTO], [presentproto >= 
$PRESENTPROTO_REQUIRED])
-PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED])
 fi

 # find the DRI deps for libGL
@@ -835,8 +834,8 @@ xyesno)

 PKG_CHECK_MODULES([DRIGL], [$dri_modules])
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV $dri_modules"
-X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS $LIBUDEV_CFLAGS"
-GL_LIB_DEPS="$DRIGL_LIBS $LIBUDEV_LIBS"
+X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS"
+GL_LIB_DEPS="$DRIGL_LIBS"

 # need DRM libs, $PTHREAD_LIBS, etc.
 GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm $PTHREAD_LIBS $DLOPEN_LIBS"
diff --git a/src/glx/dri3_common.c b/src/glx/dri3_common.c
index c758f96..01c9d09 100644
--- a/src/glx/dri3_common.c
+++ b/src/glx/dri3_common.c
@@ -72,22 +72,41 @@
 #include "dri3_priv.h"

 #define DRIVER_MAP_DRI3_ONLY
+
 #include "pci_ids/pci_id_driver_map.h"

+static dev_t
+dri3_rdev_from_fd(int fd)
+{
+   struct stat buf;
+
+   if (fstat(fd, ) < 0) {
+  ErrorMessageF("DRI3: failed to stat fd %d", fd);
+  return 0;
+   }
+   return buf.st_rdev;
+}
+
+/*
+ * There are multiple udev library versions, and they aren't polite about
+ * symbols, so just avoid using it until some glorious future when the udev
+ * developers figure out how to not break things
+ */
+
+#define USE_UDEV 0
+#if USE_UDEV
 #include 

 static struct udev_device *
 dri3_udev_device_new_from_fd(struct udev *udev, int fd)
 {
struct udev_device *device;
-   struct stat buf;
+   dev_t rdev = dri3_rdev_from_fd(fd);

-   if (fstat(fd, ) < 0) {
-  ErrorMessageF("DRI3: failed to stat fd %d", fd);
+   if (rdev == 0)
   return NULL;
-   }

-   device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+   device = udev_device_new_from_devnum(udev, 'c', rdev);
if (device == NULL) {
   ErrorMessageF("DRI3: could not create udev device for fd %d", fd);
   return NULL;
@@ -96,19 +115,20 @@ dri3_udev_device_new_from_fd(struct udev *udev, int fd)
return device;
 }

-char *
-dri3_get_driver_for_fd(int fd)
+static int
+dri3_get_pci_id_from_fd(int fd, int *vendorp, int *chipp)
 {
struct udev *udev;
struct udev_device *device, *parent;
const char *pci_id;
-   char *driver = NULL;
-   int vendor_id, chip_id, i, j;
+   int ret = 0;

udev = udev_new();
+   if (!udev)
+  goto no_udev;
device = dri3_udev_device_new_from_fd(udev, fd);
if (device == NULL)
-  return NULL;
+  goto no_dev;

parent = udev_device_get_parent(device);
if (parent == NULL) {
@@ -118,10 +138,71 @@ dri3_get_driver_for_fd(int fd)

pci_id = udev_device_get_property_value(parent, "PCI_ID");
if (pci_id == NULL ||
-   sscanf(pci_id, "%x:%x", _id, _id) != 2) {
+   sscanf(pci_id, "%x:%x", vendorp, chipp) != 2) {
   ErrorMessageF("DRI3: malformed or no PCI ID");
   goto out;
}
+   ret = 1;
+
+out:
+   udev_device_unref(device);
+no_dev:
+   udev_unref(udev);
+no_udev:
+   return ret;
+}
+#else
+
+#define SYS_PATH_MAX256
+
+static int
+dri3_read_hex(dev_t rdev, char *entry, int *value)
+{
+   char path[SYS_PATH_MAX];
+   FILE *f;
+   int  r;
+
+   snprintf(path, sizeof (path), "/sys/dev/char/%u:%u/device/%s",
+major(rdev), minor(rdev), entry);
+
+   printf ("path %s\n", path);
+
+   f = fopen(path,"r");
+   if (f == NULL)
+  return 0;
+
+   r = fscanf(f, "0x%x\n", value);
+   fclose(f);
+   if (r != 1)
+  return 0;
+   return 1;
+}
+
+static int
+dri3_get_pci_id_from_fd(int fd, int *vendorp, int *chipp)
+{
+   dev_trdev = dri3_rdev_from_fd(fd);
+   
+   if (!rdev)
+  return 0;
+
+   if (!dri3_read_hex(rdev, "vendor", vendorp))
+  return 0;
+   if (!dri3_read_hex(rdev, "device", chipp))
+  return 0;
+   return 1;
+}
+
+#endif
+
+char *
+dri3_get_driver_for_fd(int fd)
+{
+   char *driver = NULL;
+   int vendor_id, chip_id, i, j;
+
+   if (!dri3_get_pci_id_from_fd(fd, _id, _id))
+  return NULL;

for (i = 0; driver_map[i].driver; i++) {
   if (vendor_id != driver_map[i].vendor_id)
@@ -139,8 +220,5 @@ dri3_get_driver_for_fd(int fd)
}

 out:
-   udev_device_unref(device);
-   udev_unref(udev);
-
return driver;
 }
-- 
1.8.4.2



vblank_count count jumps backwards and then forwards across system suspend

2013-11-11 Thread Keith Packard

I'm getting some weird results when using vblank_count on my Ivybridge
machine across suspend/resume.

With glxgears running, I suspend the machine. At resume, I see
vblank_count temporarily jump back by a fairly large amount (usually
between 1 and 2 frames). After a short while, it recovers and
jumps back to something that looks like it's back on track with values


[PATCH 3/8] dri/intel: Add explicit size parameter to intel_region_alloc_for_fd

2013-11-06 Thread Keith Packard
Christopher James Halse Rogers 
writes:

> You've presumably noticed this already, but this is the wrong way round
> - you're passing height * stride as pitch, and stride as size. This
> makes for awesome rendering.

Thanks for catching this; I've flipped them around, and also fixed the
fact that these calls were passing '1' for cpp, which appears to not
actually matter most of the time, but as the correct value was sitting
there in the image structure for the taking, I added that as well.

You reviewed this on IRC, so I'll be merging it into the commit on my
branch, just putting it here for other people to look at:

diff --git a/src/mesa/drivers/dri/i915/intel_screen.c 
b/src/mesa/drivers/dri/i915/intel_screen.c
index 38badec..3ac5aa2 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -608,8 +608,8 @@ intel_create_image_from_fds(__DRIscreen *screen,
   return NULL;

image->region = intel_region_alloc_for_fd(intelScreen,
- 1, width, height, height * 
strides[0],
- strides[0], fds[0], "image");
+ f->planes[0].cpp, width, height, 
strides[0],
+ height * strides[0], fds[0], 
"image");
if (image->region == NULL) {
   free(image);
   return NULL;
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c 
b/src/mesa/drivers/dri/i965/intel_screen.c
index 7571921..dcfde97 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -663,8 +663,8 @@ intel_create_image_from_fds(__DRIscreen *screen,
   return NULL;

image->region = intel_region_alloc_for_fd(intelScreen,
- 1, width, height, height * 
strides[0],
- strides[0], fds[0], "image");
+ f->planes[0].cpp, width, height, 
strides[0],
+ height * strides[0], fds[0], 
"image");
if (image->region == NULL) {
   free(image);
   return NULL;

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH] Add DRM_MODE_PAGE_FLIP_ASYNC define

2013-11-06 Thread Keith Packard
Eric Anholt  writes:

> Keith Packard  writes:
>
>> This exposes the kernel API for performing asynchronous flips
>>
>> Signed-off-by: Keith Packard 
>
> Reviewed-by: Eric Anholt 

I've pushed this to master.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20131106/9e810977/attachment.pgp>


[PATCH] Add DRM_MODE_PAGE_FLIP_ASYNC define

2013-11-06 Thread Keith Packard
This exposes the kernel API for performing asynchronous flips

Signed-off-by: Keith Packard 
---

 include/drm/drm.h  | 1 +
 include/drm/drm_mode.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index 725bf51..f0b4c16 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -797,6 +797,7 @@ struct drm_event_vblank {
 #define DRM_CAP_DUMB_PREFER_SHADOW 0x4
 #define DRM_CAP_PRIME 0x5
 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
+#define DRM_CAP_ASYNC_PAGE_FLIP 0x7

 #define DRM_PRIME_CAP_IMPORT 0x1
 #define DRM_PRIME_CAP_EXPORT 0x2
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index c1bb1a3..76fd76b 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -425,7 +425,8 @@ struct drm_mode_crtc_lut {
 };

 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
-#define DRM_MODE_PAGE_FLIP_FLAGS DRM_MODE_PAGE_FLIP_EVENT
+#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
+#define DRM_MODE_PAGE_FLIP_FLAGS 
(DRM_MODE_PAGE_FLIP_EVENT|DRM_MODE_PAGE_FLIP_ASYNC)

 /*
  * Request a page flip on the specified crtc.
-- 
1.8.4.2



[PATCH 7/8] dri: add __DRIimageLoaderExtension and __DRIimageDriverExtension

2013-11-06 Thread Keith Packard
Kristian H?gsberg  writes:

> I'm OK with either approach. It does seem like cleaning up the DRI
> driver interface is orthogonal to enabling the __DRIimage based
> getBuffer callout though.

We should probably not merge what we don't want to maintain though;
let's decide over lunch. I don't think it matters very much to the
current code, it'll only bug us in small ways in the future.

> I think that's fine.  I was going to say that if we expect the
> requested and the returned set of buffers to differ, we might as well
> just memset the struct and let non-NULL images indicate returned
> images.  But in case of a driver with a newer interface that extends
> the struct (stereoscopic buffers), the loader can't memset the entire
> struct (it only knows the smaller, previous version), and the driver
> will think the non-NULL garbage fields are valid images.  So the
> image_mask makes sense.

That's what I was thinking.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 7/8] dri: add __DRIimageLoaderExtension and __DRIimageDriverExtension

2013-11-06 Thread Keith Packard
Kristian H?gsberg  writes:

> It just the two older create context functions (which fall back to
> calling driCreateContextAtribs) and allocateBuffer and releaseBuffer.
> The two buffer functions are __DRIbuffer specific of course, but we
> can implement them in terms of __DRIimage in dri_util.c now.

I guess the benefit is that we could remove the DRIdri2Extension
functions from each driver and just use the DRIimage-based wrappers in
dri_util then?

We're still stuck with leaving the DRIdri2Extension as the interface


[PATCH 7/8] dri: add __DRIimageLoaderExtension and __DRIimageDriverExtension

2013-11-06 Thread Keith Packard
Kristian H?gsberg  writes:

> Having written the GBM and Wayland suport for this, it's pretty clear
> that we just want to use __DRIdri2Extension instead of duplicating
> these functions.  Support for the __DRIimage based getBuffers is a
> small incremental patch to src/egl/drivers/dri2:

That would require drivers to support all of the DRI2 functions, rather
than just the few needed for Image support though.

> The problem is that technically we would have to do:
>
>   if (dri2_dpy->image_driver) {
>
>  /* use dri2_dpy->image_driver->createContextAttribs
>
>   } else if (dri2_dpy->dri2 &&
>dri2_dpy->dri2->base.version >= 3) {
>
>  /* use dri2_dpy->dri2->createContextAttribs
>
> all over the place even though they end up calling the same function.
> The only real purpose of __DRIimageDriverExtension is to let the
> loader know that the DRI driver supports and will use
> __DRIimageLoaderExtension if provided, but we can just expose an empty
> dummy extension to indicate that.

Alternatively, the loader could simply call through the DRI2 version,
acknowledging that they must be the same function? I'd sure like to be
able to create an ImageLoader-only driver, even if that's not practical
today.

A couple of other options:

 * Move the shared functions into a new structure which is embedded
   in both the DRIdri2ExtensionRec and the DRIimageDriverExtensionRec,
   then the loader could set a pointer to whichever it wanted to use
   in it's own structure.

 * Have the loader pull the functions out of the ExtensionRec and stick
   them directly into its own structure. Then it could use those
   directly and avoid version checks while running.

But, if we just want to use the DRI2 driver interface and create an
extension purely to mark that the driver will use an Image loader,
that's easy too.

> I think we should only look at image.front if the
> __DRI_IMAGE_BUFFER_FRONT bit is set.  We never want to set up a front
> buffer that we didn't ask for and it seems wrong that the loader has
> to clear image.front, if the driver didn't ask for front.

I simply duplicated the logic from the DRI2 path which works exactly the
same way (asks for buffers, then looks to see what it got). I didn't dig
into the details further than this, I'm afraid. The only case where asks
!= received is for pixmap targets where you always get a front buffer. I
assumed there was some deep semantic requirement for that...

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 8/8] Add DRI3+Present loader

2013-11-05 Thread Keith Packard
Eric Anholt  writes:

I've pushed a patch responding to these comments to my dri3 branch and
will send that out shortly. I will merge those changes with the original
DRI3+Present loader patch so that there is only one commit when the
review process is complete.

> I think I'm going to be griping about code duplication...

Yeah, I'm really not sure what to do about that. The alternative would
be to refactor the DRI2 backend and then land the DRI3 backend on top of
some shared code, but frankly I'm not that excited about breaking DRI2.

Do you want me to actually go ahead and try to do that?

> Patches need to land in XCB and get released before this can land.  I
> don't even see patches on the xcb list yet.

I sent out the patches to the xorg-devel list today after reworking and
cleaning them up. I'd forgotten that there was a separate xcb list.

>> +
>> +#define DRIVER_MAP_DRI3_ONLY
>
> What does this define do?

It is designed to be used in case there are two drivers for a chipset,
one DRI2 one and one DRI3 one. Much like the DRIVER_MAP_GALLIUM_ONLY
flag. It's not currently being used at all, so it should probably just
get removed until necessary.

> '{' on a separate line, please.

Fixed.

> This looks completely like dri2_create_context, except for missing
> rendertype validation and a different calloc size.

Yup. It's cult-n-paste. Note that the license at the top of the file
tries to make it clear that *lots* of the code in this file was copied


[PATCH 7/8] dri: add __DRIimageLoaderExtension and __DRIimageDriverExtension

2013-11-05 Thread Keith Packard
Kristian H?gsberg  writes:


> We can drop width and height now and just get it from either of the
> returned images.  Format is a function of the __DRIconfig and doesn't
> change, so we could make that something you can query from the config
> in the interest of further reducing the number of arguments.

Sure would be nice if there were simpler ways than calling the
getAttribs function though; I'm tempted to just leave these params in as
every single driver will need those values and passing them back here
will make the driver code shorter.

> I'll give this a try with the GBM and Wayland EGL backends now.

Cool. Having two backends using this same interface would really help
out.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 5/8] dri/common: Add functions mapping MESA_FORMAT_* <-> __DRI_IMAGE_FORMAT_*

2013-11-05 Thread Keith Packard
Kristian H?gsberg  writes:

> I'll take the bait... before the i915/i965 split, this code was only
> needed in this one place.  All other drivers are gallium drivers which
> need to convert to galliums enum pipe_format instead of the gl_format
> enum.  Anyway, the code certainly looks more at home in dri_util.c.

Yeah, the i915/i965 split wasn't fun to rebase across at all. Oh well,
I'm sure it was for the best :-)

> Reviewed-by: Kristian H?gsberg 

Thanks!

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 3/8] dri/intel: Add explicit size parameter to intel_region_alloc_for_fd

2013-11-05 Thread Keith Packard
Kristian H?gsberg  writes:

> The 3.12 kernel let's you get the bo size from lseek on the dma_buf
> fd.  I added libdrm support for getting the size that, and if that
> works, it overrides the user provided size:

Yeah, I'm happy just sending the size and not trusting that the kernel
will have the new API; back-porting happens...

> Regardless, this patchs looks good.
>
> Reviewed-by: Kristian H?gsberg 

Thanks!

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 0/8] Add DRIimage-based DRI3/Present loader

2013-11-05 Thread Keith Packard
Eric Anholt  writes:

> It seems like we could just stick these things in __DRI_CORE as opposed
> to having another new extension to look up.

Having the driver expose this new extension is how I tell that the
driver is going to actually call the __DRIimage-based loader; the
alternative to a new extension would be to stick a flag in the
__DRI_CORE structure.

> The downside I see there is
> bugs in the server, which have patches at xserver-driinterface-versions
> of my tree.  (Unfortunately, I'm having a hard time building the server
> currently, so no testing yet).  Having a new extension whose name has
> nothing to do with the functions in it seems really weird.

It defines the interface to a driver which will be using the image
loader to allocate color buffers if available. The fact that the image
loader and DRI2 loader can both share the same driver interface is a
happy coincidence.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 7/8] dri: add __DRIimageLoaderExtension and __DRIimageDriverExtension

2013-11-05 Thread Keith Packard
Eric Anholt  writes:

> Most of my review was going to be whining about yet another (broken)
> copy of dri2CreateNewScreen2.  Sounds like you've fixed that.

Yup, figured that out all on my own after I re-read the code -- the only
difference was that I need to look for the DRIimageLoader hooks, which I
now just do in the shared function.

>> +
>> +#define __DRI_DRIVER_EXTENSIONS "__driDriverExtensions"
>
> This looks like rebase fail

Removed.

>> +//struct gl_context;
>> +//struct dd_function_table;
>
> Looks like development leftovers.

Removed.

> Maybe append "Func" to the typedefs so they don't look like just another
> struct in the declarations?  And since they're supposed to be the same
> function pointers as in the __DRIswrastExtensionRec and
> __DRIdri2ExtensionRec, change them to this typedef, too?

I've moved the typedefs, renamed them and stuck that part of the patch
in the first patch of the series that renames the functions.

> It looks like getBuffers could just be two getBuffer calls, except for
> the updating of width and height.  Have you looked into doing things
> that way at all?

Yes, that was the way I started doing it. There are two reasons for
doing it in a single call:

 1) Pixmaps always need a front buffer, and the driver doesn't know
which drawables are pixmaps.

 2) Deleting buffers when changing modes. I'd need to add another
function to let the driver delete unused buffers.

Overall, I liked moving more buffer management logic to the loader and
out of the driver, so I followed the DRI2 API here.

> Style nit: we try and put braces around multi-line things like this,
> even if they are a single statement.

Fixed.

>> -bool
>> +GLboolean
>>  brwCreateContext(gl_api api,
>>   const struct gl_config *mesaVis,
>>   __DRIcontext *driContextPriv,
...
>>__DRIdrawable *drawable);
>>  
>> -bool brwCreateContext(gl_api api,
>> -  const struct gl_config *mesaVis,
>> -  __DRIcontext *driContextPriv,
>> -  unsigned major_version,
>> -  unsigned minor_version,
>> -  uint32_t flags,
>> -  unsigned *error,
>> -  void *sharedContextPrivate);
>> +GLboolean brwCreateContext(gl_api api,
>> +   const struct gl_config *mesaVis,
>> +   __DRIcontext *driContextPriv,
>> +   unsigned major_version,
>> +   unsigned minor_version,
>> +   uint32_t flags,
>> +   unsigned *error,
>> +   void *sharedContextPrivate);
...
>
> Unrelated change?

Pulled out to a separate patch -- the return type for createContext is
GLboolean, not bool, and my compiler was whinging.

I've pushed these changes, along with a bunch of new comments in
dri3_glx.c to my dri3 branch. I can send the new series to the list if
that would be helpful.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 0/8] Add DRIimage-based DRI3/Present loader

2013-11-05 Thread Keith Packard
Keith Packard  writes:

> This sequence first adds a a couple of new DRIimage extensions to the
> dri/common, dri/i915 and dri/i965 directories which define a
> loader-independent API for managing window system operations.
>
> The last patch adds a new DRI3000 loader using those new interfaces.

I've figured out that I can also re-use dri2CreateNewScreen2 for the
image driver bits, as long as I change that function to also look up the
image loader. That means there are *no* new dri_util functions needed.

To recap, the changes needed to support using the DRIimageExtension
interfaces for allocating buffers from the driver in the loader are:

DRIimageDriverExtension

A proper subset of DRIdri2DriverExtension, which uses
the same five functions involved in creating new objects:

   /* Common DRI functions, shared with DRI2 */
   __DRIcreateNewScreen2createNewScreen2;
   __DRIcreateNewDrawable   createNewDrawable;
   __DRIcreateNewContextcreateNewContext;
   __DRIcreateContextAttribscreateContextAttribs;
   __DRIgetAPIMask  getAPIMask;

DRIimageLoaderExtension

Contains just two functions, one to allocate buffers and one to
copy the fake front to the real front when flushing stuff.

   /**
* Allocate color buffers.
*
* \param driDrawable
* \param width  Width of allocated buffers
* \param height Height of allocated buffers
* \param format one of __DRI_IMAGE_FORMAT_*
* \param stamp  Address of variable to be updated when
*   getBuffers must be called again
* \param loaderPrivate  The loaderPrivate for driDrawable
* \param buffer_maskSet of buffers to allocate
* \param buffersReturned buffers
*/
   int (*getBuffers)(__DRIdrawable *driDrawable,
 int *width, int *height,
 unsigned int format,
 uint32_t *stamp,
 void *loaderPrivate,
 uint32_t buffer_mask,
 struct __DRIimageList *buffers);

/**
 * Flush pending front-buffer rendering
 *
 * Any rendering that has been performed to the
 * fake front will be flushed to the front
 *
 * \param driDrawableDrawable whose front-buffer is to be 
flushed
 * \param loaderPrivate  Loader's private data that was previously 
passed
 *   into 
__DRIdri2ExtensionRec::createNewDrawable
 */
void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void 
*loaderPrivate);

Each driver will need to have a path to use the image loader to get
color buffers using the DRIimageLoaderExtension getBuffers function.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20131105/1166c68b/attachment.pgp>


[PATCH 5/8] dri/common: Add functions mapping MESA_FORMAT_* <-> __DRI_IMAGE_FORMAT_*

2013-11-04 Thread Keith Packard
Jordan Justen  writes:


> After patch 6, this will add SARGB8, right? So, maybe add this to the
> commit message, or separate out adding SARGB8 into a separate commit?

I added the SARGB8 define in patch 4; is there some other separation you
think would be warranted?

Oh, just so everyone knows -- krh and I chatted for a while this morning
and decided that this whole __DRI_IMAGE_FORMAT_* stuff is just a bad
idea and we should remove it all and just use __DRI_IMAGE_FOURCC_*
everywhere. I didn't want to mix that change up with this series though.

> Patches 1-6: Reviewed-by: Jordan Justen 

Thanks!

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 8/8] Add DRI3+Present loader

2013-11-04 Thread Keith Packard
Uses the __DRIimage loader interfaces.

Signed-off-by: Keith Packard 
---
 configure.ac  |   12 +-
 src/glx/Makefile.am   |2 +
 src/glx/dri3_common.c |  146 +
 src/glx/dri3_glx.c| 1722 +
 src/glx/dri3_priv.h   |  199 ++
 src/glx/glxclient.h   |2 +
 src/glx/glxext.c  |6 +-
 7 files changed, 2085 insertions(+), 4 deletions(-)
 create mode 100644 src/glx/dri3_common.c
 create mode 100644 src/glx/dri3_glx.c
 create mode 100644 src/glx/dri3_priv.h

diff --git a/configure.ac b/configure.ac
index 0a25047..074368c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,6 +38,9 @@ LIBDRM_NVVIEUX_REQUIRED=2.4.33
 LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41"
 LIBDRM_FREEDRENO_REQUIRED=2.4.39
 DRI2PROTO_REQUIRED=2.6
+DRI3PROTO_REQUIRED=1.0
+PRESENTPROTO_REQUIRED=1.0
+LIBUDEV_REQUIRED=151
 GLPROTO_REQUIRED=1.4.14
 LIBDRM_XORG_REQUIRED=2.4.24
 LIBKMS_XORG_REQUIRED=1.0.0
@@ -820,10 +823,13 @@ xyesno)
 fi
 PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED"
+PKG_CHECK_MODULES([DRI3PROTO], [dri3proto >= $DRI3PROTO_REQUIRED])
+PKG_CHECK_MODULES([PRESENTPROTO], [presentproto >= 
$PRESENTPROTO_REQUIRED])
+PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED])
 fi

 # find the DRI deps for libGL
-dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 
1.8"
+dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 
1.8 xcb-dri3 xcb-present xcb-sync xshmfence"

 # add xf86vidmode if available
 PKG_CHECK_MODULES([XF86VIDMODE], [xxf86vm], HAVE_XF86VIDMODE=yes, 
HAVE_XF86VIDMODE=no)
@@ -833,8 +839,8 @@ xyesno)

 PKG_CHECK_MODULES([DRIGL], [$dri_modules])
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV $dri_modules"
-X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS"
-GL_LIB_DEPS="$DRIGL_LIBS"
+X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS $LIBUDEV_CFLAGS"
+GL_LIB_DEPS="$DRIGL_LIBS $LIBUDEV_LIBS"

 # need DRM libs, $PTHREAD_LIBS, etc.
 GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm $PTHREAD_LIBS $DLOPEN_LIBS"
diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am
index f01709b..854025d 100644
--- a/src/glx/Makefile.am
+++ b/src/glx/Makefile.am
@@ -92,6 +92,8 @@ libglx_la_SOURCES = \
  glxhash.c \
  dri2_glx.c \
  dri2.c \
+  dri3_glx.c \
+  dri3_common.c \
  applegl_glx.c

 GL_LIBS = \
diff --git a/src/glx/dri3_common.c b/src/glx/dri3_common.c
new file mode 100644
index 000..c758f96
--- /dev/null
+++ b/src/glx/dri3_common.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright ? 2013 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * This code is derived from src/egl/drivers/dri2/common.c which
+ * carries the following copyright:
+ * 
+ * Copyright ? 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MER

[PATCH 7/8] dri: add __DRIimageLoaderExtension and __DRIimageDriverExtension

2013-11-04 Thread Keith Packard
These provide an interface between the driver and the loader to allocate
color buffers through the DRIimage extension interface rather than through a
loader-specific extension (as is used by DRI2, for instance).

The driver uses the loader 'getBuffers' interface to allocate color buffers.

The loader uses the createNewScreen2, createNewDrawable, createNewContext,
getAPIMask and createContextAttribs APIS (mostly shared with DRI2).

This interface will work with the DRI3 loader, and should also work with GBM
and other loaders so that drivers need not be customized for each new loader
interface, as long as they provide this image interface.

Signed-off-by: Keith Packard 
---
 include/GL/internal/dri_interface.h   | 112 +
 src/mesa/drivers/dri/common/dri_util.c| 113 +
 src/mesa/drivers/dri/common/dri_util.h|   6 ++
 src/mesa/drivers/dri/i915/intel_context.c | 111 -
 src/mesa/drivers/dri/i915/intel_mipmap_tree.c |  33 
 src/mesa/drivers/dri/i915/intel_mipmap_tree.h |   8 ++
 src/mesa/drivers/dri/i915/intel_screen.c  |   1 +
 src/mesa/drivers/dri/i965/brw_context.c   | 114 --
 src/mesa/drivers/dri/i965/brw_context.h   |  16 ++--
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c |  61 ++
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h |   8 ++
 src/mesa/drivers/dri/i965/intel_screen.c  |   5 +-
 12 files changed, 568 insertions(+), 20 deletions(-)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 907aeca..8fc1fa6 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -86,6 +86,10 @@ typedef struct __DRIdri2LoaderExtensionRec   
__DRIdri2LoaderExtension;
 typedef struct __DRI2flushExtensionRec __DRI2flushExtension;
 typedef struct __DRI2throttleExtensionRec  __DRI2throttleExtension;

+
+typedef struct __DRIimageLoaderExtensionRec __DRIimageLoaderExtension;
+typedef struct __DRIimageDriverExtensionRec __DRIimageDriverExtension;
+
 /*@}*/


@@ -1288,4 +1292,112 @@ typedef struct __DRIDriverVtableExtensionRec {
 const struct __DriverAPIRec *vtable;
 } __DRIDriverVtableExtension;

+/**
+ * Image Loader extension. Drivers use this to allocate color buffers
+ */
+
+#define __DRI_DRIVER_EXTENSIONS "__driDriverExtensions"
+
+enum __DRIimageBufferMask {
+   __DRI_IMAGE_BUFFER_BACK = (1 << 0),
+   __DRI_IMAGE_BUFFER_FRONT = (1 << 1)
+};
+
+struct __DRIimageList {
+   __DRIimage *back;
+   __DRIimage *front;
+};
+
+#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
+#define __DRI_IMAGE_LOADER_VERSION 1
+
+struct __DRIimageLoaderExtensionRec {
+__DRIextension base;
+
+   /**
+* Allocate color buffers.
+*
+* \param driDrawable
+* \param width  Width of allocated buffers
+* \param height Height of allocated buffers
+* \param format one of __DRI_IMAGE_FORMAT_*
+* \param stamp  Address of variable to be updated when
+*   getBuffers must be called again
+* \param loaderPrivate  The loaderPrivate for driDrawable
+* \param buffer_maskSet of buffers to allocate
+* \param buffersReturned buffers
+*/
+   int (*getBuffers)(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int format,
+ uint32_t *stamp,
+ void *loaderPrivate,
+ uint32_t buffer_mask,
+ struct __DRIimageList *buffers);
+
+/**
+ * Flush pending front-buffer rendering
+ *
+ * Any rendering that has been performed to the
+ * fake front will be flushed to the front
+ *
+ * \param driDrawableDrawable whose front-buffer is to be flushed
+ * \param loaderPrivate  Loader's private data that was previously passed
+ *   into __DRIdri2ExtensionRec::createNewDrawable
+ */
+void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate);
+};
+
+/**
+ * DRI extension.
+ */
+
+//struct gl_context;
+//struct dd_function_table;
+
+typedef __DRIscreen *
+(*__DRIcreateNewScreen2)(int screen, int fd,
+ const __DRIextension **extensions,
+ const __DRIextension **driver_extensions,
+ const __DRIconfig ***driver_configs,
+ void *loaderPrivate);
+
+typedef __DRIdrawable *
+(*__DRIcreateNewDrawable)(__DRIscreen *screen,
+  const __DRIconfig *config,
+  void *loaderPrivate);
+
+typedef __DRIcontext *
+(*__DRIcreateNewContext)(__DRIscreen *screen,
+ const __DRIconfig *config,
+ __DRIcontext *shared,
+ void *loaderPrivate);
+
+typedef __DRIcontex

[PATCH 6/8] dri/i915, dri/i965: Use driGLFormatToImageFormat and driImageFormatToGLFormat

2013-11-04 Thread Keith Packard
Remove private versions of these functions

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/i915/intel_screen.c | 53 ++-
 src/mesa/drivers/dri/i965/intel_screen.c | 63 ++--
 2 files changed, 8 insertions(+), 108 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/intel_screen.c 
b/src/mesa/drivers/dri/i915/intel_screen.c
index 085e894..12113c7 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -244,32 +244,8 @@ intel_allocate_image(int dri_format, void *loaderPrivate)
 image->dri_format = dri_format;
 image->offset = 0;

-switch (dri_format) {
-case __DRI_IMAGE_FORMAT_RGB565:
-   image->format = MESA_FORMAT_RGB565;
-   break;
-case __DRI_IMAGE_FORMAT_XRGB:
-   image->format = MESA_FORMAT_XRGB;
-   break;
-case __DRI_IMAGE_FORMAT_ARGB:
-   image->format = MESA_FORMAT_ARGB;
-   break;
-case __DRI_IMAGE_FORMAT_ABGR:
-   image->format = MESA_FORMAT_RGBA_REV;
-   break;
-case __DRI_IMAGE_FORMAT_XBGR:
-   image->format = MESA_FORMAT_RGBX_REV;
-   break;
-case __DRI_IMAGE_FORMAT_R8:
-   image->format = MESA_FORMAT_R8;
-   break;
-case __DRI_IMAGE_FORMAT_GR88:
-   image->format = MESA_FORMAT_GR88;
-   break;
-case __DRI_IMAGE_FORMAT_NONE:
-   image->format = MESA_FORMAT_NONE;
-   break;
-default:
+image->format = driImageFormatToGLFormat(dri_format);
+if (image->format == 0) {
free(image);
return NULL;
 }
@@ -318,27 +294,6 @@ intel_setup_image_from_dimensions(__DRIimage *image)
image->tile_y = 0;
 }

-static inline uint32_t
-intel_dri_format(GLuint format)
-{
-   switch (format) {
-   case MESA_FORMAT_RGB565:
-  return __DRI_IMAGE_FORMAT_RGB565;
-   case MESA_FORMAT_XRGB:
-  return __DRI_IMAGE_FORMAT_XRGB;
-   case MESA_FORMAT_ARGB:
-  return __DRI_IMAGE_FORMAT_ARGB;
-   case MESA_FORMAT_RGBA_REV:
-  return __DRI_IMAGE_FORMAT_ABGR;
-   case MESA_FORMAT_R8:
-  return __DRI_IMAGE_FORMAT_R8;
-   case MESA_FORMAT_RG88:
-  return __DRI_IMAGE_FORMAT_GR88;
-   }
-
-   return MESA_FORMAT_NONE;
-}
-
 static __DRIimage *
 intel_create_image_from_name(__DRIscreen *screen,
 int width, int height, int format,
@@ -396,7 +351,7 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
image->data = loaderPrivate;
intel_region_reference(>region, irb->mt->region);
intel_setup_image_from_dimensions(image);
-   image->dri_format = intel_dri_format(image->format);
+   image->dri_format = driGLFormatToImageFormat(image->format);

rb->NeedsFinishRenderTexture = true;
return image;
@@ -450,7 +405,7 @@ intel_create_image_from_texture(__DRIcontext *context, int 
target,
image->format = obj->Image[face][level]->TexFormat;
image->data = loaderPrivate;
intel_setup_image_from_mipmap_tree(intel, image, iobj->mt, level, zoffset);
-   image->dri_format = intel_dri_format(image->format);
+   image->dri_format = driGLFormatToImageFormat(image->format);
if (image->dri_format == MESA_FORMAT_NONE) {
   *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
   free(image);
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c 
b/src/mesa/drivers/dri/i965/intel_screen.c
index b89b1a5..f9339c1 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -298,38 +298,8 @@ intel_allocate_image(int dri_format, void *loaderPrivate)
 image->dri_format = dri_format;
 image->offset = 0;

-switch (dri_format) {
-case __DRI_IMAGE_FORMAT_RGB565:
-   image->format = MESA_FORMAT_RGB565;
-   break;
-case __DRI_IMAGE_FORMAT_XRGB:
-   image->format = MESA_FORMAT_XRGB;
-   break;
-case __DRI_IMAGE_FORMAT_ARGB2101010:
-   image->format = MESA_FORMAT_ARGB2101010;
-   break;
-case __DRI_IMAGE_FORMAT_XRGB2101010:
-   image->format = MESA_FORMAT_XRGB2101010_UNORM;
-   break;
-case __DRI_IMAGE_FORMAT_ARGB:
-   image->format = MESA_FORMAT_ARGB;
-   break;
-case __DRI_IMAGE_FORMAT_ABGR:
-   image->format = MESA_FORMAT_RGBA_REV;
-   break;
-case __DRI_IMAGE_FORMAT_XBGR:
-   image->format = MESA_FORMAT_RGBX_REV;
-   break;
-case __DRI_IMAGE_FORMAT_R8:
-   image->format = MESA_FORMAT_R8;
-   break;
-case __DRI_IMAGE_FORMAT_GR88:
-   image->format = MESA_FORMAT_GR88;
-   break;
-case __DRI_IMAGE_FORMAT_NONE:
-   image->format = MESA_FORMAT_NONE;
-   break;
-default:
+image->format = driImageFormatToGLFormat(dri_format);
+if (image->format == 0) {
free(image);
return NULL;
 }
@@ -381,31 +351,6 @@ intel_setup

[PATCH 5/8] dri/common: Add functions mapping MESA_FORMAT_* <-> __DRI_IMAGE_FORMAT_*

2013-11-04 Thread Keith Packard
The __DRI_IMAGE_FORMAT codes are used by the image extension, drivers need to
be able to translate between them. Instead of duplicating this translation in
each driver, create a shared version.

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/common/dri_util.c | 62 ++
 src/mesa/drivers/dri/common/dri_util.h |  6 
 2 files changed, 68 insertions(+)

diff --git a/src/mesa/drivers/dri/common/dri_util.c 
b/src/mesa/drivers/dri/common/dri_util.c
index 95c8b41..76c8ae5 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -792,3 +792,65 @@ driUpdateFramebufferSize(struct gl_context *ctx, const 
__DRIdrawable *dPriv)
   assert(fb->Height == dPriv->h);
}
 }
+
+uint32_t
+driGLFormatToImageFormat(gl_format format)
+{
+   switch (format) {
+   case MESA_FORMAT_RGB565:
+  return __DRI_IMAGE_FORMAT_RGB565;
+   case MESA_FORMAT_XRGB:
+  return __DRI_IMAGE_FORMAT_XRGB;
+   case MESA_FORMAT_ARGB2101010:
+  return __DRI_IMAGE_FORMAT_ARGB2101010;
+   case MESA_FORMAT_XRGB2101010_UNORM:
+  return __DRI_IMAGE_FORMAT_XRGB2101010;
+   case MESA_FORMAT_ARGB:
+  return __DRI_IMAGE_FORMAT_ARGB;
+   case MESA_FORMAT_RGBA_REV:
+  return __DRI_IMAGE_FORMAT_ABGR;
+   case MESA_FORMAT_RGBX_REV:
+  return __DRI_IMAGE_FORMAT_XBGR;
+   case MESA_FORMAT_R8:
+  return __DRI_IMAGE_FORMAT_R8;
+   case MESA_FORMAT_GR88:
+  return __DRI_IMAGE_FORMAT_GR88;
+   case MESA_FORMAT_NONE:
+  return __DRI_IMAGE_FORMAT_NONE;
+   case MESA_FORMAT_SARGB8:
+  return __DRI_IMAGE_FORMAT_SARGB8;
+   default:
+  return 0;
+   }
+}
+
+gl_format
+driImageFormatToGLFormat(uint32_t image_format)
+{
+   switch (image_format) {
+   case __DRI_IMAGE_FORMAT_RGB565:
+  return MESA_FORMAT_RGB565;
+   case __DRI_IMAGE_FORMAT_XRGB:
+  return MESA_FORMAT_XRGB;
+   case __DRI_IMAGE_FORMAT_ARGB2101010:
+  return MESA_FORMAT_ARGB2101010;
+   case __DRI_IMAGE_FORMAT_XRGB2101010:
+  return MESA_FORMAT_XRGB2101010_UNORM;
+   case __DRI_IMAGE_FORMAT_ARGB:
+  return MESA_FORMAT_ARGB;
+   case __DRI_IMAGE_FORMAT_ABGR:
+  return MESA_FORMAT_RGBA_REV;
+   case __DRI_IMAGE_FORMAT_XBGR:
+  return MESA_FORMAT_RGBX_REV;
+   case __DRI_IMAGE_FORMAT_R8:
+  return MESA_FORMAT_R8;
+   case __DRI_IMAGE_FORMAT_GR88:
+  return MESA_FORMAT_GR88;
+   case __DRI_IMAGE_FORMAT_SARGB8:
+  return MESA_FORMAT_SARGB8;
+   case __DRI_IMAGE_FORMAT_NONE:
+  return MESA_FORMAT_NONE;
+   default:
+  return MESA_FORMAT_NONE;
+   }
+}
diff --git a/src/mesa/drivers/dri/common/dri_util.h 
b/src/mesa/drivers/dri/common/dri_util.h
index 5b56061..fd40769 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -271,6 +271,12 @@ struct __DRIdrawableRec {
 } dri2;
 };

+extern uint32_t
+driGLFormatToImageFormat(gl_format format);
+
+extern gl_format
+driImageFormatToGLFormat(uint32_t image_format);
+
 extern void
 dri2InvalidateDrawable(__DRIdrawable *drawable);

-- 
1.8.4.2



[PATCH 4/8] Define __DRI_IMAGE_FORMAT_SARGB8

2013-11-04 Thread Keith Packard
This format will be used by the i965 driver

Signed-off-by: Keith Packard 
---
 include/GL/internal/dri_interface.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 48993b9..907aeca 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -996,6 +996,7 @@ struct __DRIdri2ExtensionRec {
 #define __DRI_IMAGE_FORMAT_NONE 0x1008
 #define __DRI_IMAGE_FORMAT_XRGB2101010  0x1009
 #define __DRI_IMAGE_FORMAT_ARGB2101010  0x100a
+#define __DRI_IMAGE_FORMAT_SARGB8   0x100b

 #define __DRI_IMAGE_USE_SHARE  0x0001
 #define __DRI_IMAGE_USE_SCANOUT0x0002
-- 
1.8.4.2



[PATCH 3/8] dri/intel: Add explicit size parameter to intel_region_alloc_for_fd

2013-11-04 Thread Keith Packard
Instead of assuming that the size will be height * pitch, have the caller pass
in the size explicitly.

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/i915/intel_regions.c | 4 ++--
 src/mesa/drivers/dri/i915/intel_regions.h | 2 +-
 src/mesa/drivers/dri/i915/intel_screen.c  | 2 +-
 src/mesa/drivers/dri/i965/intel_regions.c | 4 ++--
 src/mesa/drivers/dri/i965/intel_regions.h | 1 +
 src/mesa/drivers/dri/i965/intel_screen.c  | 2 +-
 6 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/intel_regions.c 
b/src/mesa/drivers/dri/i915/intel_regions.c
index 44f7030..9f5b89e 100644
--- a/src/mesa/drivers/dri/i915/intel_regions.c
+++ b/src/mesa/drivers/dri/i915/intel_regions.c
@@ -209,6 +209,7 @@ struct intel_region *
 intel_region_alloc_for_fd(struct intel_screen *screen,
   GLuint cpp,
   GLuint width, GLuint height, GLuint pitch,
+  GLuint size,
   int fd, const char *name)
 {
struct intel_region *region;
@@ -216,8 +217,7 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
int ret;
uint32_t bit_6_swizzle, tiling;

-   buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr,
-   fd, height * pitch);
+   buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr, fd, size);
if (buffer == NULL)
   return NULL;
ret = drm_intel_bo_get_tiling(buffer, , _6_swizzle);
diff --git a/src/mesa/drivers/dri/i915/intel_regions.h 
b/src/mesa/drivers/dri/i915/intel_regions.h
index 5c612a9..6bc4a42 100644
--- a/src/mesa/drivers/dri/i915/intel_regions.h
+++ b/src/mesa/drivers/dri/i915/intel_regions.h
@@ -91,7 +91,7 @@ struct intel_region *
 intel_region_alloc_for_fd(struct intel_screen *screen,
   GLuint cpp,
   GLuint width, GLuint height, GLuint pitch,
-  int fd, const char *name);
+  GLuint size, int fd, const char *name);

 bool
 intel_region_flink(struct intel_region *region, uint32_t *name);
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c 
b/src/mesa/drivers/dri/i915/intel_screen.c
index 3f54752..085e894 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -653,7 +653,7 @@ intel_create_image_from_fds(__DRIscreen *screen,
   return NULL;

image->region = intel_region_alloc_for_fd(intelScreen,
- 1, width, height,
+ 1, width, height, height * 
strides[0],
  strides[0], fds[0], "image");
if (image->region == NULL) {
   free(image);
diff --git a/src/mesa/drivers/dri/i965/intel_regions.c 
b/src/mesa/drivers/dri/i965/intel_regions.c
index a6b80fd..3920f4f 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.c
+++ b/src/mesa/drivers/dri/i965/intel_regions.c
@@ -209,6 +209,7 @@ struct intel_region *
 intel_region_alloc_for_fd(struct intel_screen *screen,
   GLuint cpp,
   GLuint width, GLuint height, GLuint pitch,
+  GLuint size,
   int fd, const char *name)
 {
struct intel_region *region;
@@ -216,8 +217,7 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
int ret;
uint32_t bit_6_swizzle, tiling;

-   buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr,
-   fd, height * pitch);
+   buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr, fd, size);
if (buffer == NULL)
   return NULL;
ret = drm_intel_bo_get_tiling(buffer, , _6_swizzle);
diff --git a/src/mesa/drivers/dri/i965/intel_regions.h 
b/src/mesa/drivers/dri/i965/intel_regions.h
index f08a113..05dfef3 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.h
+++ b/src/mesa/drivers/dri/i965/intel_regions.h
@@ -92,6 +92,7 @@ struct intel_region *
 intel_region_alloc_for_fd(struct intel_screen *screen,
   GLuint cpp,
   GLuint width, GLuint height, GLuint pitch,
+  GLuint size,
   int fd, const char *name);

 bool
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c 
b/src/mesa/drivers/dri/i965/intel_screen.c
index ce8124b..b89b1a5 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -718,7 +718,7 @@ intel_create_image_from_fds(__DRIscreen *screen,
   return NULL;

image->region = intel_region_alloc_for_fd(intelScreen,
- 1, width, height,
+ 1, width, height, height * 
strides[0],
  strides[0], fds[0], "image");
if (image->region == NULL) {
   free(image);
-- 
1.8.4.2



[PATCH 2/8] dri/intel: Split out DRI2 buffer update code to separate function

2013-11-04 Thread Keith Packard
Make an easy place to splice in a DRI3 version of this function

Signed-off-by: Keith Packard 
Reviewed-by: Kristian H?gsberg 
---
 src/mesa/drivers/dri/i915/intel_context.c | 90 +--
 src/mesa/drivers/dri/i965/brw_context.c   | 22 ++--
 2 files changed, 68 insertions(+), 44 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/intel_context.c 
b/src/mesa/drivers/dri/i915/intel_context.c
index 2748514..1798bc7 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -133,15 +133,58 @@ intel_process_dri2_buffer(struct intel_context *intel,
  struct intel_renderbuffer *rb,
  const char *buffer_name);

-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+static void
+intel_update_dri2_buffers(struct intel_context *intel, __DRIdrawable *drawable)
 {
-   struct gl_framebuffer *fb = drawable->driverPrivate;
-   struct intel_renderbuffer *rb;
-   struct intel_context *intel = context->driverPrivate;
__DRIbuffer *buffers = NULL;
int i, count;
const char *region_name;
+   struct intel_renderbuffer *rb;
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+
+   intel_query_dri2_buffers(intel, drawable, , );
+
+   if (buffers == NULL)
+  return;
+
+   for (i = 0; i < count; i++) {
+  switch (buffers[i].attachment) {
+  case __DRI_BUFFER_FRONT_LEFT:
+ rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+ region_name = "dri2 front buffer";
+ break;
+
+  case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+ region_name = "dri2 fake front buffer";
+ break;
+
+  case __DRI_BUFFER_BACK_LEFT:
+ rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+ region_name = "dri2 back buffer";
+ break;
+
+  case __DRI_BUFFER_DEPTH:
+  case __DRI_BUFFER_HIZ:
+  case __DRI_BUFFER_DEPTH_STENCIL:
+  case __DRI_BUFFER_STENCIL:
+  case __DRI_BUFFER_ACCUM:
+  default:
+ fprintf(stderr,
+ "unhandled buffer attach event, attachment type %d\n",
+ buffers[i].attachment);
+ return;
+  }
+
+  intel_process_dri2_buffer(intel, drawable, [i], rb, region_name);
+   }
+}
+
+void
+intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+{
+   struct intel_context *intel = context->driverPrivate;
+   __DRIscreen *screen = intel->intelScreen->driScrnPriv;

/* Set this up front, so that in case our buffers get invalidated
 * while we're getting new buffers, we don't clobber the stamp and
@@ -151,42 +194,7 @@ intel_update_renderbuffers(__DRIcontext *context, 
__DRIdrawable *drawable)
if (unlikely(INTEL_DEBUG & DEBUG_DRI))
   fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);

-   intel_query_dri2_buffers(intel, drawable, , );
-
-   if (buffers == NULL)
-  return;
-
-   for (i = 0; i < count; i++) {
-   switch (buffers[i].attachment) {
-   case __DRI_BUFFER_FRONT_LEFT:
-  rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-  region_name = "dri2 front buffer";
-  break;
-
-   case __DRI_BUFFER_FAKE_FRONT_LEFT:
-  rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-  region_name = "dri2 fake front buffer";
-  break;
-
-   case __DRI_BUFFER_BACK_LEFT:
-  rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
-  region_name = "dri2 back buffer";
-  break;
-
-   case __DRI_BUFFER_DEPTH:
-   case __DRI_BUFFER_HIZ:
-   case __DRI_BUFFER_DEPTH_STENCIL:
-   case __DRI_BUFFER_STENCIL:
-   case __DRI_BUFFER_ACCUM:
-   default:
-  fprintf(stderr,
-  "unhandled buffer attach event, attachment type %d\n",
-  buffers[i].attachment);
-  return;
-   }
-
-   intel_process_dri2_buffer(intel, drawable, [i], rb, 
region_name);
-   }
+   intel_update_dri2_buffers(intel, drawable);

driUpdateFramebufferSize(>ctx, drawable);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_context.c 
b/src/mesa/drivers/dri/i965/brw_context.c
index 13569ad..2557d10 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -978,12 +978,11 @@ intel_process_dri2_buffer(struct brw_context *brw,
   struct intel_renderbuffer *rb,
   const char *buffer_name);

-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+static void
+intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable)
 {
struct gl_framebuffer *fb = drawable->driverPrivate;
struct intel_renderbuffer *rb;
-   struct brw_context *brw = context->driverPrivate;
__DRIbuffer *buffers

[PATCH 1/8] drivers/dri/common: A few dri2 functions are not actually DRI2 specific

2013-11-04 Thread Keith Packard
This just renames them so that they can be used with the DRI3 extension
without causing too much confusion.

Signed-off-by: Keith Packard 
Reviewed-by: Kristian H?gsberg 
---
 src/mesa/drivers/dri/common/dri_util.c | 58 +-
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/src/mesa/drivers/dri/common/dri_util.c 
b/src/mesa/drivers/dri/common/dri_util.c
index c28b0fc..95c8b41 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -291,13 +291,13 @@ validate_context_version(__DRIscreen *screen,
 /*@{*/

 static __DRIcontext *
-dri2CreateContextAttribs(__DRIscreen *screen, int api,
-const __DRIconfig *config,
-__DRIcontext *shared,
-unsigned num_attribs,
-const uint32_t *attribs,
-unsigned *error,
-void *data)
+driCreateContextAttribs(__DRIscreen *screen, int api,
+const __DRIconfig *config,
+__DRIcontext *shared,
+unsigned num_attribs,
+const uint32_t *attribs,
+unsigned *error,
+void *data)
 {
 __DRIcontext *context;
 const struct gl_config *modes = (config != NULL) ? >modes : NULL;
@@ -442,22 +442,22 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api,
 }

 static __DRIcontext *
-dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
-  const __DRIconfig *config,
-  __DRIcontext *shared, void *data)
+driCreateNewContextForAPI(__DRIscreen *screen, int api,
+  const __DRIconfig *config,
+  __DRIcontext *shared, void *data)
 {
 unsigned error;

-return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL,
-   , data);
+return driCreateContextAttribs(screen, api, config, shared, 0, NULL,
+   , data);
 }

 static __DRIcontext *
-dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
- __DRIcontext *shared, void *data)
+driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+__DRIcontext *shared, void *data)
 {
-return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
- config, shared, data);
+return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
+ config, shared, data);
 }

 /**
@@ -609,9 +609,9 @@ static void dri_put_drawable(__DRIdrawable *pdp)
 }

 static __DRIdrawable *
-dri2CreateNewDrawable(__DRIscreen *screen,
- const __DRIconfig *config,
- void *data)
+driCreateNewDrawable(__DRIscreen *screen,
+ const __DRIconfig *config,
+ void *data)
 {
 __DRIdrawable *pdraw;

@@ -698,7 +698,7 @@ dri2ConfigQueryf(__DRIscreen *screen, const char *var, 
GLfloat *val)
 }

 static unsigned int
-dri2GetAPIMask(__DRIscreen *screen)
+driGetAPIMask(__DRIscreen *screen)
 {
 return screen->api_mask;
 }
@@ -729,7 +729,7 @@ const __DRIcoreExtension driCoreExtension = {
 .createNewDrawable  = NULL,
 .destroyDrawable= driDestroyDrawable,
 .swapBuffers= driSwapBuffers, /* swrast */
-.createNewContext   = dri2CreateNewContext, /* swrast */
+.createNewContext   = driCreateNewContext, /* swrast */
 .copyContext= driCopyContext,
 .destroyContext = driDestroyContext,
 .bindContext= driBindContext,
@@ -741,22 +741,22 @@ const __DRIdri2Extension driDRI2Extension = {
 .base = { __DRI_DRI2, 4 },

 .createNewScreen= dri2CreateNewScreen,
-.createNewDrawable  = dri2CreateNewDrawable,
-.createNewContext   = dri2CreateNewContext,
-.getAPIMask = dri2GetAPIMask,
-.createNewContextForAPI = dri2CreateNewContextForAPI,
+.createNewDrawable  = driCreateNewDrawable,
+.createNewContext   = driCreateNewContext,
+.getAPIMask = driGetAPIMask,
+.createNewContextForAPI = driCreateNewContextForAPI,
 .allocateBuffer = dri2AllocateBuffer,
 .releaseBuffer  = dri2ReleaseBuffer,
-.createContextAttribs   = dri2CreateContextAttribs,
+.createContextAttribs   = driCreateContextAttribs,
 .createNewScreen2   = dri2CreateNewScreen2,
 };

 const __DRIswrastExtension driSWRastExtension = {
 { __DRI_SWRAST, 4 },
 driSWRastCreateNewScreen,
-dri2CreateNewDrawable,
-dri2CreateNewContextForAPI,
-dri2CreateContextAttribs,
+driCreateNewDrawable,
+driCreateNewContextForAPI,
+driCreateContextAttribs,
 driSWRastCreateNewS

[PATCH 0/8] Add DRIimage-based DRI3/Present loader

2013-11-04 Thread Keith Packard
This sequence first adds a a couple of new DRIimage extensions to the
dri/common, dri/i915 and dri/i965 directories which define a
loader-independent API for managing window system operations.

The last patch adds a new DRI3000 loader using those new interfaces.



[PATCH 5/6] dri3: Add DRI3 support to GLX, DRI common and Intel driver

2013-11-03 Thread Keith Packard
Kristian H?gsberg  writes:

> I sent a reply to the sourceforge addresses in the original emails,
> but I didn't see it show up in the archives.  Trying again with the
> freedesktop addresses.

(sorry for having an ancient shell script with sourceforge addresses in
it)

>> +typedef uint32_t *
>> +(*__DRIdri3Stamp)(__DRIdrawable *drawable);
>
> This looks OK, as long as it's not tied into the xcb special_event
> semantics.  From the way it's used, it looks like a loader can just
> increment this uint32_t when it needs to invalidate the buffer.  Still
> seems like an odd API - a invalidate function would be simpler, but
> I'm guessing it's limited by what you can do if you receive the
> special event in a different thread.

Yeah, I definitely do not want a callback function here. The API was
actually designed from the DRI2 side, not the xcb side as DRI2 has this
uint32_t already sitting there that just needed poking.

> With those changes, we can reuse __DRIimage for DRI3 which makes a lot
> of sense.  The GBM and Wayland backends already use __DRIimage for
> color buffers, but convert them to __DRI2buffer to be able to pass
> them into the DRI driver.  Being able to pass a __DRIimage into the
> driver in getBuffers will simplify those backends, and it should be
> fairly simple to port them to the dri3 driver interface.

Ok, so the first step would be to convert drivers from __DRI2buffer to
__DRIimage, at which point it should be trivial to use __DRIimage to
support DRI3? Or should I just take my existing __DRI3buffer code and
change that into a __DRIimage API and leave the __DRI2buffer code around
in the driver to support DRI2?

I'm game for either approach, but fixing the drivers to export a single
API that can support all of the window systems sure seems like a better
long-term plan...

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 6/6] Make GLX/dri3 use the Present extension when available

2013-10-31 Thread Keith Packard
This uses the Present extension with DRI3, which includes OML_Sync extension
support.

Signed-off-by: Keith Packard 
---
 configure.ac|   4 +-
 include/GL/internal/dri_interface.h |   1 +
 src/glx/dri3_glx.c  | 421 ++--
 src/glx/dri3_priv.h |  50 -
 4 files changed, 313 insertions(+), 163 deletions(-)

diff --git a/configure.ac b/configure.ac
index b6158d9..c91f031 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,6 +39,7 @@ LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41"
 LIBDRM_FREEDRENO_REQUIRED=2.4.39
 DRI2PROTO_REQUIRED=2.6
 DRI3PROTO_REQUIRED=1.0
+PRESENTPROTO_REQUIRED=1.0
 LIBUDEV_REQUIRED=151
 GLPROTO_REQUIRED=1.4.14
 LIBDRM_XORG_REQUIRED=2.4.24
@@ -823,11 +824,12 @@ xyesno)
 PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED"
 PKG_CHECK_MODULES([DRI3PROTO], [dri3proto >= $DRI3PROTO_REQUIRED])
+PKG_CHECK_MODULES([PRESENTPROTO], [presentproto >= 
$PRESENTPROTO_REQUIRED])
 PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED])
 fi

 # find the DRI deps for libGL
-dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 
1.8 xcb-dri3 xcb-sync xshmfence"
+dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 
1.8 xcb-dri3 xcb-present xcb-sync xshmfence"

 # add xf86vidmode if available
 PKG_CHECK_MODULES([XF86VIDMODE], [xxf86vm], HAVE_XF86VIDMODE=yes, 
HAVE_XF86VIDMODE=no)
diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index b06ad8d..b508a18 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -991,6 +991,7 @@ struct __DRIdri3BufferRec {
uint32_t pixmap;
uint32_t sync_fence;
int32_t *shm_fence;
+   GLboolean busy;
void *driverPrivate;
 };

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 4d275f2..6db984a 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -74,39 +74,24 @@
 #include 
 #include 
 #include 
+
 #include "xf86drm.h"
 #include "dri_common.h"
 #include "dri3_priv.h"

 static const struct glx_context_vtable dri3_context_vtable;

-#define HAS_SBC 0
-
-#if HAS_SBC
-
-/* For XCB's handling of ust/msc/sbc counters, we have to hand it the high and
- * low halves separately.  This helps you split them.
- */
-static void
-split_counter(uint64_t counter, uint32_t *hi, uint32_t *lo)
-{
-   *hi = (counter >> 32);
-   *lo = counter & 0x;
-}
-
-static uint64_t
-merge_counter(uint32_t hi, uint32_t lo)
-{
-   return ((uint64_t)hi << 32) | lo;
-}
-#endif /* HAS_SBC */
-
 static inline void
 dri3_fence_reset(xcb_connection_t *c, __DRIdri3Buffer *buffer) {
xshmfence_reset(buffer->shm_fence);
 }

 static inline void
+dri3_fence_set(__DRIdri3Buffer *buffer) {
+   xshmfence_trigger(buffer->shm_fence);
+}
+
+static inline void
 dri3_fence_trigger(xcb_connection_t *c, __DRIdri3Buffer *buffer) {
xcb_sync_trigger_fence(c, buffer->sync_fence);
 }
@@ -117,6 +102,11 @@ dri3_fence_await(xcb_connection_t *c, __DRIdri3Buffer 
*buffer) {
xshmfence_await(buffer->shm_fence);
 }

+static inline Bool
+dri3_fence_triggered(__DRIdri3Buffer *buffer) {
+   return xshmfence_query(buffer->shm_fence);
+}
+
 static void
 dri3_destroy_context(struct glx_context *context)
 {
@@ -375,27 +365,44 @@ dri3_create_drawable(struct glx_screen *base, XID 
xDrawable,
return >base;
 }

-#if HAS_SBC
-static int
-dri3_drawable_get_msc(struct glx_screen *psc, __GLXDRIdrawable *pdraw,
-  int64_t *ust, int64_t *msc, int64_t *sbc)
+static void
+present_handle_special_event(struct dri3_drawable *priv, 
xcb_present_generic_event_t *ge)
 {
-   xcb_connection_t *c = XGetXCBConnection(pdraw->psc->dpy);
-   xcb_dri2_get_msc_cookie_t get_msc_cookie;
-   xcb_dri2_get_msc_reply_t *get_msc_reply;
+   switch (ge->evtype) {
+   case XCB_PRESENT_CONFIGURE_NOTIFY: {
+  xcb_present_configure_notify_event_t *ce = (void *) ge;

-   get_msc_cookie = xcb_dri2_get_msc_unchecked(c, pdraw->xDrawable);
-   get_msc_reply = xcb_dri2_get_msc_reply(c, get_msc_cookie, NULL);
+  priv->width = ce->width;
+  priv->height = ce->height;
+  break;
+   }
+   case XCB_PRESENT_COMPLETE_NOTIFY: {
+  xcb_present_complete_notify_event_t *ce = (void *) ge;

-   if (!get_msc_reply)
-  return 0;
+  if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP)
+ priv->present_event_serial = ce->serial;
+  else
+ priv->present_msc_event_serial = ce->serial;
+  priv->ust = ce->ust;
+  priv->msc = ce->msc;
+  break;
+   }
+   case XCB_PRESENT_EVENT_IDLE_NOTIFY: {
+  xcb_present_idle_notify_event_t *ie = (void *) ge;
+  int b;

-   *

[PATCH 5/6] dri3: Add DRI3 support to GLX, DRI common and Intel driver

2013-10-31 Thread Keith Packard
This hooks DRI3 support into the GLX layer, the DRI common layer and the Intel
driver.

Signed-off-by: Keith Packard 
---
 configure.ac  |   10 +-
 include/GL/internal/dri_interface.h   |  158 +++
 src/glx/Makefile.am   |2 +
 src/glx/dri3_common.c |  146 +++
 src/glx/dri3_glx.c| 1539 +
 src/glx/dri3_priv.h   |  128 ++
 src/glx/glxclient.h   |2 +
 src/glx/glxext.c  |6 +-
 src/mesa/drivers/dri/common/dri_util.c|  163 ++-
 src/mesa/drivers/dri/common/dri_util.h|   23 +
 src/mesa/drivers/dri/i915/intel_context.c |  109 +-
 src/mesa/drivers/dri/i915/intel_mipmap_tree.c |   33 +
 src/mesa/drivers/dri/i915/intel_mipmap_tree.h |8 +
 src/mesa/drivers/dri/i965/brw_context.c   |  110 +-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c |   61 +
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h |8 +
 src/mesa/drivers/dri/i965/intel_screen.c  |  107 +-
 17 files changed, 2594 insertions(+), 19 deletions(-)
 create mode 100644 src/glx/dri3_common.c
 create mode 100644 src/glx/dri3_glx.c
 create mode 100644 src/glx/dri3_priv.h

diff --git a/configure.ac b/configure.ac
index f94c9b9..b6158d9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,6 +38,8 @@ LIBDRM_NVVIEUX_REQUIRED=2.4.33
 LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41"
 LIBDRM_FREEDRENO_REQUIRED=2.4.39
 DRI2PROTO_REQUIRED=2.6
+DRI3PROTO_REQUIRED=1.0
+LIBUDEV_REQUIRED=151
 GLPROTO_REQUIRED=1.4.14
 LIBDRM_XORG_REQUIRED=2.4.24
 LIBKMS_XORG_REQUIRED=1.0.0
@@ -820,10 +822,12 @@ xyesno)
 fi
 PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED"
+PKG_CHECK_MODULES([DRI3PROTO], [dri3proto >= $DRI3PROTO_REQUIRED])
+PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED])
 fi

 # find the DRI deps for libGL
-dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 
1.8"
+dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 
1.8 xcb-dri3 xcb-sync xshmfence"

 # add xf86vidmode if available
 PKG_CHECK_MODULES([XF86VIDMODE], [xxf86vm], HAVE_XF86VIDMODE=yes, 
HAVE_XF86VIDMODE=no)
@@ -833,8 +837,8 @@ xyesno)

 PKG_CHECK_MODULES([DRIGL], [$dri_modules])
 GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV $dri_modules"
-X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS"
-GL_LIB_DEPS="$DRIGL_LIBS"
+X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS $LIBUDEV_CFLAGS"
+GL_LIB_DEPS="$DRIGL_LIBS $LIBUDEV_LIBS"

 # need DRM libs, $PTHREAD_LIBS, etc.
 GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm $PTHREAD_LIBS $DLOPEN_LIBS"
diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 48993b9..b06ad8d 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -86,6 +86,11 @@ typedef struct __DRIdri2LoaderExtensionRec   
__DRIdri2LoaderExtension;
 typedef struct __DRI2flushExtensionRec __DRI2flushExtension;
 typedef struct __DRI2throttleExtensionRec  __DRI2throttleExtension;

+
+typedef struct __DRIdri3BufferRec   __DRIdri3Buffer;
+typedef struct __DRIdri3ExtensionRec__DRIdri3Extension;
+typedef struct __DRIdri3LoaderExtensionRec  __DRIdri3LoaderExtension;
+
 /*@}*/


@@ -966,6 +971,159 @@ struct __DRIdri2ExtensionRec {


 /**
+ * DRI3 Loader extension.
+ */
+
+#define __DRI3_DRIVER_EXTENSIONS "__dri3DriverExtensions"
+
+enum __DRI3bufferType {
+   __DRI3_BUFFER_BACK = 0,
+   __DRI3_BUFFER_FRONT = 1
+};
+
+struct __DRIdri3BufferRec {
+   unsigned int size;
+   unsigned int pitch;
+   unsigned int cpp;
+   unsigned int flags;
+   unsigned int width, height;
+   enum __DRI3bufferType buffer_type;
+   uint32_t pixmap;
+   uint32_t sync_fence;
+   int32_t *shm_fence;
+   void *driverPrivate;
+};
+
+#define __DRI_DRI3_LOADER "DRI_DRI3Loader"
+#define __DRI_DRI3_LOADER_VERSION 1
+
+struct __DRIdri3LoaderExtensionRec {
+__DRIextension base;
+
+   int (*getBuffers)(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int format,
+ void *loaderPrivate,
+ int need_front,
+ int need_back,
+ __DRIdri3Buffer **front,
+ __DRIdri3Buffer **back);
+
+/**
+ * Flush pending front-buffer rendering
+ *
+ * Any rendering that has been performed to the
+ * \c __DRI3_BUFFER_FAKE_FRONT_LEFT will be flushed to the
+ * \c __DRI3_BUFFER_FRONT_LEFT.
+ *
+ * \param driDrawableDrawable whose front-buffer is to be flushed
+ * \param loaderPriva

[PATCH 4/6] dri/intel: Add intel_fd_for_region

2013-10-31 Thread Keith Packard
Returns a prime file descriptor for the specified region.

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/i915/intel_regions.c | 13 +
 src/mesa/drivers/dri/i915/intel_regions.h |  4 
 src/mesa/drivers/dri/i965/intel_regions.c | 13 +
 src/mesa/drivers/dri/i965/intel_regions.h |  4 
 4 files changed, 34 insertions(+)

diff --git a/src/mesa/drivers/dri/i915/intel_regions.c 
b/src/mesa/drivers/dri/i915/intel_regions.c
index 9f5b89e..bac997d 100644
--- a/src/mesa/drivers/dri/i915/intel_regions.c
+++ b/src/mesa/drivers/dri/i915/intel_regions.c
@@ -238,6 +238,19 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
return region;
 }

+int
+intel_fd_for_region(struct intel_screen *screen,
+struct intel_region *region)
+{
+   int  fd;
+   int  ret;
+
+   ret = drm_intel_bo_gem_export_to_prime(region->bo, );
+   if (ret < 0)
+  return ret;
+   return fd;
+}
+
 void
 intel_region_reference(struct intel_region **dst, struct intel_region *src)
 {
diff --git a/src/mesa/drivers/dri/i915/intel_regions.h 
b/src/mesa/drivers/dri/i915/intel_regions.h
index 6bc4a42..84c013a 100644
--- a/src/mesa/drivers/dri/i915/intel_regions.h
+++ b/src/mesa/drivers/dri/i915/intel_regions.h
@@ -93,6 +93,10 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
   GLuint width, GLuint height, GLuint pitch,
   GLuint size, int fd, const char *name);

+int
+intel_fd_for_region(struct intel_screen *screen,
+struct intel_region *region);
+
 bool
 intel_region_flink(struct intel_region *region, uint32_t *name);

diff --git a/src/mesa/drivers/dri/i965/intel_regions.c 
b/src/mesa/drivers/dri/i965/intel_regions.c
index 3920f4f..2e70326 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.c
+++ b/src/mesa/drivers/dri/i965/intel_regions.c
@@ -238,6 +238,19 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
return region;
 }

+int
+intel_fd_for_region(struct intel_screen *screen,
+struct intel_region *region)
+{
+   int  fd;
+   int  ret;
+
+   ret = drm_intel_bo_gem_export_to_prime(region->bo, );
+   if (ret < 0)
+  return ret;
+   return fd;
+}
+
 void
 intel_region_reference(struct intel_region **dst, struct intel_region *src)
 {
diff --git a/src/mesa/drivers/dri/i965/intel_regions.h 
b/src/mesa/drivers/dri/i965/intel_regions.h
index 05dfef3..f471b94 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.h
+++ b/src/mesa/drivers/dri/i965/intel_regions.h
@@ -95,6 +95,10 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
   GLuint size,
   int fd, const char *name);

+int
+intel_fd_for_region(struct intel_screen *screen,
+struct intel_region *region);
+
 bool
 intel_region_flink(struct intel_region *region, uint32_t *name);

-- 
1.8.4.2


--
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951=/4140/ostg.clktrk
--
___
Dri-devel mailing list
Dri-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


[PATCH 2/6] dri/intel: Split out DRI2 buffer update code to separate function

2013-10-31 Thread Keith Packard
Make an easy place to splice in a DRI3 version of this function

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/i915/intel_context.c | 90 +--
 src/mesa/drivers/dri/i965/brw_context.c   | 22 ++--
 2 files changed, 68 insertions(+), 44 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/intel_context.c 
b/src/mesa/drivers/dri/i915/intel_context.c
index 2748514..1798bc7 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -133,15 +133,58 @@ intel_process_dri2_buffer(struct intel_context *intel,
  struct intel_renderbuffer *rb,
  const char *buffer_name);

-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+static void
+intel_update_dri2_buffers(struct intel_context *intel, __DRIdrawable *drawable)
 {
-   struct gl_framebuffer *fb = drawable->driverPrivate;
-   struct intel_renderbuffer *rb;
-   struct intel_context *intel = context->driverPrivate;
__DRIbuffer *buffers = NULL;
int i, count;
const char *region_name;
+   struct intel_renderbuffer *rb;
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+
+   intel_query_dri2_buffers(intel, drawable, , );
+
+   if (buffers == NULL)
+  return;
+
+   for (i = 0; i < count; i++) {
+  switch (buffers[i].attachment) {
+  case __DRI_BUFFER_FRONT_LEFT:
+ rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+ region_name = "dri2 front buffer";
+ break;
+
+  case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+ region_name = "dri2 fake front buffer";
+ break;
+
+  case __DRI_BUFFER_BACK_LEFT:
+ rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+ region_name = "dri2 back buffer";
+ break;
+
+  case __DRI_BUFFER_DEPTH:
+  case __DRI_BUFFER_HIZ:
+  case __DRI_BUFFER_DEPTH_STENCIL:
+  case __DRI_BUFFER_STENCIL:
+  case __DRI_BUFFER_ACCUM:
+  default:
+ fprintf(stderr,
+ "unhandled buffer attach event, attachment type %d\n",
+ buffers[i].attachment);
+ return;
+  }
+
+  intel_process_dri2_buffer(intel, drawable, [i], rb, region_name);
+   }
+}
+
+void
+intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+{
+   struct intel_context *intel = context->driverPrivate;
+   __DRIscreen *screen = intel->intelScreen->driScrnPriv;

/* Set this up front, so that in case our buffers get invalidated
 * while we're getting new buffers, we don't clobber the stamp and
@@ -151,42 +194,7 @@ intel_update_renderbuffers(__DRIcontext *context, 
__DRIdrawable *drawable)
if (unlikely(INTEL_DEBUG & DEBUG_DRI))
   fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);

-   intel_query_dri2_buffers(intel, drawable, , );
-
-   if (buffers == NULL)
-  return;
-
-   for (i = 0; i < count; i++) {
-   switch (buffers[i].attachment) {
-   case __DRI_BUFFER_FRONT_LEFT:
-  rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-  region_name = "dri2 front buffer";
-  break;
-
-   case __DRI_BUFFER_FAKE_FRONT_LEFT:
-  rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-  region_name = "dri2 fake front buffer";
-  break;
-
-   case __DRI_BUFFER_BACK_LEFT:
-  rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
-  region_name = "dri2 back buffer";
-  break;
-
-   case __DRI_BUFFER_DEPTH:
-   case __DRI_BUFFER_HIZ:
-   case __DRI_BUFFER_DEPTH_STENCIL:
-   case __DRI_BUFFER_STENCIL:
-   case __DRI_BUFFER_ACCUM:
-   default:
-  fprintf(stderr,
-  "unhandled buffer attach event, attachment type %d\n",
-  buffers[i].attachment);
-  return;
-   }
-
-   intel_process_dri2_buffer(intel, drawable, [i], rb, 
region_name);
-   }
+   intel_update_dri2_buffers(intel, drawable);

driUpdateFramebufferSize(>ctx, drawable);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_context.c 
b/src/mesa/drivers/dri/i965/brw_context.c
index 38147e9..c213b31 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -929,12 +929,11 @@ intel_process_dri2_buffer(struct brw_context *brw,
   struct intel_renderbuffer *rb,
   const char *buffer_name);

-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+static void
+intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable)
 {
struct gl_framebuffer *fb = drawable->driverPrivate;
struct intel_renderbuffer *rb;
-   struct brw_context *brw = context->driverPrivate;
__DRIbuffer *buffers = NULL;
int i, coun

[PATCH 1/6] drivers/dri/common: A few dri2 functions are not actually DRI2 specific

2013-10-31 Thread Keith Packard
This just renames them so that they can be used with the DRI3 extension
without causing too much confusion.

Signed-off-by: Keith Packard 
---
 src/mesa/drivers/dri/common/dri_util.c | 50 +-
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/src/mesa/drivers/dri/common/dri_util.c 
b/src/mesa/drivers/dri/common/dri_util.c
index c28b0fc..539fb4b 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -291,13 +291,13 @@ validate_context_version(__DRIscreen *screen,
 /*@{*/

 static __DRIcontext *
-dri2CreateContextAttribs(__DRIscreen *screen, int api,
-const __DRIconfig *config,
-__DRIcontext *shared,
-unsigned num_attribs,
-const uint32_t *attribs,
-unsigned *error,
-void *data)
+driCreateContextAttribs(__DRIscreen *screen, int api,
+const __DRIconfig *config,
+__DRIcontext *shared,
+unsigned num_attribs,
+const uint32_t *attribs,
+unsigned *error,
+void *data)
 {
 __DRIcontext *context;
 const struct gl_config *modes = (config != NULL) ? >modes : NULL;
@@ -442,22 +442,22 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api,
 }

 static __DRIcontext *
-dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
-  const __DRIconfig *config,
-  __DRIcontext *shared, void *data)
+driCreateNewContextForAPI(__DRIscreen *screen, int api,
+  const __DRIconfig *config,
+  __DRIcontext *shared, void *data)
 {
 unsigned error;

-return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL,
-   , data);
+return driCreateContextAttribs(screen, api, config, shared, 0, NULL,
+   , data);
 }

 static __DRIcontext *
-dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
- __DRIcontext *shared, void *data)
+driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+__DRIcontext *shared, void *data)
 {
-return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
- config, shared, data);
+return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
+ config, shared, data);
 }

 /**
@@ -609,9 +609,9 @@ static void dri_put_drawable(__DRIdrawable *pdp)
 }

 static __DRIdrawable *
-dri2CreateNewDrawable(__DRIscreen *screen,
- const __DRIconfig *config,
- void *data)
+driCreateNewDrawable(__DRIscreen *screen,
+ const __DRIconfig *config,
+ void *data)
 {
 __DRIdrawable *pdraw;

@@ -698,7 +698,7 @@ dri2ConfigQueryf(__DRIscreen *screen, const char *var, 
GLfloat *val)
 }

 static unsigned int
-dri2GetAPIMask(__DRIscreen *screen)
+driGetAPIMask(__DRIscreen *screen)
 {
 return screen->api_mask;
 }
@@ -741,13 +741,13 @@ const __DRIdri2Extension driDRI2Extension = {
 .base = { __DRI_DRI2, 4 },

 .createNewScreen= dri2CreateNewScreen,
-.createNewDrawable  = dri2CreateNewDrawable,
-.createNewContext   = dri2CreateNewContext,
-.getAPIMask = dri2GetAPIMask,
-.createNewContextForAPI = dri2CreateNewContextForAPI,
+.createNewDrawable  = driCreateNewDrawable,
+.createNewContext   = driCreateNewContext,
+.getAPIMask = driGetAPIMask,
+.createNewContextForAPI = driCreateNewContextForAPI,
 .allocateBuffer = dri2AllocateBuffer,
 .releaseBuffer  = dri2ReleaseBuffer,
-.createContextAttribs   = dri2CreateContextAttribs,
+.createContextAttribs   = driCreateContextAttribs
 .createNewScreen2   = dri2CreateNewScreen2,
 };

-- 
1.8.4.2


--
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951=/4140/ostg.clktrk
--
___
Dri-devel mailing list
Dri-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


[PATCH 0/6] Add DRI3000 support to core and i965 drivers

2013-10-31 Thread Keith Packard
The first four patches prepare the library for DRI3, then the final two
patches add DRI3 and Present support.

Minor changes:
 [PATCH 1/6] drivers/dri/common: A few dri2 functions are not actually
 [PATCH 2/6] dri/intel: Split out DRI2 buffer update code to separate
 [PATCH 3/6] dri/intel: Add explicit size parameter to
 [PATCH 4/6] dri/intel: Add intel_fd_for_region

New code:
 [PATCH 5/6] dri3: Add DRI3 support to GLX, DRI common and Intel
 [PATCH 6/6] Make GLX/dri3 use the Present extension when available

--
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951=/4140/ostg.clktrk
--
___
Dri-devel mailing list
Dri-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


[PATCH 2/2] drm/i915: Add async page flip support for SNB

2013-07-25 Thread Keith Packard
Just copies the IVB code

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_display.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 166aa2c..4a118c3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7465,20 +7465,29 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = _priv->ring[RCS];
uint32_t pf, pipesrc;
+   uint32_t cmd;
+   uint32_t base;
int ret;

ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
if (ret)
goto err;

+   cmd = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset;
+
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;

-   intel_ring_emit(ring, MI_DISPLAY_FLIP |
-   MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode);
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc->dspaddr_offset);
+   intel_ring_emit(ring, base);

/* Contrary to the suggestions in the documentation,
 * "Enable Panel Fitter" does not seem to be required when page
@@ -9731,7 +9740,7 @@ void intel_modeset_init(struct drm_device *dev)
dev->mode_config.max_height = 8192;
}

-   if (IS_GEN7(dev))
+   if (IS_GEN6(dev) || IS_GEN7(dev))
dev->mode_config.async_page_flip = true;

dev->mode_config.fb_base = dev_priv->gtt.mappable_base;
-- 
1.8.3.2



[PATCH 1/2] drm/i915: Add async page flip support for IVB

2013-07-25 Thread Keith Packard
This adds the necesary register defines for async page flipping
through the command ring, and then hooks those up for Ivybridge (gen7)
page flipping.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 ++
 drivers/gpu/drm/i915/intel_display.c | 37 
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dc3d6a7..029cfb0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -209,6 +209,7 @@
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
 #define MI_DISPLAY_FLIPMI_INSTR(0x14, 2)
 #define MI_DISPLAY_FLIP_I915   MI_INSTR(0x14, 1)
+#define   MI_DISPLAY_FLIP_ASYNC_INDICATOR  (1 << 22)
 #define   MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
 /* IVB has funny definitions for which plane to flip. */
 #define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0 << 19)
@@ -217,6 +218,11 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
+/* These go in the bottom of the base address value */
+#define   MI_DISPLAY_FLIP_TYPE_SYNC(0 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_ASYNC   (1 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_STEREO  (2 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_SYNCHRONOUS (0 << 0)
 #define MI_ARB_ON_OFF  MI_INSTR(0x08, 0)
 #define   MI_ARB_ENABLE(1<<0)
 #define   MI_ARB_DISABLE   (0<<0)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bdb8854..166aa2c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1833,8 +1833,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
alignment = 64 * 1024;
break;
case I915_TILING_X:
-   /* pin() will align the object as required by fence */
-   alignment = 0;
+   /* Async page flipping requires X tiling and 32kB alignment, so 
just
+* make all X tiled frame buffers aligned for that
+*/
+   alignment = 32 * 1024;
break;
case I915_TILING_Y:
/* Despite that we check this in framebuffer_init userspace can
@@ -7514,6 +7516,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = _priv->ring[BCS];
uint32_t plane_bit = 0;
+   uint32_t cmd;
+   uint32_t base;
int ret;

ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
@@ -7536,13 +7540,21 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
goto err_unpin;
}

+   cmd = MI_DISPLAY_FLIP_I915 | plane_bit;
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset;
+
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;

-   intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc->dspaddr_offset);
+   intel_ring_emit(ring, base);
intel_ring_emit(ring, (MI_NOOP));

intel_mark_page_flip_active(intel_crtc);
@@ -7591,6 +7603,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 fb->pitches[0] != crtc->fb->pitches[0]))
return -EINVAL;

+   /* Check tiling restrictions specific to asynchronous flips
+*/
+   if (page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* New FB must be X tiled */
+   if (obj->tiling_mode != I915_TILING_X)
+   return -EINVAL;
+
+   /* Current FB must be X tiled */
+   if (to_intel_framebuffer(old_fb)->obj->tiling_mode != 
I915_TILING_X)
+   return -EINVAL;
+   }
+
work = kzalloc(sizeof *work, GFP_KERNEL);
if (work == NULL)
return -ENOMEM;
@@ -9705,6 +9730,10 @@ void intel_modeset_init(struct drm_device *dev)
dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192;
}
+
+   if (IS_GEN7(dev))
+   dev->mode_config.async_page_flip = true;
+
dev->mode_config.fb_base = dev_priv->gtt.mappable_base;

DRM_DEBUG_KMS("%d display pipe%s available.\n",
-- 
1.8.3.2



[PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-25 Thread Keith Packard
> Generally I think checking our current sw state instead of reading hw
> registers would be safer, e.g. in case we start to queue up more than
> one pageflip. For async pageflips in benchmark mode "flip as fast as
> you can queue" would be a sensible mode.

Ok, I've moved the tiling checks to the general code and removed the
stride checks as those are already present there. These were moved to
the general code because the pointer to the previous FB has already
been overwritten by the time the queue_flip functions are called.

This should be followed by replacements for the last to patches in the
series.

-keith



[PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-25 Thread Keith Packard
Daniel Vetter  writes:

> On Wed, Jul 24, 2013 at 06:40:16PM -0700, Keith Packard wrote:
>> Daniel Vetter  writes:
>> 
>> > We could just unconditionally increase the alignement in
>> > intel_pin_and_fence_fb_obj - we already have more strict requirements due
>> > to a bunch of w/a in other places. So shouldn't hurt at all really.
>> 
>> That seems like a fine plan; 32kB isn't that onerous. Do you want the
>> trivial patch to do this from me then?
>
> Yes please, merging patches from other people is much easier than begging for
> review for my own ;-)
> -Daniel

Here's a replacement for patch #4 that just adds the alignment
requirement there. Do you want any other changes in this series?


Re: [PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-25 Thread Keith Packard
Daniel Vetter dan...@ffwll.ch writes:

 On Wed, Jul 24, 2013 at 06:40:16PM -0700, Keith Packard wrote:
 Daniel Vetter dan...@ffwll.ch writes:
 
  We could just unconditionally increase the alignement in
  intel_pin_and_fence_fb_obj - we already have more strict requirements due
  to a bunch of w/a in other places. So shouldn't hurt at all really.
 
 That seems like a fine plan; 32kB isn't that onerous. Do you want the
 trivial patch to do this from me then?

 Yes please, merging patches from other people is much easier than begging for
 review for my own ;-)
 -Daniel

Here's a replacement for patch #4 that just adds the alignment
requirement there. Do you want any other changes in this series?

From 9a51e7118fce58c835cabb192f6b6e0a4a5f6660 Mon Sep 17 00:00:00 2001
From: Keith Packard kei...@keithp.com
Date: Mon, 22 Jul 2013 18:12:28 -0700
Subject: [PATCH 4/5] drm/i915: Add async page flip support for IVB

This adds the necesary register defines for async page flipping
through the command ring, and then hooks those up for Ivybridge (gen7)
page flipping.

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 +
 drivers/gpu/drm/i915/intel_display.c | 46 
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dc3d6a7..029cfb0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -209,6 +209,7 @@
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
 #define MI_DISPLAY_FLIPMI_INSTR(0x14, 2)
 #define MI_DISPLAY_FLIP_I915   MI_INSTR(0x14, 1)
+#define   MI_DISPLAY_FLIP_ASYNC_INDICATOR  (1  22)
 #define   MI_DISPLAY_FLIP_PLANE(n) ((n)  20)
 /* IVB has funny definitions for which plane to flip. */
 #define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0  19)
@@ -217,6 +218,11 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3  19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4  19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5  19)
+/* These go in the bottom of the base address value */
+#define   MI_DISPLAY_FLIP_TYPE_SYNC(0  0)
+#define   MI_DISPLAY_FLIP_TYPE_ASYNC   (1  0)
+#define   MI_DISPLAY_FLIP_TYPE_STEREO  (2  0)
+#define   MI_DISPLAY_FLIP_TYPE_SYNCHRONOUS (0  0)
 #define MI_ARB_ON_OFF  MI_INSTR(0x08, 0)
 #define   MI_ARB_ENABLE(10)
 #define   MI_ARB_DISABLE   (00)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bdb8854..f2624a4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1833,8 +1833,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
alignment = 64 * 1024;
break;
case I915_TILING_X:
-   /* pin() will align the object as required by fence */
-   alignment = 0;
+   /* Async page flipping requires X tiling and 32kB alignment, so 
just
+* make all X tiled frame buffers aligned for that
+*/
+   alignment = 32 * 1024;
break;
case I915_TILING_Y:
/* Despite that we check this in framebuffer_init userspace can
@@ -7514,6 +7516,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = dev_priv-ring[BCS];
uint32_t plane_bit = 0;
+   uint32_t cmd;
+   uint32_t base;
int ret;
 
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
@@ -7536,13 +7540,43 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
goto err_unpin;
}
 
+   cmd = MI_DISPLAY_FLIP_I915 | plane_bit;
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc-dspaddr_offset;
+
+   if (flags  DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* XXX check limitations for async flip here */
+
+   if (fb-pitches[0] != I915_READ(DSPSTRIDE(intel_crtc-plane))) {
+   WARN_ONCE(1, mismatching stride in async plane flip 
(%d != %d)\n,
+ fb-pitches[0], 
I915_READ(DSPSTRIDE(intel_crtc-plane)));
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if (obj-tiling_mode != I915_TILING_X) {
+   WARN_ONCE(1, async plane flip requires X tiling\n);
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if ((I915_READ(DSPCNTR(intel_crtc-plane))  DISPPLANE_TILED) 
== 0) {
+   WARN_ONCE(1, display not currently tiled in async 
plane flip\n);
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+   
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret

Re: [PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-25 Thread Keith Packard
 Generally I think checking our current sw state instead of reading hw
 registers would be safer, e.g. in case we start to queue up more than
 one pageflip. For async pageflips in benchmark mode flip as fast as
 you can queue would be a sensible mode.

Ok, I've moved the tiling checks to the general code and removed the
stride checks as those are already present there. These were moved to
the general code because the pointer to the previous FB has already
been overwritten by the time the queue_flip functions are called.

This should be followed by replacements for the last to patches in the
series.

-keith

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] drm/i915: Add async page flip support for IVB

2013-07-25 Thread Keith Packard
This adds the necesary register defines for async page flipping
through the command ring, and then hooks those up for Ivybridge (gen7)
page flipping.

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 ++
 drivers/gpu/drm/i915/intel_display.c | 37 
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dc3d6a7..029cfb0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -209,6 +209,7 @@
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
 #define MI_DISPLAY_FLIPMI_INSTR(0x14, 2)
 #define MI_DISPLAY_FLIP_I915   MI_INSTR(0x14, 1)
+#define   MI_DISPLAY_FLIP_ASYNC_INDICATOR  (1  22)
 #define   MI_DISPLAY_FLIP_PLANE(n) ((n)  20)
 /* IVB has funny definitions for which plane to flip. */
 #define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0  19)
@@ -217,6 +218,11 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3  19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4  19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5  19)
+/* These go in the bottom of the base address value */
+#define   MI_DISPLAY_FLIP_TYPE_SYNC(0  0)
+#define   MI_DISPLAY_FLIP_TYPE_ASYNC   (1  0)
+#define   MI_DISPLAY_FLIP_TYPE_STEREO  (2  0)
+#define   MI_DISPLAY_FLIP_TYPE_SYNCHRONOUS (0  0)
 #define MI_ARB_ON_OFF  MI_INSTR(0x08, 0)
 #define   MI_ARB_ENABLE(10)
 #define   MI_ARB_DISABLE   (00)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bdb8854..166aa2c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1833,8 +1833,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
alignment = 64 * 1024;
break;
case I915_TILING_X:
-   /* pin() will align the object as required by fence */
-   alignment = 0;
+   /* Async page flipping requires X tiling and 32kB alignment, so 
just
+* make all X tiled frame buffers aligned for that
+*/
+   alignment = 32 * 1024;
break;
case I915_TILING_Y:
/* Despite that we check this in framebuffer_init userspace can
@@ -7514,6 +7516,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = dev_priv-ring[BCS];
uint32_t plane_bit = 0;
+   uint32_t cmd;
+   uint32_t base;
int ret;
 
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
@@ -7536,13 +7540,21 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
goto err_unpin;
}
 
+   cmd = MI_DISPLAY_FLIP_I915 | plane_bit;
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc-dspaddr_offset;
+
+   if (flags  DRM_MODE_PAGE_FLIP_ASYNC) {
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;
 
-   intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, (fb-pitches[0] | obj-tiling_mode));
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc-dspaddr_offset);
+   intel_ring_emit(ring, base);
intel_ring_emit(ring, (MI_NOOP));
 
intel_mark_page_flip_active(intel_crtc);
@@ -7591,6 +7603,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 fb-pitches[0] != crtc-fb-pitches[0]))
return -EINVAL;
 
+   /* Check tiling restrictions specific to asynchronous flips
+*/
+   if (page_flip_flags  DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* New FB must be X tiled */
+   if (obj-tiling_mode != I915_TILING_X)
+   return -EINVAL;
+
+   /* Current FB must be X tiled */
+   if (to_intel_framebuffer(old_fb)-obj-tiling_mode != 
I915_TILING_X)
+   return -EINVAL;
+   }
+
work = kzalloc(sizeof *work, GFP_KERNEL);
if (work == NULL)
return -ENOMEM;
@@ -9705,6 +9730,10 @@ void intel_modeset_init(struct drm_device *dev)
dev-mode_config.max_width = 8192;
dev-mode_config.max_height = 8192;
}
+
+   if (IS_GEN7(dev))
+   dev-mode_config.async_page_flip = true;
+
dev-mode_config.fb_base = dev_priv-gtt.mappable_base;
 
DRM_DEBUG_KMS(%d display pipe%s available.\n,
-- 
1.8.3.2

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/2] drm/i915: Add async page flip support for SNB

2013-07-25 Thread Keith Packard
Just copies the IVB code

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/intel_display.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 166aa2c..4a118c3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7465,20 +7465,29 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = dev_priv-ring[RCS];
uint32_t pf, pipesrc;
+   uint32_t cmd;
+   uint32_t base;
int ret;
 
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
if (ret)
goto err;
 
+   cmd = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc-plane);
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc-dspaddr_offset;
+
+   if (flags  DRM_MODE_PAGE_FLIP_ASYNC) {
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;
 
-   intel_ring_emit(ring, MI_DISPLAY_FLIP |
-   MI_DISPLAY_FLIP_PLANE(intel_crtc-plane));
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, fb-pitches[0] | obj-tiling_mode);
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc-dspaddr_offset);
+   intel_ring_emit(ring, base);
 
/* Contrary to the suggestions in the documentation,
 * Enable Panel Fitter does not seem to be required when page
@@ -9731,7 +9740,7 @@ void intel_modeset_init(struct drm_device *dev)
dev-mode_config.max_height = 8192;
}
 
-   if (IS_GEN7(dev))
+   if (IS_GEN6(dev) || IS_GEN7(dev))
dev-mode_config.async_page_flip = true;
 
dev-mode_config.fb_base = dev_priv-gtt.mappable_base;
-- 
1.8.3.2

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-24 Thread Keith Packard
Daniel Vetter  writes:

> We could just unconditionally increase the alignement in
> intel_pin_and_fence_fb_obj - we already have more strict requirements due
> to a bunch of w/a in other places. So shouldn't hurt at all really.

That seems like a fine plan; 32kB isn't that onerous. Do you want the
trivial patch to do this from me then?

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-24 Thread Keith Packard
Daniel Vetter  writes:

> Matching tiling modes is actually already a requirement on gen4+ (since
> the tiling bit and the linear/tiled offset registers can't be changed with
> a MI_DISPLAY_FLIP command).

Async flip has a harder requirement -- you must use X tiling, both
before and after the flip. Oh, and async flips require a 32KB aligned
buffer, which I'm not actually checking for. Not sure how to

> But atm we fail to check that in the common
> code, so imo better to move that to there.
>
> We already check for matching strides in common code, so with the tile
> check added we could drop this all here.

I don't see a requirement for matching stride and tile parameter in the
MI_DISPLAY_FLIP docs for synchronous operations, at least on DevGT+. Is
the common code too restrictive?

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



Re: [PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-24 Thread Keith Packard
Daniel Vetter dan...@ffwll.ch writes:

 Matching tiling modes is actually already a requirement on gen4+ (since
 the tiling bit and the linear/tiled offset registers can't be changed with
 a MI_DISPLAY_FLIP command).

Async flip has a harder requirement -- you must use X tiling, both
before and after the flip. Oh, and async flips require a 32KB aligned
buffer, which I'm not actually checking for. Not sure how to

 But atm we fail to check that in the common
 code, so imo better to move that to there.

 We already check for matching strides in common code, so with the tile
 check added we could drop this all here.

I don't see a requirement for matching stride and tile parameter in the
MI_DISPLAY_FLIP docs for synchronous operations, at least on DevGT+. Is
the common code too restrictive?

-- 
keith.pack...@intel.com


pgprumBf5456S.pgp
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-24 Thread Keith Packard
Daniel Vetter dan...@ffwll.ch writes:

 We could just unconditionally increase the alignement in
 intel_pin_and_fence_fb_obj - we already have more strict requirements due
 to a bunch of w/a in other places. So shouldn't hurt at all really.

That seems like a fine plan; 32kB isn't that onerous. Do you want the
trivial patch to do this from me then?

-- 
keith.pack...@intel.com


pgpjExiw41dvt.pgp
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


drm: Asynchronouse page flipping interface and Intel implementation

2013-07-23 Thread Keith Packard
Daniel Vetter  writes:

> Quick comments on the i915 kernel part:
> - Iirc the w/a database has a bunch of entries about async flips. Those
>   need to be addressed and annoted with the new w/a tag comment format
>   Damien recently created.

Where does this database live?

> - kms_flip needs to be extended to beat on async flips. Obviously the
>   timing checks don't apply but otherwise I think it won't hurt to enable
>   all the existing interaction tests with async flips, too. On top of that
>   I think we should test interactions between async flips and vblank
>   synced flips. Without the timing checks the other tests will run as fast
>   as possible, so that should gives us good coverage of the
>   non-ratelimited nature of async flips - even with vblank flips we've hit
>   ugly issues by e.g. starving the unpin workers.

async flips are still somewhat rate-limited -- the actual buffer flip
happens on a scanline boundary instead of a frame boundary, so we still
take an interrupt and report an event back to user mode. There are
worrying comments in the bspec which say that an async flip queued
during vblank may actually take a couple of scanlines *past* the vblank
interval before it takes effect. Because of the delay, the code path
differences between the two cases are limited to just setting the bits
in the hardware, which leaves me fairly confident in our ability to test
both cases successfully.

> Oh and my little comment about moving all checks into core code is a bit
> wrong, we'd still need to check for X-tiling with async flips ofc.


[PATCH 5/5] drm/i915: Add async page flip support for SNB

2013-07-22 Thread Keith Packard
Just copies the IVB code

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_display.c | 39 
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 1bcc6b4..9d7919b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7463,20 +7463,51 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = _priv->ring[RCS];
uint32_t pf, pipesrc;
+   uint32_t cmd;
+   uint32_t base;
int ret;

ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
if (ret)
goto err;

+   cmd = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset;
+
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* XXX check limitations for async flip here */
+
+   if (fb->pitches[0] != I915_READ(DSPSTRIDE(intel_crtc->plane))) {
+   WARN_ONCE(1, "mismatching stride in async plane flip 
(%d != %d)\n",
+ fb->pitches[0], 
I915_READ(DSPSTRIDE(intel_crtc->plane)));
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if (obj->tiling_mode != I915_TILING_X) {
+   WARN_ONCE(1, "async plane flip requires X tiling\n");
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if ((I915_READ(DSPCNTR(intel_crtc->plane)) & DISPPLANE_TILED) 
== 0) {
+   WARN_ONCE(1, "display not currently tiled in async 
plane flip\n");
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+   
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;

-   intel_ring_emit(ring, MI_DISPLAY_FLIP |
-   MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode);
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc->dspaddr_offset);
+   intel_ring_emit(ring, base);

/* Contrary to the suggestions in the documentation,
 * "Enable Panel Fitter" does not seem to be required when page
@@ -9738,7 +9769,7 @@ void intel_modeset_init(struct drm_device *dev)
dev->mode_config.max_height = 8192;
}

-   if (IS_GEN7(dev))
+   if (IS_GEN6(dev) || IS_GEN7(dev))
dev->mode_config.async_page_flip = true;

dev->mode_config.fb_base = dev_priv->gtt.mappable_base;
-- 
1.8.3.2



[PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-22 Thread Keith Packard
This adds the necesary register defines for async page flipping
through the command ring, and then hooks those up for Ivybridge (gen7)
page flipping.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 ++
 drivers/gpu/drm/i915/intel_display.c | 40 ++--
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dc3d6a7..029cfb0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -209,6 +209,7 @@
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
 #define MI_DISPLAY_FLIPMI_INSTR(0x14, 2)
 #define MI_DISPLAY_FLIP_I915   MI_INSTR(0x14, 1)
+#define   MI_DISPLAY_FLIP_ASYNC_INDICATOR  (1 << 22)
 #define   MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
 /* IVB has funny definitions for which plane to flip. */
 #define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0 << 19)
@@ -217,6 +218,11 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
+/* These go in the bottom of the base address value */
+#define   MI_DISPLAY_FLIP_TYPE_SYNC(0 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_ASYNC   (1 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_STEREO  (2 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_SYNCHRONOUS (0 << 0)
 #define MI_ARB_ON_OFF  MI_INSTR(0x08, 0)
 #define   MI_ARB_ENABLE(1<<0)
 #define   MI_ARB_DISABLE   (0<<0)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bdb8854..1bcc6b4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7514,6 +7514,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = _priv->ring[BCS];
uint32_t plane_bit = 0;
+   uint32_t cmd;
+   uint32_t base;
int ret;

ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
@@ -7536,13 +7538,43 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
goto err_unpin;
}

+   cmd = MI_DISPLAY_FLIP_I915 | plane_bit;
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset;
+
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* XXX check limitations for async flip here */
+
+   if (fb->pitches[0] != I915_READ(DSPSTRIDE(intel_crtc->plane))) {
+   WARN_ONCE(1, "mismatching stride in async plane flip 
(%d != %d)\n",
+ fb->pitches[0], 
I915_READ(DSPSTRIDE(intel_crtc->plane)));
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if (obj->tiling_mode != I915_TILING_X) {
+   WARN_ONCE(1, "async plane flip requires X tiling\n");
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if ((I915_READ(DSPCNTR(intel_crtc->plane)) & DISPPLANE_TILED) 
== 0) {
+   WARN_ONCE(1, "display not currently tiled in async 
plane flip\n");
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+   
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;

-   intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc->dspaddr_offset);
+   intel_ring_emit(ring, base);
intel_ring_emit(ring, (MI_NOOP));

intel_mark_page_flip_active(intel_crtc);
@@ -9705,6 +9737,10 @@ void intel_modeset_init(struct drm_device *dev)
dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192;
}
+
+   if (IS_GEN7(dev))
+   dev->mode_config.async_page_flip = true;
+
dev->mode_config.fb_base = dev_priv->gtt.mappable_base;

DRM_DEBUG_KMS("%d display pipe%s available.\n",
-- 
1.8.3.2



[PATCH 3/5] drm: Advertise async page flip ability through GETCAP ioctl

2013-07-22 Thread Keith Packard
Let applications know whether the kernel supports asynchronous page
flipping.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/drm_crtc.c  | 3 +++
 drivers/gpu/drm/drm_ioctl.c | 3 +++
 include/drm/drm_crtc.h  | 3 +++
 include/uapi/drm/drm.h  | 1 +
 4 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 989072c..0909af6 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3514,6 +3514,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
page_flip->reserved != 0)
return -EINVAL;

+   if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && 
!dev->mode_config.async_page_flip)
+   return -EINVAL;
+
obj = drm_mode_object_find(dev, page_flip->crtc_id, 
DRM_MODE_OBJECT_CRTC);
if (!obj)
return -EINVAL;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index ffd7a7b..7602177 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -303,6 +303,9 @@ int drm_getcap(struct drm_device *dev, void *data, struct 
drm_file *file_priv)
case DRM_CAP_TIMESTAMP_MONOTONIC:
req->value = drm_timestamp_monotonic;
break;
+   case DRM_CAP_ASYNC_PAGE_FLIP:
+   req->value = dev->mode_config.async_page_flip;
+   break;
default:
return -EINVAL;
}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 0820ab6..13d215f 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -845,6 +845,9 @@ struct drm_mode_config {

/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;
+
+   /* whether async page flip is supported or not */
+   bool async_page_flip;
 };

 #define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 238a166..2adfaa5 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -780,6 +780,7 @@ struct drm_event_vblank {
 #define DRM_CAP_DUMB_PREFER_SHADOW 0x4
 #define DRM_CAP_PRIME 0x5
 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
+#define DRM_CAP_ASYNC_PAGE_FLIP 0x7

 #define DRM_PRIME_CAP_IMPORT 0x1
 #define DRM_PRIME_CAP_EXPORT 0x2
-- 
1.8.3.2



[PATCH 2/5] drm: Add DRM_MODE_PAGE_FLIP_ASYNC flag definition

2013-07-22 Thread Keith Packard
This requests that the driver perform the page flip as soon as
possible, not necessarily waiting for vblank.

Signed-off-by: Keith Packard 
---
 include/uapi/drm/drm_mode.h | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 53db7ce..5508117 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -412,7 +412,8 @@ struct drm_mode_crtc_lut {
 };

 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
-#define DRM_MODE_PAGE_FLIP_FLAGS DRM_MODE_PAGE_FLIP_EVENT
+#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
+#define DRM_MODE_PAGE_FLIP_FLAGS 
(DRM_MODE_PAGE_FLIP_EVENT|DRM_MODE_PAGE_FLIP_ASYNC)

 /*
  * Request a page flip on the specified crtc.
@@ -426,11 +427,14 @@ struct drm_mode_crtc_lut {
  * flip is already pending as the ioctl is called, EBUSY will be
  * returned.
  *
- * The ioctl supports one flag, DRM_MODE_PAGE_FLIP_EVENT, which will
- * request that drm sends back a vblank event (see drm.h: struct
- * drm_event_vblank) when the page flip is done.  The user_data field
- * passed in with this ioctl will be returned as the user_data field
- * in the vblank event struct.
+ * Flag DRM_MODE_PAGE_FLIP_EVENT requests that drm sends back a vblank
+ * event (see drm.h: struct drm_event_vblank) when the page flip is
+ * done.  The user_data field passed in with this ioctl will be
+ * returned as the user_data field in the vblank event struct.
+ *
+ * Flag DRM_MODE_PAGE_FLIP_ASYNC requests that the flip happen
+ * 'as soon as possible', meaning that it not delay waiting for vblank.
+ * This may cause tearing on the screen.
  *
  * The reserved field must be zero until we figure out something
  * clever to use it for.
-- 
1.8.3.2



[PATCH 1/5] drm: Pass page flip ioctl flags to driver

2013-07-22 Thread Keith Packard
This lets drivers see the flags requested by the application

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/drm_crtc.c|  2 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |  5 +++--
 drivers/gpu/drm/i915/i915_drv.h   |  3 ++-
 drivers/gpu/drm/i915/intel_display.c  | 23 +++
 drivers/gpu/drm/nouveau/nouveau_display.c |  3 ++-
 drivers/gpu/drm/nouveau/nouveau_display.h |  3 ++-
 drivers/gpu/drm/omapdrm/omap_crtc.c   |  3 ++-
 drivers/gpu/drm/radeon/radeon_display.c   |  3 ++-
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c |  3 ++-
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c  |  3 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  3 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h   |  3 ++-
 include/drm/drm_crtc.h|  3 ++-
 13 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fc83bb9..989072c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3587,7 +3587,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
}

old_fb = crtc->fb;
-   ret = crtc->funcs->page_flip(crtc, fb, e);
+   ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
if (ret) {
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
spin_lock_irqsave(>event_lock, flags);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 9a35d17..14f5c1d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -184,8 +184,9 @@ static struct drm_crtc_helper_funcs 
exynos_crtc_helper_funcs = {
 };

 static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event)
+struct drm_framebuffer *fb,
+struct drm_pending_vblank_event *event,
+uint32_t page_flip_flags)
 {
struct drm_device *dev = crtc->dev;
struct exynos_drm_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cef35d3..c7cb2de 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -380,7 +380,8 @@ struct drm_i915_display_funcs {
void (*init_clock_gating)(struct drm_device *dev);
int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
  struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj);
+ struct drm_i915_gem_object *obj,
+ uint32_t flags);
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y);
void (*hpd_irq_setup)(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index ae3dc5d..bdb8854 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7320,7 +7320,8 @@ inline static void intel_mark_page_flip_active(struct 
intel_crtc *intel_crtc)
 static int intel_gen2_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,
 struct drm_framebuffer *fb,
-struct drm_i915_gem_object *obj)
+struct drm_i915_gem_object *obj,
+uint32_t flags)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7364,7 +7365,8 @@ err:
 static int intel_gen3_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,
 struct drm_framebuffer *fb,
-struct drm_i915_gem_object *obj)
+struct drm_i915_gem_object *obj,
+uint32_t flags)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7405,7 +7407,8 @@ err:
 static int intel_gen4_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,
 struct drm_framebuffer *fb,
-struct drm_i915_gem_object *obj)
+struct drm_i915_gem_object *obj,
+uint32_t flags)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7453,7 +7456,8 @@ err:
 static int intel_gen6_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,

drm: Asynchronouse page flipping interface and Intel implementation

2013-07-22 Thread Keith Packard
Here's a sequence of five patches that exposes an interface to request
of the driver that the page flipping request be executed without
waiting for vblank. It's optional, and drivers can expose whether it
is supported through the existing GETCAP ioctl.

This supports only Ivybridge and Sandybridge Intel graphics chips as
that's what I've got to test on; of course all of the other drivers
have been modified so that they still compile cleanly.


--
keith.packard at intel.com



[PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-22 Thread Keith Packard
This adds the necesary register defines for async page flipping
through the command ring, and then hooks those up for Ivybridge (gen7)
page flipping.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 +
 drivers/gpu/drm/i915/intel_display.c | 46 
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dc3d6a7..029cfb0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -209,6 +209,7 @@
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
 #define MI_DISPLAY_FLIPMI_INSTR(0x14, 2)
 #define MI_DISPLAY_FLIP_I915   MI_INSTR(0x14, 1)
+#define   MI_DISPLAY_FLIP_ASYNC_INDICATOR  (1 << 22)
 #define   MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
 /* IVB has funny definitions for which plane to flip. */
 #define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0 << 19)
@@ -217,6 +218,11 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
+/* These go in the bottom of the base address value */
+#define   MI_DISPLAY_FLIP_TYPE_SYNC(0 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_ASYNC   (1 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_STEREO  (2 << 0)
+#define   MI_DISPLAY_FLIP_TYPE_SYNCHRONOUS (0 << 0)
 #define MI_ARB_ON_OFF  MI_INSTR(0x08, 0)
 #define   MI_ARB_ENABLE(1<<0)
 #define   MI_ARB_DISABLE   (0<<0)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bdb8854..f2624a4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1833,8 +1833,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
alignment = 64 * 1024;
break;
case I915_TILING_X:
-   /* pin() will align the object as required by fence */
-   alignment = 0;
+   /* Async page flipping requires X tiling and 32kB alignment, so 
just
+* make all X tiled frame buffers aligned for that
+*/
+   alignment = 32 * 1024;
break;
case I915_TILING_Y:
/* Despite that we check this in framebuffer_init userspace can
@@ -7514,6 +7516,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = _priv->ring[BCS];
uint32_t plane_bit = 0;
+   uint32_t cmd;
+   uint32_t base;
int ret;

ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
@@ -7536,13 +7540,43 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
goto err_unpin;
}

+   cmd = MI_DISPLAY_FLIP_I915 | plane_bit;
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset;
+
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* XXX check limitations for async flip here */
+
+   if (fb->pitches[0] != I915_READ(DSPSTRIDE(intel_crtc->plane))) {
+   WARN_ONCE(1, "mismatching stride in async plane flip 
(%d != %d)\n",
+ fb->pitches[0], 
I915_READ(DSPSTRIDE(intel_crtc->plane)));
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if (obj->tiling_mode != I915_TILING_X) {
+   WARN_ONCE(1, "async plane flip requires X tiling\n");
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if ((I915_READ(DSPCNTR(intel_crtc->plane)) & DISPPLANE_TILED) 
== 0) {
+   WARN_ONCE(1, "display not currently tiled in async 
plane flip\n");
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+   
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;

-   intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc->dspaddr_offset);
+   intel_ring_emit(ring, base);
intel_ring_emit(ring, (MI_NOOP));

intel_mark_page_flip_active(intel_crtc);
@@ -9705,6 +9739,10 @@ void intel_modeset_init(struct drm_device *dev)
dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192;
}
+
+   if (IS_GEN7(dev))
+   dev->mode_config.async_page_flip = true;
+
dev-&g

[PATCH 2/5] drm: Add DRM_MODE_PAGE_FLIP_ASYNC flag definition

2013-07-22 Thread Keith Packard
This requests that the driver perform the page flip as soon as
possible, not necessarily waiting for vblank.

Signed-off-by: Keith Packard kei...@keithp.com
---
 include/uapi/drm/drm_mode.h | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 53db7ce..5508117 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -412,7 +412,8 @@ struct drm_mode_crtc_lut {
 };
 
 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
-#define DRM_MODE_PAGE_FLIP_FLAGS DRM_MODE_PAGE_FLIP_EVENT
+#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
+#define DRM_MODE_PAGE_FLIP_FLAGS 
(DRM_MODE_PAGE_FLIP_EVENT|DRM_MODE_PAGE_FLIP_ASYNC)
 
 /*
  * Request a page flip on the specified crtc.
@@ -426,11 +427,14 @@ struct drm_mode_crtc_lut {
  * flip is already pending as the ioctl is called, EBUSY will be
  * returned.
  *
- * The ioctl supports one flag, DRM_MODE_PAGE_FLIP_EVENT, which will
- * request that drm sends back a vblank event (see drm.h: struct
- * drm_event_vblank) when the page flip is done.  The user_data field
- * passed in with this ioctl will be returned as the user_data field
- * in the vblank event struct.
+ * Flag DRM_MODE_PAGE_FLIP_EVENT requests that drm sends back a vblank
+ * event (see drm.h: struct drm_event_vblank) when the page flip is
+ * done.  The user_data field passed in with this ioctl will be
+ * returned as the user_data field in the vblank event struct.
+ *
+ * Flag DRM_MODE_PAGE_FLIP_ASYNC requests that the flip happen
+ * 'as soon as possible', meaning that it not delay waiting for vblank.
+ * This may cause tearing on the screen.
  *
  * The reserved field must be zero until we figure out something
  * clever to use it for.
-- 
1.8.3.2

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


drm: Asynchronouse page flipping interface and Intel implementation

2013-07-22 Thread Keith Packard
Here's a sequence of five patches that exposes an interface to request
of the driver that the page flipping request be executed without
waiting for vblank. It's optional, and drivers can expose whether it
is supported through the existing GETCAP ioctl.

This supports only Ivybridge and Sandybridge Intel graphics chips as
that's what I've got to test on; of course all of the other drivers
have been modified so that they still compile cleanly.


--
keith.pack...@intel.com

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/5] drm: Pass page flip ioctl flags to driver

2013-07-22 Thread Keith Packard
This lets drivers see the flags requested by the application

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/drm_crtc.c|  2 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |  5 +++--
 drivers/gpu/drm/i915/i915_drv.h   |  3 ++-
 drivers/gpu/drm/i915/intel_display.c  | 23 +++
 drivers/gpu/drm/nouveau/nouveau_display.c |  3 ++-
 drivers/gpu/drm/nouveau/nouveau_display.h |  3 ++-
 drivers/gpu/drm/omapdrm/omap_crtc.c   |  3 ++-
 drivers/gpu/drm/radeon/radeon_display.c   |  3 ++-
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c |  3 ++-
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c  |  3 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  3 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h   |  3 ++-
 include/drm/drm_crtc.h|  3 ++-
 13 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fc83bb9..989072c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3587,7 +3587,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
}
 
old_fb = crtc-fb;
-   ret = crtc-funcs-page_flip(crtc, fb, e);
+   ret = crtc-funcs-page_flip(crtc, fb, e, page_flip-flags);
if (ret) {
if (page_flip-flags  DRM_MODE_PAGE_FLIP_EVENT) {
spin_lock_irqsave(dev-event_lock, flags);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 9a35d17..14f5c1d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -184,8 +184,9 @@ static struct drm_crtc_helper_funcs 
exynos_crtc_helper_funcs = {
 };
 
 static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event)
+struct drm_framebuffer *fb,
+struct drm_pending_vblank_event *event,
+uint32_t page_flip_flags)
 {
struct drm_device *dev = crtc-dev;
struct exynos_drm_private *dev_priv = dev-dev_private;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cef35d3..c7cb2de 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -380,7 +380,8 @@ struct drm_i915_display_funcs {
void (*init_clock_gating)(struct drm_device *dev);
int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
  struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj);
+ struct drm_i915_gem_object *obj,
+ uint32_t flags);
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y);
void (*hpd_irq_setup)(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index ae3dc5d..bdb8854 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7320,7 +7320,8 @@ inline static void intel_mark_page_flip_active(struct 
intel_crtc *intel_crtc)
 static int intel_gen2_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,
 struct drm_framebuffer *fb,
-struct drm_i915_gem_object *obj)
+struct drm_i915_gem_object *obj,
+uint32_t flags)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7364,7 +7365,8 @@ err:
 static int intel_gen3_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,
 struct drm_framebuffer *fb,
-struct drm_i915_gem_object *obj)
+struct drm_i915_gem_object *obj,
+uint32_t flags)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7405,7 +7407,8 @@ err:
 static int intel_gen4_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,
 struct drm_framebuffer *fb,
-struct drm_i915_gem_object *obj)
+struct drm_i915_gem_object *obj,
+uint32_t flags)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7453,7 +7456,8 @@ err:
 static int intel_gen6_queue_flip(struct drm_device *dev,
 struct drm_crtc *crtc,
 struct

[PATCH 3/5] drm: Advertise async page flip ability through GETCAP ioctl

2013-07-22 Thread Keith Packard
Let applications know whether the kernel supports asynchronous page
flipping.

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/drm_crtc.c  | 3 +++
 drivers/gpu/drm/drm_ioctl.c | 3 +++
 include/drm/drm_crtc.h  | 3 +++
 include/uapi/drm/drm.h  | 1 +
 4 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 989072c..0909af6 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3514,6 +3514,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
page_flip-reserved != 0)
return -EINVAL;
 
+   if ((page_flip-flags  DRM_MODE_PAGE_FLIP_ASYNC)  
!dev-mode_config.async_page_flip)
+   return -EINVAL;
+
obj = drm_mode_object_find(dev, page_flip-crtc_id, 
DRM_MODE_OBJECT_CRTC);
if (!obj)
return -EINVAL;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index ffd7a7b..7602177 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -303,6 +303,9 @@ int drm_getcap(struct drm_device *dev, void *data, struct 
drm_file *file_priv)
case DRM_CAP_TIMESTAMP_MONOTONIC:
req-value = drm_timestamp_monotonic;
break;
+   case DRM_CAP_ASYNC_PAGE_FLIP:
+   req-value = dev-mode_config.async_page_flip;
+   break;
default:
return -EINVAL;
}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 0820ab6..13d215f 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -845,6 +845,9 @@ struct drm_mode_config {
 
/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;
+
+   /* whether async page flip is supported or not */
+   bool async_page_flip;
 };
 
 #define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 238a166..2adfaa5 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -780,6 +780,7 @@ struct drm_event_vblank {
 #define DRM_CAP_DUMB_PREFER_SHADOW 0x4
 #define DRM_CAP_PRIME 0x5
 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
+#define DRM_CAP_ASYNC_PAGE_FLIP 0x7
 
 #define DRM_PRIME_CAP_IMPORT 0x1
 #define DRM_PRIME_CAP_EXPORT 0x2
-- 
1.8.3.2

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 5/5] drm/i915: Add async page flip support for SNB

2013-07-22 Thread Keith Packard
Just copies the IVB code

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/intel_display.c | 39 
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 1bcc6b4..9d7919b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7463,20 +7463,51 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = dev_priv-ring[RCS];
uint32_t pf, pipesrc;
+   uint32_t cmd;
+   uint32_t base;
int ret;
 
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
if (ret)
goto err;
 
+   cmd = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc-plane);
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc-dspaddr_offset;
+
+   if (flags  DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* XXX check limitations for async flip here */
+
+   if (fb-pitches[0] != I915_READ(DSPSTRIDE(intel_crtc-plane))) {
+   WARN_ONCE(1, mismatching stride in async plane flip 
(%d != %d)\n,
+ fb-pitches[0], 
I915_READ(DSPSTRIDE(intel_crtc-plane)));
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if (obj-tiling_mode != I915_TILING_X) {
+   WARN_ONCE(1, async plane flip requires X tiling\n);
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if ((I915_READ(DSPCNTR(intel_crtc-plane))  DISPPLANE_TILED) 
== 0) {
+   WARN_ONCE(1, display not currently tiled in async 
plane flip\n);
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+   
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;
 
-   intel_ring_emit(ring, MI_DISPLAY_FLIP |
-   MI_DISPLAY_FLIP_PLANE(intel_crtc-plane));
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, fb-pitches[0] | obj-tiling_mode);
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc-dspaddr_offset);
+   intel_ring_emit(ring, base);
 
/* Contrary to the suggestions in the documentation,
 * Enable Panel Fitter does not seem to be required when page
@@ -9738,7 +9769,7 @@ void intel_modeset_init(struct drm_device *dev)
dev-mode_config.max_height = 8192;
}
 
-   if (IS_GEN7(dev))
+   if (IS_GEN6(dev) || IS_GEN7(dev))
dev-mode_config.async_page_flip = true;
 
dev-mode_config.fb_base = dev_priv-gtt.mappable_base;
-- 
1.8.3.2

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/5] drm/i915: Add async page flip support for IVB

2013-07-22 Thread Keith Packard
This adds the necesary register defines for async page flipping
through the command ring, and then hooks those up for Ivybridge (gen7)
page flipping.

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 ++
 drivers/gpu/drm/i915/intel_display.c | 40 ++--
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dc3d6a7..029cfb0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -209,6 +209,7 @@
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
 #define MI_DISPLAY_FLIPMI_INSTR(0x14, 2)
 #define MI_DISPLAY_FLIP_I915   MI_INSTR(0x14, 1)
+#define   MI_DISPLAY_FLIP_ASYNC_INDICATOR  (1  22)
 #define   MI_DISPLAY_FLIP_PLANE(n) ((n)  20)
 /* IVB has funny definitions for which plane to flip. */
 #define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0  19)
@@ -217,6 +218,11 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3  19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4  19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5  19)
+/* These go in the bottom of the base address value */
+#define   MI_DISPLAY_FLIP_TYPE_SYNC(0  0)
+#define   MI_DISPLAY_FLIP_TYPE_ASYNC   (1  0)
+#define   MI_DISPLAY_FLIP_TYPE_STEREO  (2  0)
+#define   MI_DISPLAY_FLIP_TYPE_SYNCHRONOUS (0  0)
 #define MI_ARB_ON_OFF  MI_INSTR(0x08, 0)
 #define   MI_ARB_ENABLE(10)
 #define   MI_ARB_DISABLE   (00)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bdb8854..1bcc6b4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7514,6 +7514,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_ring_buffer *ring = dev_priv-ring[BCS];
uint32_t plane_bit = 0;
+   uint32_t cmd;
+   uint32_t base;
int ret;
 
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
@@ -7536,13 +7538,43 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
goto err_unpin;
}
 
+   cmd = MI_DISPLAY_FLIP_I915 | plane_bit;
+   base = i915_gem_obj_ggtt_offset(obj) + intel_crtc-dspaddr_offset;
+
+   if (flags  DRM_MODE_PAGE_FLIP_ASYNC) {
+
+   /* XXX check limitations for async flip here */
+
+   if (fb-pitches[0] != I915_READ(DSPSTRIDE(intel_crtc-plane))) {
+   WARN_ONCE(1, mismatching stride in async plane flip 
(%d != %d)\n,
+ fb-pitches[0], 
I915_READ(DSPSTRIDE(intel_crtc-plane)));
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if (obj-tiling_mode != I915_TILING_X) {
+   WARN_ONCE(1, async plane flip requires X tiling\n);
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+
+   if ((I915_READ(DSPCNTR(intel_crtc-plane))  DISPPLANE_TILED) 
== 0) {
+   WARN_ONCE(1, display not currently tiled in async 
plane flip\n);
+   ret = -EINVAL;
+   goto err_unpin;
+   }
+   
+   cmd |= MI_DISPLAY_FLIP_ASYNC_INDICATOR;
+   base |= MI_DISPLAY_FLIP_TYPE_ASYNC;
+   }
+
ret = intel_ring_begin(ring, 4);
if (ret)
goto err_unpin;
 
-   intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
+   intel_ring_emit(ring, cmd);
intel_ring_emit(ring, (fb-pitches[0] | obj-tiling_mode));
-   intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + 
intel_crtc-dspaddr_offset);
+   intel_ring_emit(ring, base);
intel_ring_emit(ring, (MI_NOOP));
 
intel_mark_page_flip_active(intel_crtc);
@@ -9705,6 +9737,10 @@ void intel_modeset_init(struct drm_device *dev)
dev-mode_config.max_width = 8192;
dev-mode_config.max_height = 8192;
}
+
+   if (IS_GEN7(dev))
+   dev-mode_config.async_page_flip = true;
+
dev-mode_config.fb_base = dev_priv-gtt.mappable_base;
 
DRM_DEBUG_KMS(%d display pipe%s available.\n,
-- 
1.8.3.2

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/6] gpu: host1x: Fix syncpoint wait return value

2013-05-28 Thread Keith Packard
Thierry Reding  writes:


> That doesn't sound right. Maybe drmIoctl() needs fixing instead. Looking
> at the history, drmIoctl() was introduced to automatically loop if a
> signal was received (commit 8b9ab108ec1f2ba2b503f713769c4946849b3cb2).
> However the ioctl(3p) manpage doesn't mention that ioctl() returns
> EAGAIN in case it is interrupted by a signal.

EAGAIN is being returned when the GPU is wedged to ask the application
to re-submit the request, which will presumably be held until the  GPU
is un-wedged.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



Re: [PATCH 2/6] gpu: host1x: Fix syncpoint wait return value

2013-05-28 Thread Keith Packard
Thierry Reding thierry.red...@gmail.com writes:


 That doesn't sound right. Maybe drmIoctl() needs fixing instead. Looking
 at the history, drmIoctl() was introduced to automatically loop if a
 signal was received (commit 8b9ab108ec1f2ba2b503f713769c4946849b3cb2).
 However the ioctl(3p) manpage doesn't mention that ioctl() returns
 EAGAIN in case it is interrupted by a signal.

EAGAIN is being returned when the GPU is wedged to ask the application
to re-submit the request, which will presumably be held until the  GPU
is un-wedged.

-- 
keith.pack...@intel.com


pgpuDOHJ5RMjV.pgp
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Intel-gfx] [PATCH 6/7] drm/i915: Disable FDI RX before FDI TX

2012-08-17 Thread Keith Packard
"Lespiau, Damien"  writes:

> I can't see anything in the docs about an order requirement for those.

Right, the docs don't say anything, which is a bit disconcerting.

> Not sure why the other way does not make sense. Somehow disabling TX
> before RX makes some sense to me (TX enabled without a ready RX looks
> weird?, no data should flow as the pipe is shutdown at that point
> anyway). Maybe it just does not matter?

And here I figured disabling RX before TX made more sense -- otherwise
the receiver wouldn't be seeing anything. In other areas of the driver,
we're careful to disable receivers before senders (disable CRTC before
PLL, etc).

> Another detail is that disabling the PLLs seem to have an order in the
> disabling sequence, TX, then RX.
>
> I.  Disable CPU FDI Transmitter PLL
> II. Disable PCH FDI Receiver PLL

That ordering doesn't matter as the FDI receiver and transmitter are
both disabled by that point, so they aren't talking at all.

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 



[Intel-gfx] [PATCH 2/7] drm/i915: FDI B/C share 4 lanes on Ivybridge

2012-08-17 Thread Keith Packard
"Lespiau, Damien"  writes:

> On Tue, Aug 14, 2012 at 5:34 AM, Keith Packard  wrote:
>
> @@ -3728,7 +3728,8 @@ static inline bool intel_panel_use_ssc(struct
> drm_i915_private *dev_priv)
>   */
>  static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
>  unsigned int *pipe_bpp,
> -struct drm_display_mode *mode)
> +struct drm_display_mode *mode,
> +int max_fdi_bpp)
>
> There's some kernel-doc for this function, maybe add a @max_fdi_bpp
> there?

Will do

> This chunk is being moved around in a later patch in the series,
> merging the two patches in one looks like a good idea?

Or at least move this into its final position in this patch.

> I guess this does not cover the case of pipe B using 3 lanes meaning
> pipe C can use 1?

It didn't look like that was a supported mode from the docs.

> This duplicates the code just that is just a few lines away, instead
> how about moving the logic to set target_clock up in front of this
> whole if()?

It's not the same, it's the inverse -- computing bpp from lanes+clock
clock instead of computing lanes from bpp+clock. But, yeah, it would be
nice to have these merged somehow. I couldn't figure out a good way though.

> This chunk is also reworked in a later commit in this series.

I'll see if I can't avoid that as it's confusing. Thanks for your review!

-- 
keith.packard at intel.com
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20120817/d1952604/attachment.pgp>


Re: [Intel-gfx] [PATCH 2/7] drm/i915: FDI B/C share 4 lanes on Ivybridge

2012-08-17 Thread Keith Packard
Lespiau, Damien damien.lesp...@intel.com writes:

 On Tue, Aug 14, 2012 at 5:34 AM, Keith Packard kei...@keithp.com wrote:

 @@ -3728,7 +3728,8 @@ static inline bool intel_panel_use_ssc(struct
 drm_i915_private *dev_priv)
   */
  static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
  unsigned int *pipe_bpp,
 -struct drm_display_mode *mode)
 +struct drm_display_mode *mode,
 +int max_fdi_bpp)

 There's some kernel-doc for this function, maybe add a @max_fdi_bpp
 there?

Will do

 This chunk is being moved around in a later patch in the series,
 merging the two patches in one looks like a good idea?

Or at least move this into its final position in this patch.

 I guess this does not cover the case of pipe B using 3 lanes meaning
 pipe C can use 1?

It didn't look like that was a supported mode from the docs.

 This duplicates the code just that is just a few lines away, instead
 how about moving the logic to set target_clock up in front of this
 whole if()?

It's not the same, it's the inverse -- computing bpp from lanes+clock
clock instead of computing lanes from bpp+clock. But, yeah, it would be
nice to have these merged somehow. I couldn't figure out a good way though.

 This chunk is also reworked in a later commit in this series.

I'll see if I can't avoid that as it's confusing. Thanks for your review!

-- 
keith.pack...@intel.com


pgpUeyeGIkhdL.pgp
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 6/7] drm/i915: Disable FDI RX before FDI TX

2012-08-17 Thread Keith Packard
Lespiau, Damien damien.lesp...@intel.com writes:

 I can't see anything in the docs about an order requirement for those.

Right, the docs don't say anything, which is a bit disconcerting.

 Not sure why the other way does not make sense. Somehow disabling TX
 before RX makes some sense to me (TX enabled without a ready RX looks
 weird?, no data should flow as the pipe is shutdown at that point
 anyway). Maybe it just does not matter?

And here I figured disabling RX before TX made more sense -- otherwise
the receiver wouldn't be seeing anything. In other areas of the driver,
we're careful to disable receivers before senders (disable CRTC before
PLL, etc).

 Another detail is that disabling the PLLs seem to have an order in the
 disabling sequence, TX, then RX.

 I.  Disable CPU FDI Transmitter PLL
 II. Disable PCH FDI Receiver PLL

That ordering doesn't matter as the FDI receiver and transmitter are
both disabled by that point, so they aren't talking at all.

-- 
keith.pack...@intel.com


pgpImGWgX3AWa.pgp
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 7/7] drm/i915: Merge FDI RX reg writes during training

2012-08-13 Thread Keith Packard
Need to turn on the error correction when enabling training or it
might not get enabled in time.

This seems to fix the FDI-B/FDI-C link training problem.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_display.c |   11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 754f10f..1d24d55 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2324,6 +2324,8 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
}
I915_WRITE(reg, temp);
+   POSTING_READ(reg);
+   udelay(100);

reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
@@ -2334,16 +2336,15 @@ static void intel_fdi_normal_train(struct drm_crtc 
*crtc)
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_NONE;
}
+   /* IVB wants error correction enabled */
+   if (IS_IVYBRIDGE(dev))
+   temp |= FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE;
+
I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);

/* wait one idle pattern time */
POSTING_READ(reg);
udelay(1000);
-
-   /* IVB wants error correction enabled */
-   if (IS_IVYBRIDGE(dev))
-   I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE |
-  FDI_FE_ERRC_ENABLE);
 }

 static void cpt_phase_pointer_enable(struct drm_device *dev, int pipe)
-- 
1.7.10.4



[PATCH 6/7] drm/i915: Disable FDI RX before FDI TX

2012-08-13 Thread Keith Packard
Doesn't make sense to disable in the other order.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_display.c |   10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index b099a17..754f10f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2776,17 +2776,17 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
u32 reg, temp;

/* disable CPU FDI tx and PCH FDI rx */
-   reg = FDI_TX_CTL(pipe);
-   temp = I915_READ(reg);
-   I915_WRITE(reg, temp & ~FDI_TX_ENABLE);
-   POSTING_READ(reg);
-
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~(0x7 << 16);
temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11;
I915_WRITE(reg, temp & ~FDI_RX_ENABLE);
+   POSTING_READ(reg);
+   udelay(100);

+   reg = FDI_TX_CTL(pipe);
+   temp = I915_READ(reg);
+   I915_WRITE(reg, temp & ~FDI_TX_ENABLE);
POSTING_READ(reg);
udelay(100);

-- 
1.7.10.4



[PATCH 5/7] drm/i915: Pipe-C only configurations would not get SR

2012-08-13 Thread Keith Packard
These should probably all look like

enabled |= (1 << pipe)

so that the intent is clear...

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_pm.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 94aabca..1a84425 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1815,7 +1815,7 @@ static void sandybridge_update_wm(struct drm_device *dev)
DRM_DEBUG_KMS("FIFO watermarks For pipe C -"
  " plane %d, cursor: %d\n",
  plane_wm, cursor_wm);
-   enabled |= 3;
+   enabled |= 4;
}

/*
-- 
1.7.10.4



[PATCH 4/7] drm/i915: Check display_bpc against max_fdi_bpp after display_bpc is set

2012-08-13 Thread Keith Packard
display_bpc might not have been set before comparing with the
requested mode, so wait until afterwards before comparing with the
supported fdi bandwidth. Not a significant change as any case that
mattered would have worked; this just makes the debug messages look nicer.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_display.c |   39 --
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 95248bd..b099a17 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3804,15 +3804,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc 
*crtc,
display_bpc = 6;
}

-   if (display_bpc * 3 > max_fdi_bpp) {
-   if (max_fdi_bpp < 24)
-   display_bpc = 6;
-   else if (max_fdi_bpp < 30)
-   display_bpc = 8;
-   else if (max_fdi_bpp < 36)
-   display_bpc = 10;
-   DRM_DEBUG_KMS("Dithering FDI to %dbpc\n", display_bpc);
-   }
/*
 * We could just drive the pipe at the highest bpc all the time and
 * enable dithering as needed, but that costs bandwidth.  So choose
@@ -3845,8 +3836,20 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc 
*crtc,

display_bpc = min(display_bpc, bpc);

-   DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n",
- bpc, display_bpc);
+   display_bpc = 6;
+
+   if (display_bpc * 3 > max_fdi_bpp) {
+   if (max_fdi_bpp < 24)
+   display_bpc = 6;
+   else if (max_fdi_bpp < 30)
+   display_bpc = 8;
+   else if (max_fdi_bpp < 36)
+   display_bpc = 10;
+   DRM_DEBUG_KMS("Dithering FDI to %dbpc\n", display_bpc);
+   }
+
+   DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d) (max_fdi_bpp 
%d)\n",
+ bpc, display_bpc, max_fdi_bpp);

*pipe_bpp = display_bpc * 3;

@@ -4737,8 +4740,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
max_fdi_bpp = 0;
max_lane = lane;
} else {
-   u32 fdi_bw;
-
+   u32 fdi_bw, pps;
/* [e]DP over FDI requires target mode clock
   instead of link clock */
if (is_dp)
@@ -4763,9 +4765,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 * Compute the available FDI bandwidth, use that
 * to compute the maximum supported BPP
 */
-   fdi_bw = link_bw * max_lane * 19 / 20;
-   max_fdi_bpp = fdi_bw / target_clock;
-   DRM_DEBUG_KMS("max lane %d yields max fdi bpp %d\n", max_lane, 
max_fdi_bpp);
+   fdi_bw = (link_bw * 8) * max_lane;
+   pps = target_clock * 21 / 20;
+
+   max_fdi_bpp = fdi_bw / pps;
+   DRM_DEBUG_KMS("link_bw %d max_lane %d fdi_bw %u pps %u 
max_fdi_bpp %d\n",
+ link_bw, max_lane, fdi_bw, pps, max_fdi_bpp);
}

/* [e]DP over FDI requires target mode clock instead of link clock. */
@@ -4809,6 +4814,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 */
u32 bps = target_clock * pipe_bpp * 21 / 20;
lane = bps / (link_bw * 8) + 1;
+   DRM_DEBUG_KMS("target_clock %u pipe_bpp %u bps %u link_bw %u 
lane %u\n",
+ target_clock, pipe_bpp, bps, link_bw, lane);
if (lane > max_lane) {
DRM_ERROR("Not enough lanes available for mode! (want 
%d have %d)\n",
  lane, max_lane);
-- 
1.7.10.4



[PATCH 3/7] drm/i915: Delay between FDI link training tries. Clear FDI_RX_IIR before training

2012-08-13 Thread Keith Packard
Just a bit of cleanup; it appears to have no effect.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_display.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 7106807..95248bd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2391,6 +2391,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
temp |= FDI_LINK_TRAIN_PATTERN_1;
I915_WRITE(reg, temp | FDI_TX_ENABLE);

+   I915_WRITE(FDI_RX_IIR(pipe), FDI_RX_BIT_LOCK);
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
@@ -2398,10 +2399,10 @@ static void ironlake_fdi_link_train(struct drm_crtc 
*crtc)
I915_WRITE(reg, temp | FDI_RX_ENABLE);

POSTING_READ(reg);
-   udelay(150);

/* Ironlake workaround, enable clock pointer after FDI enable*/
if (HAS_PCH_IBX(dev)) {
+   udelay(150);
I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR |
   FDI_RX_PHASE_SYNC_POINTER_EN);
@@ -2409,6 +2410,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)

reg = FDI_RX_IIR(pipe);
for (tries = 0; tries < 5; tries++) {
+   udelay(150);
temp = I915_READ(reg);
DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);

@@ -2422,6 +2424,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
DRM_ERROR("FDI train 1 fail!\n");

/* Train 2 */
+   I915_WRITE(FDI_RX_IIR(pipe), FDI_RX_SYMBOL_LOCK);
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
@@ -2435,10 +2438,10 @@ static void ironlake_fdi_link_train(struct drm_crtc 
*crtc)
I915_WRITE(reg, temp);

POSTING_READ(reg);
-   udelay(150);

reg = FDI_RX_IIR(pipe);
for (tries = 0; tries < 5; tries++) {
+   udelay(150);
temp = I915_READ(reg);
DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);

-- 
1.7.10.4



[PATCH 2/7] drm/i915: FDI B/C share 4 lanes on Ivybridge

2012-08-13 Thread Keith Packard
IVB shares 4 lanes between FDI B and FDI C. When sharing, compute the
maximum BPC based on the available bandwidth.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_display.c |  101 +++---
 1 file changed, 94 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 70d30fc..7106807 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3575,7 +3575,7 @@ void intel_encoder_destroy(struct drm_encoder *encoder)
 }

 static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
+ const struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode)
 {
struct drm_device *dev = crtc->dev;
@@ -3728,7 +3728,8 @@ static inline bool intel_panel_use_ssc(struct 
drm_i915_private *dev_priv)
  */
 static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
 unsigned int *pipe_bpp,
-struct drm_display_mode *mode)
+struct drm_display_mode *mode,
+int max_fdi_bpp)
 {
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3800,6 +3801,15 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc 
*crtc,
display_bpc = 6;
}

+   if (display_bpc * 3 > max_fdi_bpp) {
+   if (max_fdi_bpp < 24)
+   display_bpc = 6;
+   else if (max_fdi_bpp < 30)
+   display_bpc = 8;
+   else if (max_fdi_bpp < 36)
+   display_bpc = 10;
+   DRM_DEBUG_KMS("Dithering FDI to %dbpc\n", display_bpc);
+   }
/*
 * We could just drive the pipe at the highest bpc all the time and
 * enable dithering as needed, but that costs bandwidth.  So choose
@@ -4570,6 +4580,53 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
return 12;
 }

+/*
+ * FDI C can only have 2 lanes, borrowed from FDI B
+ */
+
+static int ivb_fdi_max_lanes(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   enum pipe other_pipe;
+   struct drm_crtc *other_crtc;
+   struct intel_crtc *other_intel_crtc;
+   int max_lanes;
+
+   /* FDI links B and C share 4 lanes */
+   switch (intel_crtc->pipe) {
+   case PIPE_B:
+   other_pipe = PIPE_C;
+   max_lanes = 4;
+   break;
+   case PIPE_C:
+   other_pipe = PIPE_B;
+   max_lanes = 2;
+   break;
+   default:
+   return 4;
+   }
+   other_crtc = dev_priv->pipe_to_crtc_mapping[other_pipe];
+   other_intel_crtc = to_intel_crtc(other_crtc);
+
+   /* If the other FDI link isn't running, we can use all of the
+* available lanes
+*/
+   if (!other_intel_crtc->active)
+   return max_lanes;
+
+   /* If the other FDI link is using too many lanes, we can't have
+* any
+*/
+   if (other_intel_crtc->fdi_lanes > 2)
+   return 0;
+
+   /* When both are running, we only get 2 lanes at most
+*/
+   return 2;
+}
+
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
  struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode,
@@ -4595,6 +4652,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
unsigned int pipe_bpp;
bool dither;
bool is_cpu_edp = false, is_pch_edp = false;
+   int max_fdi_bpp;
+   int max_lane;

for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
@@ -4672,7 +4731,18 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
   according to current link config */
if (is_cpu_edp) {
intel_edp_link_config(edp_encoder, , _bw);
+   max_fdi_bpp = 0;
+   max_lane = lane;
} else {
+   u32 fdi_bw;
+
+   /* [e]DP over FDI requires target mode clock
+  instead of link clock */
+   if (is_dp)
+   target_clock = mode->clock;
+   else
+   target_clock = adjusted_mode->clock;
+
/* FDI is a binary signal running at ~2.7GHz, encoding
 * each output octet as 10 bits. The actual frequency
 * is stored as a divider into a 100MHz clock, and the
@@ -4681,6 +4751,

[PATCH 1/7] drm/i915: Allow VGA on CRTC 2

2012-08-13 Thread Keith Packard
This is left over from the old PLL sharing code and isn't useful now
that PLLs are shared when possible.

Signed-off-by: Keith Packard 
---
 drivers/gpu/drm/i915/intel_crt.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index bc5e2c9..7997b24 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -664,7 +664,7 @@ void intel_crt_init(struct drm_device *dev)
if (IS_HASWELL(dev))
crt->base.crtc_mask = (1 << 0);
else
-   crt->base.crtc_mask = (1 << 0) | (1 << 1);
+   crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);

if (IS_GEN2(dev))
connector->interlace_allowed = 0;
-- 
1.7.10.4



[PATCH 0/7] drm/i915: IVB FDI B/C fixes and misc cleanups

2012-08-13 Thread Keith Packard
This is the complete set of patches that yield a working 3-pipe mode
setting configuration on my test machines. It does not make DPMS work,
so I still need to figure that out. As the DPMS paths are almost
entirely different from mode setting (whose crazy idea was that,
anyway?), that may take a bit more time.

I've managed to reproduce this bug with only two monitors just by
forcing them onto FDI B/C, but only with 1920x1080 and larger modes:

 $ xrandr --output VGA1 --off --output DP1 --off
 $ xrandr --output VGA1 --auto --crtc 1
 $ xrandr --output DP1 --auto --crtc 2

That works about 50% of the time on the original kernel. If it works,
you can just try a couple of different modes to see if you can get it
to fail. Just use reasonably large modes -- 640x480 has never failed
for me. I'd love to know why

 $ xrandr --output DP1 --mode 1600x1200 --crtc 2

Finally, the X server has a terrible bug in the RandR code. It
computes a desired initial configuration, and if that fails in any
way, it refuses to start at all. So, if you connect three monitors
that all require separate PLLs, then you get two monitors lit up, the
third one fails and the X server aborts. Need to fix that so that if
*any* monitors light up, the X server will keep going.

   *** The patches: ***

 [PATCH 1/7] drm/i915: Allow VGA on CRTC 2

Silly hold-over from the bad-old PLL sharing code.

 [PATCH 2/7] drm/i915: FDI B/C share 4 lanes on Ivybridge

Here's the patch which rejects modes that the FDI B/C lane sharing
hardware can't support. This only affects modes larger than 1920x1200
though as that mode and smaller all fit in two FDI lanes. I ran across
this while testing with a 2560x1200 monitor.

 [PATCH 3/7] drm/i915: Delay between FDI link training tries. Clear

This seems like a sensible change in the FDI link training code --
gives the FDI hardware time to adapt to changes in the
signalling. But, as I've never seen FDI fail to train, I'm not sure
it's useful.

 [PATCH 4/7] drm/i915: Check display_bpc against max_fdi_bpp after

This mostly just cleans up some debug messages by moving various BPP
computations around. "should" have no effect on the hardware.

 [PATCH 5/7] drm/i915: Pipe-C only configurations would not get SR

Just happened across this obvious bug while reading through the
driver.

 [PATCH 6/7] drm/i915: Disable FDI RX before FDI TX

The specs don't say which order to do this in, but it doesn't make
sense to do these in the current order. With this in place, I saw mode
setting errors reduced quite a bit, but not gone.

 [PATCH 7/7] drm/i915: Merge FDI RX reg writes during training

This may be the only patch necessary to get mode setting working on
FDI-B/C, it ensures that error correction is always turned on during
link training. The old code left error correction disabled as there
was no posting read after setting that. I'm hoping this explains why
the problem wasn't reliably reproducible -- the problem depended on
how long the write waited to get to the hardware. I haven't done
enough testing of this patch in isolation to know if this is true or not.

-keith


[PATCH 4/7] drm/i915: Check display_bpc against max_fdi_bpp after display_bpc is set

2012-08-13 Thread Keith Packard
display_bpc might not have been set before comparing with the
requested mode, so wait until afterwards before comparing with the
supported fdi bandwidth. Not a significant change as any case that
mattered would have worked; this just makes the debug messages look nicer.

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/intel_display.c |   39 --
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 95248bd..b099a17 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3804,15 +3804,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc 
*crtc,
display_bpc = 6;
}
 
-   if (display_bpc * 3  max_fdi_bpp) {
-   if (max_fdi_bpp  24)
-   display_bpc = 6;
-   else if (max_fdi_bpp  30)
-   display_bpc = 8;
-   else if (max_fdi_bpp  36)
-   display_bpc = 10;
-   DRM_DEBUG_KMS(Dithering FDI to %dbpc\n, display_bpc);
-   }
/*
 * We could just drive the pipe at the highest bpc all the time and
 * enable dithering as needed, but that costs bandwidth.  So choose
@@ -3845,8 +3836,20 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc 
*crtc,
 
display_bpc = min(display_bpc, bpc);
 
-   DRM_DEBUG_KMS(setting pipe bpc to %d (max display bpc %d)\n,
- bpc, display_bpc);
+   display_bpc = 6;
+
+   if (display_bpc * 3  max_fdi_bpp) {
+   if (max_fdi_bpp  24)
+   display_bpc = 6;
+   else if (max_fdi_bpp  30)
+   display_bpc = 8;
+   else if (max_fdi_bpp  36)
+   display_bpc = 10;
+   DRM_DEBUG_KMS(Dithering FDI to %dbpc\n, display_bpc);
+   }
+
+   DRM_DEBUG_KMS(setting pipe bpc to %d (max display bpc %d) (max_fdi_bpp 
%d)\n,
+ bpc, display_bpc, max_fdi_bpp);
 
*pipe_bpp = display_bpc * 3;
 
@@ -4737,8 +4740,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
max_fdi_bpp = 0;
max_lane = lane;
} else {
-   u32 fdi_bw;
-
+   u32 fdi_bw, pps;
/* [e]DP over FDI requires target mode clock
   instead of link clock */
if (is_dp)
@@ -4763,9 +4765,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 * Compute the available FDI bandwidth, use that
 * to compute the maximum supported BPP
 */
-   fdi_bw = link_bw * max_lane * 19 / 20;
-   max_fdi_bpp = fdi_bw / target_clock;
-   DRM_DEBUG_KMS(max lane %d yields max fdi bpp %d\n, max_lane, 
max_fdi_bpp);
+   fdi_bw = (link_bw * 8) * max_lane;
+   pps = target_clock * 21 / 20;
+
+   max_fdi_bpp = fdi_bw / pps;
+   DRM_DEBUG_KMS(link_bw %d max_lane %d fdi_bw %u pps %u 
max_fdi_bpp %d\n,
+ link_bw, max_lane, fdi_bw, pps, max_fdi_bpp);
}
 
/* [e]DP over FDI requires target mode clock instead of link clock. */
@@ -4809,6 +4814,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 */
u32 bps = target_clock * pipe_bpp * 21 / 20;
lane = bps / (link_bw * 8) + 1;
+   DRM_DEBUG_KMS(target_clock %u pipe_bpp %u bps %u link_bw %u 
lane %u\n,
+ target_clock, pipe_bpp, bps, link_bw, lane);
if (lane  max_lane) {
DRM_ERROR(Not enough lanes available for mode! (want 
%d have %d)\n,
  lane, max_lane);
-- 
1.7.10.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 0/7] drm/i915: IVB FDI B/C fixes and misc cleanups

2012-08-13 Thread Keith Packard
This is the complete set of patches that yield a working 3-pipe mode
setting configuration on my test machines. It does not make DPMS work,
so I still need to figure that out. As the DPMS paths are almost
entirely different from mode setting (whose crazy idea was that,
anyway?), that may take a bit more time.

I've managed to reproduce this bug with only two monitors just by
forcing them onto FDI B/C, but only with 1920x1080 and larger modes:

 $ xrandr --output VGA1 --off --output DP1 --off
 $ xrandr --output VGA1 --auto --crtc 1
 $ xrandr --output DP1 --auto --crtc 2

That works about 50% of the time on the original kernel. If it works,
you can just try a couple of different modes to see if you can get it
to fail. Just use reasonably large modes -- 640x480 has never failed
for me. I'd love to know why

 $ xrandr --output DP1 --mode 1600x1200 --crtc 2

Finally, the X server has a terrible bug in the RandR code. It
computes a desired initial configuration, and if that fails in any
way, it refuses to start at all. So, if you connect three monitors
that all require separate PLLs, then you get two monitors lit up, the
third one fails and the X server aborts. Need to fix that so that if
*any* monitors light up, the X server will keep going.
 
   *** The patches: ***

 [PATCH 1/7] drm/i915: Allow VGA on CRTC 2

Silly hold-over from the bad-old PLL sharing code.

 [PATCH 2/7] drm/i915: FDI B/C share 4 lanes on Ivybridge

Here's the patch which rejects modes that the FDI B/C lane sharing
hardware can't support. This only affects modes larger than 1920x1200
though as that mode and smaller all fit in two FDI lanes. I ran across
this while testing with a 2560x1200 monitor.

 [PATCH 3/7] drm/i915: Delay between FDI link training tries. Clear

This seems like a sensible change in the FDI link training code --
gives the FDI hardware time to adapt to changes in the
signalling. But, as I've never seen FDI fail to train, I'm not sure
it's useful.

 [PATCH 4/7] drm/i915: Check display_bpc against max_fdi_bpp after

This mostly just cleans up some debug messages by moving various BPP
computations around. should have no effect on the hardware.

 [PATCH 5/7] drm/i915: Pipe-C only configurations would not get SR

Just happened across this obvious bug while reading through the
driver.

 [PATCH 6/7] drm/i915: Disable FDI RX before FDI TX

The specs don't say which order to do this in, but it doesn't make
sense to do these in the current order. With this in place, I saw mode
setting errors reduced quite a bit, but not gone.

 [PATCH 7/7] drm/i915: Merge FDI RX reg writes during training

This may be the only patch necessary to get mode setting working on
FDI-B/C, it ensures that error correction is always turned on during
link training. The old code left error correction disabled as there
was no posting read after setting that. I'm hoping this explains why
the problem wasn't reliably reproducible -- the problem depended on
how long the write waited to get to the hardware. I haven't done
enough testing of this patch in isolation to know if this is true or not.

-keith
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 5/7] drm/i915: Pipe-C only configurations would not get SR

2012-08-13 Thread Keith Packard
These should probably all look like

enabled |= (1  pipe)

so that the intent is clear...

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/intel_pm.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 94aabca..1a84425 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1815,7 +1815,7 @@ static void sandybridge_update_wm(struct drm_device *dev)
DRM_DEBUG_KMS(FIFO watermarks For pipe C -
   plane %d, cursor: %d\n,
  plane_wm, cursor_wm);
-   enabled |= 3;
+   enabled |= 4;
}
 
/*
-- 
1.7.10.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/7] drm/i915: FDI B/C share 4 lanes on Ivybridge

2012-08-13 Thread Keith Packard
IVB shares 4 lanes between FDI B and FDI C. When sharing, compute the
maximum BPC based on the available bandwidth.

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/intel_display.c |  101 +++---
 1 file changed, 94 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 70d30fc..7106807 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3575,7 +3575,7 @@ void intel_encoder_destroy(struct drm_encoder *encoder)
 }
 
 static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
+ const struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode)
 {
struct drm_device *dev = crtc-dev;
@@ -3728,7 +3728,8 @@ static inline bool intel_panel_use_ssc(struct 
drm_i915_private *dev_priv)
  */
 static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
 unsigned int *pipe_bpp,
-struct drm_display_mode *mode)
+struct drm_display_mode *mode,
+int max_fdi_bpp)
 {
struct drm_device *dev = crtc-dev;
struct drm_i915_private *dev_priv = dev-dev_private;
@@ -3800,6 +3801,15 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc 
*crtc,
display_bpc = 6;
}
 
+   if (display_bpc * 3  max_fdi_bpp) {
+   if (max_fdi_bpp  24)
+   display_bpc = 6;
+   else if (max_fdi_bpp  30)
+   display_bpc = 8;
+   else if (max_fdi_bpp  36)
+   display_bpc = 10;
+   DRM_DEBUG_KMS(Dithering FDI to %dbpc\n, display_bpc);
+   }
/*
 * We could just drive the pipe at the highest bpc all the time and
 * enable dithering as needed, but that costs bandwidth.  So choose
@@ -4570,6 +4580,53 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
return 12;
 }
 
+/*
+ * FDI C can only have 2 lanes, borrowed from FDI B
+ */
+
+static int ivb_fdi_max_lanes(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc-dev;
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   enum pipe other_pipe;
+   struct drm_crtc *other_crtc;
+   struct intel_crtc *other_intel_crtc;
+   int max_lanes;
+
+   /* FDI links B and C share 4 lanes */
+   switch (intel_crtc-pipe) {
+   case PIPE_B:
+   other_pipe = PIPE_C;
+   max_lanes = 4;
+   break;
+   case PIPE_C:
+   other_pipe = PIPE_B;
+   max_lanes = 2;
+   break;
+   default:
+   return 4;
+   }
+   other_crtc = dev_priv-pipe_to_crtc_mapping[other_pipe];
+   other_intel_crtc = to_intel_crtc(other_crtc);
+
+   /* If the other FDI link isn't running, we can use all of the
+* available lanes
+*/
+   if (!other_intel_crtc-active)
+   return max_lanes;
+
+   /* If the other FDI link is using too many lanes, we can't have
+* any
+*/
+   if (other_intel_crtc-fdi_lanes  2)
+   return 0;
+
+   /* When both are running, we only get 2 lanes at most
+*/
+   return 2;
+}
+
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
  struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode,
@@ -4595,6 +4652,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
unsigned int pipe_bpp;
bool dither;
bool is_cpu_edp = false, is_pch_edp = false;
+   int max_fdi_bpp;
+   int max_lane;
 
for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder-type) {
@@ -4672,7 +4731,18 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
   according to current link config */
if (is_cpu_edp) {
intel_edp_link_config(edp_encoder, lane, link_bw);
+   max_fdi_bpp = 0;
+   max_lane = lane;
} else {
+   u32 fdi_bw;
+
+   /* [e]DP over FDI requires target mode clock
+  instead of link clock */
+   if (is_dp)
+   target_clock = mode-clock;
+   else
+   target_clock = adjusted_mode-clock;
+
/* FDI is a binary signal running at ~2.7GHz, encoding
 * each output octet as 10 bits. The actual frequency
 * is stored as a divider into a 100MHz clock, and the
@@ -4681,6 +4751,18 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc

[PATCH 1/7] drm/i915: Allow VGA on CRTC 2

2012-08-13 Thread Keith Packard
This is left over from the old PLL sharing code and isn't useful now
that PLLs are shared when possible.

Signed-off-by: Keith Packard kei...@keithp.com
---
 drivers/gpu/drm/i915/intel_crt.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index bc5e2c9..7997b24 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -664,7 +664,7 @@ void intel_crt_init(struct drm_device *dev)
if (IS_HASWELL(dev))
crt-base.crtc_mask = (1  0);
else
-   crt-base.crtc_mask = (1  0) | (1  1);
+   crt-base.crtc_mask = (1  0) | (1  1) | (1  2);
 
if (IS_GEN2(dev))
connector-interlace_allowed = 0;
-- 
1.7.10.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


<    1   2   3   4   5   6   7   8   9   10   >