diff --git a/src/util/meson.build b/src/util/meson.build index 072ad2bc..2f1c3b39 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -6,6 +6,7 @@ util_src = files([ 'util_luid.cpp', 'util_matrix.cpp', 'util_monitor.cpp', + 'util_shared_res.cpp', 'com/com_guid.cpp', 'com/com_private_data.cpp', diff --git a/src/util/util_shared_res.cpp b/src/util/util_shared_res.cpp new file mode 100644 index 00000000..d6ff1423 --- /dev/null +++ b/src/util/util_shared_res.cpp @@ -0,0 +1,46 @@ +#include "util_shared_res.h" + +#include "winioctl.h" + +namespace dxvk { + + #define IOCTL_SHARED_GPU_RESOURCE_OPEN CTL_CODE(FILE_DEVICE_VIDEO, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS) + + HANDLE openKmtHandle(HANDLE kmt_handle) { + HANDLE handle = ::CreateFileA("\\\\.\\SharedGpuResource", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (handle == INVALID_HANDLE_VALUE) + return handle; + + struct + { + unsigned int kmt_handle; + WCHAR name[1]; + } shared_resource_open = {0}; + shared_resource_open.kmt_handle = reinterpret_cast(kmt_handle); + + bool succeed = ::DeviceIoControl(handle, IOCTL_SHARED_GPU_RESOURCE_OPEN, &shared_resource_open, sizeof(shared_resource_open), NULL, 0, NULL, NULL); + if (!succeed) { + ::CloseHandle(handle); + return INVALID_HANDLE_VALUE; + } + return handle; + } + + #define IOCTL_SHARED_GPU_RESOURCE_SET_METADATA CTL_CODE(FILE_DEVICE_VIDEO, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS) + + bool setSharedMetadata(HANDLE handle, void *buf, uint32_t bufSize) { + DWORD retSize; + return ::DeviceIoControl(handle, IOCTL_SHARED_GPU_RESOURCE_SET_METADATA, buf, bufSize, NULL, 0, &retSize, NULL); + } + + #define IOCTL_SHARED_GPU_RESOURCE_GET_METADATA CTL_CODE(FILE_DEVICE_VIDEO, 5, METHOD_BUFFERED, FILE_READ_ACCESS) + + bool getSharedMetadata(HANDLE handle, void *buf, uint32_t bufSize, uint32_t *metadataSize) { + DWORD retSize; + bool ret = ::DeviceIoControl(handle, IOCTL_SHARED_GPU_RESOURCE_GET_METADATA, NULL, 0, buf, bufSize, &retSize, NULL); + if (metadataSize) + *metadataSize = retSize; + return ret; + } + +} diff --git a/src/util/util_shared_res.h b/src/util/util_shared_res.h new file mode 100644 index 00000000..aba742c4 --- /dev/null +++ b/src/util/util_shared_res.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include "./com/com_include.h" + +#include + +namespace dxvk { + + HANDLE openKmtHandle(HANDLE kmt_handle); + + bool setSharedMetadata(HANDLE handle, void *buf, uint32_t bufSize); + bool getSharedMetadata(HANDLE handle, void *buf, uint32_t bufSize, uint32_t *metadataSize); + + struct DxvkSharedTextureMetadata { + UINT Width; + UINT Height; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D11_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; + D3D11_TEXTURE_LAYOUT TextureLayout; + }; + +}