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:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
Reference in New Issue
Block a user