From a6db80546945f787646cb1d8ce7bab23a57ffa54 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 23 Sep 2021 07:42:04 -0700 Subject: [PATCH] d3d12: Handle opening planar resources Reviewed-by: Sil Vilerino Part-of: --- 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;