Mesa (main): d3d12: Allow creating planar resources

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Dec 8 20:58:21 UTC 2021


Module: Mesa
Branch: main
Commit: 0312142d96459fd23e3ee164cb9410f671c6f361
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0312142d96459fd23e3ee164cb9410f671c6f361

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Thu Sep 23 08:37:59 2021 -0700

d3d12: Allow creating planar resources

Also handle opening planar resources with a single handle, instead
of per-plane handles.

Reviewed-by: Sil Vilerino <sivileri at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14123>

---

 src/gallium/drivers/d3d12/d3d12_resource.cpp | 54 +++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp
index 6f0e07441e7..f6ce28d4afa 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp
@@ -253,6 +253,48 @@ init_texture(struct d3d12_screen *screen,
    return true;
 }
 
+static void
+convert_planar_resource(struct d3d12_resource *res)
+{
+   unsigned num_planes = util_format_get_num_planes(res->base.b.format);
+   if (num_planes <= 1 || res->base.b.next || !res->bo)
+      return;
+
+   struct pipe_resource *next = nullptr;
+   struct pipe_resource *planes[3] = {
+      &res->base.b, nullptr, nullptr
+   };
+   for (int plane = num_planes - 1; plane >= 0; --plane) {
+      struct d3d12_resource *plane_res = d3d12_resource(planes[plane]);
+      if (!plane_res) {
+         plane_res = CALLOC_STRUCT(d3d12_resource);
+         *plane_res = *res;
+         d3d12_bo_reference(plane_res->bo);
+         pipe_reference_init(&plane_res->base.b.reference, 1);
+         threaded_resource_init(&plane_res->base.b, false, 0);
+      }
+
+      plane_res->base.b.next = next;
+      next = &plane_res->base.b;
+
+      plane_res->base.b.format = util_format_get_plane_format(res->base.b.format, plane);
+      plane_res->base.b.width0 = util_format_get_plane_width(res->base.b.format, plane, res->base.b.width0);
+      plane_res->base.b.height0 = util_format_get_plane_height(res->base.b.format, plane, res->base.b.height0);
+
+#if DEBUG
+      struct d3d12_screen *screen = d3d12_screen(res->base.b.screen);
+      D3D12_RESOURCE_DESC desc = res->bo->res->GetDesc();
+      D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed_footprint = {};
+      D3D12_SUBRESOURCE_FOOTPRINT *footprint = &placed_footprint.Footprint;
+      unsigned subresource = plane * desc.MipLevels * desc.DepthOrArraySize;
+      screen->dev->GetCopyableFootprints(&desc, subresource, 1, 0, &placed_footprint, nullptr, nullptr, nullptr);
+      assert(plane_res->base.b.width0 == footprint->Width);
+      assert(plane_res->base.b.height0 == footprint->Height);
+      assert(plane_res->base.b.depth0 == footprint->Depth);
+#endif
+   }
+}
+
 static struct pipe_resource *
 d3d12_resource_create(struct pipe_screen *pscreen,
                       const struct pipe_resource *templ)
@@ -291,6 +333,8 @@ d3d12_resource_create(struct pipe_screen *pscreen,
 
    memset(&res->bind_counts, 0, sizeof(d3d12_resource::bind_counts));
 
+   convert_planar_resource(res);
+
    return &res->base.b;
 }
 
@@ -346,9 +390,14 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
    incoming_res_desc = d3d12_res->GetDesc();
 
    /* Get a description for this plane */
-   {
+   if (templ && handle->format != templ->format) {
       unsigned subresource = handle->plane * incoming_res_desc.MipLevels * incoming_res_desc.DepthOrArraySize;
       screen->dev->GetCopyableFootprints(&incoming_res_desc, subresource, 1, 0, &placed_footprint, nullptr, nullptr, nullptr);
+   } else {
+      footprint->Format = incoming_res_desc.Format;
+      footprint->Width = incoming_res_desc.Width;
+      footprint->Height = incoming_res_desc.Height;
+      footprint->Depth = incoming_res_desc.DepthOrArraySize;
    }
 
    if (footprint->Width > UINT32_MAX ||
@@ -478,7 +527,10 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
       res->bo = d3d12_bo_wrap_res(d3d12_res, res->overall_format);
    }
    init_valid_range(res);
+
    threaded_resource_init(&res->base.b, false, 0);
+   convert_planar_resource(res);
+
    return &res->base.b;
 
 invalid:



More information about the mesa-commit mailing list