d3d12: Implement resource_from_memobj

If the memobj wraps a resource, then we only succeed the
mapping operation if the gallium desc matches the D3D12
resource desc.

If the memobj wraps a heap, then we can place whatever
gallium is describing on the heap.

Reviewed-by: Bill Kristiansen <billkris@microsoft.com>
Reviewed-by: Giancarlo Devich <gdevich@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17446>
This commit is contained in:
Jesse Natalie
2022-07-09 18:53:53 -07:00
committed by Marge Bot
parent bd0407a4a6
commit d462325895
3 changed files with 96 additions and 32 deletions

View File

@@ -2618,7 +2618,6 @@ spec/ext_direct_state_access/named-buffers 15/mapnamedbufferrangeext: skip
spec/ext_direct_state_access/named-buffers 15/namedcopybuffersubdataext: skip spec/ext_direct_state_access/named-buffers 15/namedcopybuffersubdataext: skip
spec/ext_disjoint_timer_query/simple: skip spec/ext_disjoint_timer_query/simple: skip
spec/ext_draw_instanced/ext_draw_instanced-drawarrays: skip spec/ext_draw_instanced/ext_draw_instanced-drawarrays: skip
spec/ext_external_objects/memory-object-api-errors: skip
spec/ext_external_objects/semaphore-api-errors: skip spec/ext_external_objects/semaphore-api-errors: skip
spec/ext_external_objects/vk-buf-exchange: skip spec/ext_external_objects/vk-buf-exchange: skip
spec/ext_external_objects/vk-depth-display: skip spec/ext_external_objects/vk-depth-display: skip
@@ -3517,10 +3516,10 @@ wgl/wgl-sanity: skip
summary: summary:
name: results name: results
---- -------- ---- --------
pass: 17853 pass: 17866
fail: 2035 fail: 2035
crash: 12 crash: 12
skip: 1450 skip: 1449
timeout: 0 timeout: 0
warn: 10 warn: 10
incomplete: 0 incomplete: 0
@@ -3529,4 +3528,4 @@ summary:
changes: 0 changes: 0
fixes: 0 fixes: 0
regressions: 0 regressions: 0
total: 21369 total: 21381

View File

@@ -167,7 +167,9 @@ init_buffer(struct d3d12_screen *screen,
static bool static bool
init_texture(struct d3d12_screen *screen, init_texture(struct d3d12_screen *screen,
struct d3d12_resource *res, struct d3d12_resource *res,
const struct pipe_resource *templ) const struct pipe_resource *templ,
ID3D12Heap *heap,
uint64_t placed_offset)
{ {
ID3D12Resource *d3d12_res; ID3D12Resource *d3d12_res;
@@ -183,9 +185,18 @@ init_texture(struct d3d12_screen *screen,
desc.MipLevels = templ->last_level + 1; desc.MipLevels = templ->last_level + 1;
desc.SampleDesc.Count = MAX2(templ->nr_samples, 1); desc.SampleDesc.Count = MAX2(templ->nr_samples, 1);
desc.SampleDesc.Quality = 0; /* TODO: figure this one out */ desc.SampleDesc.Quality = 0;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
switch (templ->target) { switch (templ->target) {
case PIPE_BUFFER:
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
break;
case PIPE_TEXTURE_1D: case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_1D_ARRAY:
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D; desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D;
@@ -210,8 +221,6 @@ init_texture(struct d3d12_screen *screen,
unreachable("Invalid texture type"); unreachable("Invalid texture type");
} }
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (templ->bind & PIPE_BIND_SHADER_BUFFER) if (templ->bind & PIPE_BIND_SHADER_BUFFER)
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
@@ -241,23 +250,35 @@ init_texture(struct d3d12_screen *screen,
} }
} }
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
if (templ->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_LINEAR)) if (templ->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_LINEAR))
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
HRESULT hres = E_FAIL;
enum d3d12_residency_status init_residency;
if (heap) {
init_residency = d3d12_permanently_resident;
hres = screen->dev->CreatePlacedResource(heap,
placed_offset,
&desc,
D3D12_RESOURCE_STATE_COMMON,
nullptr,
IID_PPV_ARGS(&d3d12_res));
} else {
D3D12_HEAP_PROPERTIES heap_pris = screen->dev->GetCustomHeapProperties(0, D3D12_HEAP_TYPE_DEFAULT); D3D12_HEAP_PROPERTIES heap_pris = screen->dev->GetCustomHeapProperties(0, D3D12_HEAP_TYPE_DEFAULT);
D3D12_HEAP_FLAGS heap_flags = screen->support_create_not_resident ? D3D12_HEAP_FLAGS heap_flags = screen->support_create_not_resident ?
D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT : D3D12_HEAP_FLAG_NONE; D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT : D3D12_HEAP_FLAG_NONE;
enum d3d12_residency_status init_residency = screen->support_create_not_resident ? init_residency = screen->support_create_not_resident ? d3d12_evicted : d3d12_resident;
d3d12_evicted : d3d12_resident;
HRESULT hres = screen->dev->CreateCommittedResource(&heap_pris, hres = screen->dev->CreateCommittedResource(&heap_pris,
heap_flags, heap_flags,
&desc, &desc,
D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COMMON,
NULL, NULL,
IID_PPV_ARGS(&d3d12_res)); IID_PPV_ARGS(&d3d12_res));
}
if (FAILED(hres)) if (FAILED(hres))
return false; return false;
@@ -322,14 +343,16 @@ convert_planar_resource(struct d3d12_resource *res)
} }
static struct pipe_resource * static struct pipe_resource *
d3d12_resource_create(struct pipe_screen *pscreen, d3d12_resource_create_or_place(struct d3d12_screen *screen,
const struct pipe_resource *templ) struct d3d12_resource *res,
const struct pipe_resource *templ,
ID3D12Heap *heap,
uint64_t placed_offset)
{ {
struct d3d12_screen *screen = d3d12_screen(pscreen);
struct d3d12_resource *res = CALLOC_STRUCT(d3d12_resource);
bool ret; bool ret;
res->base.b = *templ; res->base.b = *templ;
res->overall_format = templ->format; res->overall_format = templ->format;
res->plane_slice = 0; res->plane_slice = 0;
res->first_plane = &res->base.b; res->first_plane = &res->base.b;
@@ -343,12 +366,12 @@ d3d12_resource_create(struct pipe_screen *pscreen,
} }
pipe_reference_init(&res->base.b.reference, 1); pipe_reference_init(&res->base.b.reference, 1);
res->base.b.screen = pscreen; res->base.b.screen = &screen->base;
if (templ->target == PIPE_BUFFER) { if (templ->target == PIPE_BUFFER && !heap) {
ret = init_buffer(screen, res, templ); ret = init_buffer(screen, res, templ);
} else { } else {
ret = init_texture(screen, res, templ); ret = init_texture(screen, res, templ, heap, placed_offset);
} }
if (!ret) { if (!ret) {
@@ -368,6 +391,17 @@ d3d12_resource_create(struct pipe_screen *pscreen,
return &res->base.b; return &res->base.b;
} }
static struct pipe_resource *
d3d12_resource_create(struct pipe_screen *pscreen,
const struct pipe_resource *templ)
{
struct d3d12_resource *res = CALLOC_STRUCT(d3d12_resource);
if (!res)
return NULL;
return d3d12_resource_create_or_place(d3d12_screen(pscreen), res, templ, nullptr, 0);
}
static struct pipe_resource * static struct pipe_resource *
d3d12_resource_from_handle(struct pipe_screen *pscreen, d3d12_resource_from_handle(struct pipe_screen *pscreen,
const struct pipe_resource *templ, const struct pipe_resource *templ,
@@ -391,14 +425,15 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
} }
} }
pipe_reference_init(&res->base.b.reference, 1);
res->base.b.screen = pscreen;
ID3D12Resource *d3d12_res = nullptr; ID3D12Resource *d3d12_res = nullptr;
ID3D12Heap *d3d12_heap = nullptr;
if (res->bo) { if (res->bo) {
d3d12_res = res->bo->res; d3d12_res = res->bo->res;
} else if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) { } else if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) {
d3d12_res = (ID3D12Resource *)handle->com_obj; IUnknown *obj = (IUnknown *)handle->com_obj;
(void)obj->QueryInterface(&d3d12_res);
(void)obj->QueryInterface(&d3d12_heap);
obj->Release();
} else { } else {
struct d3d12_screen *screen = d3d12_screen(pscreen); struct d3d12_screen *screen = d3d12_screen(pscreen);
@@ -414,9 +449,18 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
D3D12_SUBRESOURCE_FOOTPRINT *footprint = &placed_footprint.Footprint; D3D12_SUBRESOURCE_FOOTPRINT *footprint = &placed_footprint.Footprint;
D3D12_RESOURCE_DESC incoming_res_desc; D3D12_RESOURCE_DESC incoming_res_desc;
if (!d3d12_res) if (!d3d12_res && !d3d12_heap)
goto invalid; goto invalid;
if (d3d12_heap) {
assert(templ);
assert(!res->bo);
assert(!d3d12_res);
return d3d12_resource_create_or_place(screen, res, templ, d3d12_heap, handle->offset);
}
pipe_reference_init(&res->base.b.reference, 1);
res->base.b.screen = pscreen;
incoming_res_desc = d3d12_res->GetDesc(); incoming_res_desc = d3d12_res->GetDesc();
/* Get a description for this plane */ /* Get a description for this plane */
@@ -817,6 +861,25 @@ d3d12_memobj_destroy(struct pipe_screen *pscreen, struct pipe_memory_object *pme
free(memobj); free(memobj);
} }
static pipe_resource *
d3d12_resource_from_memobj(struct pipe_screen *pscreen,
const struct pipe_resource *templ,
struct pipe_memory_object *pmemobj,
uint64_t offset)
{
struct d3d12_memory_object *memobj = d3d12_memory_object(pmemobj);
struct winsys_handle whandle = {};
whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
whandle.com_obj = memobj->res ? (void *) memobj->res : (void *) memobj->heap;
whandle.offset = offset;
whandle.format = templ->format;
// WINSYS_HANDLE_TYPE_D3D12_RES implies taking ownership of the reference
((IUnknown *)whandle.com_obj)->AddRef();
return d3d12_resource_from_handle(pscreen, templ, &whandle, 0);
}
void void
d3d12_screen_resource_init(struct pipe_screen *pscreen) d3d12_screen_resource_init(struct pipe_screen *pscreen)
{ {
@@ -828,6 +891,7 @@ d3d12_screen_resource_init(struct pipe_screen *pscreen)
pscreen->memobj_create_from_handle = d3d12_memobj_create_from_handle; pscreen->memobj_create_from_handle = d3d12_memobj_create_from_handle;
pscreen->memobj_destroy = d3d12_memobj_destroy; pscreen->memobj_destroy = d3d12_memobj_destroy;
pscreen->resource_from_memobj = d3d12_resource_from_memobj;
} }
unsigned int unsigned int

View File

@@ -326,6 +326,7 @@ d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_DOUBLES: case PIPE_CAP_DOUBLES:
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
case PIPE_CAP_MEMOBJ:
return 1; return 1;
case PIPE_CAP_MAX_VERTEX_STREAMS: case PIPE_CAP_MAX_VERTEX_STREAMS: