Mesa (main): d3d12: Handle opening planar resources

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


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

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Thu Sep 23 07:42:04 2021 -0700

d3d12: Handle opening planar resources

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

---

 src/gallium/drivers/d3d12/d3d12_format.c     |  6 ++-
 src/gallium/drivers/d3d12/d3d12_resource.cpp | 59 +++++++++++++++++++++++-----
 src/gallium/drivers/d3d12/d3d12_resource.h   |  1 +
 3 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_format.c b/src/gallium/drivers/d3d12/d3d12_format.c
index b0537a97c34..cee66c28dde 100644
--- a/src/gallium/drivers/d3d12/d3d12_format.c
+++ b/src/gallium/drivers/d3d12/d3d12_format.c
@@ -28,6 +28,8 @@
 #include "util/u_math.h"
 #include "util/compiler.h"
 
+#define MAP_FORMAT_YUV(NAME) \
+   [PIPE_FORMAT_ ## NAME] = DXGI_FORMAT_ ## NAME,
 #define MAP_FORMAT_NO_TYPELESS(BITS, TYPE) \
    [PIPE_FORMAT_ ## BITS ## _ ## TYPE] = DXGI_FORMAT_ ## BITS ## _ ## TYPE,
 #define MAP_FORMAT2_NO_TYPELESS(BITS1, TYPE1, BITS2, TYPE2) \
@@ -160,7 +162,9 @@
 \
    MAP_FORMAT2(Z24_UNORM_S8, UINT, R24G8, TYPELESS) \
    MAP_FORMAT2(Z32_FLOAT_S8X24, UINT, R32G8X24, TYPELESS) \
-   MAP_FORMAT2(X32_S8X24, UINT, R32G8X24, TYPELESS)
+   MAP_FORMAT2(X32_S8X24, UINT, R32G8X24, TYPELESS) \
+\
+   MAP_FORMAT_YUV(NV12)
 
 static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
    FORMAT_TABLE()
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp
index d5e36e9f145..6f0e07441e7 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp
@@ -262,6 +262,7 @@ d3d12_resource_create(struct pipe_screen *pscreen,
    bool ret;
 
    res->base.b = *templ;
+   res->overall_format = templ->format;
 
    if (D3D12_DEBUG_RESOURCE & d3d12_debug) {
       debug_printf("D3D12: Create %sresource %s@%d %dx%dx%d as:%d mip:%d\n",
@@ -298,6 +299,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
                           const struct pipe_resource *templ,
                           struct winsys_handle *handle, unsigned usage)
 {
+   struct d3d12_screen *screen = d3d12_screen(pscreen);
    if (handle->type != WINSYS_HANDLE_TYPE_D3D12_RES &&
        handle->type != WINSYS_HANDLE_TYPE_FD)
       return NULL;
@@ -306,11 +308,22 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
    if (!res)
       return NULL;
 
+   if (templ && templ->next) {
+      struct d3d12_resource* next = d3d12_resource(templ->next);
+      if (next->bo) {
+         res->base.b = *templ;
+         res->bo = next->bo;
+         d3d12_bo_reference(res->bo);
+      }
+   }
+
    pipe_reference_init(&res->base.b.reference, 1);
    res->base.b.screen = pscreen;
 
    ID3D12Resource *d3d12_res = nullptr;
-   if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) {
+   if (res->bo) {
+      d3d12_res = res->bo->res;
+   } else if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) {
       d3d12_res = (ID3D12Resource *)handle->com_obj;
    } else {
       struct d3d12_screen *screen = d3d12_screen(pscreen);
@@ -323,14 +336,23 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
       screen->dev->OpenSharedHandle(d3d_handle, IID_PPV_ARGS(&d3d12_res));
    }
 
+   D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed_footprint = {};
+   D3D12_SUBRESOURCE_FOOTPRINT *footprint = &placed_footprint.Footprint;
    D3D12_RESOURCE_DESC incoming_res_desc;
 
    if (!d3d12_res)
       goto invalid;
 
    incoming_res_desc = d3d12_res->GetDesc();
-   if (incoming_res_desc.Width > UINT32_MAX ||
-       incoming_res_desc.Height > UINT16_MAX) {
+
+   /* Get a description for this plane */
+   {
+      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);
+   }
+
+   if (footprint->Width > UINT32_MAX ||
+       footprint->Height > UINT16_MAX) {
       debug_printf("d3d12: Importing resource too large\n");
       goto invalid;
    }
@@ -358,7 +380,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
       break;
    case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
       res->base.b.target = PIPE_TEXTURE_3D;
-      res->base.b.depth0 = incoming_res_desc.DepthOrArraySize;
+      res->base.b.depth0 = footprint->Depth;
       break;
    default:
       unreachable("Invalid dimension");
@@ -408,12 +430,18 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
             res->base.b.last_level + 1, templ->last_level + 1);
          goto invalid;
       }
-      if (incoming_res_desc.Format != d3d12_get_format(templ->format) &&
-          incoming_res_desc.Format != d3d12_get_typeless_format(templ->format)) {
+      if ((footprint->Format != d3d12_get_format(templ->format) &&
+           footprint->Format != d3d12_get_typeless_format(templ->format)) ||
+          (incoming_res_desc.Format != d3d12_get_format((enum pipe_format)handle->format) &&
+           incoming_res_desc.Format != d3d12_get_typeless_format((enum pipe_format)handle->format))) {
          debug_printf("d3d12: Importing resource with mismatched format: "
-            "could be DXGI format %d or %d, but is %d\n",
+            "plane could be DXGI format %d or %d, but is %d, "
+            "overall could be DXGI format %d or %d, but is %d\n",
             d3d12_get_format(templ->format),
             d3d12_get_typeless_format(templ->format),
+            footprint->Format,
+            d3d12_get_format((enum pipe_format)handle->format),
+            d3d12_get_typeless_format((enum pipe_format)handle->format),
             incoming_res_desc.Format);
          goto invalid;
       }
@@ -423,6 +451,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
       }
 
       res->base.b.format = templ->format;
+      res->overall_format = (enum pipe_format)handle->format;
    } else {
       /* Search the pipe format lookup table for an entry */
       res->base.b.format = d3d12_get_pipe_format(incoming_res_desc.Format);
@@ -436,16 +465,26 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
             goto invalid;
          }
       }
+
+      res->overall_format = res->base.b.format;
    }
 
-   res->dxgi_format = d3d12_get_format(res->base.b.format);
-   res->bo = d3d12_bo_wrap_res(d3d12_res, res->base.b.format);
+   if (!templ)
+      handle->format = res->overall_format;
+
+   res->dxgi_format = d3d12_get_format(res->overall_format);
+
+   if (!res->bo) {
+      res->bo = d3d12_bo_wrap_res(d3d12_res, res->overall_format);
+   }
    init_valid_range(res);
    threaded_resource_init(&res->base.b, false, 0);
    return &res->base.b;
 
 invalid:
-   if (d3d12_res)
+   if (res->bo)
+      d3d12_bo_unreference(res->bo);
+   else if (d3d12_res)
       d3d12_res->Release();
    FREE(res);
    return NULL;
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.h b/src/gallium/drivers/d3d12/d3d12_resource.h
index 97586f880ed..49b707739e7 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.h
+++ b/src/gallium/drivers/d3d12/d3d12_resource.h
@@ -42,6 +42,7 @@ struct d3d12_resource {
    struct threaded_resource base;
    struct d3d12_bo *bo;
    DXGI_FORMAT dxgi_format;
+   enum pipe_format overall_format;
    unsigned mip_levels;
    struct sw_displaytarget *dt;
    unsigned dt_stride;



More information about the mesa-commit mailing list