[Mesa-dev] [PATCH 04/14] gallium/radeon: add RADEON_FLAG_HANDLE

Nicolai Hähnle nhaehnle at gmail.com
Tue Sep 13 09:56:15 UTC 2016


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

When passed to winsys->buffer_create, this flag will indicate that we require
a buffer that maps 1:1 with a kernel buffer handle.

This is currently set for all textures, since textures can potentially be
exported to other processes. This is not a huge loss, since the main purpose
of this patch series is to deal with applications that allocate many small
buffers.

A hypothetical application with tons of tiny textures might still benefit
from not setting this flag, but that's not a use case I'm worried about
just now.
---
 src/gallium/drivers/r300/r300_texture.c       | 2 +-
 src/gallium/drivers/radeon/r600_texture.c     | 2 ++
 src/gallium/drivers/radeon/radeon_winsys.h    | 1 +
 src/gallium/winsys/amdgpu/drm/amdgpu_bo.c     | 3 +++
 src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 3 +++
 src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 2 +-
 6 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 5f459e4..fbac07a 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -1107,21 +1107,21 @@ r300_texture_create_object(struct r300_screen *rscreen,
         tex->domain &= ~RADEON_DOMAIN_GTT;
     }
     /* Just fail if the texture is too large. */
     if (!tex->domain) {
         goto fail;
     }
 
     /* Create the backing buffer if needed. */
     if (!tex->buf) {
         tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048,
-                                      tex->domain, 0);
+                                      tex->domain, RADEON_FLAG_HANDLE);
 
         if (!tex->buf) {
             goto fail;
         }
     }
 
     if (SCREEN_DBG_ON(rscreen, DBG_MSAA) && base->nr_samples > 1) {
         fprintf(stderr, "r300: %ix MSAA %s buffer created\n",
                 base->nr_samples,
                 util_format_is_depth_or_stencil(base->format) ? "depth" : "color");
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 41fd94b..b6e5880 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1105,20 +1105,22 @@ r600_texture_create_object(struct pipe_screen *screen,
 			rtex->dcc_offset = align64(rtex->size, rtex->surface.dcc_alignment);
 			rtex->size = rtex->dcc_offset + rtex->surface.dcc_size;
 		}
 	}
 
 	/* Now create the backing buffer. */
 	if (!buf) {
 		r600_init_resource_fields(rscreen, resource, rtex->size,
 					  rtex->surface.bo_alignment);
 
+		resource->flags |= RADEON_FLAG_HANDLE;
+
 		if (!r600_alloc_resource(rscreen, resource)) {
 			FREE(rtex);
 			return NULL;
 		}
 	} else {
 		resource->buf = buf;
 		resource->gpu_address = rscreen->ws->buffer_get_virtual_address(resource->buf);
 		resource->domains = rscreen->ws->buffer_get_initial_domain(resource->buf);
 	}
 
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index 809a203..8196358 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -45,20 +45,21 @@ enum radeon_bo_layout {
 enum radeon_bo_domain { /* bitfield */
     RADEON_DOMAIN_GTT  = 2,
     RADEON_DOMAIN_VRAM = 4,
     RADEON_DOMAIN_VRAM_GTT = RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GTT
 };
 
 enum radeon_bo_flag { /* bitfield */
     RADEON_FLAG_GTT_WC =        (1 << 0),
     RADEON_FLAG_CPU_ACCESS =    (1 << 1),
     RADEON_FLAG_NO_CPU_ACCESS = (1 << 2),
+    RADEON_FLAG_HANDLE =        (1 << 3), /* whether get_handle must be supported */
 };
 
 enum radeon_bo_usage { /* bitfield */
     RADEON_USAGE_READ = 2,
     RADEON_USAGE_WRITE = 4,
     RADEON_USAGE_READWRITE = RADEON_USAGE_READ | RADEON_USAGE_WRITE,
 
     /* The winsys ensures that the CS submission will be scheduled after
      * previously flushed CSs referencing this BO in a conflicting way.
      */
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
index 5b099b0..0dbd0fb 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
@@ -501,20 +501,23 @@ static struct pb_buffer *
 amdgpu_bo_create(struct radeon_winsys *rws,
                  uint64_t size,
                  unsigned alignment,
                  enum radeon_bo_domain domain,
                  enum radeon_bo_flag flags)
 {
    struct amdgpu_winsys *ws = amdgpu_winsys(rws);
    struct amdgpu_winsys_bo *bo;
    unsigned usage = 0, pb_cache_bucket;
 
+   /* This flag is irrelevant for the cache. */
+   flags &= ~RADEON_FLAG_HANDLE;
+
    /* Align size to page size. This is the minimum alignment for normal
     * BOs. Aligning this here helps the cached bufmgr. Especially small BOs,
     * like constant/uniform buffers, can benefit from better and more reuse.
     */
    size = align64(size, ws->info.gart_page_size);
    alignment = align(alignment, ws->info.gart_page_size);
 
    /* Only set one usage bit each for domains and flags, or the cache manager
     * might consider different sets of domains / flags compatible
     */
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 5db2061..db92035 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -743,20 +743,23 @@ radeon_winsys_bo_create(struct radeon_winsys *rws,
                         enum radeon_bo_flag flags)
 {
     struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
     struct radeon_bo *bo;
     unsigned usage = 0, pb_cache_bucket;
 
     /* Only 32-bit sizes are supported. */
     if (size > UINT_MAX)
         return NULL;
 
+    /* This flag is irrelevant for the cache. */
+    flags &= ~RADEON_FLAG_HANDLE;
+
     /* Align size to page size. This is the minimum alignment for normal
      * BOs. Aligning this here helps the cached bufmgr. Especially small BOs,
      * like constant/uniform buffers, can benefit from better and more reuse.
      */
     size = align(size, ws->info.gart_page_size);
     alignment = align(alignment, ws->info.gart_page_size);
 
     /* Only set one usage bit each for domains and flags, or the cache manager
      * might consider different sets of domains / flags compatible
      */
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index c4933f0..a3b03be 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -613,21 +613,21 @@ static bool radeon_bo_is_referenced(struct radeon_winsys_cs *rcs,
 /* FENCES */
 
 static struct pipe_fence_handle *
 radeon_cs_create_fence(struct radeon_winsys_cs *rcs)
 {
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     struct pb_buffer *fence;
 
     /* Create a fence, which is a dummy BO. */
     fence = cs->ws->base.buffer_create(&cs->ws->base, 1, 1,
-                                       RADEON_DOMAIN_GTT, 0);
+                                       RADEON_DOMAIN_GTT, RADEON_FLAG_HANDLE);
     /* Add the fence as a dummy relocation. */
     cs->ws->base.cs_add_buffer(rcs, fence,
                               RADEON_USAGE_READWRITE, RADEON_DOMAIN_GTT,
                               RADEON_PRIO_FENCE);
     return (struct pipe_fence_handle*)fence;
 }
 
 static bool radeon_fence_wait(struct radeon_winsys *ws,
                               struct pipe_fence_handle *fence,
                               uint64_t timeout)
-- 
2.7.4



More information about the mesa-dev mailing list