mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-27 09:01:46 +00:00
a/d3d,a/vk,c/client,ipc: D3D Depth texture / DXGI handle support
a/d3d: Improve allocation Enable D3D11 and D3D112 depth images using DXGI handles Allow D3D depth by default D3D: only use DXGI handles NT handles don't support depth formats and may fail to properly interop with Vulkan with some image dimensions. Removed D3D_COMPOSITOR_ALLOW_DEPTH env. D3D now always imports depth. Added authorship. Format pass Fix D3D compositor tests ipc: Fix HANDLE bit twiddling code Merge into commits related to D3D depth changes. Makes the code compile as C++, useful for Windows traceing Co-authored-by: Robbie Bridgewater <ebridgewater@magicleap.com> Co-authored-by: Fernando Velazquez Innella <finnella@magicleap.com> Co-authored-by: Jakob Bornecrantz <jakob@collabora.com>
This commit is contained in:
parent
2db2fb94b7
commit
85a897a0b5
|
@ -4,6 +4,7 @@
|
|||
* @file
|
||||
* @brief D3D11 backed image buffer allocator.
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Fernando Velazquez Innella <finnella@magicleap.com>
|
||||
* @ingroup aux_d3d
|
||||
*/
|
||||
|
||||
|
@ -55,18 +56,13 @@ DEBUG_GET_ONCE_LOG_OPTION(d3d11_log, "DXGI_LOG", U_LOGGING_WARN)
|
|||
|
||||
namespace xrt::auxiliary::d3d::d3d11 {
|
||||
|
||||
wil::unique_handle
|
||||
createSharedHandle(const wil::com_ptr<ID3D11Texture2D1> &image)
|
||||
HANDLE
|
||||
getSharedHandle(const wil::com_ptr<ID3D11Texture2D1> &image)
|
||||
{
|
||||
|
||||
wil::com_ptr<IDXGIResource1> dxgiRes;
|
||||
HANDLE h;
|
||||
image.query_to(dxgiRes.put());
|
||||
wil::unique_handle h;
|
||||
THROW_IF_FAILED(dxgiRes->CreateSharedHandle( //
|
||||
nullptr, // pAttributes
|
||||
DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, // dwAccess
|
||||
nullptr, // lpName
|
||||
h.put())); // pHandle
|
||||
THROW_IF_FAILED(dxgiRes->GetSharedHandle(&h));
|
||||
return h;
|
||||
}
|
||||
|
||||
|
@ -76,7 +72,7 @@ allocateSharedImages(ID3D11Device5 &device,
|
|||
size_t image_count,
|
||||
bool keyed_mutex,
|
||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> &out_images,
|
||||
std::vector<wil::unique_handle> &out_handles)
|
||||
std::vector<HANDLE> &out_handles)
|
||||
try {
|
||||
if (0 != (xsci.create & XRT_SWAPCHAIN_CREATE_PROTECTED_CONTENT)) {
|
||||
return XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED;
|
||||
|
@ -86,6 +82,10 @@ try {
|
|||
D3DA_ERROR("Got XRT_SWAPCHAIN_CREATE_STATIC_IMAGE but an image count greater than 1!");
|
||||
return XRT_ERROR_ALLOCATION;
|
||||
}
|
||||
if (xsci.array_size == 0) {
|
||||
D3DA_ERROR("Array size must not be 0");
|
||||
return XRT_ERROR_ALLOCATION;
|
||||
}
|
||||
CD3D11_TEXTURE2D_DESC1 desc{d3d_dxgi_format_to_typeless_dxgi((DXGI_FORMAT)xsci.format),
|
||||
xsci.width,
|
||||
xsci.height,
|
||||
|
@ -93,12 +93,11 @@ try {
|
|||
xsci.mip_count,
|
||||
d3d_convert_usage_bits_to_d3d11_bind_flags(xsci.bits)};
|
||||
desc.SampleDesc.Count = xsci.sample_count;
|
||||
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
|
||||
if (keyed_mutex) {
|
||||
desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
} else {
|
||||
desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
|
||||
}
|
||||
|
||||
// Using NT handles for sharing textures has a lot of limitations and issues.
|
||||
// Depth formats are not supported and Vulkan may fail at vkAllocateMemory
|
||||
desc.MiscFlags = keyed_mutex ? D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX : D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
if (desc.Format == 0) {
|
||||
D3DA_ERROR("Invalid format %04" PRIx64 "!", (uint64_t)xsci.format);
|
||||
return XRT_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED;
|
||||
|
@ -112,13 +111,16 @@ try {
|
|||
std::vector<wil::com_ptr<ID3D11Texture2D1>> images;
|
||||
for (size_t i = 0; i < image_count; ++i) {
|
||||
wil::com_ptr<ID3D11Texture2D1> tex;
|
||||
THROW_IF_FAILED(device.CreateTexture2D1(&desc, nullptr, tex.put()));
|
||||
if (FAILED(LOG_IF_FAILED(device.CreateTexture2D1(&desc, nullptr, tex.put())))) {
|
||||
return XRT_ERROR_ALLOCATION;
|
||||
}
|
||||
images.emplace_back(std::move(tex));
|
||||
}
|
||||
std::vector<wil::unique_handle> handles;
|
||||
|
||||
std::vector<HANDLE> handles;
|
||||
handles.reserve(image_count);
|
||||
for (const auto &tex : images) {
|
||||
handles.emplace_back(createSharedHandle(tex));
|
||||
handles.emplace_back(getSharedHandle(tex));
|
||||
}
|
||||
out_images = std::move(images);
|
||||
out_handles = std::move(handles);
|
||||
|
@ -145,16 +147,19 @@ d3d11_images_allocate(struct xrt_image_native_allocator *xina,
|
|||
d3d11_allocator *d3da = reinterpret_cast<d3d11_allocator *>(xina);
|
||||
|
||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> images;
|
||||
std::vector<wil::unique_handle> handles;
|
||||
std::vector<HANDLE> handles;
|
||||
auto result = xrt::auxiliary::d3d::d3d11::allocateSharedImages(*(d3da->device), *xsci, image_count,
|
||||
false, images, handles);
|
||||
if (XRT_SUCCESS != result) {
|
||||
|
||||
if (result != XRT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
// if we made it this far without exceptions, we can safely report back the output.
|
||||
|
||||
for (size_t i = 0; i < image_count; ++i) {
|
||||
out_images[i].handle = handles[i].release();
|
||||
out_images[i].handle = handles[i];
|
||||
out_images[i].is_dxgi_handle = true;
|
||||
}
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
DEFAULT_CATCH(XRT_ERROR_ALLOCATION)
|
||||
|
@ -164,7 +169,9 @@ static xrt_result_t
|
|||
d3d11_images_free(struct xrt_image_native_allocator *xina, size_t image_count, struct xrt_image_native *images)
|
||||
{
|
||||
for (size_t i = 0; i < image_count; ++i) {
|
||||
u_graphics_buffer_unref(&(images[i].handle));
|
||||
if (!images[i].is_dxgi_handle) {
|
||||
u_graphics_buffer_unref(&(images[i].handle));
|
||||
}
|
||||
}
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,6 @@ allocateSharedImages(ID3D11Device5 &device,
|
|||
size_t image_count,
|
||||
bool keyed_mutex,
|
||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> &out_images,
|
||||
std::vector<wil::unique_handle> &out_handles);
|
||||
std::vector<HANDLE> &out_handles);
|
||||
|
||||
}; // namespace xrt::auxiliary::d3d::d3d11
|
||||
|
|
|
@ -239,14 +239,15 @@ vk_csci_get_image_usage_flags(struct vk_bundle *vk, VkFormat format, enum xrt_sw
|
|||
}
|
||||
|
||||
VkExternalMemoryHandleTypeFlags
|
||||
vk_csci_get_image_external_handle_type(struct vk_bundle *vk)
|
||||
vk_csci_get_image_external_handle_type(struct vk_bundle *vk, struct xrt_image_native *xin)
|
||||
{
|
||||
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD)
|
||||
return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
|
||||
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER)
|
||||
return VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
|
||||
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE)
|
||||
return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
|
||||
return (xin && xin->is_dxgi_handle) ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT
|
||||
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
|
||||
#else
|
||||
#error "need port"
|
||||
#endif
|
||||
|
|
|
@ -844,7 +844,7 @@ vk_create_image_from_native(struct vk_bundle *vk,
|
|||
return VK_ERROR_FEATURE_NOT_PRESENT;
|
||||
}
|
||||
|
||||
VkExternalMemoryHandleTypeFlags handle_type = vk_csci_get_image_external_handle_type(vk);
|
||||
VkExternalMemoryHandleTypeFlags handle_type = vk_csci_get_image_external_handle_type(vk, image_native);
|
||||
|
||||
bool importable = false;
|
||||
vk_csci_get_image_external_support(vk, image_format, info->bits, handle_type, &importable, NULL);
|
||||
|
@ -903,7 +903,7 @@ vk_create_image_from_native(struct vk_bundle *vk,
|
|||
VkImportMemoryWin32HandleInfoKHR import_memory_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
|
||||
.handleType = handle_type,
|
||||
.handle = image_native->handle,
|
||||
};
|
||||
#else
|
||||
|
|
|
@ -1238,7 +1238,7 @@ vk_csci_get_image_view_aspect(VkFormat format, enum xrt_swapchain_usage_bits bit
|
|||
* CSCI = Compositor SwapChain Images.
|
||||
*/
|
||||
VkExternalMemoryHandleTypeFlags
|
||||
vk_csci_get_image_external_handle_type(struct vk_bundle *vk);
|
||||
vk_csci_get_image_external_handle_type(struct vk_bundle *vk, struct xrt_image_native *xin);
|
||||
|
||||
/*!
|
||||
* Get whether a given image can be imported/exported for a handle type.
|
||||
|
|
|
@ -349,7 +349,9 @@ vk_ic_from_natives(struct vk_bundle *vk,
|
|||
size_t i = 0;
|
||||
for (; i < image_count; i++) {
|
||||
// Ensure that all handles are consumed or none are.
|
||||
xrt_graphics_buffer_handle_t buf = u_graphics_buffer_ref(native_images[i].handle);
|
||||
xrt_graphics_buffer_handle_t buf = native_images[i].is_dxgi_handle
|
||||
? native_images[i].handle
|
||||
: u_graphics_buffer_ref(native_images[i].handle);
|
||||
|
||||
if (!xrt_graphics_buffer_is_valid(buf)) {
|
||||
U_LOG_E("Could not ref/duplicate graphics buffer handle");
|
||||
|
@ -364,7 +366,9 @@ vk_ic_from_natives(struct vk_bundle *vk,
|
|||
&out_vkic->images[i].handle, // out_image
|
||||
&out_vkic->images[i].memory); // out_mem
|
||||
if (ret != VK_SUCCESS) {
|
||||
u_graphics_buffer_unref(&buf);
|
||||
if (!native_images[i].is_dxgi_handle) {
|
||||
u_graphics_buffer_unref(&buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
native_images[i].handle = buf;
|
||||
|
@ -377,7 +381,9 @@ vk_ic_from_natives(struct vk_bundle *vk,
|
|||
// We have consumed all handles now, close all of the copies we
|
||||
// made, all this to make sure we do all or nothing.
|
||||
for (size_t k = 0; k < image_count; k++) {
|
||||
u_graphics_buffer_unref(&native_images[k].handle);
|
||||
if (!native_images[k].is_dxgi_handle) {
|
||||
u_graphics_buffer_unref(&native_images[k].handle);
|
||||
}
|
||||
native_images[k].size = 0;
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* @brief D3D11 client side glue to compositor implementation.
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Fernando Velazquez Innella <finnella@magicleap.com>
|
||||
* @ingroup comp_client
|
||||
*/
|
||||
|
||||
|
@ -50,7 +51,6 @@ using namespace std::chrono;
|
|||
using xrt::compositor::client::unique_swapchain_ref;
|
||||
|
||||
DEBUG_GET_ONCE_LOG_OPTION(log, "D3D_COMPOSITOR_LOG", U_LOGGING_INFO)
|
||||
DEBUG_GET_ONCE_BOOL_OPTION(allow_depth, "D3D_COMPOSITOR_ALLOW_DEPTH", false);
|
||||
|
||||
/*!
|
||||
* Spew level logging.
|
||||
|
@ -187,8 +187,8 @@ struct client_d3d11_swapchain_data
|
|||
|
||||
xrt::compositor::client::KeyedMutexCollection keyed_mutex_collection;
|
||||
|
||||
//! The shared handles for all our images
|
||||
std::vector<wil::unique_handle> handles;
|
||||
//! The shared DXGI handles for our images
|
||||
std::vector<HANDLE> dxgi_handles;
|
||||
|
||||
//! Images associated with client_d3d11_compositor::app_device
|
||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> app_images;
|
||||
|
@ -332,6 +332,18 @@ import_image(ID3D11Device1 &device, HANDLE h)
|
|||
return tex;
|
||||
}
|
||||
|
||||
static wil::com_ptr<ID3D11Texture2D1>
|
||||
import_image_dxgi(ID3D11Device1 &device, HANDLE h)
|
||||
{
|
||||
wil::com_ptr<ID3D11Texture2D1> tex;
|
||||
|
||||
if (h == nullptr) {
|
||||
return {};
|
||||
}
|
||||
THROW_IF_FAILED(device.OpenSharedResource(h, __uuidof(ID3D11Texture2D1), tex.put_void()));
|
||||
return tex;
|
||||
}
|
||||
|
||||
static wil::com_ptr<ID3D11Fence>
|
||||
import_fence(ID3D11Device5 &device, HANDLE h)
|
||||
{
|
||||
|
@ -383,17 +395,17 @@ try {
|
|||
sc->data = std::make_unique<client_d3d11_swapchain_data>(c->log_level);
|
||||
auto &data = sc->data;
|
||||
xret = xrt::auxiliary::d3d::d3d11::allocateSharedImages(*(c->comp_device), xinfo, image_count, true,
|
||||
data->comp_images, data->handles);
|
||||
data->comp_images, data->dxgi_handles);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
return xret;
|
||||
}
|
||||
|
||||
data->app_images.reserve(image_count);
|
||||
|
||||
// Import from the handle for the app.
|
||||
for (uint32_t i = 0; i < image_count; ++i) {
|
||||
const auto &handle = data->handles[i];
|
||||
wil::unique_handle dupedForApp{u_graphics_buffer_ref(handle.get())};
|
||||
auto image = import_image(*(c->app_device), dupedForApp.get());
|
||||
wil::com_ptr<ID3D11Texture2D1> image = import_image_dxgi(*(c->app_device), data->dxgi_handles[i]);
|
||||
|
||||
// Put the image where the OpenXR state tracker can get it
|
||||
sc->base.images[i] = image.get();
|
||||
|
||||
|
@ -409,8 +421,9 @@ try {
|
|||
}
|
||||
|
||||
// Import into the native compositor, to create the corresponding swapchain which we wrap.
|
||||
xret = xrt::compositor::client::importFromHandleDuplicates(
|
||||
*(c->xcn), data->handles, vkinfo, false /** @todo not sure - dedicated allocation */, sc->xsc);
|
||||
xret = xrt::compositor::client::importFromDxgiHandles(
|
||||
*(c->xcn), data->dxgi_handles, vkinfo, false /** @todo not sure - dedicated allocation */, sc->xsc);
|
||||
|
||||
if (xret != XRT_SUCCESS) {
|
||||
D3D_ERROR(c, "Error importing D3D11 swapchain into native compositor");
|
||||
return xret;
|
||||
|
@ -840,11 +853,6 @@ try {
|
|||
if (typeless == f) {
|
||||
continue;
|
||||
}
|
||||
// Sometimes we have to forbid depth formats to avoid errors in Vulkan.
|
||||
if (!debug_get_bool_option_allow_depth() &&
|
||||
(f == DXGI_FORMAT_D32_FLOAT || f == DXGI_FORMAT_D16_UNORM || f == DXGI_FORMAT_D24_UNORM_S8_UINT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->base.base.info.formats[count++] = f;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* @brief D3D12 client side glue to compositor implementation.
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Fernando Velazquez Innella <finnella@magicleap.com>
|
||||
* @ingroup comp_client
|
||||
*/
|
||||
|
||||
|
@ -50,7 +51,6 @@ using namespace std::chrono_literals;
|
|||
using namespace std::chrono;
|
||||
|
||||
DEBUG_GET_ONCE_LOG_OPTION(log, "D3D_COMPOSITOR_LOG", U_LOGGING_INFO)
|
||||
DEBUG_GET_ONCE_BOOL_OPTION(allow_depth, "D3D_COMPOSITOR_ALLOW_DEPTH", false);
|
||||
|
||||
DEBUG_GET_ONCE_BOOL_OPTION(barriers, "D3D12_COMPOSITOR_BARRIERS", false);
|
||||
DEBUG_GET_ONCE_BOOL_OPTION(initial_transition, "D3D12_COMPOSITOR_INITIAL_TRANSITION", true);
|
||||
|
@ -189,8 +189,8 @@ struct client_d3d12_swapchain_data
|
|||
|
||||
xrt::compositor::client::KeyedMutexCollection keyed_mutex_collection;
|
||||
|
||||
//! The shared handles for all our images
|
||||
std::vector<wil::unique_handle> handles;
|
||||
//! The shared DXGI handles for our images
|
||||
std::vector<HANDLE> dxgi_handles;
|
||||
|
||||
//! D3D11 Images
|
||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> d3d11_images;
|
||||
|
@ -433,7 +433,7 @@ try {
|
|||
|
||||
// Make images with D3D11
|
||||
xret = xrt::auxiliary::d3d::d3d11::allocateSharedImages(*(c->d3d11_device), xinfo, image_count, true,
|
||||
data->d3d11_images, data->handles);
|
||||
data->d3d11_images, data->dxgi_handles);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
return xret;
|
||||
}
|
||||
|
@ -442,9 +442,9 @@ try {
|
|||
|
||||
// Import to D3D12 from the handle.
|
||||
for (uint32_t i = 0; i < image_count; ++i) {
|
||||
const auto &handle = data->handles[i];
|
||||
wil::unique_handle dupedForD3D12{u_graphics_buffer_ref(handle.get())};
|
||||
auto d3d12Image = xrt::auxiliary::d3d::d3d12::importImage(*(c->device), dupedForD3D12.get());
|
||||
wil::com_ptr<ID3D12Resource> d3d12Image =
|
||||
xrt::auxiliary::d3d::d3d12::importImage(*(c->device), data->dxgi_handles[i]);
|
||||
|
||||
// Put the image where the OpenXR state tracker can get it
|
||||
sc->base.images[i] = d3d12Image.get();
|
||||
|
||||
|
@ -523,8 +523,8 @@ try {
|
|||
}
|
||||
|
||||
// Import into the native compositor, to create the corresponding swapchain which we wrap.
|
||||
xret = xrt::compositor::client::importFromHandleDuplicates(
|
||||
*(c->xcn), data->handles, vkinfo, false /** @todo not sure - dedicated allocation */, sc->xsc);
|
||||
xret = xrt::compositor::client::importFromDxgiHandles(
|
||||
*(c->xcn), data->dxgi_handles, vkinfo, false /** @todo not sure - dedicated allocation */, sc->xsc);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
D3D_ERROR(c, "Error importing D3D swapchain into native compositor");
|
||||
return xret;
|
||||
|
@ -967,12 +967,6 @@ try {
|
|||
if (typeless == f) {
|
||||
continue;
|
||||
}
|
||||
// Sometimes we have to forbid depth formats to avoid errors in Vulkan.
|
||||
if (!debug_get_bool_option_allow_depth() &&
|
||||
(f == DXGI_FORMAT_D32_FLOAT || f == DXGI_FORMAT_D16_UNORM || f == DXGI_FORMAT_D24_UNORM_S8_UINT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->base.base.info.formats[count++] = f;
|
||||
}
|
||||
c->base.base.info.format_count = count;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* @brief Functionality common to D3D11 and D3D12 for client side compositor implementation.
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Fernando Velazquez Innella <finnella@magicleap.com>
|
||||
* @ingroup comp_client
|
||||
*/
|
||||
#pragma once
|
||||
|
@ -34,39 +35,34 @@ using unique_swapchain_ref =
|
|||
xrt::deleters::reference_deleter<struct xrt_swapchain, xrt_swapchain_reference>>;
|
||||
|
||||
/**
|
||||
* Import the provided handles into a native compositor, without consuming them.
|
||||
* Import the provided handles into a native compositor.
|
||||
*
|
||||
* @param c The native compositor
|
||||
* @param handles A vector of uniquely-owned handles. These will be duplicated, not consumed, by this import.
|
||||
* @param xcn The native compositor
|
||||
* @param handles A vector of DXGI handles.
|
||||
* @param vkinfo The swapchain create info, with format as a Vulkan constant
|
||||
* @param use_dedicated_allocation Passed through to @ref xrt_image_native
|
||||
* @param[out] out_xsc The swapchain to populate
|
||||
* @return XRT_SUCCESS if everything went well, otherwise whatever error a call internally returned.
|
||||
*/
|
||||
static inline xrt_result_t
|
||||
importFromHandleDuplicates(xrt_compositor_native &xcn,
|
||||
std::vector<wil::unique_handle> const &handles,
|
||||
const struct xrt_swapchain_create_info &vkinfo,
|
||||
bool use_dedicated_allocation,
|
||||
unique_swapchain_ref &out_xsc)
|
||||
importFromDxgiHandles(xrt_compositor_native &xcn,
|
||||
std::vector<HANDLE> const &handles,
|
||||
const struct xrt_swapchain_create_info &vkinfo,
|
||||
bool use_dedicated_allocation,
|
||||
unique_swapchain_ref &out_xsc)
|
||||
{
|
||||
uint32_t image_count = static_cast<uint32_t>(handles.size());
|
||||
// Populate for import
|
||||
std::vector<xrt_image_native> xins;
|
||||
xins.reserve(image_count);
|
||||
|
||||
// Keep this around until after successful import, then detach all.
|
||||
std::vector<wil::unique_handle> handlesForImport;
|
||||
handlesForImport.reserve(image_count);
|
||||
|
||||
for (const wil::unique_handle &handle : handles) {
|
||||
wil::unique_handle duped{u_graphics_buffer_ref(handle.get())};
|
||||
xrt_image_native xin;
|
||||
xin.handle = duped.get();
|
||||
for (HANDLE handle : handles) {
|
||||
xrt_image_native xin{};
|
||||
xin.handle = handle;
|
||||
xin.size = 0;
|
||||
xin.use_dedicated_allocation = use_dedicated_allocation;
|
||||
xin.is_dxgi_handle = true;
|
||||
|
||||
handlesForImport.emplace_back(std::move(duped));
|
||||
xins.emplace_back(xin);
|
||||
}
|
||||
|
||||
|
@ -79,10 +75,6 @@ importFromHandleDuplicates(xrt_compositor_native &xcn,
|
|||
// Let unique_ptr manage the lifetime of xsc now
|
||||
out_xsc.reset(xsc);
|
||||
|
||||
// The imported swapchain took ownership of them now, release them from ownership here.
|
||||
for (auto &h : handlesForImport) {
|
||||
h.release();
|
||||
}
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ is_format_supported(struct vk_bundle *vk, VkFormat format, enum xrt_swapchain_us
|
|||
* Check exportability.
|
||||
*/
|
||||
|
||||
VkExternalMemoryHandleTypeFlags handle_type = vk_csci_get_image_external_handle_type(vk);
|
||||
VkExternalMemoryHandleTypeFlags handle_type = vk_csci_get_image_external_handle_type(vk, NULL);
|
||||
VkResult ret;
|
||||
|
||||
VkImageUsageFlags usage = vk_csci_get_image_usage_flags(vk, format, xbits);
|
||||
|
|
|
@ -1766,6 +1766,11 @@ struct xrt_image_native
|
|||
* Is the image created with a dedicated allocation or not.
|
||||
*/
|
||||
bool use_dedicated_allocation;
|
||||
|
||||
/*!
|
||||
* Is the native buffer handle a DXGI handle?
|
||||
*/
|
||||
bool is_dxgi_handle;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -334,6 +334,14 @@ swapchain_server_import(struct ipc_client_compositor *icc,
|
|||
for (uint32_t i = 0; i < image_count; i++) {
|
||||
handles[i] = native_images[i].handle;
|
||||
args.sizes[i] = native_images[i].size;
|
||||
|
||||
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE)
|
||||
// DXGI handles need to be dealt with differently, they are identified
|
||||
// by having their lower bit set to 1 during transfer
|
||||
if (native_images[i].is_dxgi_handle) {
|
||||
(size_t) handles[i] |= 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// This does not consume the handles, it copies them.
|
||||
|
|
|
@ -835,6 +835,14 @@ ipc_handle_swapchain_import(volatile struct ipc_client_state *ics,
|
|||
for (uint32_t i = 0; i < handle_count; i++) {
|
||||
xins[i].handle = handles[i];
|
||||
xins[i].size = args->sizes[i];
|
||||
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE)
|
||||
// DXGI handles need to be dealt with differently, they are identified
|
||||
// by having their lower bit set to 1 during transfer
|
||||
if ((size_t)xins[i].handle & 1) {
|
||||
xins[i].handle = (HANDLE)((size_t)xins[i].handle - 1);
|
||||
xins[i].is_dxgi_handle = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// create the swapchain
|
||||
|
|
|
@ -146,8 +146,11 @@ ipc_send_fds(
|
|||
v.reserve(handle_count);
|
||||
for (uint32_t i = 0; i < handle_count; i++) {
|
||||
HANDLE handle;
|
||||
if (!DuplicateHandle(current_process, handles[i], target_process, &handle, 0, false,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
if ((size_t)handles[i] & 1) {
|
||||
// This handle cannot be duplicated.
|
||||
handle = handles[i];
|
||||
} else if (!DuplicateHandle(current_process, handles[i], target_process, &handle, 0, false,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
DWORD err = GetLastError();
|
||||
IPC_ERROR(imc, "DuplicateHandle(%p) failed: %d %s", handles[i], err, ipc_winerror(err));
|
||||
CloseHandle(target_process);
|
||||
|
|
|
@ -31,18 +31,12 @@ static constexpr std::initializer_list<DXGI_FORMAT> depthStencilFormats = {
|
|||
DXGI_FORMAT_D32_FLOAT,
|
||||
};
|
||||
static constexpr std::initializer_list<std::pair<const char *, DXGI_FORMAT>> namesAndFormats = {
|
||||
MAKE_PAIR(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB),
|
||||
MAKE_PAIR(DXGI_FORMAT_B8G8R8A8_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_FLOAT),
|
||||
MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_FLOAT),
|
||||
MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB),
|
||||
MAKE_PAIR(DXGI_FORMAT_R8G8B8A8_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R32_FLOAT),
|
||||
MAKE_PAIR(DXGI_FORMAT_D16_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_D24_UNORM_S8_UINT),
|
||||
MAKE_PAIR(DXGI_FORMAT_D32_FLOAT_S8X24_UINT),
|
||||
MAKE_PAIR(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB), MAKE_PAIR(DXGI_FORMAT_B8G8R8A8_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_FLOAT), MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_FLOAT), MAKE_PAIR(DXGI_FORMAT_R16G16B16A16_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB), MAKE_PAIR(DXGI_FORMAT_R8G8B8A8_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_R32_FLOAT), MAKE_PAIR(DXGI_FORMAT_D16_UNORM),
|
||||
MAKE_PAIR(DXGI_FORMAT_D24_UNORM_S8_UINT), MAKE_PAIR(DXGI_FORMAT_D32_FLOAT_S8X24_UINT),
|
||||
MAKE_PAIR(DXGI_FORMAT_D32_FLOAT),
|
||||
};
|
||||
|
||||
|
|
|
@ -68,9 +68,7 @@ TEST_CASE("d3d11_device", "[.][needgpu]")
|
|||
#ifdef XRT_HAVE_VULKAN
|
||||
|
||||
static inline bool
|
||||
tryImport(struct vk_bundle *vk,
|
||||
std::vector<wil::unique_handle> const &handles,
|
||||
const struct xrt_swapchain_create_info &xsci)
|
||||
tryImport(struct vk_bundle *vk, std::vector<HANDLE> const &handles, const struct xrt_swapchain_create_info &xsci)
|
||||
{
|
||||
|
||||
INFO("Testing import into Vulkan");
|
||||
|
@ -94,8 +92,8 @@ tryImport(struct vk_bundle *vk,
|
|||
std::vector<wil::unique_handle> handlesForImport;
|
||||
handlesForImport.reserve(image_count);
|
||||
|
||||
for (const wil::unique_handle &handle : handles) {
|
||||
wil::unique_handle duped{u_graphics_buffer_ref(handle.get())};
|
||||
for (HANDLE handle : handles) {
|
||||
wil::unique_handle duped{u_graphics_buffer_ref(handle)};
|
||||
xrt_image_native xin;
|
||||
xin.handle = duped.get();
|
||||
xin.size = 0;
|
||||
|
@ -142,7 +140,7 @@ TEST_CASE("d3d11_allocate", "[.][needgpu]")
|
|||
std::tie(device, context) = createDevice();
|
||||
auto device5 = device.query<ID3D11Device5>();
|
||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> images;
|
||||
std::vector<wil::unique_handle> handles;
|
||||
std::vector<HANDLE> handles;
|
||||
|
||||
static constexpr bool kKeyedMutex = true;
|
||||
size_t imageCount = 3;
|
||||
|
@ -164,7 +162,6 @@ TEST_CASE("d3d11_allocate", "[.][needgpu]")
|
|||
CAPTURE(isDepthStencilFormat(format));
|
||||
xsci.format = format;
|
||||
if (isDepthStencilFormat(format)) {
|
||||
|
||||
xsci.bits = XRT_SWAPCHAIN_USAGE_DEPTH_STENCIL;
|
||||
} else {
|
||||
xsci.bits = XRT_SWAPCHAIN_USAGE_COLOR;
|
||||
|
|
|
@ -62,7 +62,9 @@ TEST_CASE("client_compositor", "[.][needgpu]")
|
|||
data->nativeImportCalled = true;
|
||||
// need to release the native handles to avoid leaks
|
||||
for (uint32_t i = 0; i < image_count; ++i) {
|
||||
u_graphics_buffer_unref(&native_images[i].handle);
|
||||
if (!native_images[i].is_dxgi_handle) {
|
||||
u_graphics_buffer_unref(&native_images[i].handle);
|
||||
}
|
||||
}
|
||||
return XRT_SUCCESS;
|
||||
};
|
||||
|
|
|
@ -64,7 +64,9 @@ TEST_CASE("d3d12_client_compositor", "[.][needgpu]")
|
|||
data->nativeImportCalled = true;
|
||||
// need to release the native handles to avoid leaks
|
||||
for (uint32_t i = 0; i < image_count; ++i) {
|
||||
u_graphics_buffer_unref(&native_images[i].handle);
|
||||
if (!native_images[i].is_dxgi_handle) {
|
||||
u_graphics_buffer_unref(&native_images[i].handle);
|
||||
}
|
||||
}
|
||||
return XRT_SUCCESS;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue