Currently looks like this (will reply in
Currently looks like this (will reply in a thread to not clog the channel)
1 Reply
// Direct3D11
// -----------------------------
Texture2DDesc texDesc =
new Texture2DDesc
(
width: captureWidth,
height: captureHeight,
mipLevels: 1,
arraySize: 1,
format: Silk.NET.DXGI.Format.FormatB8G8R8A8Unorm,
sampleDesc: new SampleDesc(count: 1, quality: 0),
usage: Usage.Default,
bindFlags: (uint)(BindFlag.RenderTarget | BindFlag.ShaderResource),
miscFlags: (uint)(ResourceMiscFlag.Shared), //TODO check NT handle support
cPUAccessFlags: 0
);
SilkMarshal.ThrowHResult(dx11Device.CreateTexture2D(&texDesc, (SubresourceData*)IntPtr.Zero, ref d3d11Texture));
ComPtr<IDXGIResource> d3d11TextureResource = default;
SilkMarshal.ThrowHResult(D3D11Texture2DVtblExtensions.QueryInterface(d3d11Texture, out d3d11TextureResource));
void* sharedHandle = default;
SilkMarshal.ThrowHResult
(
//TODO check NT handle support
d3d11TextureResource.GetSharedHandle(&sharedHandle)
);
d3d11TextureResource.Dispose();
// TEST (just loads data into the Direct3D texture)
CaptureDesktop();
// Direct3D11
// -----------------------------
Texture2DDesc texDesc =
new Texture2DDesc
(
width: captureWidth,
height: captureHeight,
mipLevels: 1,
arraySize: 1,
format: Silk.NET.DXGI.Format.FormatB8G8R8A8Unorm,
sampleDesc: new SampleDesc(count: 1, quality: 0),
usage: Usage.Default,
bindFlags: (uint)(BindFlag.RenderTarget | BindFlag.ShaderResource),
miscFlags: (uint)(ResourceMiscFlag.Shared), //TODO check NT handle support
cPUAccessFlags: 0
);
SilkMarshal.ThrowHResult(dx11Device.CreateTexture2D(&texDesc, (SubresourceData*)IntPtr.Zero, ref d3d11Texture));
ComPtr<IDXGIResource> d3d11TextureResource = default;
SilkMarshal.ThrowHResult(D3D11Texture2DVtblExtensions.QueryInterface(d3d11Texture, out d3d11TextureResource));
void* sharedHandle = default;
SilkMarshal.ThrowHResult
(
//TODO check NT handle support
d3d11TextureResource.GetSharedHandle(&sharedHandle)
);
d3d11TextureResource.Dispose();
// TEST (just loads data into the Direct3D texture)
CaptureDesktop();
//Vulkan
// -----------------------------
//TODO check NT handle support
var eii = new ExternalMemoryImageCreateInfo
{
HandleTypes = ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit
};
var ii = new ImageCreateInfo
{
PNext = &eii,
Flags = 0,
ImageType = ImageType.Type2D,
Format = Silk.NET.Vulkan.Format.B8G8R8A8Unorm,
Extent = new Extent3D(captureWidth, captureHeight, 1),
MipLevels = 1,
ArrayLayers = 1,
Samples = SampleCountFlags.Count1Bit,
Tiling = ImageTiling.Optimal,
Usage =
ImageUsageFlags.ColorAttachmentBit |
ImageUsageFlags.SampledBit |
ImageUsageFlags.TransferDstBit |
ImageUsageFlags.TransferSrcBit,
SharingMode = SharingMode.Exclusive,
QueueFamilyIndexCount = 0,
InitialLayout = ImageLayout.Undefined
};
fixed (Silk.NET.Vulkan.Image* vkSharedImageHandle = &vkSharedImage)
{
var res = VK.CreateImage(vkDevice, ii, null, vkSharedImageHandle);
GD.Print(res.ToString());
}
MemoryRequirements memReq;
VK.GetImageMemoryRequirements(vkDevice, vkSharedImage, out memReq);
KhrExternalMemoryWin32 vkExternalMemory;
if (!VK.TryGetDeviceExtension(vkInstance, vkDevice, out vkExternalMemory))
{
throw new Exception($"Failed to load KhrExternalMemoryWin32 Vulkan extension!");
}
var w32MemProps = new MemoryWin32HandlePropertiesKHR();
vkExternalMemory.GetMemoryWin32HandleProperties(
vkDevice,
ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit,
(nint)sharedHandle,
out w32MemProps
);
PhysicalDeviceMemoryProperties memProps;
VK.GetPhysicalDeviceMemoryProperties(vkPhysicalDevice, out memProps);
uint memTypeIndex =
FindMemoryTypeIndex(memProps, w32MemProps.MemoryTypeBits, MemoryPropertyFlags.DeviceLocalBit)
?? throw new Exception("Device local memory not found!");
//Vulkan
// -----------------------------
//TODO check NT handle support
var eii = new ExternalMemoryImageCreateInfo
{
HandleTypes = ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit
};
var ii = new ImageCreateInfo
{
PNext = &eii,
Flags = 0,
ImageType = ImageType.Type2D,
Format = Silk.NET.Vulkan.Format.B8G8R8A8Unorm,
Extent = new Extent3D(captureWidth, captureHeight, 1),
MipLevels = 1,
ArrayLayers = 1,
Samples = SampleCountFlags.Count1Bit,
Tiling = ImageTiling.Optimal,
Usage =
ImageUsageFlags.ColorAttachmentBit |
ImageUsageFlags.SampledBit |
ImageUsageFlags.TransferDstBit |
ImageUsageFlags.TransferSrcBit,
SharingMode = SharingMode.Exclusive,
QueueFamilyIndexCount = 0,
InitialLayout = ImageLayout.Undefined
};
fixed (Silk.NET.Vulkan.Image* vkSharedImageHandle = &vkSharedImage)
{
var res = VK.CreateImage(vkDevice, ii, null, vkSharedImageHandle);
GD.Print(res.ToString());
}
MemoryRequirements memReq;
VK.GetImageMemoryRequirements(vkDevice, vkSharedImage, out memReq);
KhrExternalMemoryWin32 vkExternalMemory;
if (!VK.TryGetDeviceExtension(vkInstance, vkDevice, out vkExternalMemory))
{
throw new Exception($"Failed to load KhrExternalMemoryWin32 Vulkan extension!");
}
var w32MemProps = new MemoryWin32HandlePropertiesKHR();
vkExternalMemory.GetMemoryWin32HandleProperties(
vkDevice,
ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit,
(nint)sharedHandle,
out w32MemProps
);
PhysicalDeviceMemoryProperties memProps;
VK.GetPhysicalDeviceMemoryProperties(vkPhysicalDevice, out memProps);
uint memTypeIndex =
FindMemoryTypeIndex(memProps, w32MemProps.MemoryTypeBits, MemoryPropertyFlags.DeviceLocalBit)
?? throw new Exception("Device local memory not found!");
//TODO check MemoryDedicatedRequirements (ImageMemoryRequirements2)
dii = new MemoryDedicatedAllocateInfoKHR { Image = vkSharedImage };
fixed (MemoryDedicatedAllocateInfoKHR* pdii = &dii)
{
imi = new ImportMemoryWin32HandleInfoKHR
{
PNext = pdii,
HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit,
Handle = (nint)sharedHandle
};
}
fixed (ImportMemoryWin32HandleInfoKHR* pimi = &imi)
{
mi = new MemoryAllocateInfo
{
PNext = pimi,
AllocationSize = memReq.Size,
MemoryTypeIndex = memTypeIndex
};
}
fixed (DeviceMemory* pDeviceMemory = &deviceMemory)
{
fixed (MemoryAllocateInfo* pmi = &mi)
{
var result1 = VK.AllocateMemory(vkDevice, pmi, null, pDeviceMemory);
var result2 = VK.BindImageMemory(vkDevice, vkSharedImage, deviceMemory, 0);
GD.Print(result1.ToString());
GD.Print(result2.ToString());
}
}
var gdSharedImageRid =
gdDevice.TextureCreateFromExtension
(
RenderingDevice.TextureType.Type2D,
RenderingDevice.DataFormat.B8G8R8A8Unorm,
RenderingDevice.TextureSamples.Samples1,
RenderingDevice.TextureUsageBits.ColorAttachmentBit |
RenderingDevice.TextureUsageBits.SamplingBit |
RenderingDevice.TextureUsageBits.CanUpdateBit |
RenderingDevice.TextureUsageBits.CanCopyFromBit |
RenderingDevice.TextureUsageBits.CanCopyToBit,
vkSharedImage.Handle,
captureWidth,
captureHeight,
0,
1
);
gdrdTexture = new Texture2Drd
{
TextureRdRid = gdSharedImageRid,
};
//TODO check MemoryDedicatedRequirements (ImageMemoryRequirements2)
dii = new MemoryDedicatedAllocateInfoKHR { Image = vkSharedImage };
fixed (MemoryDedicatedAllocateInfoKHR* pdii = &dii)
{
imi = new ImportMemoryWin32HandleInfoKHR
{
PNext = pdii,
HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit,
Handle = (nint)sharedHandle
};
}
fixed (ImportMemoryWin32HandleInfoKHR* pimi = &imi)
{
mi = new MemoryAllocateInfo
{
PNext = pimi,
AllocationSize = memReq.Size,
MemoryTypeIndex = memTypeIndex
};
}
fixed (DeviceMemory* pDeviceMemory = &deviceMemory)
{
fixed (MemoryAllocateInfo* pmi = &mi)
{
var result1 = VK.AllocateMemory(vkDevice, pmi, null, pDeviceMemory);
var result2 = VK.BindImageMemory(vkDevice, vkSharedImage, deviceMemory, 0);
GD.Print(result1.ToString());
GD.Print(result2.ToString());
}
}
var gdSharedImageRid =
gdDevice.TextureCreateFromExtension
(
RenderingDevice.TextureType.Type2D,
RenderingDevice.DataFormat.B8G8R8A8Unorm,
RenderingDevice.TextureSamples.Samples1,
RenderingDevice.TextureUsageBits.ColorAttachmentBit |
RenderingDevice.TextureUsageBits.SamplingBit |
RenderingDevice.TextureUsageBits.CanUpdateBit |
RenderingDevice.TextureUsageBits.CanCopyFromBit |
RenderingDevice.TextureUsageBits.CanCopyToBit,
vkSharedImage.Handle,
captureWidth,
captureHeight,
0,
1
);
gdrdTexture = new Texture2Drd
{
TextureRdRid = gdSharedImageRid,
};
GD
references, I am doing this in Godot