[Mesa-dev] [PATCH] svga: Remove unnecessary check for the pre flush bit for setting vertex buffers

2019-05-29 Thread Thomas Hellstrom
From: Charmaine Lee 

This fixes the missing rebind when the can_pre_flush bit
is not set and the vertex buffers are the same as what have been sent.

Cc: mesa-sta...@lists.freedesktop.org
Reviewed-by: Neha Bhende 
Signed-off-by: Charmaine Lee 
Signed-off-by: Thomas Hellstrom 
---
 src/gallium/drivers/svga/svga_draw.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_draw.c 
b/src/gallium/drivers/svga/svga_draw.c
index 9e13ee8ce6d..b6c21a866fe 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -568,11 +568,11 @@ validate_vertex_buffers(struct svga_hwtnl *hwtnl)
  vbuffer_attrs[i].sid = 0;
   }
 
-  /* If we haven't yet emitted a drawing command or if any
-   * vertex buffer state is changing, issue that state now.
+  /* If any of the vertex buffer state has changed, issue
+   * the SetVertexBuffers command. Otherwise, we will just
+   * need to rebind the resources.
*/
-  if (((hwtnl->cmd.swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) == 0) ||
-  vbuf_count != svga->state.hw_draw.num_vbuffers ||
+  if (vbuf_count != svga->state.hw_draw.num_vbuffers ||
   !vertex_buffers_equal(vbuf_count,
 vbuffer_attrs,
 vbuffers,
-- 
2.21.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH] winsys/svga/drm: Fix 32-bit RPCI send message

2019-05-29 Thread Thomas Hellstrom
From: Deepak Rawat 

Depending on whether compiled with frame-pointer or not, the temporary
memory location used for the bp parameter in these macros are referenced
relative to the stack pointer or the frame pointer.
Hence we can never reference that parameter when we've modified either
the stack pointer or the frame pointer, because then the compiler would
generate an incorrect stack reference.

Fix this by pushing the temporary memory parameter on a known location on
the stack before modifying the stack- and frame pointers.

Also in case of failuire RPCI channel is not closed which lead to vmx
running out of channels.

Cc: mesa-sta...@lists.freedesktop.org
Signed-off-by: Deepak Rawat 
Reviewed-by: Sinclair Yeh 
Reviewed-by: Thomas Hellstrom 
Signed-off-by: Thomas Hellstrom 
---
 src/gallium/winsys/svga/drm/vmw_msg.c | 35 ++-
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_msg.c 
b/src/gallium/winsys/svga/drm/vmw_msg.c
index 8cce2241f36..3e8ed2a0fb5 100644
--- a/src/gallium/winsys/svga/drm/vmw_msg.c
+++ b/src/gallium/winsys/svga/drm/vmw_msg.c
@@ -177,17 +177,23 @@ typedef uint64_t VMW_REG;
 
 typedef uint32_t VMW_REG;
 
-/* In the 32-bit version of this macro, we use "m" because there is no
- * more register left for bp
+/* In the 32-bit version of this macro, we store bp in a memory location
+ * because we've ran out of registers.
+ * Now we can't reference that memory location while we've modified
+ * %esp or %ebp, so we first push it on the stack, just before we push
+ * %ebp, and then when we need it we read it from the stack where we
+ * just pushed it.
  */
 #define VMW_PORT_HB_OUT(cmd, in_cx, in_si, in_di, \
  port_num, magic, bp, \
  ax, bx, cx, dx, si, di)  \
 ({\
-   __asm__ volatile ("push %%ebp;"\
-  "mov %12, %%ebp;"   \
+   __asm__ volatile ("push %12;"  \
+  "push %%ebp;"   \
+  "mov 0x04(%%esp), %%ebp;"   \
   "rep outsb;"\
-  "pop %%ebp;" :  \
+  "pop %%ebp;"\
+  "add $0x04, %%esp;" :   \
   "=a"(ax),   \
   "=b"(bx),   \
   "=c"(cx),   \
@@ -209,10 +215,12 @@ typedef uint32_t VMW_REG;
  port_num, magic, bp, \
  ax, bx, cx, dx, si, di)  \
 ({\
-   __asm__ volatile ("push %%ebp;"\
-  "mov %12, %%ebp;"   \
+   __asm__ volatile ("push %12;"  \
+  "push %%ebp;"   \
+  "mov 0x04(%%esp), %%ebp;"   \
   "rep insb;" \
-  "pop %%ebp" :   \
+  "pop %%ebp;"\
+  "add $0x04, %%esp;" :   \
   "=a"(ax),   \
   "=b"(bx),   \
   "=c"(cx),   \
@@ -418,6 +426,7 @@ vmw_svga_winsys_host_log(struct svga_winsys_screen *sws, 
const char *log)
struct rpc_channel channel;
char *msg;
int msg_len;
+   int ret;
 
 #ifdef MSG_NOT_IMPLEMENTED
return;
@@ -435,12 +444,14 @@ vmw_svga_winsys_host_log(struct svga_winsys_screen *sws, 
const char *log)
 
util_sprintf(msg, "log %s", log);
 
-   if (vmw_open_channel(, RPCI_PROTOCOL_NUM) ||
-   vmw_send_msg(, msg) ||
-   vmw_close_channel()) {
-  debug_printf("Failed to send log\n");
+   if (!(ret = vmw_open_channel(, RPCI_PROTOCOL_NUM))) {
+  ret = vmw_send_msg(, msg);
+  vmw_close_channel();
}
 
+   if (ret)
+  debug_printf("Failed to send log\n");
+
FREE(msg);
 
return;
-- 
2.21.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 1/5] svga: Remove the surface_invalidate winsys function

2019-05-16 Thread Thomas Hellstrom
Instead unconditionally call SVGA3D_InvalidateGBSurface() since it's needed
also for Linux for dirty buffers and operation without SurfaceDMA.
For non-guest-backed operation, remove the surface cache surface invalidation
altogether.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
Reviewed-by: Charmaine Lee 
---
 src/gallium/drivers/svga/svga_screen_cache.c | 14 ++
 src/gallium/drivers/svga/svga_surface.c  |  4 ++--
 src/gallium/drivers/svga/svga_winsys.h   |  7 ---
 src/gallium/winsys/svga/drm/vmw_context.c|  1 -
 src/gallium/winsys/svga/drm/vmw_surface.c| 13 -
 src/gallium/winsys/svga/drm/vmw_surface.h|  4 
 6 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_screen_cache.c 
b/src/gallium/drivers/svga/svga_screen_cache.c
index 82dd2b2c3a0..e2282d6a15c 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.c
+++ b/src/gallium/drivers/svga/svga_screen_cache.c
@@ -33,7 +33,7 @@
 #include "svga_screen.h"
 #include "svga_screen_cache.h"
 #include "svga_context.h"
-
+#include "svga_cmd.h"
 
 #define SVGA_SURFACE_CACHE_ENABLED 1
 
@@ -291,7 +291,12 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
 
   SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
"cache sid %p\n", entry->handle);
-  LIST_ADD(>head, >validated);
+
+  /* If we don't have gb objects, we don't need to invalidate. */
+  if (sws->have_gb_objects)
+ LIST_ADD(>head, >validated);
+  else
+ LIST_ADD(>head, >invalidated);
 
   cache->total_size += surf_size;
}
@@ -355,6 +360,7 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
   entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, head);
 
   assert(entry->handle);
+  assert(svga_have_gb_objects(svga));
 
   if (sws->surface_is_flushed(sws, entry->handle)) {
  /* remove entry from the validated list */
@@ -363,7 +369,7 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
  /* It is now safe to invalidate the surface content.
   * It will be done using the current context.
   */
- if (svga->swc->surface_invalidate(svga->swc, entry->handle) != 
PIPE_OK) {
+ if (SVGA3D_InvalidateGBSurface(svga->swc, entry->handle) != PIPE_OK) {
 MAYBE_UNUSED enum pipe_error ret;
 
 /* Even though surface invalidation here is done after the command
@@ -375,7 +381,7 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
  * this function itself is called inside svga_context_flush().
  */
 svga->swc->flush(svga->swc, NULL);
-ret = svga->swc->surface_invalidate(svga->swc, entry->handle);
+ret = SVGA3D_InvalidateGBSurface(svga->swc, entry->handle);
 assert(ret == PIPE_OK);
  }
 
diff --git a/src/gallium/drivers/svga/svga_surface.c 
b/src/gallium/drivers/svga/svga_surface.c
index 73208cf58ac..5d1f369fa90 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -591,9 +591,9 @@ svga_validate_surface_view(struct svga_context *svga, 
struct svga_surface *s)
   * need to update the host-side copy with the invalid
   * content when the associated mob is first bound to the surface.
   */
- if (svga->swc->surface_invalidate(svga->swc, stex->handle) != 
PIPE_OK) {
+ if (SVGA3D_InvalidateGBSurface(svga->swc, stex->handle) != PIPE_OK) {
 svga_context_flush(svga, NULL);
-ret = svga->swc->surface_invalidate(svga->swc, stex->handle);
+ret = SVGA3D_InvalidateGBSurface(svga->swc, stex->handle);
 assert(ret == PIPE_OK);
  }
  stex->validated = TRUE;
diff --git a/src/gallium/drivers/svga/svga_winsys.h 
b/src/gallium/drivers/svga/svga_winsys.h
index 14782e19a7d..174b5f3b78f 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -411,13 +411,6 @@ struct svga_winsys_context
 struct svga_winsys_surface *surface,
 boolean *rebind);
 
-   /**
-* Invalidate the content of this surface
-*/
-   enum pipe_error
-   (*surface_invalidate)(struct svga_winsys_context *swc,
- struct svga_winsys_surface *surface);
-
/**
 * Create and define a DX GB shader that resides in the device COTable.
 * Caller of this function will issue the DXDefineShader command.
diff --git a/src/gallium/winsys/svga/drm/vmw_context.c 
b/src/gallium/winsys/svga/drm/vmw_context.c
index 59963ff7a82..938a3b4a5bc 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
@@ -816,7 +816,6 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen 
*s

[Mesa-dev] [PATCH 3/5] svga: Set the rendered-to flag for dma transfers to surfaces

2019-05-16 Thread Thomas Hellstrom
The rendered-to flag indicates that the HW surface content is more recent
than the content of the mob. That's the case after a SurfaceDMA transfer
to the surface.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
Reviewed-by: Charmaine Lee 
---
 src/gallium/drivers/svga/svga_resource_texture.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/gallium/drivers/svga/svga_resource_texture.c 
b/src/gallium/drivers/svga/svga_resource_texture.c
index e9449e8a1ff..307b5ca4a10 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -753,6 +753,9 @@ svga_texture_transfer_unmap_dma(struct svga_context *svga,
if (st->base.usage & PIPE_TRANSFER_WRITE) {
   /* Use DMA to transfer texture data */
   SVGA3dSurfaceDMAFlags flags;
+  struct pipe_resource *texture = st->base.resource;
+  struct svga_texture *tex = svga_texture(texture);
+
 
   memset(, 0, sizeof flags);
   if (st->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
@@ -763,6 +766,7 @@ svga_texture_transfer_unmap_dma(struct svga_context *svga,
   }
 
   svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
+  svga_set_texture_rendered_to(tex, st->slice, st->base.level);
}
 
FREE(st->swbuf);
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 5/5] svga: Add an environment variable to force coherent surface memory

2019-05-16 Thread Thomas Hellstrom
The vmwgfx driver supports emulated coherent surface memory as of version
2.16. Add en environtment variable to enable this functionality for
texture- and buffer maps: SVGA_FORCE_COHERENT.
This environment variable should be used for testing only.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 .../drivers/svga/svga_resource_buffer.c   | 13 +++--
 .../drivers/svga/svga_resource_buffer.h   |  9 +++
 .../svga/svga_resource_buffer_upload.c| 11 +++-
 .../drivers/svga/svga_resource_texture.c  | 58 ---
 src/gallium/drivers/svga/svga_winsys.h|  1 +
 src/gallium/winsys/svga/drm/vmw_context.c |  1 +
 src/gallium/winsys/svga/drm/vmw_screen.c  |  6 +-
 src/gallium/winsys/svga/drm/vmw_screen.h  |  2 +
 .../winsys/svga/drm/vmw_screen_ioctl.c| 12 
 9 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c 
b/src/gallium/drivers/svga/svga_resource_buffer.c
index 3f37ef692fa..234d825d5a2 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -310,16 +310,18 @@ svga_buffer_transfer_flush_region(struct pipe_context 
*pipe,
 {
struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_buffer *sbuf = svga_buffer(transfer->resource);
-
+   struct svga_context *svga = svga_context(pipe);
unsigned offset = transfer->box.x + box->x;
unsigned length = box->width;
 
assert(transfer->usage & PIPE_TRANSFER_WRITE);
assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT);
 
-   mtx_lock(>swc_mutex);
-   svga_buffer_add_range(sbuf, offset, offset + length);
-   mtx_unlock(>swc_mutex);
+   if (!svga->swc->force_coherent || sbuf->swbuf) {
+  mtx_lock(>swc_mutex);
+  svga_buffer_add_range(sbuf, offset, offset + length);
+  mtx_unlock(>swc_mutex);
+   }
 }
 
 
@@ -359,7 +361,8 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
 
  sbuf->dma.flags.discard = TRUE;
 
- svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
+ if (!svga->swc->force_coherent || sbuf->swbuf)
+svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
   }
}
 
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h 
b/src/gallium/drivers/svga/svga_resource_buffer.h
index 464f073b34f..35ed35d61dd 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -314,6 +314,15 @@ svga_buffer_hw_storage_unmap(struct svga_context *svga,
 ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
 assert(ret == PIPE_OK);
  }
+ if (swc->force_coherent) {
+ret = SVGA3D_UpdateGBSurface(swc, sbuf->handle);
+if (ret != PIPE_OK) {
+   /* flush and retry */
+   svga_context_flush(svga, NULL);
+   ret = SVGA3D_UpdateGBSurface(swc, sbuf->handle);
+   assert(ret == PIPE_OK);
+}
+ }
   }
} else
   sws->buffer_unmap(sws, sbuf->hwbuf);
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c 
b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index 74c3bc4ed61..64f75231a65 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -448,6 +448,9 @@ svga_buffer_upload_gb_command(struct svga_context *svga,
struct pipe_resource *dummy;
unsigned i;
 
+   if (swc->force_coherent)
+  return PIPE_OK;
+
assert(svga_have_gb_objects(svga));
assert(numBoxes);
assert(sbuf->dma.updates == NULL);
@@ -645,7 +648,7 @@ svga_buffer_upload_flush(struct svga_context *svga, struct 
svga_buffer *sbuf)
unsigned i;
struct pipe_resource *dummy;
 
-   if (!sbuf->dma.pending) {
+   if (!sbuf->dma.pending || svga->swc->force_coherent) {
   //debug_printf("no dma pending on buffer\n");
   return;
}
@@ -659,6 +662,7 @@ svga_buffer_upload_flush(struct svga_context *svga, struct 
svga_buffer *sbuf)
 */
if (svga_have_gb_objects(svga)) {
   struct svga_3d_update_gb_image *update = sbuf->dma.updates;
+
   assert(update);
 
   for (i = 0; i < sbuf->map.num_ranges; ++i, ++update) {
@@ -871,6 +875,9 @@ svga_buffer_update_hw(struct svga_context *svga, struct 
svga_buffer *sbuf,
  memcpy((uint8_t *) map + start, (uint8_t *) sbuf->swbuf + start, len);
   }
 
+  if (svga->swc->force_coherent)
+ sbuf->map.num_ranges = 0;
+
   svga_buffer_hw_storage_unmap(svga, sbuf);
 
   /* This user/malloc buffer is now indistinguishable from a gpu buffer */
@@ -1029,6 +1036,8 @@ svga_buffer_handle(struct svga_context *svga, struct 
pipe_resource *buf,
}
 
assert(sbuf->handle);
+   if (svga->swc->force_coherent)
+  return sbuf->handle;
 
  

[Mesa-dev] [PATCH 4/5] pipebuffer, winsys/svga: Add functionality to update pb_validate_entry flags

2019-05-16 Thread Thomas Hellstrom
In order to be able to add access modes to a pb_validate_entry, update
the pb_validate_add_buffer function to take a pointer hash table and also
to return whether the buffer was already on the validate list.

Update the svga winsys accordingly.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Charmaine Lee 
---
 .../auxiliary/pipebuffer/pb_validate.c| 32 +--
 .../auxiliary/pipebuffer/pb_validate.h|  5 ++-
 src/gallium/winsys/svga/drm/vmw_context.c | 23 -
 3 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c 
b/src/gallium/auxiliary/pipebuffer/pb_validate.c
index 0c61c906a3a..459dde526c3 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_validate.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c
@@ -37,6 +37,7 @@
 #include "pipe/p_defines.h"
 #include "util/u_memory.h"
 #include "util/u_debug.h"
+#include "util/u_hash_table.h"
 
 #include "pb_buffer.h"
 #include "pb_validate.h"
@@ -63,9 +64,12 @@ struct pb_validate
 enum pipe_error
 pb_validate_add_buffer(struct pb_validate *vl,
struct pb_buffer *buf,
-   enum pb_usage_flags flags)
+   enum pb_usage_flags flags,
+   struct util_hash_table *ht,
+   boolean *already_present)
 {
assert(buf);
+   *already_present = FALSE;
if (!buf)
   return PIPE_ERROR;
 
@@ -73,15 +77,20 @@ pb_validate_add_buffer(struct pb_validate *vl,
assert(!(flags & ~PB_USAGE_GPU_READ_WRITE));
flags &= PB_USAGE_GPU_READ_WRITE;
 
-   /* We only need to store one reference for each buffer, so avoid storing
-* consecutive references for the same buffer. It might not be the most 
-* common pattern, but it is easy to implement.
-*/
-   if(vl->used && vl->entries[vl->used - 1].buf == buf) {
-  vl->entries[vl->used - 1].flags |= flags;
-  return PIPE_OK;
+   if (ht) {
+  unsigned long entry_idx = (unsigned long) util_hash_table_get(ht, buf);
+
+  if (entry_idx) {
+ struct pb_validate_entry *entry = >entries[entry_idx - 1];
+
+ assert(entry->buf == buf);
+ entry->flags |= flags;
+ *already_present = TRUE;
+
+ return PIPE_OK;
+  }
}
-   
+
/* Grow the table */
if(vl->used == vl->size) {
   unsigned new_size;
@@ -107,7 +116,10 @@ pb_validate_add_buffer(struct pb_validate *vl,
pb_reference(>entries[vl->used].buf, buf);
vl->entries[vl->used].flags = flags;
++vl->used;
-   
+
+   if (ht)
+  util_hash_table_set(ht, buf, (void *) (unsigned long) vl->used);
+
return PIPE_OK;
 }
 
diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h 
b/src/gallium/auxiliary/pipebuffer/pb_validate.h
index ea364330eff..3196d5290fe 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_validate.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_validate.h
@@ -46,6 +46,7 @@ extern "C" {
 
 struct pb_buffer;
 struct pipe_fence_handle;
+struct util_hash_table;
 
 
 /**
@@ -59,7 +60,9 @@ struct pb_validate;
 enum pipe_error
 pb_validate_add_buffer(struct pb_validate *vl,
struct pb_buffer *buf,
-   enum pb_usage_flags flags);
+   enum pb_usage_flags flags,
+   struct util_hash_table *ht,
+   boolean *already_present);
 
 enum pipe_error
 pb_validate_foreach(struct pb_validate *vl,
diff --git a/src/gallium/winsys/svga/drm/vmw_context.c 
b/src/gallium/winsys/svga/drm/vmw_context.c
index addb58d165a..d073cd4859f 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
@@ -370,24 +370,15 @@ vmw_swc_add_validate_buffer(struct 
vmw_svga_winsys_context *vswc,
struct pb_buffer *pb_buf,
unsigned flags)
 {
-   enum pipe_error ret;
+   MAYBE_UNUSED enum pipe_error ret;
unsigned translated_flags;
+   boolean already_present;
 
-   /*
-* TODO: Update pb_validate to provide a similar functionality
-* (Check buffer already present before adding)
-*/
-   if (util_hash_table_get(vswc->hash, pb_buf) != pb_buf) {
-  translated_flags = vmw_translate_to_pb_flags(flags);
-  ret = pb_validate_add_buffer(vswc->validate, pb_buf, translated_flags);
-  /* TODO: Update pipebuffer to reserve buffers and not fail here */
-  assert(ret == PIPE_OK);
-  (void)ret;
-  (void)util_hash_table_set(vswc->hash, pb_buf, pb_buf);
-  return TRUE;
-   }
-
-   return FALSE;
+   translated_flags = vmw_translate_to_pb_flags(flags);
+   ret = pb_validate_add_buffer(vswc->validate, pb_buf, translated_flags,
+vswc->hash, _present);
+   assert(ret == PIPE_OK);
+   return !already_present;
 }
 
 static void
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 2/5] winsys/svga: Fix RELOC_INTERNAL mob GPU access

2019-05-16 Thread Thomas Hellstrom
SVGA_RELOC_INTERNAL indicates a transfer between surface and backing mob.
This means that if the GPU for example reads from the surface it writes
to the backing mob. But since the buffer mapping code allows for
simultaneous gpu- and cpu read access, a read from the surface to the mob
will not synchronize a subsequent map to the readback.

Fix this by inverting the mob access mode in a surface relocation with
SVGA_RELOC_INTERNAL set.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
Reviewed-by: Charmaine Lee 
---
 src/gallium/winsys/svga/drm/vmw_context.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_context.c 
b/src/gallium/winsys/svga/drm/vmw_context.c
index 938a3b4a5bc..addb58d165a 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
@@ -566,7 +566,15 @@ vmw_swc_surface_relocation(struct svga_winsys_context *swc,
 
   mtx_lock(>mutex);
   assert(vsurf->buf != NULL);
-  
+
+  /*
+   * An internal reloc means that the surface transfer direction
+   * is opposite to the MOB transfer direction...
+   */
+  if ((flags & SVGA_RELOC_INTERNAL) &&
+  (flags & (SVGA_RELOC_READ | SVGA_RELOC_WRITE)) !=
+  (SVGA_RELOC_READ | SVGA_RELOC_WRITE))
+ flags ^= (SVGA_RELOC_READ | SVGA_RELOC_WRITE);
   vmw_swc_mob_relocation(swc, mobid, NULL, (struct svga_winsys_buffer *)
  vsurf->buf, 0, flags);
   mtx_unlock(>mutex);
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 3/5] svga: Avoid bouncing buffer data in malloced buffers

2019-04-30 Thread Thomas Hellstrom
Some constant- and texture upload buffer data may bounce in malloced
buffers before being transferred to hardware buffers. In the case of
texture upload buffers this seems to be an oversight. In the case of
constant buffers, code comments indicate that we want to avoid mapping
hardware buffers for reading when copying out of buffers that need
modification before being passed to hardware. In this case we avoid
data bouncing for upload manager buffers but make sure buffers that
we read out from stay in malloced memory.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/drivers/svga/svga_context.c   |  3 +-
 .../drivers/svga/svga_resource_buffer.c   | 44 ++-
 .../drivers/svga/svga_resource_texture.c  |  2 +-
 3 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_context.c 
b/src/gallium/drivers/svga/svga_context.c
index 7b3e9e81f4c..57c0dc49957 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -230,7 +230,8 @@ svga_context_create(struct pipe_screen *screen, void *priv, 
unsigned flags)
 
svga->const0_upload = u_upload_create(>pipe,
  CONST0_UPLOAD_DEFAULT_SIZE,
- PIPE_BIND_CONSTANT_BUFFER,
+ PIPE_BIND_CONSTANT_BUFFER |
+ PIPE_BIND_CUSTOM,
  PIPE_USAGE_STREAM, 0);
if (!svga->const0_upload)
   goto cleanup;
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c 
b/src/gallium/drivers/svga/svga_resource_buffer.c
index a3e11adfac6..3f37ef692fa 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -42,16 +42,37 @@
 
 
 /**
- * Vertex and index buffers need hardware backing.  Constant buffers
- * do not.  No other types of buffers currently supported.
+ * Determine what buffers eventually need hardware backing.
+ *
+ * Vertex- and index buffers need hardware backing.  Constant buffers
+ * do on vgpu10. Staging texture-upload buffers do when they are
+ * supported.
  */
 static inline boolean
-svga_buffer_needs_hw_storage(unsigned usage)
+svga_buffer_needs_hw_storage(const struct svga_screen *ss,
+ const struct pipe_resource *template)
 {
-   return (usage & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
-PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT)) != 0;
-}
+   unsigned bind_mask = (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT);
 
+   if (ss->sws->have_vgpu10) {
+  /*
+   * Driver-created upload const0- and staging texture upload buffers
+   * tagged with PIPE_BIND_CUSTOM
+   */
+  bind_mask |= PIPE_BIND_CUSTOM;
+  /* Uniform buffer objects.
+   * Make sure we don't create hardware storage for state-tracker
+   * const0 buffers, because we frequently map them for reading.
+   * They are distinguished by having PIPE_USAGE_STREAM, but not
+   * PIPE_BIND_CUSTOM.
+   */
+  if (template->usage != PIPE_USAGE_STREAM)
+ bind_mask |= PIPE_BIND_CONSTANT_BUFFER;
+   }
+
+   return !!(template->bind & bind_mask);
+}
 
 /**
  * Create a buffer transfer.
@@ -411,7 +432,7 @@ svga_buffer_create(struct pipe_screen *screen,
sbuf->b.vtbl = _buffer_vtbl;
pipe_reference_init(>b.b.reference, 1);
sbuf->b.b.screen = screen;
-   bind_flags = template->bind;
+   bind_flags = template->bind & ~PIPE_BIND_CUSTOM;
 
LIST_INITHEAD(>surfaces);
 
@@ -430,7 +451,7 @@ svga_buffer_create(struct pipe_screen *screen,
 */
sbuf->b.b.width0 = align(sbuf->b.b.width0, 16);
 
-   if (svga_buffer_needs_hw_storage(bind_flags)) {
+   if (svga_buffer_needs_hw_storage(ss, template)) {
 
   /* If the buffer is not used for constant buffer, set
* the vertex/index bind flags as well so that the buffer will be
@@ -442,9 +463,10 @@ svga_buffer_create(struct pipe_screen *screen,
* bind flag since streamout buffer is an output buffer and
* might have performance implication.
*/
-  if (!(template->bind & PIPE_BIND_CONSTANT_BUFFER)) {
- /* Not a constant buffer.  The buffer may be used for vertex data
-  * or indexes.
+  if (!(template->bind & PIPE_BIND_CONSTANT_BUFFER) &&
+  !(template->bind & PIPE_BIND_CUSTOM)) {
+ /* Not a constant- or staging buffer.
+  * The buffer may be used for vertex data or indexes.
   */
  bind_flags |= (PIPE_BIND_VERTEX_BUFFER |
 PIPE_BIND_INDEX_BUFFER);
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c 
b/src/gallium/drivers/svga/svga_resource_texture.c
index c716b66e89f..e9449e8a1ff 1

[Mesa-dev] [PATCH 4/5] winsys/svga: Update the drm interface file

2019-04-30 Thread Thomas Hellstrom
The file vmwgfx_drm.h was a bit outdated. Update to a recent version,
including defines supporting coherent memory.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 .../winsys/svga/drm/vmw_screen_ioctl.c|   4 +-
 src/gallium/winsys/svga/drm/vmwgfx_drm.h  | 358 +-
 2 files changed, 188 insertions(+), 174 deletions(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c 
b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index cdfe284c4c8..ab60265bdd2 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -107,7 +107,7 @@ vmw_ioctl_extended_context_create(struct vmw_winsys_screen 
*vws,
 
VMW_FUNC;
memset(_arg, 0, sizeof(c_arg));
-   c_arg.req = (vgpu10 ? drm_vmw_context_vgpu10 : drm_vmw_context_legacy);
+   c_arg.req = (vgpu10 ? drm_vmw_context_dx : drm_vmw_context_legacy);
ret = drmCommandWriteRead(vws->ioctl.drm_fd,
  DRM_VMW_CREATE_EXTENDED_CONTEXT,
  _arg, sizeof(c_arg));
@@ -1057,7 +1057,7 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
 
   if (vws->ioctl.have_drm_2_9) {
  memset(_arg, 0, sizeof(gp_arg));
- gp_arg.param = DRM_VMW_PARAM_VGPU10;
+ gp_arg.param = DRM_VMW_PARAM_DX;
  ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
_arg, sizeof(gp_arg));
  if (ret == 0 && gp_arg.value != 0) {
diff --git a/src/gallium/winsys/svga/drm/vmwgfx_drm.h 
b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
index 0b1e031292e..02cab33f2f2 100644
--- a/src/gallium/winsys/svga/drm/vmwgfx_drm.h
+++ b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
@@ -28,8 +28,10 @@
 #ifndef __VMWGFX_DRM_H__
 #define __VMWGFX_DRM_H__
 
-#ifndef __KERNEL__
-#include "drm-uapi/drm.h"
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
 #endif
 
 #define DRM_VMW_MAX_SURFACE_FACES 6
@@ -38,7 +40,9 @@
 
 #define DRM_VMW_GET_PARAM0
 #define DRM_VMW_ALLOC_DMABUF 1
+#define DRM_VMW_ALLOC_BO 1
 #define DRM_VMW_UNREF_DMABUF 2
+#define DRM_VMW_HANDLE_CLOSE 2
 #define DRM_VMW_CURSOR_BYPASS3
 /* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/
 #define DRM_VMW_CONTROL_STREAM   4
@@ -95,7 +99,7 @@
 #define DRM_VMW_PARAM_MAX_MOB_MEMORY   9
 #define DRM_VMW_PARAM_MAX_MOB_SIZE 10
 #define DRM_VMW_PARAM_SCREEN_TARGET11
-#define DRM_VMW_PARAM_VGPU10   12
+#define DRM_VMW_PARAM_DX   12
 #define DRM_VMW_PARAM_HW_CAPS2 13
 #define DRM_VMW_PARAM_SM4_114
 
@@ -118,9 +122,9 @@ enum drm_vmw_handle_type {
  */
 
 struct drm_vmw_getparam_arg {
-   uint64_t value;
-   uint32_t param;
-   uint32_t pad64;
+   __u64 value;
+   __u32 param;
+   __u32 pad64;
 };
 
 /*/
@@ -141,8 +145,8 @@ struct drm_vmw_getparam_arg {
  */
 
 struct drm_vmw_context_arg {
-   int32_t cid;
-   uint32_t pad64;
+   __s32 cid;
+   __u32 pad64;
 };
 
 /*/
@@ -172,7 +176,7 @@ struct drm_vmw_context_arg {
  * @mip_levels: Number of mip levels for each face.
  * An unused face should have 0 encoded.
  * @size_addr: Address of a user-space array of sruct drm_vmw_size
- * cast to an uint64_t for 32-64 bit compatibility.
+ * cast to an __u64 for 32-64 bit compatibility.
  * The size of the array should equal the total number of mipmap levels.
  * @shareable: Boolean whether other clients (as identified by file 
descriptors)
  * may reference this surface.
@@ -184,12 +188,12 @@ struct drm_vmw_context_arg {
  */
 
 struct drm_vmw_surface_create_req {
-   uint32_t flags;
-   uint32_t format;
-   uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
-   uint64_t size_addr;
-   int32_t shareable;
-   int32_t scanout;
+   __u32 flags;
+   __u32 format;
+   __u32 mip_levels[DRM_VMW_MAX_SURFACE_FACES];
+   __u64 size_addr;
+   __s32 shareable;
+   __s32 scanout;
 };
 
 /**
@@ -204,7 +208,7 @@ struct drm_vmw_surface_create_req {
  */
 
 struct drm_vmw_surface_arg {
-   int32_t sid;
+   __s32 sid;
enum drm_vmw_handle_type handle_type;
 };
 
@@ -220,10 +224,10 @@ struct drm_vmw_surface_arg {
  */
 
 struct drm_vmw_size {
-   uint32_t width;
-   uint32_t height;
-   uint32_t depth;
-   uint32_t pad64;
+   __u32 width;
+   __u32 height;
+   __u32 depth;
+   __u32 pad64;
 };
 
 /**
@@ -291,13 +295,13 @@ union drm_vmw_surface_reference_arg {
 /**
  * struct drm_vmw_execbuf_arg
  *
- * @commands: User-space address of a command buffer cast to an uint64_t.
+ * @commands: User-space address of a command buffer cast to an __u64.
  * @command-size: Size in bytes of the command buffer.
  * @throttle-us: Sleep until software is less than 

[Mesa-dev] [PATCH 2/5] winsys/svga: Enable the transfer_from_buffer GPU command for vgpu10

2019-04-30 Thread Thomas Hellstrom
We didn't have the path using this command enabled as
typically we take an alternate path using DMA uploads.
Emable it so that we can exercise that code-path by turning off
the DMA path.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/winsys/svga/drm/vmw_screen.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/gallium/winsys/svga/drm/vmw_screen.c 
b/src/gallium/winsys/svga/drm/vmw_screen.c
index e122e0c9902..56294fec60e 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
@@ -96,6 +96,7 @@ vmw_winsys_create( int fd )
if (!vmw_ioctl_init(vws))
   goto out_no_ioctl;
 
+   vws->base.have_transfer_from_buffer_cmd = vws->base.have_vgpu10;
vws->fence_ops = vmw_fence_ops_create(vws);
if (!vws->fence_ops)
   goto out_no_fence_ops;
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 1/5] winsys/svga: Add an environment variable to force host-backed operation

2019-04-30 Thread Thomas Hellstrom
The vmwgfx kernel module has a compatibility mode for user-space that is
not guest-backed resource aware. Add an environment variable to facilitate
testing of this mode on guest-backed aware kernels: if the environment
variable SVGA_FORCE_HOST_BACKED is defined, the driver will use host-backed
operation.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Deepak Rawat 
---
 src/gallium/winsys/svga/drm/vmw_screen_ioctl.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c 
b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 0ec8c1abe11..cdfe284c4c8 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -967,6 +967,7 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
drmVersionPtr version;
boolean drm_gb_capable;
boolean have_drm_2_5;
+   const char *getenv_val;
 
VMW_FUNC;
 
@@ -1006,17 +1007,21 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
   goto out_no_3d;
}
vws->ioctl.hwversion = gp_arg.value;
-
-   memset(_arg, 0, sizeof(gp_arg));
-   gp_arg.param = DRM_VMW_PARAM_HW_CAPS;
-   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
- _arg, sizeof(gp_arg));
+   getenv_val = getenv("SVGA_FORCE_HOST_BACKED");
+   if (!getenv_val || strcmp(getenv_val, "0") == 0) {
+  memset(_arg, 0, sizeof(gp_arg));
+  gp_arg.param = DRM_VMW_PARAM_HW_CAPS;
+  ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
+_arg, sizeof(gp_arg));
+   } else {
+  ret = -EINVAL;
+   }
if (ret)
   vws->base.have_gb_objects = FALSE;
else
   vws->base.have_gb_objects =
  !!(gp_arg.value & (uint64_t) SVGA_CAP_GBOBJECTS);
-   
+
if (vws->base.have_gb_objects && !drm_gb_capable)
   goto out_no_3d;
 
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 5/5] winsys/svga: Don't abort on EBUSY errors from execbuffer

2019-04-30 Thread Thomas Hellstrom
This error code typically indicated that a buffer object that was referenced
by the command stream was being used for CPU access by another client.
The correct action here is to retry after a while. Use usleep() until we
have proper kernel support for this wait.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/winsys/svga/drm/vmw_screen_ioctl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c 
b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index ab60265bdd2..3b14f1d3513 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -564,7 +564,9 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t 
cid,
 offsetof(struct drm_vmw_execbuf_arg, context_handle);
do {
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, , 
argsize);
-   } while(ret == -ERESTART);
+   if (ret == -EBUSY)
+  usleep(1000);
+   } while(ret == -ERESTART || ret == -EBUSY);
if (ret) {
   vmw_error("%s error %s.\n", __FUNCTION__, strerror(-ret));
   abort();
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Re: [Mesa-dev] [PATCH 1/3] pipebuffer: use new pb_usage_flags enum type

2019-04-23 Thread Thomas Hellstrom
Hi, Brian,

Did this series get reviewed? I don't see any replies?

/Thomas


On Tue, 2019-03-05 at 20:48 -0700, Brian Paul wrote:
> Use a new enum type instead of 'unsigned' to make things a bit more
> understandable.
> ---
>  src/gallium/auxiliary/pipebuffer/pb_buffer.h   | 34
> ++
>  .../auxiliary/pipebuffer/pb_buffer_fenced.c|  6 ++--
>  .../auxiliary/pipebuffer/pb_buffer_malloc.c|  4 +--
>  src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c |  4 +--
>  src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c |  6 ++--
>  src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c|  4 +--
>  .../auxiliary/pipebuffer/pb_bufmgr_ondemand.c  |  4 +--
>  src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c  |  5 ++--
>  src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c  |  6 ++--
>  src/gallium/auxiliary/pipebuffer/pb_validate.c |  2 +-
>  src/gallium/auxiliary/pipebuffer/pb_validate.h |  2 +-
>  11 files changed, 45 insertions(+), 32 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h
> b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
> index 33c2306..11f70ea 100644
> --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h
> +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
> @@ -59,13 +59,22 @@ struct pb_vtbl;
>  struct pb_validate;
>  struct pipe_fence_handle;
>  
> +enum pb_usage_flags {
> +   PB_USAGE_CPU_READ = (1 << 0),
> +   PB_USAGE_CPU_WRITE = (1 << 1),
> +   PB_USAGE_GPU_READ = (1 << 2),
> +   PB_USAGE_GPU_WRITE = (1 << 3),
> +   PB_USAGE_DONTBLOCK = (1 << 9),
> +   PB_USAGE_UNSYNCHRONIZED = (1 << 10),
> +};
>  
> -#define PB_USAGE_CPU_READ  (1 << 0)
> -#define PB_USAGE_CPU_WRITE (1 << 1)
> -#define PB_USAGE_GPU_READ  (1 << 2)
> -#define PB_USAGE_GPU_WRITE (1 << 3)
> -#define PB_USAGE_UNSYNCHRONIZED (1 << 10)
> -#define PB_USAGE_DONTBLOCK (1 << 9)
> +/* For error checking elsewhere */
> +#define PB_USAGE_ALL (PB_USAGE_CPU_READ | \
> +  PB_USAGE_CPU_WRITE | \
> +  PB_USAGE_GPU_READ | \
> +  PB_USAGE_GPU_WRITE | \
> +  PB_USAGE_DONTBLOCK | \
> +  PB_USAGE_UNSYNCHRONIZED)
>  
>  #define PB_USAGE_CPU_READ_WRITE \
> ( PB_USAGE_CPU_READ | PB_USAGE_CPU_WRITE )
> @@ -82,7 +91,7 @@ struct pipe_fence_handle;
>  struct pb_desc
>  {
> unsigned alignment;
> -   unsigned usage;
> +   enum pb_usage_flags usage;
>  };
>  
>  
> @@ -100,7 +109,7 @@ struct pb_buffer
> struct pipe_reference  reference;
> unsigned   alignment;
> pb_sizesize;
> -   unsigned   usage;
> +   enum pb_usage_flagsusage;
>  
> /**
>  * Pointer to the virtual function table.
> @@ -126,13 +135,13 @@ struct pb_vtbl
>  * flags is bitmask of PB_USAGE_CPU_READ/WRITE. 
>  */
> void *(*map)( struct pb_buffer *buf, 
> - unsigned flags, void *flush_ctx );
> + enum pb_usage_flags flags, void *flush_ctx );
> 
> void (*unmap)( struct pb_buffer *buf );
>  
> enum pipe_error (*validate)( struct pb_buffer *buf, 
>  struct pb_validate *vl,
> -unsigned flags );
> +enum pb_usage_flags flags );
>  
> void (*fence)( struct pb_buffer *buf, 
>struct pipe_fence_handle *fence );
> @@ -160,7 +169,7 @@ struct pb_vtbl
>   */
>  static inline void *
>  pb_map(struct pb_buffer *buf, 
> -   unsigned flags, void *flush_ctx)
> +   enum pb_usage_flags flags, void *flush_ctx)
>  {
> assert(buf);
> if (!buf)
> @@ -201,7 +210,8 @@ pb_get_base_buffer( struct pb_buffer *buf,
>  
>  
>  static inline enum pipe_error 
> -pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned
> flags)
> +pb_validate(struct pb_buffer *buf, struct pb_validate *vl,
> +enum pb_usage_flags flags)
>  {
> assert(buf);
> if (!buf)
> diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
> b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
> index 7421741..53b9ce0 100644
> --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
> +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
> @@ -139,7 +139,7 @@ struct fenced_buffer
>  * A bitmask of PB_USAGE_CPU/GPU_READ/WRITE describing the
> current
>  * buffer usage.
>  */
> -   unsigned flags;
> +   enum pb_usage_flags flags;
>  
> unsigned mapcount;
>  
> @@ -662,7 +662,7 @@ fenced_buffer_destroy(struct pb_buffer *buf)
>  
>  static void *
>  fenced_buffer_map(struct pb_buffer *buf,
> -  unsigned flags, void *flush_ctx)
> +  enum pb_usage_flags flags, void *flush_ctx)
>  {
> struct fenced_buffer *fenced_buf = fenced_buffer(buf);
> struct fenced_manager *fenced_mgr = fenced_buf->mgr;
> @@ -739,7 +739,7 @@ fenced_buffer_unmap(struct pb_buffer *buf)
>  static enum pipe_error
>  fenced_buffer_validate(struct pb_buffer *buf,
>   

Re: [Mesa-dev] [PATCH 3/3] winsys/svga: use new pb_usage_flags enum type

2019-03-07 Thread Thomas Hellstrom
On Tue, 2019-03-05 at 20:48 -0700, Brian Paul wrote:
> And add a comment that we're implicitly converting PIPE_TRANSFER_
> flags to PB_USAGE_ flags in one place.  And statically assert that
> the enum values match.


LGTM. Thanks for fixing this!

Reviewed-by: Thomas Hellstrom 



> ---
>  src/gallium/winsys/svga/drm/vmw_buffer.c  | 27
> +++
>  src/gallium/winsys/svga/drm/vmw_buffer.h  |  1 +
>  src/gallium/winsys/svga/drm/vmw_context.c |  4 ++--
>  3 files changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.c
> b/src/gallium/winsys/svga/drm/vmw_buffer.c
> index 3ac80c7..91b5b25 100644
> --- a/src/gallium/winsys/svga/drm/vmw_buffer.c
> +++ b/src/gallium/winsys/svga/drm/vmw_buffer.c
> @@ -90,6 +90,11 @@ static inline struct vmw_gmr_bufmgr *
>  vmw_gmr_bufmgr(struct pb_manager *mgr)
>  {
> assert(mgr);
> +
> +   /* Make sure our extra flags don't collide with pipebuffer's
> flags */
> +   STATIC_ASSERT((VMW_BUFFER_USAGE_SHARED & PB_USAGE_ALL) == 0);
> +   STATIC_ASSERT((VMW_BUFFER_USAGE_SYNC & PB_USAGE_ALL) == 0);
> +
> return (struct vmw_gmr_bufmgr *)mgr;
>  }
>  
> @@ -109,7 +114,7 @@ vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
>  
>  static void *
>  vmw_gmr_buffer_map(struct pb_buffer *_buf,
> -   unsigned flags,
> +   enum pb_usage_flags flags,
> void *flush_ctx)
>  {
> struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
> @@ -140,7 +145,7 @@ static void
>  vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
>  {
> struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
> -   unsigned flags = buf->map_flags;
> +   enum pb_usage_flags flags = buf->map_flags;
>  
> if ((_buf->usage & VMW_BUFFER_USAGE_SYNC) &&
> !(flags & PB_USAGE_UNSYNCHRONIZED)) {
> @@ -164,7 +169,7 @@ vmw_gmr_buffer_get_base_buffer(struct pb_buffer
> *buf,
>  static enum pipe_error
>  vmw_gmr_buffer_validate( struct pb_buffer *_buf, 
>   struct pb_validate *vl,
> - unsigned flags )
> + enum pb_usage_flags flags )
>  {
> /* Always pinned */
> return PIPE_OK;
> @@ -338,7 +343,7 @@ vmw_svga_winsys_buffer_destroy(struct
> svga_winsys_screen *sws,
>  void *
>  vmw_svga_winsys_buffer_map(struct svga_winsys_screen *sws,
> struct svga_winsys_buffer *buf,
> -   unsigned flags)
> +   enum pipe_transfer_usage flags)
>  {
> void *map;
>  
> @@ -346,6 +351,20 @@ vmw_svga_winsys_buffer_map(struct
> svga_winsys_screen *sws,
> if (flags & PIPE_TRANSFER_UNSYNCHRONIZED)
>flags &= ~PIPE_TRANSFER_DONTBLOCK;
>  
> +   /* NOTE: we're passing PIPE_TRANSFER_x flags instead of
> +* PB_USAGE_x flags here.  We should probably fix that.
> +*/
> +   STATIC_ASSERT((unsigned) PB_USAGE_CPU_READ ==
> + (unsigned) PIPE_TRANSFER_READ);
> +   STATIC_ASSERT((unsigned) PB_USAGE_CPU_WRITE ==
> + (unsigned) PIPE_TRANSFER_WRITE);
> +   STATIC_ASSERT((unsigned) PB_USAGE_GPU_READ ==
> + (unsigned) PIPE_TRANSFER_MAP_DIRECTLY);
> +   STATIC_ASSERT((unsigned) PB_USAGE_DONTBLOCK ==
> + (unsigned) PIPE_TRANSFER_DONTBLOCK);
> +   STATIC_ASSERT((unsigned) PB_USAGE_UNSYNCHRONIZED ==
> + (unsigned) PIPE_TRANSFER_UNSYNCHRONIZED);
> +
> map = pb_map(vmw_pb_buffer(buf), flags, NULL);
>  
>  #ifdef DEBUG
> diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.h
> b/src/gallium/winsys/svga/drm/vmw_buffer.h
> index 6e1151e..8ed56d4 100644
> --- a/src/gallium/winsys/svga/drm/vmw_buffer.h
> +++ b/src/gallium/winsys/svga/drm/vmw_buffer.h
> @@ -33,6 +33,7 @@
>  #include "util/u_debug_flush.h"
>  
>  
> +/* These extra flags are used wherever the pb_usage_flags enum type
> is used */
>  #define VMW_BUFFER_USAGE_SHARED(1 << 20)
>  #define VMW_BUFFER_USAGE_SYNC  (1 << 21)
>  
> diff --git a/src/gallium/winsys/svga/drm/vmw_context.c
> b/src/gallium/winsys/svga/drm/vmw_context.c
> index c0ee833..59963ff 100644
> --- a/src/gallium/winsys/svga/drm/vmw_context.c
> +++ b/src/gallium/winsys/svga/drm/vmw_context.c
> @@ -161,10 +161,10 @@ vmw_svga_winsys_context(struct
> svga_winsys_context *swc)
>  }
>  
>  
> -static inline unsigned
> +static inline enum pb_usage_flags
>  vmw_translate_to_pb_flags(unsigned flags)
>  {
> -   unsigned f = 0;
> +   enum pb_usage_flags f = 0;
> if (flags & SVGA_RELOC_READ)
>f |= PB_USAGE_GPU_READ;
>  
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Re: [Mesa-dev] [PATCH] svga: remove SVGA_RELOC_READ flag in SVGA3D_BindGBSurface()

2019-03-07 Thread Thomas Hellstrom
On Thu, 2019-03-07 at 19:45 -0700, Brian Paul wrote:
> This fixes a rendering issue where UBO updates aren't always picked
> up by drawing calls.  This issue effected the Webots robotics
> simulator.  VMware bug 2175527.
> 
> Testing Done: Webots replay, piglit, misc Linux games
> ---
>  src/gallium/drivers/svga/svga_cmd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/src/gallium/drivers/svga/svga_cmd.c
> b/src/gallium/drivers/svga/svga_cmd.c
> index 5557d20..6577c83 100644
> --- a/src/gallium/drivers/svga/svga_cmd.c
> +++ b/src/gallium/drivers/svga/svga_cmd.c
> @@ -1693,7 +1693,7 @@ SVGA3D_BindGBSurface(struct svga_winsys_context
> *swc,
>return PIPE_ERROR_OUT_OF_MEMORY;
>  
> swc->surface_relocation(swc, >sid, >mobid, surface,
> -   SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
> +   SVGA_RELOC_READ);
>  
> swc->commit(swc);
>  

Reviewed-by:
Thomas Hellström 

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH] winsys/svga: Fix a memory leak

2018-11-28 Thread Thomas Hellstrom
The ioctl.cap_3d member was never freed.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Sinclair Yeh 
---
 src/gallium/winsys/svga/drm/vmw_screen_ioctl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c 
b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 739e4ea131f..0ec8c1abe11 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -1198,4 +1198,6 @@ void
 vmw_ioctl_cleanup(struct vmw_winsys_screen *vws)
 {
VMW_FUNC;
+
+   free(vws->ioctl.cap_3d);
 }
-- 
2.19.0.rc1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] st/xa: Fix a memory leak

2018-11-28 Thread Thomas Hellstrom
Free the context after destruction.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Sinclair Yeh 
---
 src/gallium/state_trackers/xa/xa_context.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/gallium/state_trackers/xa/xa_context.c 
b/src/gallium/state_trackers/xa/xa_context.c
index 94f7185272a..a4630cf09ca 100644
--- a/src/gallium/state_trackers/xa/xa_context.c
+++ b/src/gallium/state_trackers/xa/xa_context.c
@@ -91,6 +91,7 @@ xa_context_destroy(struct xa_context *r)
 }
 
 r->pipe->destroy(r->pipe);
+free(r);
 }
 
 XA_EXPORT int
-- 
2.19.0.rc1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 3/3] st/xa: Support Component Alpha with trivial blending

2018-11-13 Thread Thomas Hellstrom
Support Component Alpha for those composite operations that do not require
per-channel alpha blending.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/state_trackers/xa/xa_composite.c | 33 
 src/gallium/state_trackers/xa/xa_priv.h  |  1 +
 src/gallium/state_trackers/xa/xa_tgsi.c  | 18 ---
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c 
b/src/gallium/state_trackers/xa/xa_composite.c
index b0746327522..34d78027e27 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -111,12 +111,6 @@ blend_for_op(struct xa_composite_blend *blend,
 int i;
 boolean supported = FALSE;
 
-/*
- * No component alpha yet.
- */
-if (mask_pic && mask_pic->component_alpha)
-   return FALSE;
-
 /*
  * our default in case something goes wrong
  */
@@ -130,6 +124,12 @@ blend_for_op(struct xa_composite_blend *blend,
}
 }
 
+/*
+ * No component alpha yet.
+ */
+if (mask_pic && mask_pic->component_alpha && blend->alpha_src)
+   return FALSE;
+
 if (!dst_pic->srf)
return supported;
 
@@ -224,15 +224,9 @@ xa_src_pict_is_accelerated(const union xa_source_pict 
*src_pic)
 XA_EXPORT int
 xa_composite_check_accelerated(const struct xa_composite *comp)
 {
-struct xa_composite_blend blend;
 struct xa_picture *src_pic = comp->src;
 struct xa_picture *mask_pic = comp->mask;
-
-/*
- * No component alpha yet.
- */
-if (mask_pic && mask_pic->component_alpha)
-   return -XA_ERR_INVAL;
+struct xa_composite_blend blend;
 
 if (!xa_is_filter_accelerated(src_pic) ||
!xa_is_filter_accelerated(comp->mask)) {
@@ -246,6 +240,12 @@ xa_composite_check_accelerated(const struct xa_composite 
*comp)
 if (!blend_for_op(, comp->op, comp->src, comp->mask, comp->dst))
return -XA_ERR_INVAL;
 
+/*
+ * No component alpha yet.
+ */
+if (mask_pic && mask_pic->component_alpha && blend.alpha_src)
+   return -XA_ERR_INVAL;
+
 return XA_ERR_NONE;
 }
 
@@ -382,10 +382,15 @@ bind_shaders(struct xa_context *ctx, const struct 
xa_composite *comp)
 struct xa_shader shader;
 struct xa_picture *src_pic = comp->src;
 struct xa_picture *mask_pic = comp->mask;
+struct xa_picture *dst_pic = comp->dst;
 
 ctx->has_solid_src = FALSE;
 ctx->has_solid_mask = FALSE;
 
+if (dst_pic && xa_format_type(dst_pic->pict_format) !=
+xa_format_type(xa_surface_format(dst_pic->srf)))
+   return -XA_ERR_INVAL;
+
 if (src_pic) {
if (src_pic->wrap == xa_wrap_clamp_to_border && src_pic->has_transform)
fs_traits |= FS_SRC_REPEAT_NONE;
@@ -405,6 +410,8 @@ bind_shaders(struct xa_context *ctx, const struct 
xa_composite *comp)
 if (mask_pic) {
vs_traits |= VS_MASK;
fs_traits |= FS_MASK;
+if (mask_pic->component_alpha)
+   fs_traits |= FS_CA;
 if (mask_pic->src_pict) {
 if (!xa_handle_src_pict(ctx, mask_pic->src_pict, true))
 return -XA_ERR_INVAL;
diff --git a/src/gallium/state_trackers/xa/xa_priv.h 
b/src/gallium/state_trackers/xa/xa_priv.h
index 09a858ff972..f368de3b81f 100644
--- a/src/gallium/state_trackers/xa/xa_priv.h
+++ b/src/gallium/state_trackers/xa/xa_priv.h
@@ -166,6 +166,7 @@ enum xa_fs_traits {
 FS_SRC_LUMINANCE = 1 << 11,
 FS_MASK_LUMINANCE = 1 << 12,
 FS_DST_LUMINANCE = 1 << 13,
+FS_CA = 1 << 14,
 };
 
 struct xa_shader {
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c 
b/src/gallium/state_trackers/xa/xa_tgsi.c
index 5f2608aee55..ed3e0895d98 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -82,6 +82,7 @@ print_fs_traits(int fs_traits)
"FS_SRC_LUMINANCE", /* = 1 << 11, */
"FS_MASK_LUMINANCE",/* = 1 << 12, */
"FS_DST_LUMINANCE", /* = 1 << 13, */
+"FS_CA",/* = 1 << 14, */
 };
 int i, k;
 
@@ -107,12 +108,20 @@ src_in_mask(struct ureg_program *ureg,
struct ureg_dst dst,
struct ureg_src src,
struct ureg_src mask,
-   unsigned mask_luminance)
+   unsigned mask_luminance, boolean component_alpha)
 {
 if (mask_luminance)
-ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X));
-else
+if (component_alpha) {
+ureg_MOV(ureg, dst, src);
+ureg_MUL(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W),
+ src, ureg_scalar(mask, TGSI_SWIZZLE_X));
+} else {
+ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X));
+}
+else 

[Mesa-dev] [PATCH 1/3] st/xa: Fix transformations when we have both source and mask samplers

2018-11-13 Thread Thomas Hellstrom
In the case when we had both source and mask samplers, transformations were
typically not applied correctly.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/state_trackers/xa/xa_renderer.c | 117 
 1 file changed, 49 insertions(+), 68 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_renderer.c 
b/src/gallium/state_trackers/xa/xa_renderer.c
index 0cb75a8c968..ac26c5508cf 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -192,47 +192,55 @@ add_vertex_2tex(struct xa_context *r,
 }
 
 static void
-add_vertex_data1(struct xa_context *r,
- float srcX, float srcY,  float dstX, float dstY,
- float width, float height,
- struct pipe_resource *src, const float *src_matrix)
+compute_src_coords(float sx, float sy, struct pipe_resource *src,
+   const float *src_matrix,
+   float width, float height,
+   float tc0[2], float tc1[2], float tc2[2], float tc3[2])
 {
-float s0, t0, s1, t1, s2, t2, s3, t3;
-float pt0[2], pt1[2], pt2[2], pt3[2];
-
-pt0[0] = srcX;
-pt0[1] = srcY;
-pt1[0] = (srcX + width);
-pt1[1] = srcY;
-pt2[0] = (srcX + width);
-pt2[1] = (srcY + height);
-pt3[0] = srcX;
-pt3[1] = (srcY + height);
+tc0[0] = sx;
+tc0[1] = sy;
+tc1[0] = (sx + width);
+tc1[1] = sy;
+tc2[0] = (sx + width);
+tc2[1] = (sy + height);
+tc3[0] = sx;
+tc3[1] = (sy + height);
 
 if (src_matrix) {
-   map_point((float *)src_matrix, pt0[0], pt0[1], [0], [1]);
-   map_point((float *)src_matrix, pt1[0], pt1[1], [0], [1]);
-   map_point((float *)src_matrix, pt2[0], pt2[1], [0], [1]);
-   map_point((float *)src_matrix, pt3[0], pt3[1], [0], [1]);
+   map_point((float *)src_matrix, tc0[0], tc0[1], [0], [1]);
+   map_point((float *)src_matrix, tc1[0], tc1[1], [0], [1]);
+   map_point((float *)src_matrix, tc2[0], tc2[1], [0], [1]);
+   map_point((float *)src_matrix, tc3[0], tc3[1], [0], [1]);
 }
 
-s0 =  pt0[0] / src->width0;
-s1 =  pt1[0] / src->width0;
-s2 =  pt2[0] / src->width0;
-s3 =  pt3[0] / src->width0;
-t0 =  pt0[1] / src->height0;
-t1 =  pt1[1] / src->height0;
-t2 =  pt2[1] / src->height0;
-t3 =  pt3[1] / src->height0;
+tc0[0] /= src->width0;
+tc1[0] /= src->width0;
+tc2[0] /= src->width0;
+tc3[0] /= src->width0;
+tc0[1] /= src->height0;
+tc1[1] /= src->height0;
+tc2[1] /= src->height0;
+tc3[1] /= src->height0;
+}
 
+static void
+add_vertex_data1(struct xa_context *r,
+ float srcX, float srcY,  float dstX, float dstY,
+ float width, float height,
+ struct pipe_resource *src, const float *src_matrix)
+{
+float tc0[2], tc1[2], tc2[2], tc3[2];
+
+compute_src_coords(srcX, srcY, src, src_matrix, width, height,
+   tc0, tc1, tc2, tc3);
 /* 1st vertex */
-add_vertex_1tex(r, dstX, dstY, s0, t0);
+add_vertex_1tex(r, dstX, dstY, tc0[0], tc0[1]);
 /* 2nd vertex */
-add_vertex_1tex(r, dstX + width, dstY, s1, t1);
+add_vertex_1tex(r, dstX + width, dstY, tc1[0], tc1[1]);
 /* 3rd vertex */
-add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
+add_vertex_1tex(r, dstX + width, dstY + height, tc2[0], tc2[1]);
 /* 4th vertex */
-add_vertex_1tex(r, dstX, dstY + height, s3, t3);
+add_vertex_1tex(r, dstX, dstY + height, tc3[0], tc3[1]);
 }
 
 static void
@@ -243,53 +251,26 @@ add_vertex_data2(struct xa_context *r,
  struct pipe_resource *mask,
  const float *src_matrix, const float *mask_matrix)
 {
-float src_s0, src_t0, src_s1, src_t1;
-float mask_s0, mask_t0, mask_s1, mask_t1;
-float spt0[2], spt1[2];
-float mpt0[2], mpt1[2];
-
-spt0[0] = srcX;
-spt0[1] = srcY;
-spt1[0] = srcX + width;
-spt1[1] = srcY + height;
-
-mpt0[0] = maskX;
-mpt0[1] = maskY;
-mpt1[0] = maskX + width;
-mpt1[1] = maskY + height;
-
-if (src_matrix) {
-   map_point((float *)src_matrix, spt0[0], spt0[1], [0], [1]);
-   map_point((float *)src_matrix, spt1[0], spt1[1], [0], [1]);
-}
-
-if (mask_matrix) {
-   map_point((float *)mask_matrix, mpt0[0], mpt0[1], [0], [1]);
-   map_point((float *)mask_matrix, mpt1[0], mpt1[1], [0], [1]);
-}
-
-src_s0 = spt0[0] / src->width0;
-src_t0 = spt0[1] / src->height0;
-src_s1 = spt1[0] / src->width0;
-src_t1 = spt1[1] / src->height0;
+float spt0[2], spt1[2], spt2[2], spt3[2];
+float mpt0[2], mpt1[2], mpt2[2], mpt3[2];
 
-mask_s0 = mpt0[0] / mask->width0;
-mask_t0 = mpt0[1] / mask->height0;
-mask_s1 = mpt1[0] / mask->width0;
-mask_t1 = mpt1[1] / mask->height0;
+compute_src_coords(srcX, srcY, src, s

[Mesa-dev] [PATCH 2/3] st/xa: Minor renderer cleanups

2018-11-13 Thread Thomas Hellstrom
constify function arguments to clean up the code a bit.

Reported-by: Brian Paul 
Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/state_trackers/xa/xa_renderer.c | 24 ++---
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_renderer.c 
b/src/gallium/state_trackers/xa/xa_renderer.c
index ac26c5508cf..582a5fa1308 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -46,14 +46,14 @@ renderer_set_constants(struct xa_context *r,
   int shader_type, const float *params, int param_bytes);
 
 static inline boolean
-is_affine(float *matrix)
+is_affine(const float *matrix)
 {
 return floatIsZero(matrix[2]) && floatIsZero(matrix[5])
&& floatsEqual(matrix[8], 1);
 }
 
 static inline void
-map_point(float *mat, float x, float y, float *out_x, float *out_y)
+map_point(const float *mat, float x, float y, float *out_x, float *out_y)
 {
 if (!mat) {
*out_x = x;
@@ -192,25 +192,25 @@ add_vertex_2tex(struct xa_context *r,
 }
 
 static void
-compute_src_coords(float sx, float sy, struct pipe_resource *src,
+compute_src_coords(float sx, float sy, const struct pipe_resource *src,
const float *src_matrix,
float width, float height,
float tc0[2], float tc1[2], float tc2[2], float tc3[2])
 {
 tc0[0] = sx;
 tc0[1] = sy;
-tc1[0] = (sx + width);
+tc1[0] = sx + width;
 tc1[1] = sy;
-tc2[0] = (sx + width);
-tc2[1] = (sy + height);
+tc2[0] = sx + width;
+tc2[1] = sy + height;
 tc3[0] = sx;
-tc3[1] = (sy + height);
+tc3[1] = sy + height;
 
 if (src_matrix) {
-   map_point((float *)src_matrix, tc0[0], tc0[1], [0], [1]);
-   map_point((float *)src_matrix, tc1[0], tc1[1], [0], [1]);
-   map_point((float *)src_matrix, tc2[0], tc2[1], [0], [1]);
-   map_point((float *)src_matrix, tc3[0], tc3[1], [0], [1]);
+   map_point(src_matrix, tc0[0], tc0[1], [0], [1]);
+   map_point(src_matrix, tc1[0], tc1[1], [0], [1]);
+   map_point(src_matrix, tc2[0], tc2[1], [0], [1]);
+   map_point(src_matrix, tc3[0], tc3[1], [0], [1]);
 }
 
 tc0[0] /= src->width0;
@@ -227,7 +227,7 @@ static void
 add_vertex_data1(struct xa_context *r,
  float srcX, float srcY,  float dstX, float dstY,
  float width, float height,
- struct pipe_resource *src, const float *src_matrix)
+ const struct pipe_resource *src, const float *src_matrix)
 {
 float tc0[2], tc1[2], tc2[2], tc3[2];
 
-- 
2.19.0.rc1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/4] st/xa: Support higher color precision for solid pictures

2018-11-12 Thread Thomas Hellstrom
The only solid fill picture type we supported only had 8 bit color
channels. Add a new solid picture type that supports float channels.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/state_trackers/xa/xa_composite.c | 106 ++-
 src/gallium/state_trackers/xa/xa_composite.h |  20 +++-
 2 files changed, 100 insertions(+), 26 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c 
b/src/gallium/state_trackers/xa/xa_composite.c
index 8de51b34d96..b0746327522 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -200,6 +200,27 @@ xa_is_filter_accelerated(struct xa_picture *pic)
 return 1;
 }
 
+/**
+ * xa_src_pict_is_accelerated - Check whether we support acceleration
+ * of the given src_pict type
+ *
+ * \param src_pic[in]: Pointer to a union xa_source_pict to check.
+ *
+ * \returns TRUE if accelerated, FALSE otherwise.
+ */
+static boolean
+xa_src_pict_is_accelerated(const union xa_source_pict *src_pic)
+{
+if (!src_pic)
+return TRUE;
+
+if (src_pic->type == xa_src_pict_solid_fill ||
+src_pic->type == xa_src_pict_float_solid_fill)
+return TRUE;
+
+return FALSE;
+}
+
 XA_EXPORT int
 xa_composite_check_accelerated(const struct xa_composite *comp)
 {
@@ -218,7 +239,8 @@ xa_composite_check_accelerated(const struct xa_composite 
*comp)
return -XA_ERR_INVAL;
 }
 
-if (src_pic->src_pict &_pic->src_pict->type != xa_src_pict_solid_fill)
+if (!xa_src_pict_is_accelerated(src_pic->src_pict) ||
+(mask_pic && !xa_src_pict_is_accelerated(mask_pic->src_pict)))
 return -XA_ERR_INVAL;
 
 if (!blend_for_op(, comp->op, comp->src, comp->mask, comp->dst))
@@ -307,6 +329,52 @@ xa_src_in_mask(float src[4], const float mask[4])
src[3] *= mask[3];
 }
 
+/**
+ * xa_handle_src_pict - Set up xa_context state and fragment shader
+ * input based on scr_pict type
+ *
+ * \param ctx[in, out]: Pointer to the xa context.
+ * \param src_pict[in]: Pointer to the union xa_source_pict to consider.
+ * \param is_mask[in]: Whether we're considering a mask picture.
+ *
+ * \returns TRUE if succesful, FALSE otherwise.
+ *
+ * This function computes some xa_context state used to determine whether
+ * to upload the solid color and also the solid color itself used as an input
+ * to the fragment shader.
+ */
+static boolean
+xa_handle_src_pict(struct xa_context *ctx,
+   const union xa_source_pict *src_pict,
+   boolean is_mask)
+{
+float solid_color[4];
+
+switch(src_pict->type) {
+case xa_src_pict_solid_fill:
+xa_pixel_to_float4(src_pict->solid_fill.color, solid_color);
+break;
+case xa_src_pict_float_solid_fill:
+memcpy(solid_color, src_pict->float_solid_fill.color,
+   sizeof(solid_color));
+break;
+default:
+return FALSE;
+}
+
+if (is_mask && ctx->has_solid_src)
+xa_src_in_mask(ctx->solid_color, solid_color);
+else
+memcpy(ctx->solid_color, solid_color, sizeof(solid_color));
+
+if (is_mask)
+ctx->has_solid_mask = TRUE;
+else
+ctx->has_solid_src = TRUE;
+
+return TRUE;
+}
+
 static int
 bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 {
@@ -326,13 +394,10 @@ bind_shaders(struct xa_context *ctx, const struct 
xa_composite *comp)
 vs_traits |= VS_COMPOSITE;
 
if (src_pic->src_pict) {
-   if (src_pic->src_pict->type == xa_src_pict_solid_fill) {
-   fs_traits |= FS_SRC_SRC;
-   vs_traits |= VS_SRC_SRC;
-   xa_pixel_to_float4(src_pic->src_pict->solid_fill.color,
-  ctx->solid_color);
-   ctx->has_solid_src = TRUE;
-   }
+if (!xa_handle_src_pict(ctx, src_pic->src_pict, false))
+return -XA_ERR_INVAL;
+fs_traits |= FS_SRC_SRC;
+vs_traits |= VS_SRC_SRC;
} else
fs_traits |= picture_format_fixups(src_pic, 0);
 }
@@ -341,22 +406,15 @@ bind_shaders(struct xa_context *ctx, const struct 
xa_composite *comp)
vs_traits |= VS_MASK;
fs_traits |= FS_MASK;
 if (mask_pic->src_pict) {
-if (mask_pic->src_pict->type == xa_src_pict_solid_fill) {
-if (ctx->has_solid_src) {
-float solid_mask[4];
-
-xa_pixel_to_float4(mask_pic->src_pict->solid_fill.color,
-   solid_mask);
-xa_src_in_mask(ctx->solid_color, solid_mask);
-vs_traits &= ~(VS_MASK);
-fs_traits &= ~(FS_MASK);
-} else {
-xa_pixel_to_float4(mask_pic->src_pict->solid_fill.color,
-  

[Mesa-dev] [PATCH 1/4] st/xa: Render update. Better support for solid pictures

2018-11-12 Thread Thomas Hellstrom
Remove unused and obsolete code for gradients and component-alpha
Support solid source- and mask pictures using a variable number
of samplers in the composite pipeline rather than the fixed number
we used before.

Tested using rendercheck for XA.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/state_trackers/xa/xa_composite.c | 211 +--
 src/gallium/state_trackers/xa/xa_context.c   |  10 +-
 src/gallium/state_trackers/xa/xa_priv.h  |  44 +--
 src/gallium/state_trackers/xa/xa_renderer.c  |  46 ++-
 src/gallium/state_trackers/xa/xa_tgsi.c  | 354 +--
 5 files changed, 225 insertions(+), 440 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c 
b/src/gallium/state_trackers/xa/xa_composite.c
index bcb27ea1825..8de51b34d96 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -112,7 +112,7 @@ blend_for_op(struct xa_composite_blend *blend,
 boolean supported = FALSE;
 
 /*
- * Temporarily disable component alpha since it appears buggy.
+ * No component alpha yet.
  */
 if (mask_pic && mask_pic->component_alpha)
return FALSE;
@@ -126,6 +126,7 @@ blend_for_op(struct xa_composite_blend *blend,
if (xa_blends[i].op == op) {
*blend = xa_blends[i];
supported = TRUE;
+break;
}
 }
 
@@ -150,21 +151,6 @@ blend_for_op(struct xa_composite_blend *blend,
blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
 }
 
-/*
- * If the source alpha is being used, then we should only be in a case 
where
- * the source blend factor is 0, and the source blend value is the mask
- * channels multiplied by the source picture's alpha.
- */
-if (mask_pic && mask_pic->component_alpha &&
-   xa_format_rgb(mask_pic->pict_format) &&
-   blend->alpha_src) {
-   if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
-   blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
-   } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
-   blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
-   }
-}
-
 return supported;
 }
 
@@ -219,38 +205,26 @@ xa_composite_check_accelerated(const struct xa_composite 
*comp)
 {
 struct xa_composite_blend blend;
 struct xa_picture *src_pic = comp->src;
+struct xa_picture *mask_pic = comp->mask;
+
+/*
+ * No component alpha yet.
+ */
+if (mask_pic && mask_pic->component_alpha)
+   return -XA_ERR_INVAL;
 
 if (!xa_is_filter_accelerated(src_pic) ||
!xa_is_filter_accelerated(comp->mask)) {
return -XA_ERR_INVAL;
 }
 
+if (src_pic->src_pict &_pic->src_pict->type != xa_src_pict_solid_fill)
+return -XA_ERR_INVAL;
 
-if (src_pic->src_pict) {
-   if (src_pic->src_pict->type != xa_src_pict_solid_fill)
-   return -XA_ERR_INVAL;
-
-   /*
-* Currently we don't support solid fill with a mask.
-* We can easily do that, but that would require shader,
-* sampler view setup and vertex setup modification.
-*/
-   if (comp->mask)
-   return -XA_ERR_INVAL;
-}
-
-if (blend_for_op(, comp->op, comp->src, comp->mask, comp->dst)) {
-   struct xa_picture *mask = comp->mask;
-   if (mask && mask->component_alpha &&
-   xa_format_rgb(mask->pict_format)) {
-   if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
-   return -XA_ERR_INVAL;
-   }
-   }
+if (!blend_for_op(, comp->op, comp->src, comp->mask, comp->dst))
+   return -XA_ERR_INVAL;
 
-   return XA_ERR_NONE;
-}
-return -XA_ERR_INVAL;
+return XA_ERR_NONE;
 }
 
 static int
@@ -293,7 +267,7 @@ picture_format_fixups(struct xa_picture *src_pic,
 src_hw_format = xa_surface_format(src);
 src_pic_format = src_pic->pict_format;
 
-set_alpha = (xa_format_type_is_color(src_pic_format) &&
+set_alpha = (xa_format_type_is_color(src_hw_format) &&
 xa_format_a(src_pic_format) == 0);
 
 if (set_alpha)
@@ -324,6 +298,15 @@ picture_format_fixups(struct xa_picture *src_pic,
 return ret;
 }
 
+static void
+xa_src_in_mask(float src[4], const float mask[4])
+{
+   src[0] *= mask[3];
+   src[1] *= mask[3];
+   src[2] *= mask[3];
+   src[3] *= mask[3];
+}
+
 static int
 bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 {
@@ -332,47 +315,56 @@ bind_shaders(struct xa_context *ctx, const struct 
xa_composite *comp)
 struct xa_picture *src_pic = comp->src;
 struct xa_picture *mask_pic = comp->mask;
 
-ctx->has_solid_color = FALSE;
+ctx->has_solid_src = FALSE;
+ctx->has_solid_mask = FALSE;
 
 if (src_pic) {
  

[Mesa-dev] [PATCH 3/4] st/xa: Support a couple of new formats

2018-11-12 Thread Thomas Hellstrom
Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/state_trackers/xa/xa_tracker.c| 33 ++-
 src/gallium/state_trackers/xa/xa_tracker.h.in |  5 +++
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_tracker.c 
b/src/gallium/state_trackers/xa/xa_tracker.c
index 5ac98f8eed0..0909044fb91 100644
--- a/src/gallium/state_trackers/xa/xa_tracker.c
+++ b/src/gallium/state_trackers/xa/xa_tracker.c
@@ -89,6 +89,15 @@ xa_get_pipe_format(struct xa_tracker *xa, enum xa_formats 
xa_format)
 fdesc.xa_format = xa_format;
 
 switch (xa_format) {
+case xa_format_a8:
+if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM,
+PIPE_TEXTURE_2D, 0, 0,
+stype_bind[xa_type_a] |
+PIPE_BIND_RENDER_TARGET))
+fdesc.format = PIPE_FORMAT_R8_UNORM;
+else
+fdesc.format = PIPE_FORMAT_L8_UNORM;
+   break;
 case xa_format_a8r8g8b8:
fdesc.format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
@@ -101,15 +110,21 @@ xa_get_pipe_format(struct xa_tracker *xa, enum xa_formats 
xa_format)
 case xa_format_x1r5g5b5:
fdesc.format = PIPE_FORMAT_B5G5R5A1_UNORM;
break;
-case xa_format_a8:
-if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM,
-PIPE_TEXTURE_2D, 0, 0,
-stype_bind[xa_type_a] |
-PIPE_BIND_RENDER_TARGET))
-fdesc.format = PIPE_FORMAT_R8_UNORM;
-else
-fdesc.format = PIPE_FORMAT_L8_UNORM;
-   break;
+case xa_format_a4r4g4b4:
+fdesc.format = PIPE_FORMAT_B4G4R4A4_UNORM;
+break;
+case xa_format_a2b10g10r10:
+fdesc.format = PIPE_FORMAT_R10G10B10A2_UNORM;
+break;
+case xa_format_x2b10g10r10:
+fdesc.format = PIPE_FORMAT_R10G10B10X2_UNORM;
+break;
+case xa_format_b8g8r8a8:
+fdesc.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+break;
+case xa_format_b8g8r8x8:
+fdesc.format = PIPE_FORMAT_X8R8G8B8_UNORM;
+break;
 case xa_format_z24:
fdesc.format = PIPE_FORMAT_Z24X8_UNORM;
break;
diff --git a/src/gallium/state_trackers/xa/xa_tracker.h.in 
b/src/gallium/state_trackers/xa/xa_tracker.h.in
index fc721eed38b..3d136707152 100644
--- a/src/gallium/state_trackers/xa/xa_tracker.h.in
+++ b/src/gallium/state_trackers/xa/xa_tracker.h.in
@@ -126,6 +126,11 @@ enum xa_formats {
 xa_format_x8r8g8b8 = xa_format(32, xa_type_argb, 0, 8, 8, 8),
 xa_format_r5g6b5 = xa_format(16, xa_type_argb, 0, 5, 6, 5),
 xa_format_x1r5g5b5 = xa_format(16, xa_type_argb, 0, 5, 5, 5),
+xa_format_a4r4g4b4 = xa_format(16, xa_type_argb, 4, 4, 4, 4),
+xa_format_a2b10g10r10 = xa_format(32, xa_type_abgr, 2, 10, 10, 10),
+xa_format_x2b10g10r10 = xa_format(32, xa_type_abgr, 0, 10, 10, 10),
+xa_format_b8g8r8a8 = xa_format(32, xa_type_bgra, 8, 8, 8, 8),
+xa_format_b8g8r8x8 = xa_format(32, xa_type_bgra, 0, 8, 8, 8),
 
 xa_format_z16 = xa_format_c(16, xa_type_z, 16, 0),
 xa_format_z32 = xa_format_c(32, xa_type_z, 32, 0),
-- 
2.19.0.rc1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 4/4] st/xa: Bump minor

2018-11-12 Thread Thomas Hellstrom
Bump minor to signal support for new formats and higher precision
solid pictures.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 configure.ac  | 2 +-
 src/gallium/state_trackers/xa/meson.build | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index d782f56205d..2573e0da57e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3053,7 +3053,7 @@ AC_SUBST([XVMC_MAJOR], 1)
 AC_SUBST([XVMC_MINOR], 0)
 
 AC_SUBST([XA_MAJOR], 2)
-AC_SUBST([XA_MINOR], 4)
+AC_SUBST([XA_MINOR], 5)
 AC_SUBST([XA_PATCH], 0)
 AC_SUBST([XA_VERSION], "$XA_MAJOR.$XA_MINOR.$XA_PATCH")
 
diff --git a/src/gallium/state_trackers/xa/meson.build 
b/src/gallium/state_trackers/xa/meson.build
index aff39634b3c..44d97586240 100644
--- a/src/gallium/state_trackers/xa/meson.build
+++ b/src/gallium/state_trackers/xa/meson.build
@@ -18,7 +18,7 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
-xa_version = ['2', '4', '0']
+xa_version = ['2', '5', '0']
 
 xa_conf = configuration_data()
 xa_conf.set('XA_MAJOR', xa_version[0])
-- 
2.19.0.rc1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 1/2] loader/dri3: Only wait for back buffer fences in dri3_get_buffer

2018-09-11 Thread Thomas Hellstrom


On 09/11/2018 02:41 PM, Michel Dänzer wrote:

Any feedback on this patch? Without negative feedback, I'll push it
later this week.

Hi, Michel,

This looks ok to me.

Reviewed-by: Thomas Hellstrom 

/Thomas




On 2018-09-04 6:22 p.m., Michel Dänzer wrote:

From: Michel Dänzer 

We don't need to wait before drawing to the fake front buffer, as front
buffer rendering by definition is allowed to produce artifacts.

Fixes hangs in some cases when re-using the fake front buffer, due to it
still being busy (i.e. in use for presentation).

Cc: mesa-sta...@lists.freedesktop.org
Bugzilla: 
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.freedesktop.org%2F106404data=02%7C01%7Cthellstrom%40vmware.com%7C758cf6c04efd4541578a08d617e3e821%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636722664962505455sdata=RvqyEylP%2B96KAl6k9H5j7cyx1PW%2B3FFMmtpD0PwiQwU%3Dreserved=0
Bugzilla: 
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.freedesktop.org%2F107757data=02%7C01%7Cthellstrom%40vmware.com%7C758cf6c04efd4541578a08d617e3e821%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636722664962505455sdata=PC8P3cOYWvFLWmb8uorlEHbf8PgdSnznaRprhrCm1BU%3Dreserved=0
Signed-off-by: Michel Dänzer 
---
  src/loader/loader_dri3_helper.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 91bad86afd8..6c162553f33 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1819,7 +1819,9 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
buffer = new_buffer;
draw->buffers[buf_id] = buffer;
 }
-   dri3_fence_await(draw->conn, draw, buffer);
+
+   if (buffer_type == loader_dri3_buffer_back)
+  dri3_fence_await(draw->conn, draw, buffer);
  
 /*

  * Do we need to preserve the content of a previous buffer?





___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 0/9] dri2: Swapbuffer update v3.

2018-09-05 Thread Thomas Hellstrom

On 09/05/2018 04:30 PM, Timothy Arceri wrote:

On 05/09/18 23:36, Thomas Hellstrom wrote:

On 09/05/2018 02:36 PM, Timothy Arceri wrote:

On 05/09/18 22:09, Thomas Hellstrom wrote:

On 09/05/2018 01:45 PM, Timothy Arceri wrote:



On 16/08/17 04:31, Thomas Hellstrom wrote:

Implement back-to-fake-front flips,
Fix EGL_BUFFER_PRESERVED path.
Implement dri3 support for GLX_SWAP_EXCHANGE_OML and 
GLX_SWAP_COPY_OML.


The back-to-fake-front flips will save a full buffer copy in the 
case of a

fake front being enabled and GLX_SWAP_UNDEFINED_OML.

Support for EGL_BUFFER_PRESERVED and GLX_SWAP_X_OML are mostly 
useful for
things like glretrace if traces are capured with applications 
relying on a

specific swapbuffer behavior.

The EGL_BUFFER_PRESERVED path previously made sure the present 
was done as

a copy, but there was nothing making sure that after the present,
the same back buffer was chosen.
This has now been changed so that if the previous back buffer is
idle, we reuse it. Otherwise we grab a new and copy the contents and
buffer age from the previous back buffer. Server side flips are 
allowed.


GLX_SWAP_COPY_OML will behave like EGL_BUFFER_PRESERVED.

GLX_SWAP_EXCHANGE_OML will behave similarly, except that we try 
to reuse the
previous fake front as the new back buffer if it's idle. If not, 
we grab
a new back buffer and copy the contents and buffer age from the 
old fake front.


v2:
- Split the original patch,
- Make sure we have a context for blitImage even if we don't have a
current context.
- Make sure the delayed backbuffer allocation is performed before
glXSwapBuffers, glXCopyBuffers and querying buffer age.
v3:
- squash three patches related to the same change.
- Address review comments by Michel Dänzer.

Testing done:
piglit tests/quick without regressions on svga.
A modified piglit glx-swap-exchange posted for review on the 
piglit list.
That test required modifying the dri2 state tracke to advertise 
unconditional

support for GLX_SWAP_EXCHANGE_OML


What exactly do I need to do to force this to be advertised? A 
bigger question is what more is required to expose 
GLX_SWAP_EXCHANGE_OML more generally?


It seems this is required for a few games running on wine [1].

[1] 
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.freedesktop.org%2Fshow_bug.cgi%3Fid%3D97516data=02%7C01%7Cthellstrom%40vmware.com%7Cbf80baf0e82c4d4339e708d6133c25d7%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636717546404445044sdata=RhyyM9A45NftarY5SsJbUz8pMaRTnIbx%2Fp4P2ZRcS64%3Dreserved=0 






You need to get the X server AIGLX to advertize it, because the 
available features are the intersection of the X server AIGLX 
features and the dri driver features, even if this is purely 
implemented in the dri client. The reason GLX works this way is 
that after you've choosen your config you can either choose to 
select a direct or indirect context. That was a poor design.


Now the problem is that AIGLX isn't able to support it, because it 
uses the dri driver dri2 path rather than the dri3 path, and I 
never got to modifying AIGLX to use the dri3 path. Didn't think it 
was worth the extra work.


Hmm ... thanks for the info. I should at least add some of this to 
the bug report.




In any case, you can hack-enable GLX_SWAP_EXCHANGE_OML if the 
client is using dri3 by adding __DRI_ATTRIB_SWAP_EXCHANGE to 
back_buffer_modes[] in src/gallium/state_trackers/dri/dri_screen.c, 
recompile and make sure the X server also picks up the recompiled 
driver. That is if you have a gallium driver. This worked fine with 
vmwgfx at the time I pushed the patch as tested by the 
corresponding piglit test.


I did try this already with radeonsi but it didn't seem to work. I 
even restarted my PC to make sure the correct driver was selected.


How did you test? I'll give it a test on vmwgfx + piglit.
/Thomas


I just tried running the glx-swap-exchange piglit test. I was still 
getting:


Couldn't get a GLX_SWAP_EXCHANGE_OML, RGBA, double-buffered fbconfig
PIGLIT: {"result": "skip" }


It works fine here, piglit test is passing. Didn't work at first, but I 
got the dri driver installation directory wrong, once that was resolved 
and the X server really picked up the correct driver it worked fine. 
What distro are you on?


/Thomas

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 0/9] dri2: Swapbuffer update v3.

2018-09-05 Thread Thomas Hellstrom

On 09/05/2018 02:36 PM, Timothy Arceri wrote:

On 05/09/18 22:09, Thomas Hellstrom wrote:

On 09/05/2018 01:45 PM, Timothy Arceri wrote:



On 16/08/17 04:31, Thomas Hellstrom wrote:

Implement back-to-fake-front flips,
Fix EGL_BUFFER_PRESERVED path.
Implement dri3 support for GLX_SWAP_EXCHANGE_OML and 
GLX_SWAP_COPY_OML.


The back-to-fake-front flips will save a full buffer copy in the 
case of a

fake front being enabled and GLX_SWAP_UNDEFINED_OML.

Support for EGL_BUFFER_PRESERVED and GLX_SWAP_X_OML are mostly 
useful for
things like glretrace if traces are capured with applications 
relying on a

specific swapbuffer behavior.

The EGL_BUFFER_PRESERVED path previously made sure the present was 
done as

a copy, but there was nothing making sure that after the present,
the same back buffer was chosen.
This has now been changed so that if the previous back buffer is
idle, we reuse it. Otherwise we grab a new and copy the contents and
buffer age from the previous back buffer. Server side flips are 
allowed.


GLX_SWAP_COPY_OML will behave like EGL_BUFFER_PRESERVED.

GLX_SWAP_EXCHANGE_OML will behave similarly, except that we try to 
reuse the
previous fake front as the new back buffer if it's idle. If not, we 
grab
a new back buffer and copy the contents and buffer age from the old 
fake front.


v2:
- Split the original patch,
- Make sure we have a context for blitImage even if we don't have a
current context.
- Make sure the delayed backbuffer allocation is performed before
glXSwapBuffers, glXCopyBuffers and querying buffer age.
v3:
- squash three patches related to the same change.
- Address review comments by Michel Dänzer.

Testing done:
piglit tests/quick without regressions on svga.
A modified piglit glx-swap-exchange posted for review on the piglit 
list.
That test required modifying the dri2 state tracke to advertise 
unconditional

support for GLX_SWAP_EXCHANGE_OML


What exactly do I need to do to force this to be advertised? A 
bigger question is what more is required to expose 
GLX_SWAP_EXCHANGE_OML more generally?


It seems this is required for a few games running on wine [1].

[1] 
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.freedesktop.org%2Fshow_bug.cgi%3Fid%3D97516data=02%7C01%7Cthellstrom%40vmware.com%7Cc71a9d949e56467614c108d6132c3212%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636717488813233512sdata=%2FmIsVYyD7Uvg2DwynXKJS3Am%2FEKiyBVz1d%2BSwjIq2Jw%3Dreserved=0 






You need to get the X server AIGLX to advertize it, because the 
available features are the intersection of the X server AIGLX 
features and the dri driver features, even if this is purely 
implemented in the dri client. The reason GLX works this way is that 
after you've choosen your config you can either choose to select a 
direct or indirect context. That was a poor design.


Now the problem is that AIGLX isn't able to support it, because it 
uses the dri driver dri2 path rather than the dri3 path, and I never 
got to modifying AIGLX to use the dri3 path. Didn't think it was 
worth the extra work.


Hmm ... thanks for the info. I should at least add some of this to the 
bug report.




In any case, you can hack-enable GLX_SWAP_EXCHANGE_OML if the client 
is using dri3 by adding __DRI_ATTRIB_SWAP_EXCHANGE to 
back_buffer_modes[] in src/gallium/state_trackers/dri/dri_screen.c, 
recompile and make sure the X server also picks up the recompiled 
driver. That is if you have a gallium driver. This worked fine with 
vmwgfx at the time I pushed the patch as tested by the corresponding 
piglit test.


I did try this already with radeonsi but it didn't seem to work. I 
even restarted my PC to make sure the correct driver was selected.


How did you test? I'll give it a test on vmwgfx + piglit.
/Thomas






For the other dri drivers there should be a similar way to set the 
back_buffer_modes[].


Thanks,
Thomas


A piglit glx-swap-copy test derived from the glx-swap-exchange test.
Not posted yet.


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Fmesa-devdata=02%7C01%7Cthellstrom%40vmware.com%7Cc71a9d949e56467614c108d6132c3212%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636717488813243551sdata=iG47YiO49K4vh1C0aV5SiSX%2BlthujiFPXro5DiDNInY%3Dreserved=0 







___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 0/9] dri2: Swapbuffer update v3.

2018-09-05 Thread Thomas Hellstrom

On 09/05/2018 01:45 PM, Timothy Arceri wrote:



On 16/08/17 04:31, Thomas Hellstrom wrote:

Implement back-to-fake-front flips,
Fix EGL_BUFFER_PRESERVED path.
Implement dri3 support for GLX_SWAP_EXCHANGE_OML and GLX_SWAP_COPY_OML.

The back-to-fake-front flips will save a full buffer copy in the case 
of a

fake front being enabled and GLX_SWAP_UNDEFINED_OML.

Support for EGL_BUFFER_PRESERVED and GLX_SWAP_X_OML are mostly useful 
for
things like glretrace if traces are capured with applications relying 
on a

specific swapbuffer behavior.

The EGL_BUFFER_PRESERVED path previously made sure the present was 
done as

a copy, but there was nothing making sure that after the present,
the same back buffer was chosen.
This has now been changed so that if the previous back buffer is
idle, we reuse it. Otherwise we grab a new and copy the contents and
buffer age from the previous back buffer. Server side flips are allowed.

GLX_SWAP_COPY_OML will behave like EGL_BUFFER_PRESERVED.

GLX_SWAP_EXCHANGE_OML will behave similarly, except that we try to 
reuse the

previous fake front as the new back buffer if it's idle. If not, we grab
a new back buffer and copy the contents and buffer age from the old 
fake front.


v2:
- Split the original patch,
- Make sure we have a context for blitImage even if we don't have a
current context.
- Make sure the delayed backbuffer allocation is performed before
glXSwapBuffers, glXCopyBuffers and querying buffer age.
v3:
- squash three patches related to the same change.
- Address review comments by Michel Dänzer.

Testing done:
piglit tests/quick without regressions on svga.
A modified piglit glx-swap-exchange posted for review on the piglit 
list.
That test required modifying the dri2 state tracke to advertise 
unconditional

support for GLX_SWAP_EXCHANGE_OML


What exactly do I need to do to force this to be advertised? A bigger 
question is what more is required to expose GLX_SWAP_EXCHANGE_OML more 
generally?


It seems this is required for a few games running on wine [1].

[1] 
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.freedesktop.org%2Fshow_bug.cgi%3Fid%3D97516data=02%7C01%7Cthellstrom%40vmware.com%7Ce4a72f032d3f4912556608d6132507df%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636717447117422764sdata=wFjbtCf59vWLBdSziwUfqVFVYAHEoDcorDx%2FcZxJBr0%3Dreserved=0





You need to get the X server AIGLX to advertize it, because the 
available features are the intersection of the X server AIGLX features 
and the dri driver features, even if this is purely implemented in the 
dri client. The reason GLX works this way is that after you've choosen 
your config you can either choose to select a direct or indirect 
context. That was a poor design.


Now the problem is that AIGLX isn't able to support it, because it uses 
the dri driver dri2 path rather than the dri3 path, and I never got to 
modifying AIGLX to use the dri3 path. Didn't think it was worth the 
extra work.


In any case, you can hack-enable GLX_SWAP_EXCHANGE_OML if the client is 
using dri3 by adding __DRI_ATTRIB_SWAP_EXCHANGE to back_buffer_modes[] 
in src/gallium/state_trackers/dri/dri_screen.c, recompile and make sure 
the X server also picks up the recompiled driver. That is if you have a 
gallium driver. This worked fine with vmwgfx at the time I pushed the 
patch as tested by the corresponding piglit test.


For the other dri drivers there should be a similar way to set the 
back_buffer_modes[].


Thanks,
Thomas


A piglit glx-swap-copy test derived from the glx-swap-exchange test.
Not posted yet.


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Fmesa-devdata=02%7C01%7Cthellstrom%40vmware.com%7Ce4a72f032d3f4912556608d6132507df%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C636717447117422764sdata=Y4n8dYa33hRjHN2KJlw9gZEQbuWGGz0oWR5FRj0ygd8%3Dreserved=0 





___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] pipe-loader: move dup(fd) within pipe_loader_drm_probe_fd

2018-08-29 Thread Thomas Hellstrom

Hi, Emil,

On 08/29/2018 07:13 PM, Emil Velikov wrote:

From: Emil Velikov 

Currently pipe_loader_drm_probe_fd takes ownership of the fd given.
To match that, pipe_loader_release closes it.

Yet we have many instances which do not want the change of ownership,
and thus duplicate the fd before passing it to the pipe-loader.

Move the dup() within pipe-loader, explicitly document that and document
all the cases through the codebase.

A trivial git grep -2 pipe_loader_release makes things as obvious as it
gets ;-)

Cc: Leo Liu 
Cc: Thomas Hellstrom 
Cc: Axel Davy 
Cc: Patrick Rudolph 
Signed-off-by: Emil Velikov 
---
I'm 99% sure that the VAAPI/XA notes are correct, but I left it as CHECK
since it's been a while since I useed those ;-)

Leo, Thomas, can you please confirm the respective CHECK notes?



Yes, The user of the xa API maintains ownership of the drm fd passed to XA.

For the xa part:
Reviewed-by: Thomas Hellstrom 


Thanks,
Thomas

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH rfc 0/3] Be able to disable EGL/GLX_EXT_buffer_age

2018-07-05 Thread Thomas Hellstrom

On 07/05/2018 03:54 PM, Emil Velikov wrote:

On 5 July 2018 at 14:31, Emil Velikov  wrote:

Hi Qiang Yu

On 5 July 2018 at 03:31, Qiang Yu  wrote:

For GPU like ARM mali Utgard EGL/GLX_EXT_buffer_age will make
performace worse. But mesa has no way to disable it.

This patch series make driver be able to disable it and add a
gallium pipe cap for gallium driver usage. Due to currently
only out of tree lima driver need it, and not sure if this is
the right way to disable it, so I send this RFC before lima be
able to upstream.


Pretty sure we already have a way to handle that. Look for
glx_disable_ext_buffer_age - it was introduced for the VMWare driver.
Although we should:
a) tweak the name - kind of split if we need to
b) add glx/dri2 and egl support


Looking at the implementation - it uses a driver query, meaning that
one could enable it at a later stage.
No need to worry if the user has old drirc/etc as with current solution.

Having two ways of doing the same thing is a bad idea.
Perhaps we can remove the drirc implementation and use this instead?

Thomas, what do you think?


The thing is that we only notice a performance regression with GL 
compositors like gnome-shell and compiz, and that's typically because of 
side effects of these compositors. They're using full buffer swaps when 
the extension is enabled rather than damage regions. For other 
applications we want it enabled.


So we need a way to turn it off for certain apps.

/Thomas


Thanks
Emil



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] st/xa: Bump minor

2018-05-14 Thread Thomas Hellstrom
Bump xa minor to signal that the underlying mesa version is suitable for dri3.

This is a bit ugly since it doesn't relate to a specific xa interface change.
Recently there has been a number of fixes in mesa that helps enabling dri3
without any significant regressions in automated testing and common desktop
usage latency. However, the xf86-video-vmware driver has no other way to tell
but inspecting the xa version.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Brian Paul <bri...@vmware.com>
---
 configure.ac  | 2 +-
 src/gallium/state_trackers/xa/meson.build | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 35ade98..a9babec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2969,7 +2969,7 @@ AC_SUBST([XVMC_MAJOR], 1)
 AC_SUBST([XVMC_MINOR], 0)
 
 AC_SUBST([XA_MAJOR], 2)
-AC_SUBST([XA_MINOR], 3)
+AC_SUBST([XA_MINOR], 4)
 AC_SUBST([XA_PATCH], 0)
 AC_SUBST([XA_VERSION], "$XA_MAJOR.$XA_MINOR.$XA_PATCH")
 
diff --git a/src/gallium/state_trackers/xa/meson.build 
b/src/gallium/state_trackers/xa/meson.build
index 109abc1..aff3963 100644
--- a/src/gallium/state_trackers/xa/meson.build
+++ b/src/gallium/state_trackers/xa/meson.build
@@ -18,7 +18,7 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
-xa_version = ['2', '3', '0']
+xa_version = ['2', '4', '0']
 
 xa_conf = configuration_data()
 xa_conf.set('XA_MAJOR', xa_version[0])
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] egl/x11: Send invalidate to the driver on dri2_copy_region

2018-04-26 Thread Thomas Hellstrom

On 04/26/2018 11:56 AM, Michel Dänzer wrote:

On 2018-04-26 11:33 AM, Thomas Hellstrom wrote:

On 04/26/2018 10:30 AM, Michel Dänzer wrote:

On 2018-04-25 07:49 PM, Deepak Rawat wrote:

Similar to what is done in dri2_x11_swap_buffers_msc send invalidate
to the driver because egl/X11 is not watching for for server's
invalidate events. The dri2_copy_region path is trigerred when
server supports DRI2 version minor 1.

Tested with piglit egl tests for regression.

Cc: <mesa-sta...@lists.freedesktop.org>
Signed-off-by: Deepak Rawat <dra...@vmware.com>
Reviewed-by: Thomas Hellstrom <thellst...@vmware.com>
---
   src/egl/drivers/dri2/platform_x11.c | 7 +++
   1 file changed, 7 insertions(+)

diff --git a/src/egl/drivers/dri2/platform_x11.c
b/src/egl/drivers/dri2/platform_x11.c
index 6c287b4d06..e99434ea3a 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -841,6 +841,13 @@ dri2_copy_region(_EGLDriver *drv, _EGLDisplay
*disp,
  render_attachment);
  free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
   +   /*
+    * Just like as done in dri2_x11_swap_buffers_msc we aren't
watching for
+    * server's invalidate events, so just send invalidate to driver.
+    */
+   if (dri2_dpy->flush->base.version >= 3 &&
dri2_dpy->flush->invalidate)
+  dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
+
  return EGL_TRUE;
   }

Why is invalidate needed after copy_region? That's surprising, I suspect
it just papers over the real problem.



I had a quick look into the platform_x11 code. dri2_copy_region is
called only from the various swap_buffers() paths,
dri2_x11_swap_buffers() and dri2_x11_swap_buffers_region(). Explicit
invalidation is, before this patch, done only if the server supports
dri2 swaps. Probably because most drivers do, vmware does not, so we can
hit swapbuffers without doing explicit invalidation.

In comparison, GLX does explicit invalidation on swapbuffers,
bind_context and bind_texture for the same protocol version, so this
patch should only bring the EGL swapbuffer paths closer to what GLX is
doing, while still not addressing bind_context and bind_texture.

FWIW, EGL platform_x11 (dri2) seems to not parse server invalidate
events for the higher protocol versions, relying solely on explicit
invalidation.

The purpose of the invalidate callback is to trigger updating the DRI2
buffers before drawing the next frame. This isn't necessary after a
copy_region operation, so you seem to be relying on some kind of side
effect of the invalidate callback. Which may be okay, but I think it
would be clearer not to put this code in dri2_copy_region itself.


The purpose in this case is to update the dri2 buffers after a 
swapbuffer operation, which *is* needed, but I agree that there might be 
cases where the dri2_copy_region could theoretically be used without 
requiring an invalidation.


So we could of course move out the invalidation to the swapbuffer functions.

/Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] egl/x11: Send invalidate to the driver on dri2_copy_region

2018-04-26 Thread Thomas Hellstrom

On 04/26/2018 10:30 AM, Michel Dänzer wrote:

On 2018-04-25 07:49 PM, Deepak Rawat wrote:

Similar to what is done in dri2_x11_swap_buffers_msc send invalidate
to the driver because egl/X11 is not watching for for server's
invalidate events. The dri2_copy_region path is trigerred when
server supports DRI2 version minor 1.

Tested with piglit egl tests for regression.

Cc: <mesa-sta...@lists.freedesktop.org>
Signed-off-by: Deepak Rawat <dra...@vmware.com>
Reviewed-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/egl/drivers/dri2/platform_x11.c | 7 +++
  1 file changed, 7 insertions(+)

diff --git a/src/egl/drivers/dri2/platform_x11.c 
b/src/egl/drivers/dri2/platform_x11.c
index 6c287b4d06..e99434ea3a 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -841,6 +841,13 @@ dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
   render_attachment);
 free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
  
+   /*

+* Just like as done in dri2_x11_swap_buffers_msc we aren't watching for
+* server's invalidate events, so just send invalidate to driver.
+*/
+   if (dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate)
+  dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
+
 return EGL_TRUE;
  }

Why is invalidate needed after copy_region? That's surprising, I suspect
it just papers over the real problem.


I had a quick look into the platform_x11 code. dri2_copy_region is 
called only from the various swap_buffers() paths, 
dri2_x11_swap_buffers() and dri2_x11_swap_buffers_region(). Explicit 
invalidation is, before this patch, done only if the server supports 
dri2 swaps. Probably because most drivers do, vmware does not, so we can 
hit swapbuffers without doing explicit invalidation.


In comparison, GLX does explicit invalidation on swapbuffers, 
bind_context and bind_texture for the same protocol version, so this 
patch should only bring the EGL swapbuffer paths closer to what GLX is 
doing, while still not addressing bind_context and bind_texture.


FWIW, EGL platform_x11 (dri2) seems to not parse server invalidate 
events for the higher protocol versions, relying solely on explicit 
invalidation.


/Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] svga: Fix incorrect advertizing of EGL_KHR_gl_colorspace

2018-04-19 Thread Thomas Hellstrom
When advertizing this extension, egl_dri2 uses the DRI2_RENDERER_QUERY
extension to query whether an sRGB format is supported. That extension will
query our driver with the BIND flag PIPE_BIND_RENDER_TARGET rather than
PIPE_BIND_DISPLAY_TARGET which is used when building the configs.
We only return the correct value for PIPE_BIND_DISPLAY_TARGET.

The inconsistency causes EGL to crash at surface initialization if sRGB is
not supported. Fix this by supporting both bind flags.

Testing done:
piglit egl_gl_colorspace srgb

Cc: <mesa-sta...@lists.freedesktop.org>
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Brian Paul <bri...@vmware.com>
Reviewed-by: Charmaine Lee <charmai...@vmware.com>
---
 src/gallium/drivers/svga/svga_format.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gallium/drivers/svga/svga_format.c 
b/src/gallium/drivers/svga/svga_format.c
index 20a6e6b159f..c9adee11afb 100644
--- a/src/gallium/drivers/svga/svga_format.c
+++ b/src/gallium/drivers/svga/svga_format.c
@@ -2107,7 +2107,7 @@ svga_is_format_supported(struct pipe_screen *screen,
 
if (!ss->sws->have_vgpu10 &&
util_format_is_srgb(format) &&
-   (bindings & PIPE_BIND_DISPLAY_TARGET)) {
+   (bindings & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET))) {
/* We only support sRGB rendering with vgpu10 */
   return FALSE;
}
-- 
2.14.3

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] dri3: Prevent multiple freeing of buffers.

2018-04-06 Thread Thomas Hellstrom

Hi,

On 04/06/2018 04:51 PM, Daniel Stone wrote:

Hi Sergii,

On 6 April 2018 at 09:12, Sergii Romantsov  wrote:

Commit 3160cb86aa92 adds optimization with flag 'reallocate'.
Processing of flag causes buffers freeing while pointer
is still hold in caller stack and than again used to be freed.

Thanks a lot for writing this. I take it the core of the problem is
that dri3_handle_present_event() can be called whilst we're inside
dri3_get_buffer(), which wasn't the case before.

This was only introduced as of a727c804a2c1, and I'm not sure I fully
follow the rationale for that commit. Thomas, why do we need to
process the events? I guess we could also fake it by turning 'busy'
into a refcount, which would be incremented/decremented as it is today
when posting buffers and getting Idle events, but also when we're
holding a local pointer which we can't have stolen from under us.

Cheers,
Daniel


The motivation for this commit IIRC was that with internal glretrace 
automated tests, we typically would end up with corrupt rendering due to 
invalid viewports after window resizes. The resize events were typically 
not picked up as fast with dri3 as with dri2, so due to the lack of 
documented strategy how to handle window- and viewport resizes with dri3 
clients, I tried to make it mimic dri2 where we had no such issues. The 
reason for the slow pick up was that dri3 was waiting for fences rather 
than on X replies...


/Thomas

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 1/3] glx/dri: Add a driconf option to disable GLX_SGI_video_sync

2018-03-05 Thread Thomas Hellstrom
Drivers on virtual hardware don't want to expose this extension to
GLX compositors, similarly to GLX_OML_sync_control, since that significantly
increases latency.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Brian Paul <bri...@vmware.com>
Reviewed-by: Sinclair Yeh <s...@vmware.com>
Reviewed-by: Deepak Rawat <dra...@vmware.com>
---
 src/glx/dri2_glx.c   | 9 ++---
 src/glx/dri3_glx.c   | 6 +-
 src/util/xmlpool/t_options.h | 5 +
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 0f44635725..91afc33750 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -1102,7 +1102,6 @@ dri2BindExtensions(struct dri2_screen *psc, struct 
glx_display * priv,
 
extensions = psc->core->getExtensions(psc->driScreen);
 
-   __glXEnableDirectExtension(>base, "GLX_SGI_video_sync");
__glXEnableDirectExtension(>base, "GLX_SGI_swap_control");
__glXEnableDirectExtension(>base, "GLX_MESA_swap_control");
__glXEnableDirectExtension(>base, "GLX_SGI_make_current_read");
@@ -1207,6 +1206,7 @@ dri2CreateScreen(int screen, struct glx_display * priv)
char *driverName = NULL, *loader_driverName, *deviceName, *tmp;
drm_magic_t magic;
int i;
+   unsigned char disable;
 
psc = calloc(1, sizeof *psc);
if (psc == NULL)
@@ -1325,8 +1325,6 @@ dri2CreateScreen(int screen, struct glx_display * priv)
psp->getBufferAge = NULL;
 
if (pdp->driMinor >= 2) {
-  unsigned char disable;
-
   psp->getDrawableMSC = dri2DrawableGetMSC;
   psp->waitForMSC = dri2WaitForMSC;
   psp->waitForSBC = dri2WaitForSBC;
@@ -1338,6 +1336,11 @@ dri2CreateScreen(int screen, struct glx_display * priv)
  __glXEnableDirectExtension(>base, "GLX_OML_sync_control");
}
 
+   if (psc->config->configQueryb(psc->driScreen,
+ "glx_disable_sgi_video_sync",
+ ) || !disable)
+  __glXEnableDirectExtension(>base, "GLX_SGI_video_sync");
+
/* DRI2 supports SubBuffer through DRI2CopyRegion, so it's always
 * available.*/
psp->copySubBuffer = dri2CopySubBuffer;
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 016f91b196..adfc349968 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -721,7 +721,6 @@ dri3_bind_extensions(struct dri3_screen *psc, struct 
glx_display * priv,
 
extensions = psc->core->getExtensions(psc->driScreen);
 
-   __glXEnableDirectExtension(>base, "GLX_SGI_video_sync");
__glXEnableDirectExtension(>base, "GLX_SGI_swap_control");
__glXEnableDirectExtension(>base, "GLX_MESA_swap_control");
__glXEnableDirectExtension(>base, "GLX_SGI_make_current_read");
@@ -956,6 +955,11 @@ dri3_create_screen(int screen, struct glx_display * priv)
  ) || !disable)
   __glXEnableDirectExtension(>base, "GLX_OML_sync_control");
 
+   if (psc->config->configQueryb(psc->driScreen,
+ "glx_disable_sgi_video_sync",
+ ) || !disable)
+  __glXEnableDirectExtension(>base, "GLX_SGI_video_sync");
+
psp->copySubBuffer = dri3_copy_sub_buffer;
__glXEnableDirectExtension(>base, "GLX_MESA_copy_sub_buffer");
 
diff --git a/src/util/xmlpool/t_options.h b/src/util/xmlpool/t_options.h
index 5f377c9dcd..3ada813d63 100644
--- a/src/util/xmlpool/t_options.h
+++ b/src/util/xmlpool/t_options.h
@@ -346,6 +346,11 @@ DRI_CONF_OPT_BEGIN_B(glx_disable_oml_sync_control, def) \
DRI_CONF_DESC(en, gettext("Disable the GLX_OML_sync_control extension")) \
 DRI_CONF_OPT_END
 
+#define DRI_CONF_DISABLE_SGI_VIDEO_SYNC(def) \
+DRI_CONF_OPT_BEGIN_B(glx_disable_sgi_video_sync, def) \
+   DRI_CONF_DESC(en, gettext("Disable the GLX_SGI_video_sync extension")) \
+DRI_CONF_OPT_END
+
 
 /**
  * \brief Software-fallback options.  To allow using features (like
-- 
2.14.3

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 3/3] drirc: Disable the GLX_SGI_video_sync extension for gnome-shell on vmware

2018-03-05 Thread Thomas Hellstrom
With this extension enabled and a server GLX implementation that actually
honors it, Window movement lags considerably on gnome-shell/vmware, so
disable it by default.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Brian Paul <bri...@vmware.com>
Reviewed-by: Sinclair Yeh <s...@vmware.com>
Reviewed-by: Deepak Rawat <dra...@vmware.com>
---
 src/util/drirc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/util/drirc b/src/util/drirc
index bdc90227c6..c964588e72 100644
--- a/src/util/drirc
+++ b/src/util/drirc
@@ -275,6 +275,7 @@ TODO: document the other workarounds.
 
 
 
+
 

 
-- 
2.14.3

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 0/3] Fix vmware dri3 latency on gnome-shell

2018-03-05 Thread Thomas Hellstrom
Similarly to what we previously did for GLX_OML_sync_control, we want to
disable the GLX_SGI_video_sync extension for gnome-shell on vmware. With
either of these extensions enabled, window movement lag increases
significantly.

The reason this hits with dri3 and not with dri2 is that with dri2 on
xf86-video-vmware, this extension is enabled, although not fully implemented.
With dri3 we actually sync to the X server's built in fake 60Hz vblank
interval.


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/3] gallium/st_dri: Honor the glx_disable_sgi_video_sync config option

2018-03-05 Thread Thomas Hellstrom
This option is disabled by default. Primarily intended for drivers on
virtual hardware.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Brian Paul <bri...@vmware.com>
Reviewed-by: Sinclair Yeh <s...@vmware.com>
Reviewed-by: Deepak Rawat <dra...@vmware.com>
---
 src/gallium/auxiliary/pipe-loader/driinfo_gallium.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h 
b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
index 505aae402e..21dc599dc2 100644
--- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
+++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
@@ -4,6 +4,7 @@ DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_MESA_NO_ERROR("false")
DRI_CONF_DISABLE_EXT_BUFFER_AGE("false")
DRI_CONF_DISABLE_OML_SYNC_CONTROL("false")
+   DRI_CONF_DISABLE_SGI_VIDEO_SYNC("false")
 DRI_CONF_SECTION_END
 
 DRI_CONF_SECTION_QUALITY
-- 
2.14.3

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] loader_dri3/glx/egl: Reinstate the loader_dri3_vtable get_dri_screen callback

2018-02-12 Thread Thomas Hellstrom

Hi!

It would be good if somebody could review this so we can get the fix in.

Thanks,
Thomas


On 02/09/2018 09:37 AM, Thomas Hellstrom wrote:

Removing this callback caused rendering corruption in some multi-screen cases,
so it is reinstated but without the drawable argument which was never used
by implementations and was confusing since the drawable could have been
created with another screen.

Cc: "17.3" mesa-sta...@lists.freedesktop.org
Fixes: 5198e48a0d (loader_dri3/glx/egl: Remove the loader_dri3_vtable 
get_dri_screen callback)
Bugzilla: 
https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.freedesktop.org_show-5Fbug.cgi-3Fid-3D105013=DwIGaQ=uilaK90D4TOVoH58JNXRgQ=wnSlgOCqfpNS4d02vP68_E9q2BNMCwfD2OZ_6dCFVQQ=XWphEAw-49womV9tmv90qPaEgOeyVd98mULQPxCMsy0=EC7q92tLLJ_BOkb9bWoQEHpl07D4zKI-gaOq3y87TcE=
Reported-by: Daniel van Vugt <daniel.van.v...@canonical.com>
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/egl/drivers/dri2/platform_x11_dri3.c | 12 
  src/glx/dri3_glx.c   | 11 +++
  src/loader/loader_dri3_helper.c  | 12 +++-
  src/loader/loader_dri3_helper.h  |  1 +
  4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c 
b/src/egl/drivers/dri2/platform_x11_dri3.c
index 6e40eaa596..060b5f83a3 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -75,6 +75,17 @@ egl_dri3_get_dri_context(struct loader_dri3_drawable *draw)
 return dri2_ctx->dri_context;
  }
  
+static __DRIscreen *

+egl_dri3_get_dri_screen(void)
+{
+   _EGLContext *ctx = _eglGetCurrentContext();
+   struct dri2_egl_context *dri2_ctx;
+   if (!ctx)
+  return NULL;
+   dri2_ctx = dri2_egl_context(ctx);
+   return dri2_egl_display(dri2_ctx->base.Resource.Display)->dri_screen;
+}
+
  static void
  egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
  {
@@ -88,6 +99,7 @@ static const struct loader_dri3_vtable egl_dri3_vtable = {
 .set_drawable_size = egl_dri3_set_drawable_size,
 .in_current_context = egl_dri3_in_current_context,
 .get_dri_context = egl_dri3_get_dri_context,
+   .get_dri_screen = egl_dri3_get_dri_screen,
 .flush_drawable = egl_dri3_flush_drawable,
 .show_fps = NULL,
  };
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index f280a8cef7..016f91b196 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -116,6 +116,16 @@ glx_dri3_get_dri_context(struct loader_dri3_drawable *draw)
 return (gc != ) ? dri3Ctx->driContext : NULL;
  }
  
+static __DRIscreen *

+glx_dri3_get_dri_screen(void)
+{
+   struct glx_context *gc = __glXGetCurrentContext();
+   struct dri3_context *pcp = (struct dri3_context *) gc;
+   struct dri3_screen *psc = (struct dri3_screen *) pcp->base.psc;
+
+   return (gc !=  && psc) ? psc->driScreen : NULL;
+}
+
  static void
  glx_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
  {
@@ -150,6 +160,7 @@ static const struct loader_dri3_vtable glx_dri3_vtable = {
 .set_drawable_size = glx_dri3_set_drawable_size,
 .in_current_context = glx_dri3_in_current_context,
 .get_dri_context = glx_dri3_get_dri_context,
+   .get_dri_screen = glx_dri3_get_dri_screen,
 .flush_drawable = glx_dri3_flush_drawable,
 .show_fps = glx_dri3_show_fps,
  };
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index fbda3d635c..2e3b6c619e 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1311,6 +1311,7 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, 
unsigned int format,
 xcb_sync_fence_t sync_fence;
 struct xshmfence *shm_fence;
 int  fence_fd;
+   __DRIscreen  *cur_screen;
  
 if (buffer)

return buffer;
@@ -1341,8 +1342,17 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, 
unsigned int format,
 if (!bp_reply)
goto no_image;
  
+   /* Get the currently-bound screen or revert to using the drawable's screen if

+* no contexts are currently bound. The latter case is at least necessary 
for
+* obs-studio, when using Window Capture (Xcomposite) as a Source.
+*/
+   cur_screen = draw->vtable->get_dri_screen();
+   if (!cur_screen) {
+   cur_screen = draw->dri_screen;
+   }
+
 buffer->image = loader_dri3_create_image(draw->conn, bp_reply, format,
-draw->dri_screen, draw->ext->image,
+cur_screen, draw->ext->image,
  buffer);
 if (!buffer->image)
goto no_image;
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 4ce98b8c59..839cba30df 100644
--- a/src/loader/loader_dri3_helper.h

[Mesa-dev] [PATCH] loader_dri3/glx/egl: Reinstate the loader_dri3_vtable get_dri_screen callback

2018-02-09 Thread Thomas Hellstrom
Removing this callback caused rendering corruption in some multi-screen cases,
so it is reinstated but without the drawable argument which was never used
by implementations and was confusing since the drawable could have been
created with another screen.

Cc: "17.3" mesa-sta...@lists.freedesktop.org
Fixes: 5198e48a0d (loader_dri3/glx/egl: Remove the loader_dri3_vtable 
get_dri_screen callback)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105013
Reported-by: Daniel van Vugt <daniel.van.v...@canonical.com>
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/egl/drivers/dri2/platform_x11_dri3.c | 12 
 src/glx/dri3_glx.c   | 11 +++
 src/loader/loader_dri3_helper.c  | 12 +++-
 src/loader/loader_dri3_helper.h  |  1 +
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c 
b/src/egl/drivers/dri2/platform_x11_dri3.c
index 6e40eaa596..060b5f83a3 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -75,6 +75,17 @@ egl_dri3_get_dri_context(struct loader_dri3_drawable *draw)
return dri2_ctx->dri_context;
 }
 
+static __DRIscreen *
+egl_dri3_get_dri_screen(void)
+{
+   _EGLContext *ctx = _eglGetCurrentContext();
+   struct dri2_egl_context *dri2_ctx;
+   if (!ctx)
+  return NULL;
+   dri2_ctx = dri2_egl_context(ctx);
+   return dri2_egl_display(dri2_ctx->base.Resource.Display)->dri_screen;
+}
+
 static void
 egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
 {
@@ -88,6 +99,7 @@ static const struct loader_dri3_vtable egl_dri3_vtable = {
.set_drawable_size = egl_dri3_set_drawable_size,
.in_current_context = egl_dri3_in_current_context,
.get_dri_context = egl_dri3_get_dri_context,
+   .get_dri_screen = egl_dri3_get_dri_screen,
.flush_drawable = egl_dri3_flush_drawable,
.show_fps = NULL,
 };
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index f280a8cef7..016f91b196 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -116,6 +116,16 @@ glx_dri3_get_dri_context(struct loader_dri3_drawable *draw)
return (gc != ) ? dri3Ctx->driContext : NULL;
 }
 
+static __DRIscreen *
+glx_dri3_get_dri_screen(void)
+{
+   struct glx_context *gc = __glXGetCurrentContext();
+   struct dri3_context *pcp = (struct dri3_context *) gc;
+   struct dri3_screen *psc = (struct dri3_screen *) pcp->base.psc;
+
+   return (gc !=  && psc) ? psc->driScreen : NULL;
+}
+
 static void
 glx_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
 {
@@ -150,6 +160,7 @@ static const struct loader_dri3_vtable glx_dri3_vtable = {
.set_drawable_size = glx_dri3_set_drawable_size,
.in_current_context = glx_dri3_in_current_context,
.get_dri_context = glx_dri3_get_dri_context,
+   .get_dri_screen = glx_dri3_get_dri_screen,
.flush_drawable = glx_dri3_flush_drawable,
.show_fps = glx_dri3_show_fps,
 };
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index fbda3d635c..2e3b6c619e 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1311,6 +1311,7 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, 
unsigned int format,
xcb_sync_fence_t sync_fence;
struct xshmfence *shm_fence;
int  fence_fd;
+   __DRIscreen  *cur_screen;
 
if (buffer)
   return buffer;
@@ -1341,8 +1342,17 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, 
unsigned int format,
if (!bp_reply)
   goto no_image;
 
+   /* Get the currently-bound screen or revert to using the drawable's screen 
if
+* no contexts are currently bound. The latter case is at least necessary 
for
+* obs-studio, when using Window Capture (Xcomposite) as a Source.
+*/
+   cur_screen = draw->vtable->get_dri_screen();
+   if (!cur_screen) {
+   cur_screen = draw->dri_screen;
+   }
+
buffer->image = loader_dri3_create_image(draw->conn, bp_reply, format,
-draw->dri_screen, draw->ext->image,
+cur_screen, draw->ext->image,
 buffer);
if (!buffer->image)
   goto no_image;
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 4ce98b8c59..839cba30df 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -99,6 +99,7 @@ struct loader_dri3_vtable {
void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);
bool (*in_current_context)(struct loader_dri3_drawable *);
__DRIcontext *(*get_dri_context)(struct loader_dri3_drawable *);
+   __DRIscreen *(*get_dri_screen)(void);
void (*flush_drawable)(struct loader_dri3_drawable *, unsigne

[Mesa-dev] [PATCH v2] loader/dri3: Avoid freeing renderbuffers in use

2018-01-12 Thread Thomas Hellstrom
Upon reception of an event that lowered the number of active back buffers,
the code would immediately try to free all back buffers with an id equal to or
higher than the new number of active back buffers.

However, that could lead to an active or to-be-active back buffer being freed,
since the old number of back buffers was used when obtaining an idle back
buffer for use.

This lead to crashes when lowering the number of active back buffers by
transitioning from page-flipping to non-page-flipping presents.

Fix this by computing the number of active back buffers only when trying to
obtain a new back buffer.

Fixes: 15e208c4cc ("loader/dri3: Don't accidently free buffer holding new back 
content")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104214
Cc: "17.3" <mesa-sta...@lists.freedesktop.org>
Tested-by: Andriy.Khulap <andriy.khu...@globallogic.com>
Tested-by: Vadym Shovkoplias <vadym.shovkopl...@globallogic.com>
Reviewed-by: Michel Dänzer <michel.daen...@amd.com>
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index cc890bc..8f8efcb 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -205,7 +205,6 @@ void
 loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw, int interval)
 {
draw->swap_interval = interval;
-   dri3_update_num_back(draw);
 }
 
 /** dri3_free_render_buffer
@@ -377,7 +376,6 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
 draw->flipping = false;
 break;
  }
- dri3_update_num_back(draw);
 
  if (draw->vtable->show_fps)
 draw->vtable->show_fps(draw, ce->ust);
@@ -402,7 +400,8 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
 buf->busy = 0;
 
  if (buf && draw->num_back <= b && b < LOADER_DRI3_MAX_BACK &&
- draw->cur_blit_source != b) {
+ draw->cur_blit_source != b &&
+ !buf->busy) {
 dri3_free_render_buffer(draw, buf);
 draw->buffers[b] = NULL;
  }
@@ -537,6 +536,7 @@ dri3_find_back(struct loader_dri3_drawable *draw)
/* Check whether we need to reuse the current back buffer as new back.
 * In that case, wait until it's not busy anymore.
 */
+   dri3_update_num_back(draw);
num_to_consider = draw->num_back;
if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1) {
   num_to_consider = 1;
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] loader/dri3: Avoid freeing renderbuffers in use

2018-01-11 Thread Thomas Hellstrom

On 01/11/2018 04:32 PM, Michel Dänzer wrote:

On 2018-01-11 10:53 AM, Thomas Hellstrom wrote:

Upon reception of an event that lowered the number of active back buffers,
the code would immediately try to free all back buffers with an id equal to or
higher than the new number of active back buffers.

However, that could lead to an active or to-be-active back buffer being freed,
since the old number of back buffers was used when obtaining an idle back
buffer for use.

This lead to crashes when lowering the number of active back buffers by
transitioning from page-flipping to non-page-flipping presents.

Fix this by computing the number of active back buffers only when trying to
obtain a new back buffer.

Fixes: 15e208c4cc ("loader/dri3: Don't accidently free buffer holding new back 
content")
Bugzilla: 
https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.freedesktop.org_show-5Fbug.cgi-3Fid-3D104214=DwIDaQ=uilaK90D4TOVoH58JNXRgQ=wnSlgOCqfpNS4d02vP68_E9q2BNMCwfD2OZ_6dCFVQQ=9HcYeSD_Icbfrmtsk2Opj_2kYsyb6xfcoE81n8lODzc=lObZAF_CMRHJk8C3_gsSJLnjZRBb6WAWotpNW70UMK4=
Cc: "17.3" <mesa-sta...@lists.freedesktop.org>
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>

[...]


@@ -402,7 +400,8 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
  buf->busy = 0;
  
   if (buf && draw->num_back <= b && b < LOADER_DRI3_MAX_BACK &&

- draw->cur_blit_source != b) {
+ draw->cur_blit_source != b &&
+ buf->busy == 0) {
  dri3_free_render_buffer(draw, buf);
  draw->buffers[b] = NULL;
   }

Maybe write this as !buf->busy for consistency with dri3_find_back.
Either way,


Thanks for reviewing, Michel. I'll incorporate that, resend and push.

/Thomas



Reviewed-by: Michel Dänzer <michel.daen...@amd.com>




___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] loader/dri3: Avoid freeing renderbuffers in use

2018-01-11 Thread Thomas Hellstrom
Upon reception of an event that lowered the number of active back buffers,
the code would immediately try to free all back buffers with an id equal to or
higher than the new number of active back buffers.

However, that could lead to an active or to-be-active back buffer being freed,
since the old number of back buffers was used when obtaining an idle back
buffer for use.

This lead to crashes when lowering the number of active back buffers by
transitioning from page-flipping to non-page-flipping presents.

Fix this by computing the number of active back buffers only when trying to
obtain a new back buffer.

Fixes: 15e208c4cc ("loader/dri3: Don't accidently free buffer holding new back 
content")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104214
Cc: "17.3" <mesa-sta...@lists.freedesktop.org>
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index cc890bc..c01b0ac 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -205,7 +205,6 @@ void
 loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw, int interval)
 {
draw->swap_interval = interval;
-   dri3_update_num_back(draw);
 }
 
 /** dri3_free_render_buffer
@@ -377,7 +376,6 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
 draw->flipping = false;
 break;
  }
- dri3_update_num_back(draw);
 
  if (draw->vtable->show_fps)
 draw->vtable->show_fps(draw, ce->ust);
@@ -402,7 +400,8 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
 buf->busy = 0;
 
  if (buf && draw->num_back <= b && b < LOADER_DRI3_MAX_BACK &&
- draw->cur_blit_source != b) {
+ draw->cur_blit_source != b &&
+ buf->busy == 0) {
 dri3_free_render_buffer(draw, buf);
 draw->buffers[b] = NULL;
  }
@@ -537,6 +536,7 @@ dri3_find_back(struct loader_dri3_drawable *draw)
/* Check whether we need to reuse the current back buffer as new back.
 * In that case, wait until it's not busy anymore.
 */
+   dri3_update_num_back(draw);
num_to_consider = draw->num_back;
if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1) {
   num_to_consider = 1;
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] loader/dri3: Improve dri3 thread-safety

2017-11-21 Thread Thomas Hellstrom

Hi, Nicolai,

On 11/21/2017 11:50 AM, Nicolai Hähnle wrote:

Hi Thomas,

On 20.11.2017 18:19, Thomas Hellstrom wrote:
Is this a multithreaded test? Do you see the error with Ubuntu 17.10 
+ Xorg?


The dEQP-GLES31 tests are all single-threaded.

I could finally test with the Ubuntu 17.10 on Xorg desktop on the same 
system (some other tests were running before in parallel), and indeed 
I don't get hangs there. Looks like it's due to Xwayland -- whether a 
bug in there or "just" some surprising interaction.


Cheers,
Nicolai




Yes, it indeed sounds like the event is never being sent. Could you file 
a bug so that we can track this problem?


/Thomas



/Thomas


On 11/20/2017 06:03 PM, Nicolai Hähnle wrote:

Hi Thomas,

not actually a regression, but I am seeing hangs now with builds 
that include this patch when running the dEQP-GLES31 test. The 
backtrace is:


#3  0x7f947918262a in xcb_wait_for_special_event () from 
/usr/lib/x86_64-linux-gnu/libxcb.so.1
#4  0x7f947c80984e in dri3_wait_for_event_locked 
(draw=0x6140cc78)

    at ../../../mesa-src/src/loader/loader_dri3_helper.c:486
#5  0x7f947c80b8e8 in loader_dri3_wait_for_sbc 
(draw=draw@entry=0x6140cc78, target_sbc=61,
    target_sbc@entry=0, ust=ust@entry=0x7ffd1510d230, 
msc=msc@entry=0x7ffd1510d270,
    sbc=sbc@entry=0x7ffd1510d2b0) at 
../../../mesa-src/src/loader/loader_dri3_helper.c:562
#6  0x7f947c80fbe4 in loader_dri3_swapbuffer_barrier 
(draw=0x6140cc78)

    at ../../../mesa-src/src/loader/loader_dri3_helper.c:1714
#7  0x7f9474ced029 in dri_st_framebuffer_flush_swapbuffers 
(stctx=,
    stfbi=) at 
../../../../../mesa-src/src/gallium/state_trackers/dri/dri_drawable.c:135

#8  0x7f94747730c0 in st_finish (st=st@entry=0x6260c100)
    at ../../../mesa-src/src/mesa/state_tracker/st_cb_flush.c:74
#9  0x7f947477319f in st_glFinish (ctx=)
    at ../../../mesa-src/src/mesa/state_tracker/st_cb_flush.c:104
#10 0x5595fe7d5cfd in glu::CallLogWrapper::glFinish 
(this=0x6030002b9b10)
    at 
/home/nha/amd/tests/deqp/framework/opengl/gluCallLogWrapper.inl:1166
#11 0x5595fe3179dc in deqp::gles31::Functional::(anonymous 
namespace)::GeometryShaderRenderTest::renderWithContext 
(this=this@entry=0x61200dc0, ctx=..., program=..., dstSurface=...)
    at 
/home/nha/amd/tests/deqp/modules/gles31/functional/es31fGeometryShaderTests.cpp:2145 

#12 0x5595fe31d2dc in deqp::gles31::Functional::(anonymous 
namespace)::GeometryShaderRenderTest::iterate (this=0x61200dc0)
    at 
/home/nha/amd/tests/deqp/modules/gles31/functional/es31fGeometryShaderTests.cpp:1934 

#13 0x5595fe2d6cfe in deqp::gles31::TestCaseWrapper::iterate 
(this=0x6020e950,
    testCase=) at 
/home/nha/amd/tests/deqp/modules/gles31/tes31TestPackage.cpp:76
#14 0x5595fe7417d3 in tcu::TestSessionExecutor::iterateTestCase 
(this=this@entry=0x60e0df60,

    testCase=0x61200dc0)

A command-line that fairly reliably causes the hang (but not always 
in the same subtest) is:


/home/nha/amd/tests/deqp/build/modules/gles31/deqp-gles31 
--deqp-caselist="{dEQP-GLES31{functional{geometry_shading{input{basic_primitive{points,lines,line_loop,line_strip,triangles,triangle_strip,triangle_fan,lines_adjacency,line_strip_adjacency,triangles_adjacency},triangle_strip_adjacency{vertex_count_0,vertex_count_1,vertex_count_2,vertex_count_3,vertex_count_4,vertex_count_5,vertex_count_6,vertex_count_7,vertex_count_8,vertex_count_9,vertex_count_10,vertex_count_11,vertex_count_12}},conversion{triangles_to_points,lines_to_points,points_to_lines,triangles_to_lines,points_to_triangles,lines_to_triangles},emit{points_emit_0_end_0,points_emit_0_end_1,points_emit_1_end_1,points_emit_0_end_2,points_emit_1_end_2,line_strip_emit_0_end_0,line_strip_emit_0_end_1,line_strip_emit_1_end_1,line_strip_emit_2_end_1,line_strip_emit_0_end_2,line_strip_emit_1_end_2,line_strip_emit_2_end_2,line_strip_emit_2_end_2_emit_2_end_0,triangle_strip_emit_0_end_0,triangle_strip_emit_0_end_1,triangle_strip_emit_1_end_1,triangle_strip_emit_2_end_1,triangle_strip_emit_3_end_1,triangle_strip_emit_0_end_2,triangle_strip_emit_1_end_2,triangle_strip_emit_2_end_2,triangle_strip_emit_3_end_2,triangle_strip_emit_3_end_2_emit_3_end_0},varying{vertex_no_op_geometry_out_1,vertex_out_0_geometry_out_1,vertex_out_0_geometry_out_2,vertex_out_1_geometry_out_0,vertex_out_1_geometry_out_2},layered{render_with_default_layer_cubemap,render_with_default_layer_3d,render_with_default_layer_2d_array,render_with_default_layer_2d_multisample_array,render_to_one_cubemap,render_to_one_3d,render_to_one_2d_array,render_to_one_2d_multisample_array,render_to_all_cubemap,render_to_all_3d,render_to_all_2d_array,render_to_all_2d_multisample_array,render_different_to_cubemap,render_different_to_3d,render_different_to_2d_array,render_different_to_2d_multisample_array,fragment_layer_cubemap,fragment_layer_3d,fragment_layer_2d_array,fragment_layer_2d_multisample_array,layer_provoking

Re: [Mesa-dev] [PATCH] loader/dri3: Improve dri3 thread-safety

2017-11-20 Thread Thomas Hellstrom
on_3d,multiple_layers_per_invocation_2d_array,multiple_layers_per_invocation_2d_multisample_array,invocation_output_vary_by_attribute,invocation_output_vary_by_uniform} 
" --deqp-visibility hidden


This does not actually appear to be a regression in Mesa -- I started 
seeing it after updating to Ubuntu 17.10, so it may be related to 
Wayland or something else. Running the same setup on 17.04 (with Xorg) 
doesn't see the hangs. Disabling Gallium threading makes no 
difference. Any ideas what's going on?


Thanks,
Nicolai


On 03.11.2017 12:02, Thomas Hellstrom wrote:
It turned out that with recent changes that call into dri3 from 
glFinish(),
it appears like different thread end up waiting for X events 
simultaneously,
causing deadlocks since they steal events from eachoter and update 
the dri3

counters behind eachothers backs.

This patch intends to improve on that. It allows at most one thread at a
time to wait on events for a single drawable. If another thread 
intends to
do the same, it's put to sleep until the first thread finishes 
waiting, and
then it rechecks counters and optionally retries the waiting. Threads 
that

poll for X events never pulls X events off the event queue if there are
other threads waiting for events on that drawable. Counters in the
dri3 drawable structure are protected by a mutex. Finally, the mutex we
introduce is never held while waiting for the X server to avoid
unnecessary stalls.

This does not make dri3 drawables completely thread-safe but at least 
it's a

first step.

Bugzilla: 
https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.freedesktop.org_show-5Fbug.cgi-3Fid-3D102358=DwIGaQ=uilaK90D4TOVoH58JNXRgQ=wnSlgOCqfpNS4d02vP68_E9q2BNMCwfD2OZ_6dCFVQQ=iDJcqIMFeVj6iTFCMMETKjNE_Ea04MZmEuaK4Qd9pVk=6HqE58_DXmtahSSCMcZlXab6GfjZ-S6fFA6ZkJKAprc=
Fixes: d5ba75f8881 "st/dri2 Plumb the flush_swapbuffer functionality 
through to dri3"

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 77 
+++--

  src/loader/loader_dri3_helper.h | 10 ++
  2 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c 
b/src/loader/loader_dri3_helper.c

index 19ab581..7e6b8b2 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -32,7 +32,6 @@
    #include 
  -#include 
  #include "loader_dri3_helper.h"
    /* From xmlpool/options.h, user exposed so should be stable */
@@ -186,8 +185,11 @@ dri3_fence_await(xcb_connection_t *c, struct 
loader_dri3_drawable *draw,

  {
 xcb_flush(c);
 xshmfence_await(buffer->shm_fence);
-   if (draw)
+   if (draw) {
+  mtx_lock(>mtx);
    dri3_flush_present_events(draw);
+  mtx_unlock(>mtx);
+   }
  }
    static void
@@ -245,6 +247,9 @@ loader_dri3_drawable_fini(struct 
loader_dri3_drawable *draw)

    xcb_discard_reply(draw->conn, cookie.sequence);
    xcb_unregister_for_special_event(draw->conn, 
draw->special_event);

 }
+
+   cnd_destroy(>event_cnd);
+   mtx_destroy(>mtx);
  }
    int
@@ -276,6 +281,8 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
   draw->cur_blit_source = -1;
 draw->back_format = __DRI_IMAGE_FORMAT_NONE;
+   mtx_init(>mtx, mtx_plain);
+   cnd_init(>event_cnd);
   if (draw->ext->config)
draw->ext->config->configQueryi(draw->dri_screen,
@@ -407,13 +414,27 @@ dri3_handle_present_event(struct 
loader_dri3_drawable *draw,

  }
    static bool
-dri3_wait_for_event(struct loader_dri3_drawable *draw)
+dri3_wait_for_event_locked(struct loader_dri3_drawable *draw)
  {
 xcb_generic_event_t *ev;
 xcb_present_generic_event_t *ge;
   xcb_flush(draw->conn);
-   ev = xcb_wait_for_special_event(draw->conn, draw->special_event);
+
+   /* Only have one thread waiting for events at a time */
+   if (draw->has_event_waiter) {
+  cnd_wait(>event_cnd, >mtx);
+  /* Another thread has updated the protected info, so retest. */
+  return true;
+   } else {
+  draw->has_event_waiter = true;
+  /* Allow other threads access to the drawable while we're 
waiting. */

+  mtx_unlock(>mtx);
+  ev = xcb_wait_for_special_event(draw->conn, draw->special_event);
+  mtx_lock(>mtx);
+  draw->has_event_waiter = false;
+  cnd_broadcast(>event_cnd);
+   }
 if (!ev)
    return false;
 ge = (void *) ev;
@@ -442,19 +463,23 @@ loader_dri3_wait_for_msc(struct 
loader_dri3_drawable *draw,

    divisor,
    remainder);
  +   mtx_lock(>mtx);
 xcb_flush(draw->conn);
   /* Wait for the event */
 if (draw->special_event) {
    while ((int32_t) (msc_serial - draw->recv_msc_serial) > 0) {
- if (!dri3_wait_for_event(draw))
+ if (!dri3_wait_for_event_locked(draw)) {
+    mtx_unlock(>mtx);
  retur

Re: [Mesa-dev] [PATCH] loader/dri3: Improve dri3 thread-safety

2017-11-06 Thread Thomas Hellstrom

On 11/06/2017 12:14 PM, Nicolai Hähnle wrote:

On 03.11.2017 12:02, Thomas Hellstrom wrote:
It turned out that with recent changes that call into dri3 from 
glFinish(),
it appears like different thread end up waiting for X events 
simultaneously,
causing deadlocks since they steal events from eachoter and update 
the dri3

counters behind eachothers backs.

This patch intends to improve on that. It allows at most one thread at a
time to wait on events for a single drawable. If another thread 
intends to
do the same, it's put to sleep until the first thread finishes 
waiting, and
then it rechecks counters and optionally retries the waiting. Threads 
that

poll for X events never pulls X events off the event queue if there are
other threads waiting for events on that drawable. Counters in the
dri3 drawable structure are protected by a mutex. Finally, the mutex we
introduce is never held while waiting for the X server to avoid
unnecessary stalls.

This does not make dri3 drawables completely thread-safe but at least 
it's a

first step.

Bugzilla: 
https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.freedesktop.org_show-5Fbug.cgi-3Fid-3D102358=DwICaQ=uilaK90D4TOVoH58JNXRgQ=wnSlgOCqfpNS4d02vP68_E9q2BNMCwfD2OZ_6dCFVQQ=yqE5Xb9bQg5hA8gP7s0b3dSSZoPWaAEKACqD8qfhdZo=wf-xBzPlZ805RCV1hnDgoyW0fYe2ZX3Qwie66SU936g=
Fixes: d5ba75f8881 "st/dri2 Plumb the flush_swapbuffer functionality 
through to dri3"

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 77 
+++--

  src/loader/loader_dri3_helper.h | 10 ++
  2 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c 
b/src/loader/loader_dri3_helper.c

index 19ab581..7e6b8b2 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -32,7 +32,6 @@
    #include 
  -#include 
  #include "loader_dri3_helper.h"
    /* From xmlpool/options.h, user exposed so should be stable */
@@ -186,8 +185,11 @@ dri3_fence_await(xcb_connection_t *c, struct 
loader_dri3_drawable *draw,

  {
 xcb_flush(c);
 xshmfence_await(buffer->shm_fence);
-   if (draw)
+   if (draw) {
+  mtx_lock(>mtx);
    dri3_flush_present_events(draw);
+  mtx_unlock(>mtx);
+   }
  }
    static void
@@ -245,6 +247,9 @@ loader_dri3_drawable_fini(struct 
loader_dri3_drawable *draw)

    xcb_discard_reply(draw->conn, cookie.sequence);
    xcb_unregister_for_special_event(draw->conn, 
draw->special_event);

 }
+
+   cnd_destroy(>event_cnd);
+   mtx_destroy(>mtx);
  }
    int
@@ -276,6 +281,8 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
   draw->cur_blit_source = -1;
 draw->back_format = __DRI_IMAGE_FORMAT_NONE;
+   mtx_init(>mtx, mtx_plain);
+   cnd_init(>event_cnd);
   if (draw->ext->config)
draw->ext->config->configQueryi(draw->dri_screen,
@@ -407,13 +414,27 @@ dri3_handle_present_event(struct 
loader_dri3_drawable *draw,

  }
    static bool
-dri3_wait_for_event(struct loader_dri3_drawable *draw)
+dri3_wait_for_event_locked(struct loader_dri3_drawable *draw)
  {
 xcb_generic_event_t *ev;
 xcb_present_generic_event_t *ge;
   xcb_flush(draw->conn);


(Why) Doesn't the flush need to be protected as well? Can it be 
removed entirely given that it's already called from 
loader_dri3_wait_for_msc? Though dri3_find_back is different - why?




Thanks for reviewing.

AFAIK, (correc me if I'm wrong) xcb should be thread-safe enough to 
allow multiple threads to call xcb_flush() simultaneously so we 
shouldn't need to explicitly "serialize" it.


There might indeed be unnecessary xcb_flushes(). In the dri3_find_back 
case when we're initially just checking for arrived events, we know that 
any preceding swapbuffers (that govern the reuse of back buffers) will 
have flushed xcb. However when we explicitly wait for special events, 
any forgotten flush would be catastrophic, causing a deadlock.


We should probably audit the code for unnecessary xcb flushes, but as a 
follow-up patch.


/Thomas



Apart from that, the patch does indeed look like a good first step, 
though Keep in mind that I'm not too familiar with this stuff...


Cheers,
Nicolai


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] loader/dri3: Improve dri3 thread-safety

2017-11-03 Thread Thomas Hellstrom
It turned out that with recent changes that call into dri3 from glFinish(),
it appears like different thread end up waiting for X events simultaneously,
causing deadlocks since they steal events from eachoter and update the dri3
counters behind eachothers backs.

This patch intends to improve on that. It allows at most one thread at a
time to wait on events for a single drawable. If another thread intends to
do the same, it's put to sleep until the first thread finishes waiting, and
then it rechecks counters and optionally retries the waiting. Threads that
poll for X events never pulls X events off the event queue if there are
other threads waiting for events on that drawable. Counters in the
dri3 drawable structure are protected by a mutex. Finally, the mutex we
introduce is never held while waiting for the X server to avoid
unnecessary stalls.

This does not make dri3 drawables completely thread-safe but at least it's a
first step.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102358
Fixes: d5ba75f8881 "st/dri2 Plumb the flush_swapbuffer functionality through to 
dri3"
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 77 +++--
 src/loader/loader_dri3_helper.h | 10 ++
 2 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 19ab581..7e6b8b2 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -32,7 +32,6 @@
 
 #include 
 
-#include 
 #include "loader_dri3_helper.h"
 
 /* From xmlpool/options.h, user exposed so should be stable */
@@ -186,8 +185,11 @@ dri3_fence_await(xcb_connection_t *c, struct 
loader_dri3_drawable *draw,
 {
xcb_flush(c);
xshmfence_await(buffer->shm_fence);
-   if (draw)
+   if (draw) {
+  mtx_lock(>mtx);
   dri3_flush_present_events(draw);
+  mtx_unlock(>mtx);
+   }
 }
 
 static void
@@ -245,6 +247,9 @@ loader_dri3_drawable_fini(struct loader_dri3_drawable *draw)
   xcb_discard_reply(draw->conn, cookie.sequence);
   xcb_unregister_for_special_event(draw->conn, draw->special_event);
}
+
+   cnd_destroy(>event_cnd);
+   mtx_destroy(>mtx);
 }
 
 int
@@ -276,6 +281,8 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
 
draw->cur_blit_source = -1;
draw->back_format = __DRI_IMAGE_FORMAT_NONE;
+   mtx_init(>mtx, mtx_plain);
+   cnd_init(>event_cnd);
 
if (draw->ext->config)
   draw->ext->config->configQueryi(draw->dri_screen,
@@ -407,13 +414,27 @@ dri3_handle_present_event(struct loader_dri3_drawable 
*draw,
 }
 
 static bool
-dri3_wait_for_event(struct loader_dri3_drawable *draw)
+dri3_wait_for_event_locked(struct loader_dri3_drawable *draw)
 {
xcb_generic_event_t *ev;
xcb_present_generic_event_t *ge;
 
xcb_flush(draw->conn);
-   ev = xcb_wait_for_special_event(draw->conn, draw->special_event);
+
+   /* Only have one thread waiting for events at a time */
+   if (draw->has_event_waiter) {
+  cnd_wait(>event_cnd, >mtx);
+  /* Another thread has updated the protected info, so retest. */
+  return true;
+   } else {
+  draw->has_event_waiter = true;
+  /* Allow other threads access to the drawable while we're waiting. */
+  mtx_unlock(>mtx);
+  ev = xcb_wait_for_special_event(draw->conn, draw->special_event);
+  mtx_lock(>mtx);
+  draw->has_event_waiter = false;
+  cnd_broadcast(>event_cnd);
+   }
if (!ev)
   return false;
ge = (void *) ev;
@@ -442,19 +463,23 @@ loader_dri3_wait_for_msc(struct loader_dri3_drawable 
*draw,
   divisor,
   remainder);
 
+   mtx_lock(>mtx);
xcb_flush(draw->conn);
 
/* Wait for the event */
if (draw->special_event) {
   while ((int32_t) (msc_serial - draw->recv_msc_serial) > 0) {
- if (!dri3_wait_for_event(draw))
+ if (!dri3_wait_for_event_locked(draw)) {
+mtx_unlock(>mtx);
 return false;
+ }
   }
}
 
*ust = draw->notify_ust;
*msc = draw->notify_msc;
*sbc = draw->recv_sbc;
+   mtx_unlock(>mtx);
 
return true;
 }
@@ -476,17 +501,21 @@ loader_dri3_wait_for_sbc(struct loader_dri3_drawable 
*draw,
 *  swaps requested with glXSwapBuffersMscOML for that window have
 *  completed."
 */
+   mtx_lock(>mtx);
if (!target_sbc)
   target_sbc = draw->send_sbc;
 
while (draw->recv_sbc < target_sbc) {
-  if (!dri3_wait_for_event(draw))
+  if (!dri3_wait_for_event_locked(draw)) {
+ mtx_unlock(>mtx);
  return 0;
+  }
}
 
*ust = draw->ust;
*msc = draw->msc;
*sbc = draw->recv_sbc;
+   mtx_unlock(>mtx);
return 1;
 }
 
@@ -499,16 +528,16 @@ static int
 dri3_find_back

Re: [Mesa-dev] [PATCH v2] st/mesa: Initialize textures array in st_framebuffer_validate

2017-10-17 Thread Thomas Hellstrom

On 10/17/2017 04:39 PM, Michel Dänzer wrote:

From: Michel Dänzer <michel.daen...@amd.com>

And just reference pipe_resources to it in the validate callbacks.

Avoids pipe_resource leaks when st_framebuffer_validate ends up calling
the validate callback multiple times, e.g. when a window is resized.

v2:
* Use generic stable tag instead of Fixes: tag, since the problem could
   already happen before the commit referenced in v1 (Thomas Hellstrom)
* Use memset to initialize the array on the stack instead of allocating
   the array with os_calloc.

Cc: mesa-sta...@lists.freedesktop.org
Reviewed-by: Thomas Hellstrom <thellst...@vmware.com> # v1
Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
---
  src/gallium/state_trackers/dri/dri_drawable.c | 4 +---
  src/gallium/state_trackers/glx/xlib/xm_st.c   | 4 +---
  src/gallium/state_trackers/hgl/hgl.c  | 4 +---
  src/gallium/state_trackers/osmesa/osmesa.c| 1 +
  src/gallium/state_trackers/wgl/stw_st.c   | 4 +---
  src/mesa/state_tracker/st_manager.c   | 2 ++
  6 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/src/gallium/state_trackers/dri/dri_drawable.c 
b/src/gallium/state_trackers/dri/dri_drawable.c
index 75a8197d330..d586b7564ef 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -99,10 +99,8 @@ dri_st_framebuffer_validate(struct st_context_iface *stctx,
return TRUE;
  
 /* Set the window-system buffers for the state tracker. */

-   for (i = 0; i < count; i++) {
-  out[i] = NULL;
+   for (i = 0; i < count; i++)
pipe_resource_reference([i], textures[statts[i]]);
-   }
  
 return TRUE;

  }
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c 
b/src/gallium/state_trackers/glx/xlib/xm_st.c
index 0c42e653c76..946b5dcff29 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -245,10 +245,8 @@ xmesa_st_framebuffer_validate(struct st_context_iface 
*stctx,
}
 }
  
-   for (i = 0; i < count; i++) {

-  out[i] = NULL;
+   for (i = 0; i < count; i++)
pipe_resource_reference([i], xstfb->textures[statts[i]]);
-   }
  
 return TRUE;

  }
diff --git a/src/gallium/state_trackers/hgl/hgl.c 
b/src/gallium/state_trackers/hgl/hgl.c
index 1b702815a3a..bbc477a978c 100644
--- a/src/gallium/state_trackers/hgl/hgl.c
+++ b/src/gallium/state_trackers/hgl/hgl.c
@@ -193,10 +193,8 @@ hgl_st_framebuffer_validate(struct st_context_iface 
*stctxi,
//}
}
  
-	for (i = 0; i < count; i++) {

-   out[i] = NULL;
+   for (i = 0; i < count; i++)
pipe_resource_reference([i], buffer->textures[statts[i]]);
-   }
  
  	return TRUE;

  }
diff --git a/src/gallium/state_trackers/osmesa/osmesa.c 
b/src/gallium/state_trackers/osmesa/osmesa.c
index 2f9558db312..44a0cc43812 100644
--- a/src/gallium/state_trackers/osmesa/osmesa.c
+++ b/src/gallium/state_trackers/osmesa/osmesa.c
@@ -432,6 +432,7 @@ osmesa_st_framebuffer_validate(struct st_context_iface 
*stctx,
  
templat.format = format;

templat.bind = bind;
+  pipe_resource_reference([i], NULL);
out[i] = osbuffer->textures[statts[i]] =
   screen->resource_create(screen, );
 }
diff --git a/src/gallium/state_trackers/wgl/stw_st.c 
b/src/gallium/state_trackers/wgl/stw_st.c
index 5e165c89f56..7cf18f0a8b0 100644
--- a/src/gallium/state_trackers/wgl/stw_st.c
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -161,10 +161,8 @@ stw_st_framebuffer_validate(struct st_context_iface *stctx,
stwfb->fb->must_resize = FALSE;
 }
  
-   for (i = 0; i < count; i++) {

-  out[i] = NULL;
+   for (i = 0; i < count; i++)
pipe_resource_reference([i], stwfb->textures[statts[i]]);
-   }
  
 stw_framebuffer_unlock(stwfb->fb);
  
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c

index 50bc3c33c62..047337e22db 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -190,6 +190,8 @@ st_framebuffer_validate(struct st_framebuffer *stfb,
 if (stfb->iface_stamp == new_stamp)
return;
  
+   memset(textures, 0, stfb->num_statts * sizeof(textures[0]));

+
 /* validate the fb */
 do {
if (!stfb->iface->validate(>iface, stfb->iface, stfb->statts,


Also for v2:

Reviewed-by: Thomas Hellstrom <thellst...@vmware.com>


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] loader/dri3: Make sure we invalidate a drawable on size change

2017-10-16 Thread Thomas Hellstrom

On 10/16/2017 04:39 PM, Michel Dänzer wrote:

On 16/10/17 02:21 PM, Thomas Hellstrom wrote:

On 10/16/2017 12:53 PM, Thomas Hellstrom wrote:

Hi, Michel,

On 10/16/2017 12:35 PM, Michel Dänzer wrote:

Hi Thomas,

On 05/09/17 10:15 AM, Thomas Hellstrom wrote:

If we're seeing a drawable size change, in particular after
processing a
configure notify event, make sure we invalidate so that the state
tracker
picks up the new geometry.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
   src/loader/loader_dri3_helper.c | 2 ++
   1 file changed, 2 insertions(+)

diff --git a/src/loader/loader_dri3_helper.c
b/src/loader/loader_dri3_helper.c
index 51e4e97..bcd5a66 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -348,6 +348,7 @@ dri3_handle_present_event(struct
loader_dri3_drawable *draw,
     draw->width = ce->width;
     draw->height = ce->height;
     draw->vtable->set_drawable_size(draw, draw->width,
draw->height);
+ draw->ext->flush->invalidate(draw->dri_drawable);
     break;
  }
  case XCB_PRESENT_COMPLETE_NOTIFY: {
@@ -1592,6 +1593,7 @@ loader_dri3_update_drawable_geometry(struct
loader_dri3_drawable *draw)
     draw->width = geom_reply->width;
     draw->height = geom_reply->height;
     draw->vtable->set_drawable_size(draw, draw->width,
draw->height);
+ draw->ext->flush->invalidate(draw->dri_drawable);
       free(geom_reply);
  }


unfortunately, I just bisected a regression to this commit. With it, the
pipe_resource textures backing DRI3 back buffers are leaked when the
window is resized:

==3408== 273,760 (228,464 direct, 45,296 indirect) bytes in 131
blocks are definitely lost in loss record 1,285 of 1,286
==3408==    at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
==3408==    by 0xA04D5D3: r600_texture_create_object
(r600_texture.c:1125)
==3408==    by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
==3408==    by 0x9CE3A17: dri2_allocate_textures (dri2.c:803)
==3408==    by 0x9CDDAE2: dri_st_framebuffer_validate
(dri_drawable.c:85)
==3408==    by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
==3408==    by 0x9B6EE84: st_manager_validate_framebuffers
(st_manager.c:1063)
==3408==    by 0x9B21807: st_validate_state (st_atom.c:202)
==3408==    by 0x9B2AF75: st_Clear (st_cb_clear.c:411)
==3408==    by 0x10A6BD: ??? (in /usr/bin/glxgears)
==3408==    by 0x109E37: ??? (in /usr/bin/glxgears)
==3408==    by 0x5E202E0: (below main) (libc-start.c:291)
==3408==
==3408== 362,768 (230,208 direct, 132,560 indirect) bytes in 132
blocks are definitely lost in loss record 1,286 of 1,286
==3408==    at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
==3408==    by 0xA04D5D3: r600_texture_create_object
(r600_texture.c:1125)
==3408==    by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
==3408==    by 0x9CE0C0D: dri2_create_image_common (dri2.c:1119)
==3408==    by 0x9CE0C6F: dri2_create_image (dri2.c:1140)
==3408==    by 0x5386BA8: dri3_alloc_render_buffer
(loader_dri3_helper.c:1030)
==3408==    by 0x53876F4: dri3_get_buffer.isra.15
(loader_dri3_helper.c:1364)
==3408==    by 0x53886DC: loader_dri3_get_buffers
(loader_dri3_helper.c:1549)
==3408==    by 0x9CE298C: dri_image_drawable_get_buffers (dri2.c:452)
==3408==    by 0x9CE298C: dri2_allocate_textures (dri2.c:576)
==3408==    by 0x9CDDAE2: dri_st_framebuffer_validate
(dri_drawable.c:85)
==3408==    by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
==3408==    by 0x9B6EE84: st_manager_validate_framebuffers
(st_manager.c:1063)


Can you reproduce this with vmwgfx as well? Any ideas why this is
happening / how to fix it?



Looks like other buffers (depth ?) are leaked too, outside dri3, right?

I'll take a look.

/Thomas



Could you try the attached patch? Fixes the issue on my side.

Yes, it fixes the problem for me as well, thanks! I was looking at that
code as well, but didn't realize what's going on.

I think the attached patch would be a cleaner solution though.


I agree. I had that in mind but had a bit too much on my plate today.

Perhaps we should not restrict the application of the patch patch with a 
Fixes: tag, though:

Although improbable, the bug could be hit also without that dri3 patch.

Also do we need to do a os_calloc() of the texture pointer array in 
st_framebuffer_validate(),

cant we just memset() the fixed size array?  Your decision.

Reviewed-by:
Thomas Hellstrom <thellst...@vmware.com>

Thanks,
Thomas



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] loader/dri3: Make sure we invalidate a drawable on size change

2017-10-16 Thread Thomas Hellstrom

Hi, Michel,

On 10/16/2017 12:35 PM, Michel Dänzer wrote:

Hi Thomas,

On 05/09/17 10:15 AM, Thomas Hellstrom wrote:

If we're seeing a drawable size change, in particular after processing a
configure notify event, make sure we invalidate so that the state tracker
picks up the new geometry.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 51e4e97..bcd5a66 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -348,6 +348,7 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
draw->width = ce->width;
draw->height = ce->height;
draw->vtable->set_drawable_size(draw, draw->width, draw->height);
+  draw->ext->flush->invalidate(draw->dri_drawable);
break;
 }
 case XCB_PRESENT_COMPLETE_NOTIFY: {
@@ -1592,6 +1593,7 @@ loader_dri3_update_drawable_geometry(struct 
loader_dri3_drawable *draw)
draw->width = geom_reply->width;
draw->height = geom_reply->height;
draw->vtable->set_drawable_size(draw, draw->width, draw->height);
+  draw->ext->flush->invalidate(draw->dri_drawable);
  
free(geom_reply);

 }


unfortunately, I just bisected a regression to this commit. With it, the
pipe_resource textures backing DRI3 back buffers are leaked when the
window is resized:

==3408== 273,760 (228,464 direct, 45,296 indirect) bytes in 131 blocks are 
definitely lost in loss record 1,285 of 1,286
==3408==at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
==3408==by 0xA04D5D3: r600_texture_create_object (r600_texture.c:1125)
==3408==by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
==3408==by 0x9CE3A17: dri2_allocate_textures (dri2.c:803)
==3408==by 0x9CDDAE2: dri_st_framebuffer_validate (dri_drawable.c:85)
==3408==by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
==3408==by 0x9B6EE84: st_manager_validate_framebuffers (st_manager.c:1063)
==3408==by 0x9B21807: st_validate_state (st_atom.c:202)
==3408==by 0x9B2AF75: st_Clear (st_cb_clear.c:411)
==3408==by 0x10A6BD: ??? (in /usr/bin/glxgears)
==3408==by 0x109E37: ??? (in /usr/bin/glxgears)
==3408==by 0x5E202E0: (below main) (libc-start.c:291)
==3408==
==3408== 362,768 (230,208 direct, 132,560 indirect) bytes in 132 blocks are 
definitely lost in loss record 1,286 of 1,286
==3408==at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
==3408==by 0xA04D5D3: r600_texture_create_object (r600_texture.c:1125)
==3408==by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
==3408==by 0x9CE0C0D: dri2_create_image_common (dri2.c:1119)
==3408==by 0x9CE0C6F: dri2_create_image (dri2.c:1140)
==3408==by 0x5386BA8: dri3_alloc_render_buffer (loader_dri3_helper.c:1030)
==3408==by 0x53876F4: dri3_get_buffer.isra.15 (loader_dri3_helper.c:1364)
==3408==by 0x53886DC: loader_dri3_get_buffers (loader_dri3_helper.c:1549)
==3408==by 0x9CE298C: dri_image_drawable_get_buffers (dri2.c:452)
==3408==by 0x9CE298C: dri2_allocate_textures (dri2.c:576)
==3408==by 0x9CDDAE2: dri_st_framebuffer_validate (dri_drawable.c:85)
==3408==by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
==3408==by 0x9B6EE84: st_manager_validate_framebuffers (st_manager.c:1063)


Can you reproduce this with vmwgfx as well? Any ideas why this is
happening / how to fix it?



Looks like other buffers (depth ?) are leaked too, outside dri3, right?

I'll take a look.

/Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] loader/dri3: Make sure we invalidate a drawable on size change

2017-10-16 Thread Thomas Hellstrom


On 10/16/2017 12:53 PM, Thomas Hellstrom wrote:

Hi, Michel,

On 10/16/2017 12:35 PM, Michel Dänzer wrote:

Hi Thomas,

On 05/09/17 10:15 AM, Thomas Hellstrom wrote:
If we're seeing a drawable size change, in particular after 
processing a
configure notify event, make sure we invalidate so that the state 
tracker

picks up the new geometry.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/src/loader/loader_dri3_helper.c 
b/src/loader/loader_dri3_helper.c

index 51e4e97..bcd5a66 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -348,6 +348,7 @@ dri3_handle_present_event(struct 
loader_dri3_drawable *draw,

    draw->width = ce->width;
    draw->height = ce->height;
    draw->vtable->set_drawable_size(draw, draw->width, 
draw->height);

+ draw->ext->flush->invalidate(draw->dri_drawable);
    break;
 }
 case XCB_PRESENT_COMPLETE_NOTIFY: {
@@ -1592,6 +1593,7 @@ loader_dri3_update_drawable_geometry(struct 
loader_dri3_drawable *draw)

    draw->width = geom_reply->width;
    draw->height = geom_reply->height;
    draw->vtable->set_drawable_size(draw, draw->width, 
draw->height);

+ draw->ext->flush->invalidate(draw->dri_drawable);
      free(geom_reply);
 }


unfortunately, I just bisected a regression to this commit. With it, the
pipe_resource textures backing DRI3 back buffers are leaked when the
window is resized:

==3408== 273,760 (228,464 direct, 45,296 indirect) bytes in 131 
blocks are definitely lost in loss record 1,285 of 1,286

==3408==    at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
==3408==    by 0xA04D5D3: r600_texture_create_object 
(r600_texture.c:1125)

==3408==    by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
==3408==    by 0x9CE3A17: dri2_allocate_textures (dri2.c:803)
==3408==    by 0x9CDDAE2: dri_st_framebuffer_validate 
(dri_drawable.c:85)

==3408==    by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
==3408==    by 0x9B6EE84: st_manager_validate_framebuffers 
(st_manager.c:1063)

==3408==    by 0x9B21807: st_validate_state (st_atom.c:202)
==3408==    by 0x9B2AF75: st_Clear (st_cb_clear.c:411)
==3408==    by 0x10A6BD: ??? (in /usr/bin/glxgears)
==3408==    by 0x109E37: ??? (in /usr/bin/glxgears)
==3408==    by 0x5E202E0: (below main) (libc-start.c:291)
==3408==
==3408== 362,768 (230,208 direct, 132,560 indirect) bytes in 132 
blocks are definitely lost in loss record 1,286 of 1,286

==3408==    at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
==3408==    by 0xA04D5D3: r600_texture_create_object 
(r600_texture.c:1125)

==3408==    by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
==3408==    by 0x9CE0C0D: dri2_create_image_common (dri2.c:1119)
==3408==    by 0x9CE0C6F: dri2_create_image (dri2.c:1140)
==3408==    by 0x5386BA8: dri3_alloc_render_buffer 
(loader_dri3_helper.c:1030)
==3408==    by 0x53876F4: dri3_get_buffer.isra.15 
(loader_dri3_helper.c:1364)
==3408==    by 0x53886DC: loader_dri3_get_buffers 
(loader_dri3_helper.c:1549)

==3408==    by 0x9CE298C: dri_image_drawable_get_buffers (dri2.c:452)
==3408==    by 0x9CE298C: dri2_allocate_textures (dri2.c:576)
==3408==    by 0x9CDDAE2: dri_st_framebuffer_validate 
(dri_drawable.c:85)

==3408==    by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
==3408==    by 0x9B6EE84: st_manager_validate_framebuffers 
(st_manager.c:1063)



Can you reproduce this with vmwgfx as well? Any ideas why this is
happening / how to fix it?



Looks like other buffers (depth ?) are leaked too, outside dri3, right?

I'll take a look.

/Thomas



Could you try the attached patch? Fixes the issue on my side.

/Thomas


>From db02c2b57d84f0ce5a4292204f3cfdfa3547be8d Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellst...@vmware.com>
Date: Mon, 16 Oct 2017 14:13:37 +0200
Subject: [PATCH] st/mesa: Fix a texture reference leak on revalidation

If the state tracker needed to rerun the validation due to a stamp update
while validating, the references from the previous validation iterations were
never unreferenced.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/mesa/state_tracker/st_manager.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 50bc3c3..52492fe 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -198,6 +198,16 @@ st_framebuffer_validate(struct st_framebuffer *stfb,
 
   stfb->iface_stamp = new_stamp;
   new_stamp = p_atomic_read(>iface->stamp);
+
+  /* If we need to rerun the validation, make sure we unreference the
+   * textures first. The validate function will just clear the pointers.
+   */
+
+  if (stfb->iface_stamp != new_stamp) {
+ for (i = 0; i <

[Mesa-dev] dri3 thread safe

2017-10-10 Thread Thomas Hellstrom

Hi, Gregory.

I just noticed the following text in dri3_glx.c:

63b78c93 (Gregory Hainaut   2017-05-29 13:18:26 +0200  506)    /* Unlike 
DRI2, DRI3 doesn't call GetBuffers/GetBuffersWithFormat
63b78c93 (Gregory Hainaut   2017-05-29 13:18:26 +0200  507) * during 
draw so we're safe here.

63b78c93 (Gregory Hainaut   2017-05-29 13:18:26 +0200  508) */

This isn't true anymore, as dri3 now invalidates drawables 
asynchronously, as the previous code generated numerous viewport
inconsistencies and rendering errors. Do we need to explicitly make dri3 
thread-safe for your glthread work?


Thanks,

Thomas



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 1/3] loader/dri3: Use local blits and local buffers when resizing

2017-10-03 Thread Thomas Hellstrom

On 10/03/2017 06:15 PM, Sinclair Yeh wrote:

On Tue, Oct 03, 2017 at 02:16:42PM +0200, Thomas Hellstrom wrote:

Hi!

Could anyone please review this series?

Thanks,
Thomas

Minor typo in the commit message of 1/3:

[Mesa-dev] [PATCH 1/3] loader/dri3: Use local blits and local buffers when
resizing

When a drawable is resized, and we we fill the resized buffers, with data
  ^
 typo


For 3/3, I don't know which buffer LOADER_DRI3_FRONT_ID represents, so I'm
assuming that line checks the correct condition.

Other than those the series:  Reviewed-by: Sinclair Yeh <s...@vmware.com>

Will fix. Thanks!

Thomas

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 1/3] loader/dri3: Use local blits and local buffers when resizing

2017-10-03 Thread Thomas Hellstrom

Hi!

Could anyone please review this series?

Thanks,
Thomas


On 09/15/2017 10:48 AM, Thomas Hellstrom wrote:

When a drawable is resized, and we we fill the resized buffers, with data
from the old buffers, use a local blit if there is a local buffer (back or
fake front), and we have local blitting capability.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 50 -
  1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index bcd5a66..aea0f68 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1373,30 +1373,30 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
/* When resizing, copy the contents of the old buffer, waiting for that
 * copy to complete using our fences before proceeding
 */
-  switch (buffer_type) {
-  case loader_dri3_buffer_back:
- if (buffer) {
-if (!buffer->linear_buffer) {
-   dri3_fence_reset(draw->conn, new_buffer);
-   dri3_fence_await(draw->conn, draw, buffer);
-   dri3_copy_area(draw->conn,
-  buffer->pixmap,
-  new_buffer->pixmap,
-  dri3_drawable_gc(draw),
-  0, 0, 0, 0,
-  draw->width, draw->height);
-   dri3_fence_trigger(draw->conn, new_buffer);
-} else if (draw->vtable->in_current_context(draw)) {
-   (void) loader_dri3_blit_image(draw,
- new_buffer->image,
- buffer->image,
- 0, 0, draw->width, draw->height,
- 0, 0, 0);
-}
-dri3_free_render_buffer(draw, buffer);
+  if ((buffer_type == loader_dri3_buffer_back ||
+   (buffer_type == loader_dri3_buffer_front && draw->have_fake_front))
+  && buffer) {
+
+ /* Fill the new buffer with data from an old buffer */
+ dri3_fence_await(draw->conn, draw, buffer);
+ if (!loader_dri3_blit_image(draw,
+ new_buffer->image,
+ buffer->image,
+ 0, 0, draw->width, draw->height,
+ 0, 0, 0) &&
+ !buffer->linear_buffer) {
+dri3_fence_reset(draw->conn, new_buffer);
+dri3_copy_area(draw->conn,
+   buffer->pixmap,
+   new_buffer->pixmap,
+   dri3_drawable_gc(draw),
+   0, 0, 0, 0,
+   draw->width, draw->height);
+dri3_fence_trigger(draw->conn, new_buffer);
   }
- break;
-  case loader_dri3_buffer_front:
+ dri3_free_render_buffer(draw, buffer);
+  } else if (buffer_type == loader_dri3_buffer_front) {
+ /* Fill the new fake front with data from a real front */
   loader_dri3_swapbuffer_barrier(draw);
   dri3_fence_reset(draw->conn, new_buffer);
   dri3_copy_area(draw->conn,
@@ -1407,8 +1407,7 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
  draw->width, draw->height);
   dri3_fence_trigger(draw->conn, new_buffer);
  
- if (new_buffer->linear_buffer &&

- draw->vtable->in_current_context(draw)) {
+ if (new_buffer->linear_buffer) {
  dri3_fence_await(draw->conn, draw, new_buffer);
  (void) loader_dri3_blit_image(draw,
new_buffer->image,
@@ -1416,7 +1415,6 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
0, 0, draw->width, draw->height,
0, 0, 0);
   }
- break;
}
buffer = new_buffer;
draw->buffers[buf_id] = buffer;



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] st/dri: Add an option to always request a front buffer from the loader

2017-09-18 Thread Thomas Hellstrom

On 09/18/2017 12:43 PM, Eric Anholt wrote:

Thomas Hellstrom <thellst...@vmware.com> writes:


When an application decides to read from the front buffer of a window,
typically a fake front is created and initialized with the real front window
contents. However, if there was a window manager reparenting operation between
the last swapbuffer and the read the real front window contents would be
invalid. This hurts piglit applications that read from the front.

So add an option to always request a front buffer from the dri loader. This
makes the fake front initialization typically happen before any drawing- or
swapbuffer operations take place and, as a result, piglit results from tests
that read from the frontbuffer become robust with dri3.
While there is a memory usage overhead with this option enabled, the
performance overhead with dri3 should be minimal.

With dri2 the situation is different and require more work.

Instead of hacking the GL driver to have a special path for these tests,
could we make those piglit tests loop and try again when they get a
failure but have an expose event pending?  That should work for everyone
and handle the race properly.


Given that this is actually what's happening (Keithp thinks that's not 
really the case), I think
finding and changing all potentially affected piglit tests is really not 
worth the effort.


/Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] st/dri: Add an option to always request a front buffer from the loader

2017-09-18 Thread Thomas Hellstrom

On 09/18/2017 01:10 PM, Thomas Hellstrom wrote:

On 09/18/2017 12:43 PM, Eric Anholt wrote:

Thomas Hellstrom <thellst...@vmware.com> writes:


When an application decides to read from the front buffer of a window,
typically a fake front is created and initialized with the real 
front window
contents. However, if there was a window manager reparenting 
operation between
the last swapbuffer and the read the real front window contents 
would be

invalid. This hurts piglit applications that read from the front.

So add an option to always request a front buffer from the dri 
loader. This
makes the fake front initialization typically happen before any 
drawing- or
swapbuffer operations take place and, as a result, piglit results 
from tests

that read from the frontbuffer become robust with dri3.
While there is a memory usage overhead with this option enabled, the
performance overhead with dri3 should be minimal.

With dri2 the situation is different and require more work.

Instead of hacking the GL driver to have a special path for these tests,
could we make those piglit tests loop and try again when they get a
failure but have an expose event pending?  That should work for everyone
and handle the race properly.


Given that this is actually what's happening (Keithp thinks that's not 
really the case), I think
finding and changing all potentially affected piglit tests is really 
not worth the effort.


Actually, that wouldn't bee to hard. A change in the piglit mainloop. 
I'll take a look at that.

Still confused as to what might be causing the initial problem, though.

Thomas



/Thomas




___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] st/dri: Add an option to always request a front buffer from the loader

2017-09-18 Thread Thomas Hellstrom

Hi.

On 09/18/2017 12:18 PM, Keith Packard wrote:

Thomas Hellstrom <thellst...@vmware.com> writes:


When an application decides to read from the front buffer of a window,
typically a fake front is created and initialized with the real front window
contents. However, if there was a window manager reparenting operation between
the last swapbuffer and the read the real front window contents would be
invalid. This hurts piglit applications that read from the front.

What do you mean by 'invalid'? On a running desktop, reparenting is
typically done before the window gets mapped, so there shouldn't be
*anything* done to the window by this operation. If you restart the
window manager, it will have to reparent all existing windows, which
looks like an unmap followed by a map, but those operations all do well
defined things to the window contents.


Hmm,

So what's happening (timing dependent) is that a window that's supposed 
to be all red after a swapbuffer instead has black borders at the bottom 
and to the right.
So my guess as to what was happening was the server executing the 
swapbuffer, then the window manager would reparent and draw window 
decorations.


But if that's not the case, any idea what might be causing this? It 
happens with both dri2 and dri3, more frequently with dri3.


/Thomas



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 1/3] loader/dri3: Use local blits and local buffers when resizing

2017-09-15 Thread Thomas Hellstrom
When a drawable is resized, and we we fill the resized buffers, with data
from the old buffers, use a local blit if there is a local buffer (back or
fake front), and we have local blitting capability.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 50 -
 1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index bcd5a66..aea0f68 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1373,30 +1373,30 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
   /* When resizing, copy the contents of the old buffer, waiting for that
* copy to complete using our fences before proceeding
*/
-  switch (buffer_type) {
-  case loader_dri3_buffer_back:
- if (buffer) {
-if (!buffer->linear_buffer) {
-   dri3_fence_reset(draw->conn, new_buffer);
-   dri3_fence_await(draw->conn, draw, buffer);
-   dri3_copy_area(draw->conn,
-  buffer->pixmap,
-  new_buffer->pixmap,
-  dri3_drawable_gc(draw),
-  0, 0, 0, 0,
-  draw->width, draw->height);
-   dri3_fence_trigger(draw->conn, new_buffer);
-} else if (draw->vtable->in_current_context(draw)) {
-   (void) loader_dri3_blit_image(draw,
- new_buffer->image,
- buffer->image,
- 0, 0, draw->width, draw->height,
- 0, 0, 0);
-}
-dri3_free_render_buffer(draw, buffer);
+  if ((buffer_type == loader_dri3_buffer_back ||
+   (buffer_type == loader_dri3_buffer_front && draw->have_fake_front))
+  && buffer) {
+
+ /* Fill the new buffer with data from an old buffer */
+ dri3_fence_await(draw->conn, draw, buffer);
+ if (!loader_dri3_blit_image(draw,
+ new_buffer->image,
+ buffer->image,
+ 0, 0, draw->width, draw->height,
+ 0, 0, 0) &&
+ !buffer->linear_buffer) {
+dri3_fence_reset(draw->conn, new_buffer);
+dri3_copy_area(draw->conn,
+   buffer->pixmap,
+   new_buffer->pixmap,
+   dri3_drawable_gc(draw),
+   0, 0, 0, 0,
+   draw->width, draw->height);
+dri3_fence_trigger(draw->conn, new_buffer);
  }
- break;
-  case loader_dri3_buffer_front:
+ dri3_free_render_buffer(draw, buffer);
+  } else if (buffer_type == loader_dri3_buffer_front) {
+ /* Fill the new fake front with data from a real front */
  loader_dri3_swapbuffer_barrier(draw);
  dri3_fence_reset(draw->conn, new_buffer);
  dri3_copy_area(draw->conn,
@@ -1407,8 +1407,7 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
 draw->width, draw->height);
  dri3_fence_trigger(draw->conn, new_buffer);
 
- if (new_buffer->linear_buffer &&
- draw->vtable->in_current_context(draw)) {
+ if (new_buffer->linear_buffer) {
 dri3_fence_await(draw->conn, draw, new_buffer);
 (void) loader_dri3_blit_image(draw,
   new_buffer->image,
@@ -1416,7 +1415,6 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
   0, 0, draw->width, draw->height,
   0, 0, 0);
  }
- break;
   }
   buffer = new_buffer;
   draw->buffers[buf_id] = buffer;
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/3] loader/dri3: Avoid resizing existing buffers in dri3_find_back_alloc

2017-09-15 Thread Thomas Hellstrom
Resize only in loader_dri3_get_buffers(),
where the dri driver has a chance to immediately update the viewport.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 41 +++--
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index aea0f68..dcc713d 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1639,6 +1639,7 @@ loader_dri3_close_screen(__DRIscreen *dri_screen)
  * Find a potentially new back buffer, and if it's not been allocated yet and
  * in addition needs initializing, then try to allocate and initialize it.
  */
+#include 
 static struct loader_dri3_buffer *
 dri3_find_back_alloc(struct loader_dri3_drawable *draw)
 {
@@ -1646,16 +1647,36 @@ dri3_find_back_alloc(struct loader_dri3_drawable *draw)
int id;
 
id = dri3_find_back(draw);
-   back = (id >= 0) ? draw->buffers[id] : NULL;
-
-   if (back || (id >= 0 && draw->back_format != __DRI_IMAGE_FORMAT_NONE)) {
-  if (dri3_update_drawable(draw->dri_drawable, draw)) {
- (void) dri3_get_buffer(draw->dri_drawable,
-draw->back_format,
-loader_dri3_buffer_back,
-draw);
- back = (id >= 0) ? draw->buffers[id] : NULL;
-  }
+   if (id < 0)
+  return NULL;
+
+   back = draw->buffers[id];
+   /* Allocate a new back if we haven't got one */
+   if (!back && draw->back_format != __DRI_IMAGE_FORMAT_NONE &&
+   dri3_update_drawable(draw->dri_drawable, draw))
+  back = dri3_alloc_render_buffer(draw, draw->back_format,
+  draw->width, draw->height, draw->depth);
+
+   if (!back)
+  return NULL;
+
+   draw->buffers[id] = back;
+
+   /* If necessary, prefill the back with data according to swap_method mode. 
*/
+   if (draw->cur_blit_source != -1 &&
+   draw->buffers[draw->cur_blit_source] &&
+   back != draw->buffers[draw->cur_blit_source]) {
+  struct loader_dri3_buffer *source = draw->buffers[draw->cur_blit_source];
+
+  dri3_fence_await(draw->conn, draw, source);
+  dri3_fence_await(draw->conn, draw, back);
+  (void) loader_dri3_blit_image(draw,
+back->image,
+source->image,
+0, 0, draw->width, draw->height,
+0, 0, 0);
+  back->last_swap = source->last_swap;
+  draw->cur_blit_source = -1;
}
 
return back;
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 3/3] loader/dri3: Don't accidently free buffer holding new back content

2017-09-15 Thread Thomas Hellstrom
Avoid freeing buffers holding new back content
(with GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML)
Prevously that would have resulted in back buffer content becoming
incorrect after a swap, although I haven't managed to trigger such a
situation yet.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index dcc713d..19ab581 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -391,13 +391,13 @@ dri3_handle_present_event(struct loader_dri3_drawable 
*draw,
   for (b = 0; b < sizeof(draw->buffers) / sizeof(draw->buffers[0]); b++) {
  struct loader_dri3_buffer *buf = draw->buffers[b];
 
- if (buf && buf->pixmap == ie->pixmap) {
+ if (buf && buf->pixmap == ie->pixmap)
 buf->busy = 0;
-if (draw->num_back <= b && b < LOADER_DRI3_MAX_BACK) {
-   dri3_free_render_buffer(draw, buf);
-   draw->buffers[b] = NULL;
-}
-break;
+
+ if (buf && draw->num_back <= b && b < LOADER_DRI3_MAX_BACK &&
+ draw->cur_blit_source != b) {
+dri3_free_render_buffer(draw, buf);
+draw->buffers[b] = NULL;
  }
   }
   break;
@@ -1469,10 +1469,12 @@ dri3_free_buffers(__DRIdrawable *driDrawable,
case loader_dri3_buffer_back:
   first_id = LOADER_DRI3_BACK_ID(0);
   n_id = LOADER_DRI3_MAX_BACK;
+  draw->cur_blit_source = -1;
   break;
case loader_dri3_buffer_front:
   first_id = LOADER_DRI3_FRONT_ID;
-  n_id = 1;
+  /* Don't free a fake front holding new backbuffer content. */
+  n_id = (draw->cur_blit_source == LOADER_DRI3_FRONT_ID) ? 0 : 1;
}
 
for (buf_id = first_id; buf_id < first_id + n_id; buf_id++) {
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] st/dri: Add an option to always request a front buffer from the loader

2017-09-15 Thread Thomas Hellstrom
When an application decides to read from the front buffer of a window,
typically a fake front is created and initialized with the real front window
contents. However, if there was a window manager reparenting operation between
the last swapbuffer and the read the real front window contents would be
invalid. This hurts piglit applications that read from the front.

So add an option to always request a front buffer from the dri loader. This
makes the fake front initialization typically happen before any drawing- or
swapbuffer operations take place and, as a result, piglit results from tests
that read from the frontbuffer become robust with dri3.
While there is a memory usage overhead with this option enabled, the
performance overhead with dri3 should be minimal.

With dri2 the situation is different and require more work.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 .../auxiliary/pipe-loader/driinfo_gallium.h|  1 +
 src/gallium/state_trackers/dri/dri2.c  | 22 +-
 src/gallium/state_trackers/dri/dri_screen.c|  2 ++
 src/gallium/state_trackers/dri/dri_screen.h|  1 +
 src/util/xmlpool/t_options.h   |  6 ++
 5 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h 
b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
index 48a57c9..fe69570 100644
--- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
+++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
@@ -32,4 +32,5 @@ DRI_CONF_SECTION_END
 DRI_CONF_SECTION_MISCELLANEOUS
DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("false")
DRI_CONF_GLSL_ZERO_INIT("false")
+   DRI_CONF_ALWAYS_REQUEST_FRONT_BUFFER("false")
 DRI_CONF_SECTION_END
diff --git a/src/gallium/state_trackers/dri/dri2.c 
b/src/gallium/state_trackers/dri/dri2.c
index 1e8bb48..839 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -312,6 +312,8 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
int num_buffers;
unsigned attachments[10];
unsigned num_attachments, i;
+   boolean have_front = FALSE;
+   int back_depth = 0;
 
assert(loader);
with_format = dri_with_format(drawable->sPriv);
@@ -319,8 +321,10 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
num_attachments = 0;
 
/* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */
-   if (!with_format)
+   if (!with_format) {
   attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT;
+  have_front = TRUE;
+   }
 
for (i = 0; i < *count; i++) {
   enum pipe_format format;
@@ -333,6 +337,7 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
 
   switch (atts[i]) {
   case ST_ATTACHMENT_FRONT_LEFT:
+ have_front = TRUE;
  /* already added */
  if (!with_format)
 continue;
@@ -376,6 +381,17 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
   if (with_format) {
  attachments[num_attachments++] = depth;
   }
+
+  if (att == __DRI_BUFFER_BACK_LEFT)
+ back_depth = depth;
+   }
+
+   if (dri_screen(drawable->sPriv)->always_request_front &&
+   !have_front &&
+   back_depth != 0) {
+  attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT;
+  if (with_format)
+ attachments[num_attachments++] = back_depth;
}
 
if (with_format) {
@@ -449,6 +465,10 @@ dri_image_drawable_get_buffers(struct dri_drawable 
*drawable,
   }
}
 
+   if (dri_screen(sPriv)->always_request_front &&
+   image_format != __DRI_IMAGE_FORMAT_NONE)
+  buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
+
return (*sPriv->image.loader->getBuffers) (dPriv, image_format,
(uint32_t *) >base.stamp,
dPriv->loaderPrivate, buffer_mask,
diff --git a/src/gallium/state_trackers/dri/dri_screen.c 
b/src/gallium/state_trackers/dri/dri_screen.c
index 1d9f441..eeb125d 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -485,6 +485,8 @@ dri_init_options(struct dri_screen *screen)
pipe_loader_load_options(screen->dev);
 
dri_fill_st_options(screen);
+   screen->always_request_front = driQueryOptionb(>dev->option_cache,
+  "always_request_front");
 }
 
 const __DRIconfig **
diff --git a/src/gallium/state_trackers/dri/dri_screen.h 
b/src/gallium/state_trackers/dri/dri_screen.h
index 677e945..5b076ce 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -59,6 +59,7 @@ struct dri_screen
__DRIscreen *sPriv;
boolean throttling_enabled;
int default_throttle_frames;
+   boolean always_request_front;
 
struct st_config_options opti

[Mesa-dev] [PATCH] mesa/st: Fix frontbuffer rendering regression

2017-09-07 Thread Thomas Hellstrom
This fixes a regression introduced with commit
eceb6710024716433069d705fbd873d6d136c2cc:
"mesa/st: Reduce the number of frontbuffer flush calls"
where we, after flushing the front buffer marked it as not-rendered-to,
the idea being that it should be marked as "rendered-to" again as soon as
any rendering was touching the front.

Now the latter part never happened, because it was part of a state
validation and we never marked that part of the state as dirty.

So mark the framebuffer state dirty after a frontbuffer flush.
(fdo bugzilla 102496)

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Tested-by: Dieter Nützel <die...@nuetzel-hh.de>
Tested-by: Bruce Cherniak <bruce.chern...@intel.com>
Tested-By: Gert Wollny <gw.foss...@gmail.com>
---
 src/mesa/state_tracker/st_manager.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/mesa/state_tracker/st_manager.c 
b/src/mesa/state_tracker/st_manager.c
index 07c430d..6c7d836 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -1044,6 +1044,9 @@ st_manager_flush_frontbuffer(struct st_context *st)
   stfb->iface->flush_front(>iface, stfb->iface,
ST_ATTACHMENT_FRONT_LEFT);
   strb->defined = GL_FALSE;
+
+  /* Trigger an update of strb->defined on next draw */
+  st->dirty |= ST_NEW_FB_STATE;
}
 }
 
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/2] loader/dri3: Make sure we invalidate a drawable on size change

2017-09-05 Thread Thomas Hellstrom
If we're seeing a drawable size change, in particular after processing a
configure notify event, make sure we invalidate so that the state tracker
picks up the new geometry.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 51e4e97..bcd5a66 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -348,6 +348,7 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
   draw->width = ce->width;
   draw->height = ce->height;
   draw->vtable->set_drawable_size(draw, draw->width, draw->height);
+  draw->ext->flush->invalidate(draw->dri_drawable);
   break;
}
case XCB_PRESENT_COMPLETE_NOTIFY: {
@@ -1592,6 +1593,7 @@ loader_dri3_update_drawable_geometry(struct 
loader_dri3_drawable *draw)
   draw->width = geom_reply->width;
   draw->height = geom_reply->height;
   draw->vtable->set_drawable_size(draw, draw->width, draw->height);
+  draw->ext->flush->invalidate(draw->dri_drawable);
 
   free(geom_reply);
}
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 1/2] loader/dri3: Process event after each fence wait

2017-09-05 Thread Thomas Hellstrom
This tries to mimic dri2 behaviour where events are typically processed
while waiting for X replies. Since, during steady-state dri3 rendering, we
seldom wait for xcb replies, and haven't enabled any automatic event
processing, instead check for events after a fence wait.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index c0a6e0d..51e4e97 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -181,10 +181,13 @@ dri3_fence_trigger(xcb_connection_t *c, struct 
loader_dri3_buffer *buffer)
 }
 
 static inline void
-dri3_fence_await(xcb_connection_t *c, struct loader_dri3_buffer *buffer)
+dri3_fence_await(xcb_connection_t *c, struct loader_dri3_drawable *draw,
+ struct loader_dri3_buffer *buffer)
 {
xcb_flush(c);
xshmfence_await(buffer->shm_fence);
+   if (draw)
+  dri3_flush_present_events(draw);
 }
 
 static void
@@ -662,9 +665,9 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
  dri3_drawable_gc(draw),
  x, y, x, y, width, height);
   dri3_fence_trigger(draw->conn, dri3_fake_front_buffer(draw));
-  dri3_fence_await(draw->conn, dri3_fake_front_buffer(draw));
+  dri3_fence_await(draw->conn, NULL, dri3_fake_front_buffer(draw));
}
-   dri3_fence_await(draw->conn, back);
+   dri3_fence_await(draw->conn, draw, back);
 }
 
 void
@@ -680,7 +683,7 @@ loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
   dri3_drawable_gc(draw),
   0, 0, 0, 0, draw->width, draw->height);
dri3_fence_trigger(draw->conn, dri3_fake_front_buffer(draw));
-   dri3_fence_await(draw->conn, dri3_fake_front_buffer(draw));
+   dri3_fence_await(draw->conn, draw, dri3_fake_front_buffer(draw));
 }
 
 void
@@ -1374,7 +1377,7 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
  if (buffer) {
 if (!buffer->linear_buffer) {
dri3_fence_reset(draw->conn, new_buffer);
-   dri3_fence_await(draw->conn, buffer);
+   dri3_fence_await(draw->conn, draw, buffer);
dri3_copy_area(draw->conn,
   buffer->pixmap,
   new_buffer->pixmap,
@@ -1405,7 +1408,7 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
 
  if (new_buffer->linear_buffer &&
  draw->vtable->in_current_context(draw)) {
-dri3_fence_await(draw->conn, new_buffer);
+dri3_fence_await(draw->conn, draw, new_buffer);
 (void) loader_dri3_blit_image(draw,
   new_buffer->image,
   new_buffer->linear_buffer,
@@ -1417,7 +1420,7 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
   buffer = new_buffer;
   draw->buffers[buf_id] = buffer;
}
-   dri3_fence_await(draw->conn, buffer);
+   dri3_fence_await(draw->conn, draw, buffer);
 
/*
 * Do we need to preserve the content of a previous buffer?
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] loader/dri3: Invalidate the drawable after copySubBuffer

2017-09-05 Thread Thomas Hellstrom

On 09/05/2017 08:50 AM, Thomas Hellstrom wrote:

Hi, Michel,



[...]

I guess what could perhaps be done is to process any received events 
in dri3_fence_await, and invalidate only if we see a drawable change 
to try to mimic dri2 behaviour..


Actually this seems like a better and more general approach. I'll send 
out a new patch in a moment.


/Thomas




/Thomas






___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 1/2] loader/dri3: Use client local back to front blit in copySubBuffer if available

2017-09-05 Thread Thomas Hellstrom

On 09/05/2017 08:49 AM, Axel Davy wrote:

Hi,

[...]



Reviewed-by: Axel Davy 


Thanks for reviewing, Axel.

/Thomas

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] loader/dri3: Invalidate the drawable after copySubBuffer

2017-09-05 Thread Thomas Hellstrom

Hi, Michel,

On 09/05/2017 06:02 AM, Michel Dänzer wrote:

On 04/09/17 09:27 PM, Thomas Hellstrom wrote:

Anyone using copySubBuffer as a replacement for swapBuffers would probably
want window resizing to update the viewport.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index c0a6e0d..9549b18 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -664,6 +664,8 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
dri3_fence_trigger(draw->conn, dri3_fake_front_buffer(draw));
dri3_fence_await(draw->conn, dri3_fake_front_buffer(draw));
 }
+
+   draw->ext->flush->invalidate(draw->dri_drawable);
 dri3_fence_await(draw->conn, back);
  }

Your rationale makes some sense to me, but I notice that
dri2CopySubBuffer doesn't seem to do this. Do you have a test case where
this makes a difference?


If you hack glxgears to use copySubBuffer as done in the attached diff, 
you'll see the problem. With dri3 without this patch the window stops 
updating if you resize it.


The bahavior with dri2 is different. If the server doesn't send 
invalidate events (old dri2 server side drivers), then the behavior is, 
as expected, similar to dri3 except rendering continues with an 
incorrect viewport. dri2 with server side events works.


Now dri3 also get server side events on resizing, but the difference 
compared to dri2 is that the dri2 events are processed in _Xreply, so 
they'd automatically get processed when we wait for the server's 
copy_sub_buffer reply, and if there is an invalidate event, we 
invalidate. With dri3 currently we need to explicitly post an 
invalidation to have the code even check for events.


I guess what could perhaps be done is to process any received events in 
dri3_fence_await, and invalidate only if we see a drawable change to try 
to mimic dri2 behaviour..


/Thomas




diff --git a/src/xdemos/glxgears.c b/src/xdemos/glxgears.c
index 54fbf97..e0e823d 100644
--- a/src/xdemos/glxgears.c
+++ b/src/xdemos/glxgears.c
@@ -107,7 +107,8 @@ static GLboolean animate = GL_TRUE;	/* Animation */
 static GLfloat eyesep = 5.0;		/* Eye separation. */
 static GLfloat fix_point = 40.0;	/* Fixation point distance.  */
 static GLfloat left, right, asp;	/* Stereo frustum params.  */
-
+static int savedWidth, savedHeight;
+static PFNGLXCOPYSUBBUFFERMESAPROC pglXCopySubBufferMESA;
 
 /*
  *
@@ -339,7 +340,11 @@ draw_frame(Display *dpy, Window win)
}
 
draw_gears();
-   glXSwapBuffers(dpy, win);
+   if (pglXCopySubBufferMESA) {
+  (*pglXCopySubBufferMESA)(dpy, win, 0, 0, savedWidth, savedHeight);
+   } else {
+  glXSwapBuffers(dpy, win);
+   }
 
frames++;

@@ -361,6 +366,9 @@ draw_frame(Display *dpy, Window win)
 static void
 reshape(int width, int height)
 {
+   savedWidth = width;
+   savedHeight = height;
+
glViewport(0, 0, (GLint) width, (GLint) height);
 
if (stereo) {
@@ -632,6 +640,14 @@ query_vsync(Display *dpy, GLXDrawable drawable)
 interval);
   }
}
+
+   if (is_glx_extension_supported(dpy, "GLX_MESA_copy_sub_buffer")) {
+  pglXCopySubBufferMESA =
+	 (PFNGLXCOPYSUBBUFFERMESAPROC)
+	 glXGetProcAddressARB((const GLubyte *) "glXCopySubBufferMESA");
+  if (pglXCopySubBufferMESA)
+	 printf("Using glXCopySubBuffer.\n");
+   }
 }
 
 /**
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 1/2] loader/dri3: Use client local back to front blit in copySubBuffer if available

2017-09-05 Thread Thomas Hellstrom

Hi!

On 09/05/2017 07:36 AM, Axel Davy wrote:

On 04/09/2017 14:27, Thomas Hellstrom wrote:

The copySubBuffer functionality always attempted a server side blit from
back to fake front if a fake front was present, and we weren't 
displaying

on a remote GPU.

Now that we always have local blit capability on modern drivers, first
attempt a local blit, and only if that fails, try the server blit.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 16 +++-
  1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c 
b/src/loader/loader_dri3_helper.c

index e3120f5..c0a6e0d 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -635,14 +635,6 @@ loader_dri3_copy_sub_buffer(struct 
loader_dri3_drawable *draw,

  back->image,
  0, 0, back->width, back->height,
  0, 0, __BLIT_FLAG_FLUSH);
-  /* We use blit_image to update our fake front,
-   */
-  if (draw->have_fake_front)
- (void) loader_dri3_blit_image(draw,
- dri3_fake_front_buffer(draw)->image,
-   back->image,
-   x, y, width, height,
-   x, y, __BLIT_FLAG_FLUSH);
 }
Why removing that part ? It's a bit easier to read when the 
is_different_gpu path is separated to the normal path here.


It's less code. We're avoiding duplicating the same code in two paths.




loader_dri3_swapbuffer_barrier(draw);
@@ -656,7 +648,13 @@ loader_dri3_copy_sub_buffer(struct 
loader_dri3_drawable *draw,
 /* Refresh the fake front (if present) after we just damaged the 
real

  * front.
  */
-   if (draw->have_fake_front && !draw->is_different_gpu) {
+   if (draw->have_fake_front &&
+   !loader_dri3_blit_image(draw,
+ dri3_fake_front_buffer(draw)->image,
+   back->image,
+   x, y, width, height,
+   x, y, __BLIT_FLAG_FLUSH) &&
+   !draw->is_different_gpu) {
dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
dri3_copy_area(draw->conn,
   back->pixmap,


In the case of is_different_gpu, reverting to using a server copy if 
loader_dri3_blit_image fails doesn't seem a good choice, because what 
the server sees is the linear copy of the buffers. You'd have to add a 
blit from the linear copy to the tiled buffer (which won't work if 
local blit is not available).


The server copy is never performed if is_different_gpu is true. In the 
"is_different_gpu" path, the functionality is not changed, except the 
back-to-fake-front blit is processed *after* the linear-to-real-front 
blit has been scheduled.


Since, in the is_different_gpu case, dri3 refuses to start unless we 
have local blit capability, a failure of loader_dri3_blit_image means 
that we have failed a context creation and in that case, skipping the 
back-to-fake-front blit seems reasonable to me.


Thanks,
/Thomas




Yours,


Axel Davy



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/2] loader/dri3: Invalidate the drawable after copySubBuffer

2017-09-04 Thread Thomas Hellstrom
Anyone using copySubBuffer as a replacement for swapBuffers would probably
want window resizing to update the viewport.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index c0a6e0d..9549b18 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -664,6 +664,8 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
   dri3_fence_trigger(draw->conn, dri3_fake_front_buffer(draw));
   dri3_fence_await(draw->conn, dri3_fake_front_buffer(draw));
}
+
+   draw->ext->flush->invalidate(draw->dri_drawable);
dri3_fence_await(draw->conn, back);
 }
 
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 1/2] loader/dri3: Use client local back to front blit in copySubBuffer if available

2017-09-04 Thread Thomas Hellstrom
The copySubBuffer functionality always attempted a server side blit from
back to fake front if a fake front was present, and we weren't displaying
on a remote GPU.

Now that we always have local blit capability on modern drivers, first
attempt a local blit, and only if that fails, try the server blit.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index e3120f5..c0a6e0d 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -635,14 +635,6 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
 back->image,
 0, 0, back->width, back->height,
 0, 0, __BLIT_FLAG_FLUSH);
-  /* We use blit_image to update our fake front,
-   */
-  if (draw->have_fake_front)
- (void) loader_dri3_blit_image(draw,
-   dri3_fake_front_buffer(draw)->image,
-   back->image,
-   x, y, width, height,
-   x, y, __BLIT_FLAG_FLUSH);
}
 
loader_dri3_swapbuffer_barrier(draw);
@@ -656,7 +648,13 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
/* Refresh the fake front (if present) after we just damaged the real
 * front.
 */
-   if (draw->have_fake_front && !draw->is_different_gpu) {
+   if (draw->have_fake_front &&
+   !loader_dri3_blit_image(draw,
+   dri3_fake_front_buffer(draw)->image,
+   back->image,
+   x, y, width, height,
+   x, y, __BLIT_FLAG_FLUSH) &&
+   !draw->is_different_gpu) {
   dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
   dri3_copy_area(draw->conn,
  back->pixmap,
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/9] loader_dri3/glx/egl: Optionally use a blit context for blitting operations

2017-08-18 Thread Thomas Hellstrom

On 08/18/2017 07:02 PM, Emil Velikov wrote:

Hi Thomas,

On 15 August 2017 at 19:31, Thomas Hellstrom <thellst...@vmware.com> wrote:


+/**
+ * A cached blit context.
+ */
+struct loader_dri3_blit_context {
+   mtx_t mtx;
+   __DRIcontext *ctx;
+   __DRIscreen *cur_screen;
+   const __DRIcoreExtension *core;
+};
+
+/* For simplicity we maintain the cache only for a single screen at a time */
+static struct loader_dri3_blit_context blit_context = {
+   _MTX_INITIALIZER_NP, NULL

Use a C99 designated initializer?


+};
+/**
+ * Blit (parts of) the contents of a DRI image to another dri image
+ *
+ * \param draw[in]  The drawable which owns the images.
+ * \param dst[in]  The destination image.
+ * \param src[in]  The source image.
+ * \param dstx0[in]  Start destination coordinate.
+ * \param dsty0[in]  Start destination coordinate.
+ * \param width[in]  Blit width.
+ * \param height[in] Blit height.
+ * \param srcx0[in]  Start source coordinate.
+ * \param srcy0[in]  Start source coordinate.
+ * \param flush_flag[in]  Image blit flush flag.
+ * \return true iff successful.

s/iff/if/

With the above
Reviewed-by: Emil Velikov <emil.veli...@collabora.com>

Please don't bother re-sending the patch. Squash locally before pushing.

Thanks
Emil


Hi, Emil!

The patch is already pushed, If you want to, I can fix up the 
initializer in a follow-up. iff is a common abbreviation for if and only if.


Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 9/9] loader_dri3: Make sure we have an updated back v3

2017-08-16 Thread Thomas Hellstrom
With GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML it may happen in situations
when glXSwapBuffers() is immediately followed by for example another
glXSwapBuffers() or glXCopyBuffers() or back buffer age querying, that we
haven't yet allocated and initialized a new back buffer because there was
no GL rendering in between.

Make sure that we have a back buffer in those situations.

v2: Eliminate the drawable have_back_format member.
v3: Make sure we re-initialize the back even if it exists.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/loader/loader_dri3_helper.c | 59 ++---
 src/loader/loader_dri3_helper.h |  1 +
 2 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 55e1471..e7d4715 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -59,6 +59,9 @@ static struct loader_dri3_blit_context blit_context = {
 static void
 dri3_flush_present_events(struct loader_dri3_drawable *draw);
 
+static struct loader_dri3_buffer *
+dri3_find_back_alloc(struct loader_dri3_drawable *draw);
+
 /**
  * Do we have blit functionality in the image blit extension?
  *
@@ -269,6 +272,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->first_init = true;
 
draw->cur_blit_source = -1;
+   draw->back_format = __DRI_IMAGE_FORMAT_NONE;
 
if (draw->ext->config)
   draw->ext->config->configQueryi(draw->dri_screen,
@@ -616,7 +620,10 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
   flags |= __DRI2_FLUSH_CONTEXT;
loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
 
-   back = dri3_back_buffer(draw);
+   back = dri3_find_back_alloc(draw);
+   if (!back)
+  return;
+
y = draw->height - y - height;
 
if (draw->is_different_gpu) {
@@ -641,7 +648,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
loader_dri3_swapbuffer_barrier(draw);
dri3_fence_reset(draw->conn, back);
dri3_copy_area(draw->conn,
-  dri3_back_buffer(draw)->pixmap,
+  back->pixmap,
   draw->drawable,
   dri3_drawable_gc(draw),
   x, y, x, y, width, height);
@@ -652,7 +659,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
if (draw->have_fake_front && !draw->is_different_gpu) {
   dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
   dri3_copy_area(draw->conn,
- dri3_back_buffer(draw)->pixmap,
+ back->pixmap,
  dri3_fake_front_buffer(draw)->pixmap,
  dri3_drawable_gc(draw),
  x, y, x, y, width, height);
@@ -763,7 +770,8 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 
draw->vtable->flush_drawable(draw, flush_flags);
 
-   back = draw->buffers[dri3_find_back(draw)];
+   back = dri3_find_back_alloc(draw);
+
if (draw->is_different_gpu && back) {
   /* Update the linear buffer before presenting the pixmap */
   (void) loader_dri3_blit_image(draw,
@@ -892,15 +900,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 int
 loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
 {
-   int back_id = LOADER_DRI3_BACK_ID(dri3_find_back(draw));
+   struct loader_dri3_buffer *back = dri3_find_back_alloc(draw);
 
-   if (back_id < 0 || !draw->buffers[back_id])
+   if (!back || back->last_swap == 0)
   return 0;
 
-   if (draw->buffers[back_id]->last_swap != 0)
-  return draw->send_sbc - draw->buffers[back_id]->last_swap + 1;
-   else
-  return 0;
+   return draw->send_sbc - back->last_swap + 1;
 }
 
 /** loader_dri3_open
@@ -1334,6 +1339,8 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
int buf_id;
 
if (buffer_type == loader_dri3_buffer_back) {
+  draw->back_format = format;
+
   buf_id = dri3_find_back(draw);
 
   if (buf_id < 0)
@@ -1620,3 +1627,35 @@ loader_dri3_close_screen(__DRIscreen *dri_screen)
}
mtx_unlock(_context.mtx);
 }
+
+/**
+ * Find a backbuffer slot - potentially allocating a back buffer
+ *
+ * \param draw[in,out]  Pointer to the drawable for which to find back.
+ * \return Pointer to a new back buffer or NULL if allocation failed or was
+ * not mandated.
+ *
+ * Find a potentially new back buffer, and if it's not been allocated yet and
+ * in addition needs initializing, then try to allocate and initialize it.
+ */
+static struct loader_dri3_buffer *
+dri3_find_back_alloc(struct loader_dri3_drawable *draw)
+{
+   struct loader_dri3_buffer *back;
+   int id;
+
+   id = dri3_find_back(draw);
+   back = (id >= 0) ? draw->buffers[id] : NULL;
+
+   if (back || (id >= 0 &&

[Mesa-dev] [PATCH 9/9] loader_dri3: Make sure we have an updated back v2

2017-08-15 Thread Thomas Hellstrom
With GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML it may happen in situations
when glXSwapBuffers() is immediately followed by for example another
glXSwapBuffers() or glXCopyBuffers() or back buffer age querying, that we
haven't yet allocated and initialized a new back buffer because there was
no GL rendering in between.

Make sure that we have a back buffer in those situations.

v2: Eliminate the drawable have_back_format member.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 62 ++---
 src/loader/loader_dri3_helper.h |  1 +
 2 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 55e1471..a2885ac 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -59,6 +59,9 @@ static struct loader_dri3_blit_context blit_context = {
 static void
 dri3_flush_present_events(struct loader_dri3_drawable *draw);
 
+static struct loader_dri3_buffer *
+dri3_find_back_alloc(struct loader_dri3_drawable *draw);
+
 /**
  * Do we have blit functionality in the image blit extension?
  *
@@ -269,6 +272,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->first_init = true;
 
draw->cur_blit_source = -1;
+   draw->back_format = __DRI_IMAGE_FORMAT_NONE;
 
if (draw->ext->config)
   draw->ext->config->configQueryi(draw->dri_screen,
@@ -616,7 +620,10 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
   flags |= __DRI2_FLUSH_CONTEXT;
loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
 
-   back = dri3_back_buffer(draw);
+   back = dri3_find_back_alloc(draw);
+   if (!back)
+  return;
+
y = draw->height - y - height;
 
if (draw->is_different_gpu) {
@@ -641,7 +648,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
loader_dri3_swapbuffer_barrier(draw);
dri3_fence_reset(draw->conn, back);
dri3_copy_area(draw->conn,
-  dri3_back_buffer(draw)->pixmap,
+  back->pixmap,
   draw->drawable,
   dri3_drawable_gc(draw),
   x, y, x, y, width, height);
@@ -652,7 +659,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
if (draw->have_fake_front && !draw->is_different_gpu) {
   dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
   dri3_copy_area(draw->conn,
- dri3_back_buffer(draw)->pixmap,
+ back->pixmap,
  dri3_fake_front_buffer(draw)->pixmap,
  dri3_drawable_gc(draw),
  x, y, x, y, width, height);
@@ -763,7 +770,8 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 
draw->vtable->flush_drawable(draw, flush_flags);
 
-   back = draw->buffers[dri3_find_back(draw)];
+   back = dri3_find_back_alloc(draw);
+
if (draw->is_different_gpu && back) {
   /* Update the linear buffer before presenting the pixmap */
   (void) loader_dri3_blit_image(draw,
@@ -892,15 +900,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 int
 loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
 {
-   int back_id = LOADER_DRI3_BACK_ID(dri3_find_back(draw));
+   struct loader_dri3_buffer *back = dri3_find_back_alloc(draw);
 
-   if (back_id < 0 || !draw->buffers[back_id])
+   if (!back || back->last_swap == 0)
   return 0;
 
-   if (draw->buffers[back_id]->last_swap != 0)
-  return draw->send_sbc - draw->buffers[back_id]->last_swap + 1;
-   else
-  return 0;
+   return draw->send_sbc - back->last_swap + 1;
 }
 
 /** loader_dri3_open
@@ -1334,6 +1339,8 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
int buf_id;
 
if (buffer_type == loader_dri3_buffer_back) {
+  draw->back_format = format;
+
   buf_id = dri3_find_back(draw);
 
   if (buf_id < 0)
@@ -1620,3 +1627,38 @@ loader_dri3_close_screen(__DRIscreen *dri_screen)
}
mtx_unlock(_context.mtx);
 }
+
+/**
+ * Find a backbuffer slot - potentially allocating a back buffer
+ *
+ * \param draw[in,out]  Pointer to the drawable for which to find back.
+ * \return Pointer to a new back buffer or NULL if allocation failed or was
+ * not mandated.
+ *
+ * Find a potentially new back buffer, and if it's not been allocated yet and
+ * in addition needs initializing, then try to allocate and initialize it.
+ */
+static struct loader_dri3_buffer *
+dri3_find_back_alloc(struct loader_dri3_drawable *draw)
+{
+   struct loader_dri3_buffer *back;
+   int id;
+
+   id = dri3_find_back(draw);
+   back = (id >= 0) ? draw->buffers[id] : NULL;
+
+   if (!back && draw->back_format != __DRI_IMAGE_FORMAT_NONE) {
+  (void) dri3_get_buffer(draw->dri_drawable,
+ draw-

[Mesa-dev] [PATCH 8/9] loader_dri3: Support GLX_SWAP_EXCHANGE_OML

2017-08-15 Thread Thomas Hellstrom
Add support for the exchange swap method. Since we're now forcing a fake front
buffer and we exchange the back and fake front on swaps, we don't need to add
much code.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/loader/loader_dri3_helper.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 3434af3..55e1471 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -777,7 +777,7 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 * The force_copy parameter is used by EGL to attempt to preserve
 * the back buffer across a call to this function.
 */
-   if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY || force_copy)
+   if (draw->swap_method != __DRI_ATTRIB_SWAP_UNDEFINED || force_copy)
   draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
 
/* Exchange the back and fake front. Even though the server knows about 
these
@@ -1504,8 +1504,10 @@ loader_dri3_get_buffers(__DRIdrawable *driDrawable,
if (!dri3_update_drawable(driDrawable, draw))
   return false;
 
-   /* pixmaps always have front buffers */
-   if (draw->is_pixmap)
+   /* pixmaps always have front buffers.
+* Exchange swaps also mandate fake front buffers.
+*/
+   if (draw->is_pixmap || draw->swap_method == __DRI_ATTRIB_SWAP_EXCHANGE)
   buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
 
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 0/9] dri2: Swapbuffer update v3.

2017-08-15 Thread Thomas Hellstrom
Implement back-to-fake-front flips,
Fix EGL_BUFFER_PRESERVED path.
Implement dri3 support for GLX_SWAP_EXCHANGE_OML and GLX_SWAP_COPY_OML.

The back-to-fake-front flips will save a full buffer copy in the case of a
fake front being enabled and GLX_SWAP_UNDEFINED_OML.

Support for EGL_BUFFER_PRESERVED and GLX_SWAP_X_OML are mostly useful for
things like glretrace if traces are capured with applications relying on a
specific swapbuffer behavior.

The EGL_BUFFER_PRESERVED path previously made sure the present was done as
a copy, but there was nothing making sure that after the present,
the same back buffer was chosen.
This has now been changed so that if the previous back buffer is
idle, we reuse it. Otherwise we grab a new and copy the contents and
buffer age from the previous back buffer. Server side flips are allowed.

GLX_SWAP_COPY_OML will behave like EGL_BUFFER_PRESERVED.

GLX_SWAP_EXCHANGE_OML will behave similarly, except that we try to reuse the
previous fake front as the new back buffer if it's idle. If not, we grab
a new back buffer and copy the contents and buffer age from the old fake front.

v2:
- Split the original patch,
- Make sure we have a context for blitImage even if we don't have a
current context.
- Make sure the delayed backbuffer allocation is performed before
glXSwapBuffers, glXCopyBuffers and querying buffer age.
v3:
- squash three patches related to the same change.
- Address review comments by Michel Dänzer.

Testing done:
piglit tests/quick without regressions on svga.
A modified piglit glx-swap-exchange posted for review on the piglit list.
That test required modifying the dri2 state tracke to advertise unconditional
support for GLX_SWAP_EXCHANGE_OML
A piglit glx-swap-copy test derived from the glx-swap-exchange test.
Not posted yet.


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 3/9] loader_dri3: Increase the likelyhood of reusing the current swap buffer

2017-08-15 Thread Thomas Hellstrom
Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/loader/loader_dri3_helper.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 131c9e9..b3f0482 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -56,6 +56,9 @@ static struct loader_dri3_blit_context blit_context = {
_MTX_INITIALIZER_NP, NULL
 };
 
+static void
+dri3_flush_present_events(struct loader_dri3_drawable *draw);
+
 /**
  * Do we have blit functionality in the image blit extension?
  *
@@ -482,6 +485,9 @@ dri3_find_back(struct loader_dri3_drawable *draw)
xcb_generic_event_t *ev;
xcb_present_generic_event_t *ge;
 
+   /* Increase the likelyhood of reusing current buffer */
+   dri3_flush_present_events(draw);
+
for (;;) {
   for (b = 0; b < draw->num_back; b++) {
  int id = LOADER_DRI3_BACK_ID((b + draw->cur_back) % draw->num_back);
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/9] loader_dri3/glx/egl: Optionally use a blit context for blitting operations

2017-08-15 Thread Thomas Hellstrom
The code was relying on us always having a current context for client local
image blit operations. Otherwise the blit would be skipped. However,
glxSwapBuffers, for example, doesn't require a current context and that was a
common problem in the dri1 era. It seems the problem has resurfaced with dri3.

If we don't have a current context when we want to blit, try creating a private
dri context and maintain a context cache of a single context.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/egl/drivers/dri2/egl_dri2.c  |   5 +-
 src/egl/drivers/dri2/egl_dri2.h  |   2 +
 src/egl/drivers/dri2/platform_x11_dri3.c |   9 ++
 src/glx/dri3_glx.c   |   1 +
 src/loader/loader_dri3_helper.c  | 243 ++-
 src/loader/loader_dri3_helper.h  |   3 +
 6 files changed, 196 insertions(+), 67 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 975d39d..ed79e0d 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -945,8 +945,11 @@ dri2_display_destroy(_EGLDisplay *disp)
 {
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
 
-   if (dri2_dpy->own_dri_screen)
+   if (dri2_dpy->own_dri_screen) {
+  if (dri2_dpy->vtbl->close_screen_notify)
+ dri2_dpy->vtbl->close_screen_notify(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+   }
if (dri2_dpy->fd >= 0)
   close(dri2_dpy->fd);
if (dri2_dpy->driver)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 751e7a4..f471561 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -154,6 +154,8 @@ struct dri2_egl_display_vtbl {
  EGLuint64KHR *sbc);
 
__DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf);
+
+   void (*close_screen_notify)(_EGLDisplay *dpy);
 };
 
 struct dri2_egl_display
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c 
b/src/egl/drivers/dri2/platform_x11_dri3.c
index 9917498..290b150 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -401,6 +401,14 @@ dri3_get_dri_drawable(_EGLSurface *surf)
return dri3_surf->loader_drawable.dri_drawable;
 }
 
+static void
+dri3_close_screen_notify(_EGLDisplay *dpy)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+
+   loader_dri3_close_screen(dri2_dpy->dri_screen);
+}
+
 struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
.authenticate = dri3_authenticate,
.create_window_surface = dri3_create_window_surface,
@@ -420,6 +428,7 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
.create_wayland_buffer_from_image = 
dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri3_get_sync_values,
.get_dri_drawable = dri3_get_dri_drawable,
+   .close_screen_notify = dri3_close_screen_notify,
 };
 
 EGLBoolean
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index dc94740..b79fec7 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -572,6 +572,7 @@ dri3_destroy_screen(struct glx_screen *base)
struct dri3_screen *psc = (struct dri3_screen *) base;
 
/* Free the direct rendering per screen data */
+   loader_dri3_close_screen(psc->driScreen);
(*psc->core->destroyScreen) (psc->driScreen);
driDestroyConfigs(psc->driver_configs);
close(psc->fd);
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 5346d07..131c9e9 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -32,6 +32,7 @@
 
 #include 
 
+#include 
 #include "loader_dri3_helper.h"
 
 /* From xmlpool/options.h, user exposed so should be stable */
@@ -40,6 +41,121 @@
 #define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
 #define DRI_CONF_VBLANK_ALWAYS_SYNC 3
 
+/**
+ * A cached blit context.
+ */
+struct loader_dri3_blit_context {
+   mtx_t mtx;
+   __DRIcontext *ctx;
+   __DRIscreen *cur_screen;
+   const __DRIcoreExtension *core;
+};
+
+/* For simplicity we maintain the cache only for a single screen at a time */
+static struct loader_dri3_blit_context blit_context = {
+   _MTX_INITIALIZER_NP, NULL
+};
+
+/**
+ * Do we have blit functionality in the image blit extension?
+ *
+ * \param draw[in]  The drawable intended to blit from / to.
+ * \return  true if we have blit functionality. false otherwise.
+ */
+static bool loader_dri3_have_image_blit(const struct loader_dri3_drawable 
*draw)
+{
+   return draw->ext->image->base.version >= 9 &&
+  draw->ext->image->blitImage != NULL;
+}
+
+/**
+ * Get and lock (for use with the current thread) a dri context associated
+ * with the drawable's dri screen. The context is intended to be used with
+ * the dri image extension's blitImage method.
+ *
+ * \param draw[in]  Pointer to the drawable whose dri screen we want 

[Mesa-dev] [PATCH 4/9] loader_dri3: Honor the request to preserve back buffer content

2017-08-15 Thread Thomas Hellstrom
EGL uses the force_copy parameter to loader_dri3_swap_buffers_msc() to indicate
that it wants to preserve back buffer contents across a buffer swap.

While the loader then turns off server-side page-flipping there's nothing to
guarantee that a new backbuffer isn't chosen when EGL starts to render again,
and that buffer's content is of course undefined.

So rework the functionality:
If the client supports local blits, allow server-side page flipping and when
a new back is grabbed, if needed, blit the old back's content to the new back.
If the client doesn't support local blits, disallow server-side page-flipping
to avoid a client deadlock and then, when grabbing a new back buffer, sleep
until the old back is idle, which may take a substantial time depending on
swap interval.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 54 ++---
 src/loader/loader_dri3_helper.h |  1 +
 2 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index b3f0482..bc7c57f 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -268,6 +268,8 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->have_fake_front = 0;
draw->first_init = true;
 
+   draw->cur_blit_source = -1;
+
if (draw->ext->config)
   draw->ext->config->configQueryi(draw->dri_screen,
   "vblank_mode", _mode);
@@ -484,12 +486,21 @@ dri3_find_back(struct loader_dri3_drawable *draw)
int b;
xcb_generic_event_t *ev;
xcb_present_generic_event_t *ge;
+   int num_to_consider = draw->num_back;
 
/* Increase the likelyhood of reusing current buffer */
dri3_flush_present_events(draw);
 
+   /* Check whether we need to reuse the current back buffer as new back.
+* In that case, wait until it's not busy anymore.
+*/
+   if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1) {
+  num_to_consider = 1;
+  draw->cur_blit_source = -1;
+   }
+
for (;;) {
-  for (b = 0; b < draw->num_back; b++) {
+  for (b = 0; b < num_to_consider; b++) {
  int id = LOADER_DRI3_BACK_ID((b + draw->cur_back) % draw->num_back);
  struct loader_dri3_buffer *buffer = draw->buffers[id];
 
@@ -762,6 +773,13 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
0, 0, __BLIT_FLAG_FLUSH);
}
 
+   /* If we need to preload the new back buffer, remember the source.
+* The force_copy parameter is used by EGL to attempt to preserve
+* the back buffer across a call to this function.
+*/
+   if (force_copy)
+  draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
+
dri3_flush_present_events(draw);
 
if (back && !draw->is_pixmap) {
@@ -800,8 +818,13 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
*/
   if (draw->swap_interval == 0)
   options |= XCB_PRESENT_OPTION_ASYNC;
-  if (force_copy)
-  options |= XCB_PRESENT_OPTION_COPY;
+
+  /* If we need to populate the new back, but need to reuse the back
+   * buffer slot due to lack of local blit capabilities, make sure
+   * the server doesn't flip and we deadlock.
+   */
+  if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1)
+ options |= XCB_PRESENT_OPTION_COPY;
 
   back->busy = 1;
   back->last_swap = draw->send_sbc;
@@ -1374,6 +1397,31 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
}
dri3_fence_await(draw->conn, buffer);
 
+   /*
+* Do we need to preserve the content of a previous buffer?
+*
+* Note that this blit is needed only to avoid a wait for a buffer that
+* is currently in the flip chain or being scanned out from. That's really
+* a tradeoff. If we're ok with the wait we can reduce the number of back
+* buffers to 1 for SWAP_EXCHANGE, and 1 for SWAP_COPY,
+* but in the latter case we must disallow page-flipping.
+*/
+   if (buffer_type == loader_dri3_buffer_back &&
+   draw->cur_blit_source != -1 &&
+   draw->buffers[draw->cur_blit_source] &&
+   buffer != draw->buffers[draw->cur_blit_source]) {
+
+  struct loader_dri3_buffer *source = draw->buffers[draw->cur_blit_source];
+
+  /* Avoid flushing here. Will propably do good for tiling hardware. */
+  (void) loader_dri3_blit_image(draw,
+buffer->image,
+source->image,
+0, 0, draw->width, draw->height,
+0, 0, 0);
+  buffer->last_swap = source->last_swap;
+  draw->cur_blit_source = -1;
+   

[Mesa-dev] [PATCH 7/9] loader_dri3: Eliminate the back-to-fake-front copy

2017-08-15 Thread Thomas Hellstrom
Eliminate the back-to-fake-front copy by exchanging the previous back buffer
and the fake front buffer. This is a gain except when we need to preserve
the back buffer content but in that case we still typically gain by replacing
a server-side blit by a client side non-flushing blit.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
Reviewed-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/loader/loader_dri3_helper.c | 50 +
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 67dabe0..3434af3 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -771,13 +771,6 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 back->image,
 0, 0, back->width, back->height,
 0, 0, __BLIT_FLAG_FLUSH);
-  /* Update the fake front */
-  if (draw->have_fake_front)
- (void) loader_dri3_blit_image(draw,
-   
draw->buffers[LOADER_DRI3_FRONT_ID]->image,
-   back->image,
-   0, 0, draw->width, draw->height,
-   0, 0, __BLIT_FLAG_FLUSH);
}
 
/* If we need to preload the new back buffer, remember the source.
@@ -787,6 +780,20 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY || force_copy)
   draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
 
+   /* Exchange the back and fake front. Even though the server knows about 
these
+* buffers, it has no notion of back and fake front.
+*/
+   if (back && draw->have_fake_front) {
+  struct loader_dri3_buffer *tmp;
+
+  tmp = dri3_fake_front_buffer(draw);
+  draw->buffers[LOADER_DRI3_FRONT_ID] = back;
+  draw->buffers[LOADER_DRI3_BACK_ID(draw->cur_back)] = tmp;
+
+  if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY  || force_copy)
+ draw->cur_blit_source = LOADER_DRI3_FRONT_ID;
+   }
+
dri3_flush_present_events(draw);
 
if (back && !draw->is_pixmap) {
@@ -852,21 +859,26 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
  remainder, 0, NULL);
   ret = (int64_t) draw->send_sbc;
 
-  /* If there's a fake front, then copy the source back buffer
-   * to the fake front to keep it up to date. This needs
-   * to reset the fence and make future users block until
-   * the X server is done copying the bits
+  /* Schedule a server-side back-preserving blit if necessary.
+   * This happens iff all conditions below are satisfied:
+   * a) We have a fake front,
+   * b) We need to preserve the back buffer,
+   * c) We don't have local blit capabilities.
*/
-  if (draw->have_fake_front && !draw->is_different_gpu) {
- dri3_fence_reset(draw->conn, draw->buffers[LOADER_DRI3_FRONT_ID]);
- dri3_copy_area(draw->conn,
-back->pixmap,
-draw->buffers[LOADER_DRI3_FRONT_ID]->pixmap,
+  if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1 &&
+  draw->cur_blit_source != LOADER_DRI3_BACK_ID(draw->cur_back)) {
+ struct loader_dri3_buffer *new_back = dri3_back_buffer(draw);
+ struct loader_dri3_buffer *src = draw->buffers[draw->cur_blit_source];
+
+ dri3_fence_reset(draw->conn, new_back);
+ dri3_copy_area(draw->conn, src->pixmap,
+new_back->pixmap,
 dri3_drawable_gc(draw),
-0, 0, 0, 0,
-draw->width, draw->height);
- dri3_fence_trigger(draw->conn, draw->buffers[LOADER_DRI3_FRONT_ID]);
+0, 0, 0, 0, draw->width, draw->height);
+ dri3_fence_trigger(draw->conn, new_back);
+ new_back->last_swap = src->last_swap;
   }
+
   xcb_flush(draw->conn);
   if (draw->stamp)
  ++(*draw->stamp);
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 02/11] loader/dri3: Make sure we always have a context for image blit operations

2017-08-15 Thread Thomas Hellstrom

Hi, Michel, Thanks for reviewing.

On 08/15/2017 08:57 AM, Michel Dänzer wrote:

On 11/08/17 11:14 PM, Thomas Hellstrom wrote:

The code was relying on us always having a current context for client local
image blit operations. Otherwise the blit would be skipped. However,
glxSwapBuffers, for example, doesn't require a current context and that was a
common problem in the dri1 era. It seems the problem has resurfaced with dri3.

If we don't have a current context when we want to blit, try creating a private
dri context and maintain a context cache of a single context.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>

[...]


+/**
+ * A cached blit context.
+ */
+struct loader_dri3_blit_context {
+   mtx_t mtx;
+   __DRIcontext *ctx;
+   __DRIscreen *cur_screen;

The cur_screen field seems redundant with __DRIcontextRec::driScreenPriv.


Problem is __DRIcontextRec is opaque here, so we can't access its members.





@@ -149,6 +254,9 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
 draw->have_fake_front = 0;
 draw->first_init = true;
  
+   draw->have_image_blit = draw->ext->image->base.version >= 9 &&

+  draw->ext->image->blitImage != NULL;

Is it really worth having a dedicated drawable field for this? Seems
like open-coding this in loader_dri3_blit_image should be fine.


Sure, will do.





@@ -1340,7 +1426,7 @@ loader_dri3_get_buffers(__DRIdrawable *driDrawable,
return false;
  
 /* pixmaps always have front buffers */

-   if (draw->is_pixmap)
+//   if (draw->is_pixmap)
buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;


Hmm, this shouldn't be here. It's a leftover debug thing. I'll fix it up 
to the next version.



Either leave the line uncommented, or remove it and fix up the
indentation of the following line.



Thanks,

Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 06/11] loader_dri3: Honour the request to preserve back buffer content

2017-08-15 Thread Thomas Hellstrom

On 08/15/2017 09:33 AM, Michel Dänzer wrote:

On 11/08/17 11:14 PM, Thomas Hellstrom wrote:

EGL uses the force_copy parameter to loader_dri3_swap_buffers_msc() to indicate
that it wants to preserve back buffer contents across a buffer swap.

While the loader then turns off server-side page-flipping there's nothing to
guarantee that a new backbuffer isn't chosen when EGL starts to render again,
and that buffer's content is of course undefined.

So rework the functionality:
If the client supports local blits, allow server-side page flipping and when
a new back is grabbed, if needed, blit the old back's content to the new back.
If the client doesn't support local blits, disallow server-side page-flipping
to avoid a client deadlock and then, when grabbing a new back buffer, sleep
until the old back is idle, which may take a substantial time depending on
swap interval.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>

[...]


@@ -475,12 +476,21 @@ dri3_find_back(struct loader_dri3_drawable *draw)
 int b;
 xcb_generic_event_t *ev;
 xcb_present_generic_event_t *ge;
+   int num_to_consider = draw->num_back;
  
 /* Increase the likelyhood of reusing current buffer */

 dri3_flush_present_events(draw);
  
+   /* Check whether we need to reuse the current back buffer as new back.

+* In that case, wait until it's not busy anymore.
+*/
+   if (!draw->have_image_blit && draw->cur_blit_source != -1) {
+  num_to_consider = 1;
+  draw->cur_blit_source = -1;
+   }

Is it possible that dri3_find_back gets called with
draw->cur_blit_source != -1, entering this block (assuming
!draw->have_image_blit)...



 for (;;) {
-  for (b = 0; b < draw->num_back; b++) {
+  for (b = 0; b < num_to_consider; b++) {
   int id = LOADER_DRI3_BACK_ID((b + draw->cur_back) % draw->num_back);
   struct loader_dri3_buffer *buffer = draw->buffers[id];

... Then later gets called again with draw->cur_blit_source == -1,
choosing a different back buffer here, because the previous one is still
busy?


I don't think that's possible. If dri3_find_back returns a back buffer, 
it should be idle, in the sense that it's not currently in the swap 
chain or being scanned out from. It may still have a non-signaled fence 
though. If a later call to dri_find_back() decides it's busy then 
someone must have called swapBuffer in between and it's time to change 
back anyway...


/Thomas



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 11/11] loader_dri3: Make sure we have an updated back

2017-08-15 Thread Thomas Hellstrom

On 08/15/2017 09:32 AM, Michel Dänzer wrote:

On 11/08/17 11:14 PM, Thomas Hellstrom wrote:

With GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML it may happen in situations
when glXSwapBuffers() is immediately followed by for example another
glXSwapBuffers() or glXCopyBuffers() or back buffer age querying, that we
haven't yet allocated and initialized a new back buffer because there was
no GL rendering in between.

Make sure that we have a back buffer in those situations.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  src/loader/loader_dri3_helper.c | 64 ++---
  src/loader/loader_dri3_helper.h |  3 ++
  2 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index dee0df8..0440633 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -35,6 +35,7 @@
  #include 
  #include "loader_dri3_helper.h"
  
+

  /* From xmlpool/options.h, user exposed so should be stable */
  #define DRI_CONF_VBLANK_NEVER 0
  #define DRI_CONF_VBLANK_DEF_INTERVAL_0 1

Drop this hunk.


Sure.



diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index c8f63fd..b06a9ad 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -159,6 +159,9 @@ struct loader_dri3_drawable {
  
 bool have_image_blit;

 unsigned int swap_method;
+
+   bool have_back_format;
+   unsigned int back_format;
  };

Is 0 a valid value for the back_format field? If not, the
have_back_format field is redundant.



I'll see if I can eliminate that field.

Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 10/11] loader_dri3: Support GLX_SWAP_EXCHANGE_OML

2017-08-11 Thread Thomas Hellstrom
Add support for the exchange swap method. Since we're now forcing a fake front
buffer and we exchange the back and fake front on swaps, we don't need to add
much code.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 7056f46..dee0df8 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -767,7 +767,7 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 * The force_copy parameter is used by EGL to attempt to preserve
 * the back buffer across a call to this function.
 */
-   if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY || force_copy)
+   if (draw->swap_method != __DRI_ATTRIB_SWAP_UNDEFINED || force_copy)
   draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
 
/* Exchange the back and fake front. Even though the server knows about 
these
@@ -1494,8 +1494,10 @@ loader_dri3_get_buffers(__DRIdrawable *driDrawable,
if (!dri3_update_drawable(driDrawable, draw))
   return false;
 
-   /* pixmaps always have front buffers */
-   if (draw->is_pixmap)
+   /* pixmaps always have front buffers.
+* Exchange swaps also mandate fake front buffers.
+*/
+   if (draw->is_pixmap || draw->swap_method == __DRI_ATTRIB_SWAP_EXCHANGE)
   buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
 
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 11/11] loader_dri3: Make sure we have an updated back

2017-08-11 Thread Thomas Hellstrom
With GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML it may happen in situations
when glXSwapBuffers() is immediately followed by for example another
glXSwapBuffers() or glXCopyBuffers() or back buffer age querying, that we
haven't yet allocated and initialized a new back buffer because there was
no GL rendering in between.

Make sure that we have a back buffer in those situations.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 64 ++---
 src/loader/loader_dri3_helper.h |  3 ++
 2 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index dee0df8..0440633 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -35,6 +35,7 @@
 #include 
 #include "loader_dri3_helper.h"
 
+
 /* From xmlpool/options.h, user exposed so should be stable */
 #define DRI_CONF_VBLANK_NEVER 0
 #define DRI_CONF_VBLANK_DEF_INTERVAL_0 1
@@ -59,6 +60,9 @@ static struct loader_dri3_blit_context blit_context = {
 static void
 dri3_flush_present_events(struct loader_dri3_drawable *draw);
 
+static struct loader_dri3_buffer *
+dri3_find_back_alloc(struct loader_dri3_drawable *draw);
+
 /**
  * Get and lock (for use with the current thread) a dri context associated
  * with the drawable's dri screen. The context is intended to be used with
@@ -259,6 +263,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->have_image_blit = draw->ext->image->base.version >= 9 &&
   draw->ext->image->blitImage != NULL;
draw->cur_blit_source = -1;
+   draw->have_back_format = false;
 
if (draw->ext->config)
   draw->ext->config->configQueryi(draw->dri_screen,
@@ -606,7 +611,10 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
   flags |= __DRI2_FLUSH_CONTEXT;
loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
 
-   back = dri3_back_buffer(draw);
+   back = dri3_find_back_alloc(draw);
+   if (!back)
+  return;
+
y = draw->height - y - height;
 
if (draw->is_different_gpu) {
@@ -631,7 +639,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
loader_dri3_swapbuffer_barrier(draw);
dri3_fence_reset(draw->conn, back);
dri3_copy_area(draw->conn,
-  dri3_back_buffer(draw)->pixmap,
+  back->pixmap,
   draw->drawable,
   dri3_drawable_gc(draw),
   x, y, x, y, width, height);
@@ -642,7 +650,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable 
*draw,
if (draw->have_fake_front && !draw->is_different_gpu) {
   dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
   dri3_copy_area(draw->conn,
- dri3_back_buffer(draw)->pixmap,
+ back->pixmap,
  dri3_fake_front_buffer(draw)->pixmap,
  dri3_drawable_gc(draw),
  x, y, x, y, width, height);
@@ -753,7 +761,8 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 
draw->vtable->flush_drawable(draw, flush_flags);
 
-   back = draw->buffers[dri3_find_back(draw)];
+   back = dri3_find_back_alloc(draw);
+
if (draw->is_different_gpu && back) {
   /* Update the linear buffer before presenting the pixmap */
   (void) loader_dri3_blit_image(draw,
@@ -882,15 +891,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 int
 loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
 {
-   int back_id = LOADER_DRI3_BACK_ID(dri3_find_back(draw));
+   struct loader_dri3_buffer *back = dri3_find_back_alloc(draw);
 
-   if (back_id < 0 || !draw->buffers[back_id])
+   if (!back || back->last_swap == 0)
   return 0;
 
-   if (draw->buffers[back_id]->last_swap != 0)
-  return draw->send_sbc - draw->buffers[back_id]->last_swap + 1;
-   else
-  return 0;
+   return draw->send_sbc - back->last_swap + 1;
 }
 
 /** loader_dri3_open
@@ -1324,6 +1330,9 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
int buf_id;
 
if (buffer_type == loader_dri3_buffer_back) {
+  draw->have_back_format = true;
+  draw->back_format = format;
+
   buf_id = dri3_find_back(draw);
 
   if (buf_id < 0)
@@ -1610,3 +1619,38 @@ loader_dri3_close_screen(__DRIscreen *dri_screen)
}
mtx_unlock(_context.mtx);
 }
+
+/**
+ * Find a backbuffer slot - potentially allocating a back buffer
+ *
+ * \param draw[in,out]  Pointer to the drawable for which to find back.
+ * \return Pointer to a new back buffer or NULL if allocation failed or was
+ * not mandated.
+ *
+ * Find a potentially new back buffer, and if it's not been allocated yet and
+ * in addition needs initializing, then try to allocate and initialize it.
+ */
+static struct l

[Mesa-dev] [PATCH 06/11] loader_dri3: Honour the request to preserve back buffer content

2017-08-11 Thread Thomas Hellstrom
EGL uses the force_copy parameter to loader_dri3_swap_buffers_msc() to indicate
that it wants to preserve back buffer contents across a buffer swap.

While the loader then turns off server-side page-flipping there's nothing to
guarantee that a new backbuffer isn't chosen when EGL starts to render again,
and that buffer's content is of course undefined.

So rework the functionality:
If the client supports local blits, allow server-side page flipping and when
a new back is grabbed, if needed, blit the old back's content to the new back.
If the client doesn't support local blits, disallow server-side page-flipping
to avoid a client deadlock and then, when grabbing a new back buffer, sleep
until the old back is idle, which may take a substantial time depending on
swap interval.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 55 ++---
 src/loader/loader_dri3_helper.h |  1 +
 2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 6f84a43..812adcc 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -258,6 +258,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
 
draw->have_image_blit = draw->ext->image->base.version >= 9 &&
   draw->ext->image->blitImage != NULL;
+   draw->cur_blit_source = -1;
 
if (draw->ext->config)
   draw->ext->config->configQueryi(draw->dri_screen,
@@ -475,12 +476,21 @@ dri3_find_back(struct loader_dri3_drawable *draw)
int b;
xcb_generic_event_t *ev;
xcb_present_generic_event_t *ge;
+   int num_to_consider = draw->num_back;
 
/* Increase the likelyhood of reusing current buffer */
dri3_flush_present_events(draw);
 
+   /* Check whether we need to reuse the current back buffer as new back.
+* In that case, wait until it's not busy anymore.
+*/
+   if (!draw->have_image_blit && draw->cur_blit_source != -1) {
+  num_to_consider = 1;
+  draw->cur_blit_source = -1;
+   }
+
for (;;) {
-  for (b = 0; b < draw->num_back; b++) {
+  for (b = 0; b < num_to_consider; b++) {
  int id = LOADER_DRI3_BACK_ID((b + draw->cur_back) % draw->num_back);
  struct loader_dri3_buffer *buffer = draw->buffers[id];
 
@@ -753,6 +763,13 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
0, 0, __BLIT_FLAG_FLUSH);
}
 
+   /* If we need to preload the new back buffer, remember the source.
+* The force_copy parameter is used by EGL to attempt to preserve
+* the back buffer across a call to this function.
+*/
+   if (force_copy)
+  draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
+
dri3_flush_present_events(draw);
 
if (back && !draw->is_pixmap) {
@@ -791,8 +808,13 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
*/
   if (draw->swap_interval == 0)
   options |= XCB_PRESENT_OPTION_ASYNC;
-  if (force_copy)
-  options |= XCB_PRESENT_OPTION_COPY;
+
+  /* If we need to populate the new back, but need to reuse the back
+   * buffer slot due to lack of local blit capabilities, make sure
+   * the server doesn't flip and we deadlock.
+   */
+  if (!draw->have_image_blit && draw->cur_blit_source != -1)
+ options |= XCB_PRESENT_OPTION_COPY;
 
   back->busy = 1;
   back->last_swap = draw->send_sbc;
@@ -1365,6 +1387,31 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
}
dri3_fence_await(draw->conn, buffer);
 
+   /*
+* Do we need to preserve the content of a previous buffer?
+*
+* Note that this blit is needed only to avoid a wait for a buffer that
+* is currently in the flip chain or being scanned out from. That's really
+* a tradeoff. If we're ok with the wait we can reduce the number of back
+* buffers to 1 for SWAP_EXCHANGE, and 1 for SWAP_COPY,
+* but in the latter case we must disallow page-flipping.
+*/
+   if (buffer_type == loader_dri3_buffer_back &&
+   draw->cur_blit_source != -1 &&
+   draw->buffers[draw->cur_blit_source] &&
+   buffer != draw->buffers[draw->cur_blit_source]) {
+
+  struct loader_dri3_buffer *source = draw->buffers[draw->cur_blit_source];
+
+  /* Avoid flushing here. Will propably do good for tiling hardware. */
+  (void) loader_dri3_blit_image(draw,
+buffer->image,
+source->image,
+0, 0, draw->width, draw->height,
+0, 0, 0);
+  buffer->last_swap = source->last_swap;
+  draw->cur_blit_source = -1;
+   }
/* Return the

[Mesa-dev] [PATCH 09/11] loader_dri3: Eliminate the back-to-fake-front copy

2017-08-11 Thread Thomas Hellstrom
Eliminate the back-to-fake-front copy by exchanging the previous back buffer
and the fake front buffer. This is a gain except when we need to preserve
the back buffer content but in that case we still typically gain by replacing
a server-side blit by a client side non-flushing blit.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 50 +
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 2787f9f..7056f46 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -761,13 +761,6 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 back->image,
 0, 0, back->width, back->height,
 0, 0, __BLIT_FLAG_FLUSH);
-  /* Update the fake front */
-  if (draw->have_fake_front)
- (void) loader_dri3_blit_image(draw,
-   
draw->buffers[LOADER_DRI3_FRONT_ID]->image,
-   back->image,
-   0, 0, draw->width, draw->height,
-   0, 0, __BLIT_FLAG_FLUSH);
}
 
/* If we need to preload the new back buffer, remember the source.
@@ -777,6 +770,20 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY || force_copy)
   draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
 
+   /* Exchange the back and fake front. Even though the server knows about 
these
+* buffers, it has no notion of back and fake front.
+*/
+   if (back && draw->have_fake_front) {
+  struct loader_dri3_buffer *tmp;
+
+  tmp = dri3_fake_front_buffer(draw);
+  draw->buffers[LOADER_DRI3_FRONT_ID] = back;
+  draw->buffers[LOADER_DRI3_BACK_ID(draw->cur_back)] = tmp;
+
+  if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY  || force_copy)
+ draw->cur_blit_source = LOADER_DRI3_FRONT_ID;
+   }
+
dri3_flush_present_events(draw);
 
if (back && !draw->is_pixmap) {
@@ -842,21 +849,26 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
  remainder, 0, NULL);
   ret = (int64_t) draw->send_sbc;
 
-  /* If there's a fake front, then copy the source back buffer
-   * to the fake front to keep it up to date. This needs
-   * to reset the fence and make future users block until
-   * the X server is done copying the bits
+  /* Schedule a server-side back-preserving blit if necessary.
+   * This happens iff all conditions below are satisfied:
+   * a) We have a fake front,
+   * b) We need to preserve the back buffer,
+   * c) We don't have local blit capabilities.
*/
-  if (draw->have_fake_front && !draw->is_different_gpu) {
- dri3_fence_reset(draw->conn, draw->buffers[LOADER_DRI3_FRONT_ID]);
- dri3_copy_area(draw->conn,
-back->pixmap,
-draw->buffers[LOADER_DRI3_FRONT_ID]->pixmap,
+  if (!draw->have_image_blit && draw->cur_blit_source != -1 &&
+  draw->cur_blit_source != LOADER_DRI3_BACK_ID(draw->cur_back)) {
+ struct loader_dri3_buffer *new_back = dri3_back_buffer(draw);
+ struct loader_dri3_buffer *src = draw->buffers[draw->cur_blit_source];
+
+ dri3_fence_reset(draw->conn, new_back);
+ dri3_copy_area(draw->conn, src->pixmap,
+new_back->pixmap,
 dri3_drawable_gc(draw),
-0, 0, 0, 0,
-draw->width, draw->height);
- dri3_fence_trigger(draw->conn, draw->buffers[LOADER_DRI3_FRONT_ID]);
+0, 0, 0, 0, draw->width, draw->height);
+ dri3_fence_trigger(draw->conn, new_back);
+ new_back->last_swap = src->last_swap;
   }
+
   xcb_flush(draw->conn);
   if (draw->stamp)
  ++(*draw->stamp);
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 07/11] loader_dri3: Support GLX_SWAP_COPY_OML

2017-08-11 Thread Thomas Hellstrom
Support the GLX_SWAP_COPY_OML method. When this method is requested, we use
the same swapbuffer code path as EGL_BUFFER_PRESERVED.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 9 -
 src/loader/loader_dri3_helper.h | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 812adcc..774256f 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -301,6 +301,13 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->vtable->set_drawable_size(draw, draw->width, draw->height);
free(reply);
 
+   draw->swap_method = __DRI_ATTRIB_SWAP_UNDEFINED;
+   if (draw->ext->core->base.version >= 2) {
+  (void )draw->ext->core->getConfigAttrib(dri_config,
+  __DRI_ATTRIB_SWAP_METHOD,
+  >swap_method);
+   }
+
/*
 * Make sure server has the same swap interval we do for the new
 * drawable.
@@ -767,7 +774,7 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable 
*draw,
 * The force_copy parameter is used by EGL to attempt to preserve
 * the back buffer across a call to this function.
 */
-   if (force_copy)
+   if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY || force_copy)
   draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
 
dri3_flush_present_events(draw);
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 82c5363..f7db45d 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -160,6 +160,7 @@ struct loader_dri3_drawable {
const struct loader_dri3_vtable *vtable;
 
bool have_image_blit;
+   unsigned int swap_method;
 };
 
 void
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 08/11] loader_dri3: Remove buffer_type from buffer metadata

2017-08-11 Thread Thomas Hellstrom
It's not used anywhere and now that we're about to exchange back- and
fake fronts it doesn't serve a purpose.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 2 --
 src/loader/loader_dri3_helper.h | 2 --
 2 files changed, 4 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 774256f..2787f9f 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1279,7 +1279,6 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, 
unsigned int format,
buffer->own_pixmap = false;
buffer->width = bp_reply->width;
buffer->height = bp_reply->height;
-   buffer->buffer_type = buffer_type;
buffer->shm_fence = shm_fence;
buffer->sync_fence = sync_fence;
 
@@ -1389,7 +1388,6 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
  break;
   }
   buffer = new_buffer;
-  buffer->buffer_type = buffer_type;
   draw->buffers[buf_id] = buffer;
}
dri3_fence_await(draw->conn, buffer);
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index f7db45d..c8f63fd 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -67,8 +67,6 @@ struct loader_dri3_buffer {
uint32_t flags;
uint32_t width, height;
uint64_t last_swap;
-
-   enum loader_dri3_buffer_typebuffer_type;
 };
 
 
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 03/11] glx: Notify the dri3 loader if we are about destroy a dri screen

2017-08-11 Thread Thomas Hellstrom
This gives the dri3 loader a chance to clean up the blit context cache.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/glx/dri3_glx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index dc94740..b79fec7 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -572,6 +572,7 @@ dri3_destroy_screen(struct glx_screen *base)
struct dri3_screen *psc = (struct dri3_screen *) base;
 
/* Free the direct rendering per screen data */
+   loader_dri3_close_screen(psc->driScreen);
(*psc->core->destroyScreen) (psc->driScreen);
driDestroyConfigs(psc->driver_configs);
close(psc->fd);
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 00/10] dri3: Swapbuffer update v2

2017-08-11 Thread Thomas Hellstrom
Implement back-to-fake-front flips,
Fix EGL_BUFFER_PRESERVED path.
Implement dri3 support for GLX_SWAP_EXCHANGE_OML and GLX_SWAP_COPY_OML.

The back-to-fake-front flips will save a full buffer copy in the case of a
fake front being enabled and GLX_SWAP_UNDEFINED_OML.

Support for EGL_BUFFER_PRESERVED and GLX_SWAP_X_OML are mostly useful for
things like glretrace if traces are capured with applications relying on a
specific swapbuffer behavior.

The EGL_BUFFER_PRESERVED path previously made sure the present was done as
a copy, but there was nothing making sure that after the present,
the same back buffer was chosen.
This has now been changed so that if the previous back buffer is
idle, we reuse it. Otherwise we grab a new and copy the contents and
buffer age from the previous back buffer. Server side flips are allowed.

GLX_SWAP_COPY_OML will behave like EGL_BUFFER_PRESERVED.

GLX_SWAP_EXCHANGE_OML will behave similarly, except that we try to reuse the
previous fake front as the new back buffer if it's idle. If not, we grab
a new back buffer and copy the contents and buffer age from the old fake front.

v2:
- Split the original patch,
- Make sure we have a context for blitImage even if we don't have a
current context.
- Make sure the delayed backbuffer allocation is performed before
glXSwapBuffers, glXCopyBuffers and querying buffer age.

Testing done:
piglit tests/quick without regressions on svga.
A modified piglit glx-swap-exchange posted for review on the piglit list.
That test required modifying the dri2 state tracke to advertise unconditional
support for GLX_SWAP_EXCHANGE_OML
A piglit glx-swap-copy test derived from the glx-swap-exchange test.
Not posted yet.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 02/11] loader/dri3: Make sure we always have a context for image blit operations

2017-08-11 Thread Thomas Hellstrom
The code was relying on us always having a current context for client local
image blit operations. Otherwise the blit would be skipped. However,
glxSwapBuffers, for example, doesn't require a current context and that was a
common problem in the dri1 era. It seems the problem has resurfaced with dri3.

If we don't have a current context when we want to blit, try creating a private
dri context and maintain a context cache of a single context.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/loader/loader_dri3_helper.c | 237 
 src/loader/loader_dri3_helper.h |   5 +
 2 files changed, 175 insertions(+), 67 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 5346d07..4959e95 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -32,6 +32,7 @@
 
 #include 
 
+#include 
 #include "loader_dri3_helper.h"
 
 /* From xmlpool/options.h, user exposed so should be stable */
@@ -40,6 +41,110 @@
 #define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
 #define DRI_CONF_VBLANK_ALWAYS_SYNC 3
 
+/**
+ * A cached blit context.
+ */
+struct loader_dri3_blit_context {
+   mtx_t mtx;
+   __DRIcontext *ctx;
+   __DRIscreen *cur_screen;
+   const __DRIcoreExtension *core;
+};
+
+/* For simplicity we maintain the cache only for a single screen at a time */
+static struct loader_dri3_blit_context blit_context = {
+   _MTX_INITIALIZER_NP, NULL
+};
+
+
+/**
+ * Get and lock (for use with the current thread) a dri context associated
+ * with the drawable's dri screen. The context is intended to be used with
+ * the dri image extension's blitImage method.
+ *
+ * \param draw[in]  Pointer to the drawable whose dri screen we want a
+ * dri context for.
+ * \return A dri context or NULL if context creation failed.
+ *
+ * When the caller is done with the context (even if the context returned was
+ * NULL), the caller must call loader_dri3_blit_context_put.
+ */
+static __DRIcontext *
+loader_dri3_blit_context_get(struct loader_dri3_drawable *draw)
+{
+   mtx_lock(_context.mtx);
+
+   if (blit_context.ctx && blit_context.cur_screen != draw->dri_screen) {
+  blit_context.core->destroyContext(blit_context.ctx);
+  blit_context.ctx = NULL;
+   }
+
+   if (!blit_context.ctx) {
+  blit_context.ctx = draw->ext->core->createNewContext(draw->dri_screen,
+   NULL, NULL, NULL);
+  blit_context.cur_screen = draw->dri_screen;
+  blit_context.core = draw->ext->core;
+   }
+
+   return blit_context.ctx;
+}
+
+/**
+ * Release (for use with other threads) a dri context previously obtained using
+ * loader_dri3_blit_context_get.
+ */
+static void
+loader_dri3_blit_context_put(void)
+{
+   mtx_unlock(_context.mtx);
+}
+
+/**
+ * Blit (parts of) the contents of a DRI image to another dri image
+ *
+ * \param draw[in]  The drawable which owns the images.
+ * \param dst[in]  The destination image.
+ * \param src[in]  The source image.
+ * \param dstx0[in]  Start destination coordinate.
+ * \param dsty0[in]  Start destination coordinate.
+ * \param width[in]  Blit width.
+ * \param height[in] Blit height.
+ * \param srcx0[in]  Start source coordinate.
+ * \param srcy0[in]  Start source coordinate.
+ * \param flush_flag[in]  Image blit flush flag.
+ * \return true iff successful.
+ */
+static bool
+loader_dri3_blit_image(struct loader_dri3_drawable *draw,
+   __DRIimage *dst, __DRIimage *src,
+   int dstx0, int dsty0, int width, int height,
+   int srcx0, int srcy0, int flush_flag)
+{
+   __DRIcontext *dri_context;
+   bool use_blit_context = false;
+
+   if (!draw->have_image_blit)
+  return false;
+
+   dri_context = draw->vtable->get_dri_context(draw);
+
+   if (!dri_context || !draw->vtable->in_current_context(draw)) {
+  dri_context = loader_dri3_blit_context_get(draw);
+  use_blit_context = true;
+  flush_flag |= __BLIT_FLAG_FLUSH;
+   }
+
+   if (dri_context)
+  draw->ext->image->blitImage(dri_context, dst, src, dstx0, dsty0,
+  width, height, srcx0, srcy0,
+  width, height, flush_flag);
+
+   if (use_blit_context)
+  loader_dri3_blit_context_put();
+
+   return dri_context != NULL;
+}
+
 static inline void
 dri3_fence_reset(xcb_connection_t *c, struct loader_dri3_buffer *buffer)
 {
@@ -149,6 +254,9 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->have_fake_front = 0;
draw->first_init = true;
 
+   draw->have_image_blit = draw->ext->image->base.version >= 9 &&
+  draw->ext->image->blitImage != NULL;
+
if (draw->ext->config)
   draw->ext->config->configQueryi(draw->dri_screen,
   "vblank_mode", _mode);
@

[Mesa-dev] [PATCH 04/11] egl/x11_dri3: Notify the dri3 loader when we're about to close a screen

2017-08-11 Thread Thomas Hellstrom
This gives the dri3 loader a chance to clean up the blit context cache.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/egl/drivers/dri2/egl_dri2.c  | 5 -
 src/egl/drivers/dri2/egl_dri2.h  | 2 ++
 src/egl/drivers/dri2/platform_x11_dri3.c | 9 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index f584740..a6ac49a 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -945,8 +945,11 @@ dri2_display_destroy(_EGLDisplay *disp)
 {
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
 
-   if (dri2_dpy->own_dri_screen)
+   if (dri2_dpy->own_dri_screen) {
+  if (dri2_dpy->vtbl->close_screen_notify)
+ dri2_dpy->vtbl->close_screen_notify(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+   }
if (dri2_dpy->fd >= 0)
   close(dri2_dpy->fd);
if (dri2_dpy->driver)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 751e7a4..f471561 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -154,6 +154,8 @@ struct dri2_egl_display_vtbl {
  EGLuint64KHR *sbc);
 
__DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf);
+
+   void (*close_screen_notify)(_EGLDisplay *dpy);
 };
 
 struct dri2_egl_display
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c 
b/src/egl/drivers/dri2/platform_x11_dri3.c
index 9917498..290b150 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -401,6 +401,14 @@ dri3_get_dri_drawable(_EGLSurface *surf)
return dri3_surf->loader_drawable.dri_drawable;
 }
 
+static void
+dri3_close_screen_notify(_EGLDisplay *dpy)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+
+   loader_dri3_close_screen(dri2_dpy->dri_screen);
+}
+
 struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
.authenticate = dri3_authenticate,
.create_window_surface = dri3_create_window_surface,
@@ -420,6 +428,7 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
.create_wayland_buffer_from_image = 
dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri3_get_sync_values,
.get_dri_drawable = dri3_get_dri_drawable,
+   .close_screen_notify = dri3_close_screen_notify,
 };
 
 EGLBoolean
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 1/4] dri: Fix __DRIconfig reporting of __DRI_ATTRIB_SWAP_METHOD

2017-08-10 Thread Thomas Hellstrom

Hi, Emil,

On 08/10/2017 06:20 PM, Emil Velikov wrote:

Hi Thomas,

Apologies for dropping in so late.

On 9 August 2017 at 10:53, Thomas Hellstrom <thellst...@vmware.com> wrote:

The attribMap had two entries for this attribute, and
driGetConfigAttribIndex didn't return a proper value for this attribute.
Fix this, and also make sure we return SWAP_UNDEFINED for single-buffer
configs as required by the GLX_OML_swap_method spec.

Finally bump the dri core extension version to 2, indicating that we
correctly report __DRI_ATTRIB_SWAP_METHOD.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
  include/GL/internal/dri_interface.h| 5 -
  src/mesa/drivers/dri/common/dri_util.c | 2 +-
  src/mesa/drivers/dri/common/utils.c| 8 ++--
  3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index f676ac5..5e8fce7 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -726,9 +726,12 @@ struct __DRIuseInvalidateExtensionRec {

  /**
   * This extension defines the core DRI functionality.
+ *
+ * Version >= 2 indicates that getConfigAttrib with __DRI_ATTRIB_SWAP_METHOD
+ * returns a reliable value.
   */
  #define __DRI_CORE "DRI_Core"
-#define __DRI_CORE_VERSION 1
+#define __DRI_CORE_VERSION 2


The interface is bumped, yet nobody checks it.

If I understand your series correctly, when old drivers are present we
fallback to UNDEFINED and things should just work.
Hence the version bump isn't really needed.

Am I missing something?

Thanks
Emil


It's checked in a later patch

https://lists.freedesktop.org/archives/mesa-dev/2017-August/165848.html

But I'm currently splitting it up into a series with some extra fixes in it.

/Thomas


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] dri3: Swapbuffer update

2017-08-10 Thread Thomas Hellstrom

On 08/10/2017 05:27 AM, Michel Dänzer wrote:

On 09/08/17 04:07 PM, Thomas Hellstrom wrote:

On 08/09/2017 08:36 AM, Michel Dänzer wrote:

On 08/08/17 03:48 PM, Thomas Hellstrom wrote:

Implement back-to-fake-front flips, Fix EGL_BUFFER_PRESERVED
path. Implement dri3 support for GLX_SWAP_EXCHANGE_OML and
GLX_SWAP_COPY_OML.

The back-to-fake-front flips will save a full buffer copy in the
case of a fake front being enabled and GLX_SWAP_UNDEFINED_OML.

Support for EGL_BUFFER_PRESERVED and GLX_SWAP_X_OML are mostly
useful for things like glretrace if traces are capured with
applications relying on a specific swapbuffer behavior.

The EGL_BUFFER_PRESERVED path previously made sure the present
was done as a copy, but there was nothing making sure that after
the present, the same back buffer was chosen. This has now been
changed so that if the previous back buffer is idle, we reuse it.
Otherwise we grab a new and copy the contents and buffer age from
the previous back buffer. Server side flips are allowed.

GLX_SWAP_COPY_OML will behave like EGL_BUFFER_PRESERVED.

GLX_SWAP_EXCHANGE_OML will behave similarly, except that we try
to reuse the previous fake front as the new back buffer if it's
idle. If not, we grab a new back buffer and copy the contents and
buffer age from the old fake front.

I'm not sure it's worth copying the contents of the desired next
back buffer to a different one and using that instead. There might
be cases where doing so results in lower performance than simply
using the desired back buffer anyway. Have you made any
measurements WRT this?

Agreed. I haven't done any measurements but my reasoning was that
probably any performance loss would be mostly associated with the
allocating itself, hence a short-lived problem once enough buffers
are allocated. The copying would, at least on modern tiling
hardware, probably not be a big loss since we don't flush.



With EGL_BUFFER_PRESERVED/GLX_SWAP_COPY_OML, always re-using the
same back buffer means that the client only needs to allocate one
back buffer, resulting in lower graphics memory consumption.



True. But there are some implications:

First, with GLX_SWAP_COPY_OML, reusing the back buffer means we need
to disable server-side page-flipping, otherwise the buffer would
never be idle. Second, if we have a fake front, there will be at
least one copy anyway. So in essence we need to disable server-side
page-flipping and might not gain anything in the end if using a fake
front.

With GLX_SWAP_EXCHANGE_OML, we'd be reusing the old fake front which
will, after a delay, always be idle. Also we don't need an extra copy
so the only loss will be a delay which might impact
latency-sensitive applications. I don't expect SWAP_EXCHANGE will be
used much anyway and even if we enable it in st/dri, it won't be
advertised until the server side AIGLX starts to use the image loader
extension or we rewrite the GLX fbconfig selection.

Okay, you've convinced me. Any chance this patch can be split up as well
though?



Yes, I'll try to split it up.

Thanks,
Thomas




What do you think of adding a driConf option to select "wait for
backbuffer idle in swapbuffers"

Seems like overkill. Let's wait for actual problem reports before
considering that.




___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 4/4] dri: Introduce SWAP_METHOD tokens

2017-08-09 Thread Thomas Hellstrom

On 08/10/2017 05:20 AM, Michel Dänzer wrote:

On 09/08/17 06:53 PM, Thomas Hellstrom wrote:

We shouldn't be using GLX tokens in the dri subsystem, so define dri
SWAP_METHOD tokens and translate when necessary. Unfortunately the X server
uses the dri swap method value untranslated as the GLX fbconfig swapMethod,
so we can't enumerate these tokens arbitrarily, but rather need to make them
have the same values as the corresponding GLX tokens.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>

[...]


diff --git a/src/gallium/state_trackers/dri/dri_screen.c 
b/src/gallium/state_trackers/dri/dri_screen.c
index 406e97d..1d9f441 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -156,7 +156,8 @@ dri_fill_in_modes(struct dri_screen *screen)
 boolean mixed_color_depth;
  
 static const GLenum back_buffer_modes[] = {

-  GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+  __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED,
+  __DRI_ATTRIB_SWAP_COPY
 };

BTW, does this array need to include __DRI_ATTRIB_SWAP_EXCHANGE as well,
or is it possible to use GLX_SWAP_EXCHANGE_OML anyway?


No it's not. I have a patch that adds __DRI_ATTRIB_SWAP_EXCHANGE for 
dri3 only (that's when the DRI driver / state tracker is initialized 
with the image loader extension) but still it doesn't get advertised 
since the advertised direct rendering fbconfigs are a subset only of the 
AIGLX exported fbconfigs, and AIGLX doesn't use the image loader 
extension / dri3 path. See the following email thread for more insight 
on this:


https://lists.freedesktop.org/archives/mesa-dev/2017-June/161417.html

As agreed in that thread, that should probably be remedied by rewriting 
the GLX fbconfig selection code so that the DRI startup decides what 
fbconfigs should be exported and the GLX code only makes sure there is a 
matching visual if needed. Since my primary motivation for doing these 
changes is to be able to run glretrace with GLX_SWAP_COPY_OML enabled, 
actually advertising GLX_SWAP_EXCHANGE_OML has lower priority ATM, but 
I'll try to do that at some point.


For the record, though, the code was tested with me unconditionally 
adding __DRI_ATTRIB_SWAP_EXCHANGE for both server and client and using a 
fixed version of  piglit glx-swap-exchange (posted on the piglit list).


Thanks,

Thomas




___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 1/4] dri: Fix __DRIconfig reporting of __DRI_ATTRIB_SWAP_METHOD

2017-08-09 Thread Thomas Hellstrom

On 08/10/2017 05:20 AM, Michel Dänzer wrote:

On 09/08/17 06:53 PM, Thomas Hellstrom wrote:

The attribMap had two entries for this attribute, and
driGetConfigAttribIndex didn't return a proper value for this attribute.
Fix this, and also make sure we return SWAP_UNDEFINED for single-buffer
configs as required by the GLX_OML_swap_method spec.

Finally bump the dri core extension version to 2, indicating that we
correctly report __DRI_ATTRIB_SWAP_METHOD.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>

[...]


diff --git a/src/mesa/drivers/dri/common/utils.c 
b/src/mesa/drivers/dri/common/utils.c
index c37d446..f3ea61e 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -284,8 +284,9 @@ driCreateConfigs(mesa_format format,
modes->transparentIndex = GLX_DONT_CARE;
modes->rgbMode = GL_TRUE;
  
-		if ( db_modes[i] == GLX_NONE ) {

+   if ( db_modes[i] == GLX_NONE) {
modes->doubleBufferMode = GL_FALSE;
+modes->swapMethod = GLX_SWAP_UNDEFINED_OML;

The indentation of the added line doesn't match that of the previous
line. Patch 4 further changes this code (which is also what Brian's
comment was about AFAICT) to be even less consistently indented compared
to the surrounding code.


Hmm, Actually this looks awkward in the patches only due to me using 
spaces rather than tabs to indent in the new code (old code uses tabs).  
Not sure what the preferred strategy is here, use mesa coding style 
(spaces) or old dri coding style (tabs). If the latter, we should 
probably at some point add subsystem editor setup files that override 
the mesa default ones.




With that fixed in both patches, the series is





Reviewed-by: Michel Dänzer <michel.daen...@amd.com>



Thanks for reviewing!

Thomas



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 3/4] glx: Fix swap method config matching

2017-08-09 Thread Thomas Hellstrom
Due to bugs in dri swap method reporting, neither the fbconfigs received from
the server nor the value reported from driconfigs were correct. Now that's been
fixed and we can enable config swapmethod matching again.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 src/glx/dri_common.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 854733a..0f8f713 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -242,10 +242,8 @@ static const struct
   __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
   __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
   __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
-#if 0
   __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
-#endif
-__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
+  __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
   __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
   __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,
  bindToMipmapTexture),
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 4/4] dri: Introduce SWAP_METHOD tokens

2017-08-09 Thread Thomas Hellstrom
We shouldn't be using GLX tokens in the dri subsystem, so define dri
SWAP_METHOD tokens and translate when necessary. Unfortunately the X server
uses the dri swap method value untranslated as the GLX fbconfig swapMethod,
so we can't enumerate these tokens arbitrarily, but rather need to make them
have the same values as the corresponding GLX tokens.

Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
---
 include/GL/internal/dri_interface.h   | 12 
 src/gallium/state_trackers/dri/dri_screen.c   |  3 ++-
 src/glx/dri_common.c  | 13 +
 src/mesa/drivers/dri/common/utils.c   |  6 +++---
 src/mesa/drivers/dri/i915/intel_screen.c  |  2 +-
 src/mesa/drivers/dri/i965/intel_screen.c  |  2 +-
 src/mesa/drivers/dri/nouveau/nouveau_screen.c |  2 +-
 src/mesa/drivers/dri/radeon/radeon_screen.c   |  6 ++
 src/mesa/drivers/dri/swrast/swrast.c  |  2 +-
 9 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 5e8fce7..2cbd738 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -724,6 +724,18 @@ struct __DRIuseInvalidateExtensionRec {
 #define __DRI_ATTRIB_TEXTURE_2D_BIT0x02
 #define __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT 0x04
 
+/* __DRI_ATTRIB_SWAP_METHOD */
+/* Note that with the exception of __DRI_ATTRIB_SWAP_NONE, we need to define
+ * the same tokens as GLX. This is because old and current X servers will
+ * transmit the driconf value grabbed from the AIGLX driver untranslated as
+ * the GLX fbconfig value. __DRI_ATTRIB_SWAP_NONE is only used by dri drivers
+ * to signal to the dri core that the driconfig is single-buffer.
+ */
+#define __DRI_ATTRIB_SWAP_NONE  0x
+#define __DRI_ATTRIB_SWAP_EXCHANGE  0x8061
+#define __DRI_ATTRIB_SWAP_COPY  0x8062
+#define __DRI_ATTRIB_SWAP_UNDEFINED 0x8063
+
 /**
  * This extension defines the core DRI functionality.
  *
diff --git a/src/gallium/state_trackers/dri/dri_screen.c 
b/src/gallium/state_trackers/dri/dri_screen.c
index 406e97d..1d9f441 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -156,7 +156,8 @@ dri_fill_in_modes(struct dri_screen *screen)
boolean mixed_color_depth;
 
static const GLenum back_buffer_modes[] = {
-  GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+  __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED,
+  __DRI_ATTRIB_SWAP_COPY
};
 
if (driQueryOptionb(>dev->option_cache, 
"always_have_depth_buffer")) {
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 0f8f713..e2bbd48 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -317,6 +317,19 @@ driConfigEqual(const __DRIcoreExtension *core,
 return GL_FALSE;
  break;
 
+  case __DRI_ATTRIB_SWAP_METHOD:
+ if (value == __DRI_ATTRIB_SWAP_EXCHANGE)
+glxValue = GLX_SWAP_EXCHANGE_OML;
+ else if (value == __DRI_ATTRIB_SWAP_COPY)
+glxValue = GLX_SWAP_COPY_OML;
+ else
+glxValue = GLX_SWAP_UNDEFINED_OML;
+
+ if (!scalarEqual(config, attrib, glxValue))
+return GL_FALSE;
+
+ break;
+
   default:
  if (!scalarEqual(config, attrib, value))
 return GL_FALSE;
diff --git a/src/mesa/drivers/dri/common/utils.c 
b/src/mesa/drivers/dri/common/utils.c
index f3ea61e..1ad4a62 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -284,9 +284,9 @@ driCreateConfigs(mesa_format format,
modes->transparentIndex = GLX_DONT_CARE;
modes->rgbMode = GL_TRUE;
 
-   if ( db_modes[i] == GLX_NONE) {
-   modes->doubleBufferMode = GL_FALSE;
-modes->swapMethod = GLX_SWAP_UNDEFINED_OML;
+if ( db_modes[i] == __DRI_ATTRIB_SWAP_NONE ) {
+modes->doubleBufferMode = GL_FALSE;
+modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED;
}
else {
modes->doubleBufferMode = GL_TRUE;
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c 
b/src/mesa/drivers/dri/i915/intel_screen.c
index 367a734..6e32ac2 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -1060,7 +1060,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
 
/* GLX_SWAP_COPY_OML is not supported due to page flipping. */
static const GLenum back_buffer_modes[] = {
-   GLX_SWAP_UNDEFINED_OML, GLX_NONE,
+  __DRI_ATTRIB_SWAP_UNDEFINED, __DRI_ATTRIB_SWAP_NONE
};
 
static const uint8_t singlesample_samples[1] = {0};
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c 
b/src/mesa/drivers/dri

[Mesa-dev] [0/4] glx/dri: Attempt to fix GLX_OML_swap_method v2

2017-08-09 Thread Thomas Hellstrom
The current implementation was suffering from the following problems:
1) The driGetConfigAttribIndex function was not returning any value for
the driconfig swapMethod.
2) The X server GLX code is using the value obtained from
the AIGLX dri driver driGetConfigAttribIndex to populate its GLX fbconfig.
3) The client side GLX code was assuming fbconfig and driconfig match
regardless of whether there actually was a swapMethod match.
4) We were using GLX tokens in the dri code.
5) dri3 does currently not support GLX_SWAP_COPY_OML, even if that's
advertized by the gallium dri2 state tracker.

Attempt to fix 1-4. Some highlights:

Because of 1) in combination with 2), if the X server uses an AIGLX dri driver
that doesn't have this fix, the GLX transmitted fbconfig swapMethod value will
be bogus. So if we, on the client side detect a bogus value, change it to
GLX_SWAP_UNDEFINED_OML.

v2: Split the single patch into four patches.


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


  1   2   3   4   >