Mesa (master): d3d12: Use buffer pipe usage to inform allocation

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 5 23:03:11 UTC 2021


Module: Mesa
Branch: master
Commit: ee1463db3c829a00040d4436befd6cd2f9ac4c01
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ee1463db3c829a00040d4436befd6cd2f9ac4c01

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Mon Dec 14 11:53:13 2020 -0800

d3d12: Use buffer pipe usage to inform allocation

For non-CPU-accessible pipe resource types (DEFAULT/IMMUTABLE),
allocate non-CPU-accessible buffers directly from the cache_bufmgr.
Update the d3d12_bo creation to handle nonmappable buffers.

For CPU-write-only (DYNAMIC/STREAM), use the upload slab_bufmgr.
Update this slab manager to use CPU_WRITE | GPU_READ PB usage.

For CPU-read-write (STAGING), use the readback_slab_bufmgr.

Reviewed-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8095>

---

 src/gallium/drivers/d3d12/d3d12_bufmgr.cpp   | 26 +++++++++++++++++---------
 src/gallium/drivers/d3d12/d3d12_context.cpp  |  5 +++--
 src/gallium/drivers/d3d12/d3d12_resource.cpp | 26 +++++++++++++++++++++-----
 src/gallium/drivers/d3d12/d3d12_screen.cpp   |  2 +-
 4 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
index f48f677aab3..0144410a234 100644
--- a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
@@ -88,14 +88,14 @@ d3d12_bo_wrap_res(ID3D12Resource *res, enum pipe_format format)
 }
 
 struct d3d12_bo *
-d3d12_bo_new(ID3D12Device *dev, uint64_t size, uint64_t alignment)
+d3d12_bo_new(ID3D12Device *dev, uint64_t size, const pb_desc *pb_desc)
 {
    ID3D12Resource *res;
 
    D3D12_RESOURCE_DESC res_desc;
    res_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
    res_desc.Format = DXGI_FORMAT_UNKNOWN;
-   res_desc.Alignment = alignment;
+   res_desc.Alignment = pb_desc->alignment;
    res_desc.Width = size;
    res_desc.Height = 1;
    res_desc.DepthOrArraySize = 1;
@@ -105,7 +105,13 @@ d3d12_bo_new(ID3D12Device *dev, uint64_t size, uint64_t alignment)
    res_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
    res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
 
-   D3D12_HEAP_PROPERTIES heap_pris = dev->GetCustomHeapProperties(0, D3D12_HEAP_TYPE_UPLOAD);
+   D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_DEFAULT;
+   if (pb_desc->usage & PB_USAGE_CPU_READ)
+      heap_type = D3D12_HEAP_TYPE_READBACK;
+   else if (pb_desc->usage & PB_USAGE_CPU_WRITE)
+      heap_type = D3D12_HEAP_TYPE_UPLOAD;
+
+   D3D12_HEAP_PROPERTIES heap_pris = dev->GetCustomHeapProperties(0, heap_type);
    HRESULT hres = dev->CreateCommittedResource(&heap_pris,
                                                D3D12_HEAP_FLAG_NONE,
                                                &res_desc,
@@ -287,17 +293,19 @@ d3d12_bufmgr_create_buffer(struct pb_manager *pmgr,
    buf->range.Begin = 0;
    buf->range.End = size;
 
-   buf->bo = d3d12_bo_new(mgr->dev, size, pb_desc->alignment);
+   buf->bo = d3d12_bo_new(mgr->dev, size, pb_desc);
    if (!buf->bo) {
       FREE(buf);
       return NULL;
    }
 
-   buf->map = d3d12_bo_map(buf->bo, &buf->range);
-   if (!buf->map) {
-      d3d12_bo_unreference(buf->bo);
-      FREE(buf);
-      return NULL;
+   if (pb_desc->usage & PB_USAGE_CPU_READ_WRITE) {
+      buf->map = d3d12_bo_map(buf->bo, &buf->range);
+      if (!buf->map) {
+         d3d12_bo_unreference(buf->bo);
+         FREE(buf);
+         return NULL;
+      }
    }
 
    return &buf->base;
diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp
index 7bc1ff428de..944341b0169 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_context.cpp
@@ -1313,8 +1313,9 @@ d3d12_create_stream_output_target(struct pipe_context *pctx,
    cso->base.buffer_size = buffer_size;
    cso->base.context = pctx;
 
-   util_range_add(pres, &res->valid_buffer_range, buffer_offset,
-                  buffer_offset + buffer_size);
+   if (res->bo && res->bo->buffer && d3d12_buffer(res->bo->buffer)->map)
+      util_range_add(pres, &res->valid_buffer_range, buffer_offset,
+                     buffer_offset + buffer_size);
 
    return &cso->base;
 }
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp
index 7ec82ab438e..6f15d4f92ab 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp
@@ -46,7 +46,9 @@ static bool
 can_map_directly(struct pipe_resource *pres)
 {
    return pres->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_LINEAR) ||
-          pres->target == PIPE_BUFFER;
+         (pres->target == PIPE_BUFFER &&
+          pres->usage != PIPE_USAGE_DEFAULT &&
+          pres->usage != PIPE_USAGE_IMMUTABLE);
 }
 
 static void
@@ -118,11 +120,25 @@ init_buffer(struct d3d12_screen *screen,
     * element state */
    assert(templ->format == d3d12_emulated_vtx_format(templ->format));
 
-   /* Don't use slab buffer manager for GPU writable buffers */
-   bufmgr = templ->bind & PIPE_BIND_STREAM_OUTPUT ? screen->cache_bufmgr
-                                                  : screen->slab_bufmgr;
+   switch (templ->usage) {
+   case PIPE_USAGE_DEFAULT:
+   case PIPE_USAGE_IMMUTABLE:
+      bufmgr = screen->cache_bufmgr;
+      buf_desc.usage = (pb_usage_flags)PB_USAGE_GPU_READ_WRITE;
+      break;
+   case PIPE_USAGE_DYNAMIC:
+   case PIPE_USAGE_STREAM:
+      bufmgr = screen->slab_bufmgr;
+      buf_desc.usage = (pb_usage_flags)(PB_USAGE_CPU_WRITE | PB_USAGE_GPU_READ);
+      break;
+   case PIPE_USAGE_STAGING:
+      bufmgr = screen->readback_slab_bufmgr;
+      buf_desc.usage = (pb_usage_flags)(PB_USAGE_GPU_WRITE | PB_USAGE_CPU_READ_WRITE);
+      break;
+   default:
+      unreachable("Invalid pipe usage");
+   }
    buf_desc.alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
-   buf_desc.usage = (pb_usage_flags)PB_USAGE_ALL;
    res->dxgi_format = DXGI_FORMAT_UNKNOWN;
    buf = bufmgr->create_buffer(bufmgr, templ->width0, &buf_desc);
    if (!buf)
diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp
index 0cb388277e2..44e44729440 100644
--- a/src/gallium/drivers/d3d12/d3d12_screen.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp
@@ -863,7 +863,7 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow
 
    struct pb_desc desc;
    desc.alignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT;
-   desc.usage = (pb_usage_flags)PB_USAGE_ALL;
+   desc.usage = (pb_usage_flags)(PB_USAGE_CPU_WRITE | PB_USAGE_GPU_READ);
 
    screen->bufmgr = d3d12_bufmgr_create(screen);
    screen->cache_bufmgr = pb_cache_manager_create(screen->bufmgr, 0xfffff, 2, 0, 64 * 1024 * 1024);



More information about the mesa-commit mailing list