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_disjoint_timer_query/simple: 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/vk-buf-exchange: skip
spec/ext_external_objects/vk-depth-display: skip
@@ -3517,10 +3516,10 @@ wgl/wgl-sanity: skip
summary:
name: results
---- --------
pass: 17853
pass: 17866
fail: 2035
crash: 12
skip: 1450
skip: 1449
timeout: 0
warn: 10
incomplete: 0
@@ -3529,4 +3528,4 @@ summary:
changes: 0
fixes: 0
regressions: 0
total: 21369
total: 21381

View File

@@ -167,7 +167,9 @@ init_buffer(struct d3d12_screen *screen,
static bool
init_texture(struct d3d12_screen *screen,
struct d3d12_resource *res,
const struct pipe_resource *templ)
const struct pipe_resource *templ,
ID3D12Heap *heap,
uint64_t placed_offset)
{
ID3D12Resource *d3d12_res;
@@ -183,9 +185,18 @@ init_texture(struct d3d12_screen *screen,
desc.MipLevels = templ->last_level + 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) {
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_ARRAY:
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D;
@@ -210,8 +221,6 @@ init_texture(struct d3d12_screen *screen,
unreachable("Invalid texture type");
}
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (templ->bind & PIPE_BIND_SHADER_BUFFER)
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))
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_FLAGS heap_flags = screen->support_create_not_resident ?
D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT : D3D12_HEAP_FLAG_NONE;
enum d3d12_residency_status init_residency = screen->support_create_not_resident ?
d3d12_evicted : d3d12_resident;
init_residency = screen->support_create_not_resident ? d3d12_evicted : d3d12_resident;
HRESULT hres = screen->dev->CreateCommittedResource(&heap_pris,
hres = screen->dev->CreateCommittedResource(&heap_pris,
heap_flags,
&desc,
D3D12_RESOURCE_STATE_COMMON,
NULL,
IID_PPV_ARGS(&d3d12_res));
}
if (FAILED(hres))
return false;
@@ -322,14 +343,16 @@ convert_planar_resource(struct d3d12_resource *res)
}
static struct pipe_resource *
d3d12_resource_create(struct pipe_screen *pscreen,
const struct pipe_resource *templ)
d3d12_resource_create_or_place(struct d3d12_screen *screen,
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;
res->base.b = *templ;
res->overall_format = templ->format;
res->plane_slice = 0;
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);
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);
} else {
ret = init_texture(screen, res, templ);
ret = init_texture(screen, res, templ, heap, placed_offset);
}
if (!ret) {
@@ -368,6 +391,17 @@ d3d12_resource_create(struct pipe_screen *pscreen,
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 *
d3d12_resource_from_handle(struct pipe_screen *pscreen,
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;
ID3D12Heap *d3d12_heap = nullptr;
if (res->bo) {
d3d12_res = res->bo->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 {
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_RESOURCE_DESC incoming_res_desc;
if (!d3d12_res)
if (!d3d12_res && !d3d12_heap)
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();
/* Get a description for this plane */
@@ -817,6 +861,25 @@ d3d12_memobj_destroy(struct pipe_screen *pscreen, struct pipe_memory_object *pme
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
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_destroy = d3d12_memobj_destroy;
pscreen->resource_from_memobj = d3d12_resource_from_memobj;
}
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_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
case PIPE_CAP_MEMOBJ:
return 1;
case PIPE_CAP_MAX_VERTEX_STREAMS: