forked from amkovkov/GranuSightSoftware2
feat: GSS2.Test Vulkan render image
This commit is contained in:
+263
-124
@@ -9,16 +9,13 @@ using Avalonia.Threading;
|
||||
|
||||
using GSS2.Vulkan;
|
||||
|
||||
using Iot.Device.FtCommon;
|
||||
|
||||
using LibCameraSharp;
|
||||
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
using Silk.NET.Core;
|
||||
using Silk.NET.Vulkan;
|
||||
using Silk.NET.Vulkan.Extensions.KHR;
|
||||
|
||||
using Image = Silk.NET.Vulkan.Image;
|
||||
|
||||
namespace GSS2.Test;
|
||||
|
||||
interface IImage
|
||||
@@ -46,7 +43,7 @@ class VkImage
|
||||
{
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
Format = PlatformGraphicsExternalImageFormat.R8G8B8A8UNorm,
|
||||
Format = PlatformGraphicsExternalImageFormat.B8G8R8A8UNorm,
|
||||
MemorySize = MemorySize
|
||||
},
|
||||
Semaphore
|
||||
@@ -63,66 +60,22 @@ class VkRenderer
|
||||
return new PlatformHandle(new IntPtr(fd), KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor);
|
||||
}
|
||||
|
||||
unsafe public VkImage ImportOrUpdate(int fd, int width, int height)
|
||||
unsafe public VkImage ImportOrUpdate(int fd, int width, int height, int stride)
|
||||
{
|
||||
try
|
||||
{
|
||||
var extImageInfo = new ExternalMemoryImageCreateInfo
|
||||
{
|
||||
SType = StructureType.ExternalMemoryImageCreateInfo,
|
||||
HandleTypes = ExternalMemoryHandleTypeFlags.OpaqueFDBit
|
||||
};
|
||||
var (importImage, importMemoryReqirements, importMemory) = ImportImage(fd, width, height, stride);
|
||||
var (exportImage, exportMemoryReqirements, exportMemory) = CreateExportImage(width, height);
|
||||
|
||||
var imageInfo = new ImageCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageCreateInfo,
|
||||
PNext = &extImageInfo,
|
||||
ImageType = ImageType.Type2D,
|
||||
Format = Format.R8G8B8A8Unorm,
|
||||
Extent = new Extent3D
|
||||
{
|
||||
Width = checked((uint)width),
|
||||
Height = checked((uint)height),
|
||||
Depth = 1
|
||||
},
|
||||
MipLevels = 1,
|
||||
ArrayLayers = 1,
|
||||
Samples = SampleCountFlags.Count1Bit,
|
||||
Tiling = ImageTiling.Optimal,
|
||||
Usage = ImageUsageFlags.TransferDstBit | ImageUsageFlags.SampledBit,
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
InitialLayout = ImageLayout.Undefined
|
||||
};
|
||||
|
||||
context.Api.CreateImage(context.Device, &imageInfo, null, out var image).ThrowOnError();
|
||||
context.Api.GetImageMemoryRequirements(context.Device, image, out var memReq);
|
||||
|
||||
var exportAllocInfo = new ExportMemoryAllocateInfo
|
||||
{
|
||||
SType = StructureType.ExportMemoryAllocateInfo,
|
||||
HandleTypes = ExternalMemoryHandleTypeFlags.OpaqueFDBit
|
||||
};
|
||||
|
||||
var allocInfo = new MemoryAllocateInfo
|
||||
{
|
||||
SType = StructureType.MemoryAllocateInfo,
|
||||
PNext = &exportAllocInfo,
|
||||
AllocationSize = memReq.Size,
|
||||
MemoryTypeIndex = checked((uint)FindMemoryType(memReq.MemoryTypeBits, MemoryPropertyFlags.DeviceLocalBit))
|
||||
};
|
||||
|
||||
context.Api.AllocateMemory(context.Device, &allocInfo, null, out var memory).ThrowOnError();
|
||||
context.Api.BindImageMemory(context.Device, image, memory, 0).ThrowOnError();
|
||||
|
||||
var poolInfo = new CommandPoolCreateInfo
|
||||
var commandPoolCreateInfo = new CommandPoolCreateInfo
|
||||
{
|
||||
SType = StructureType.CommandPoolCreateInfo,
|
||||
Flags = CommandPoolCreateFlags.ResetCommandBufferBit,
|
||||
QueueFamilyIndex = context.QueueFamilyIndex
|
||||
};
|
||||
context.Api.CreateCommandPool(context.Device, &poolInfo, null, out var commandPool).ThrowOnError();
|
||||
context.Api.CreateCommandPool(context.Device, &commandPoolCreateInfo, null, out var commandPool).ThrowOnError();
|
||||
|
||||
var cmdBufferAllocInfo = new CommandBufferAllocateInfo
|
||||
var commandBufferAllocateInfo = new CommandBufferAllocateInfo
|
||||
{
|
||||
SType = StructureType.CommandBufferAllocateInfo,
|
||||
CommandPool = commandPool,
|
||||
@@ -130,65 +83,75 @@ class VkRenderer
|
||||
CommandBufferCount = 1
|
||||
};
|
||||
|
||||
context.Api.AllocateCommandBuffers(context.Device, &cmdBufferAllocInfo, out var cmd).ThrowOnError();
|
||||
context.Api.AllocateCommandBuffers(context.Device, &commandBufferAllocateInfo, out var commandBuffers).ThrowOnError();
|
||||
|
||||
var clearColor = new ClearColorValue((float)Random.Shared.NextDouble(), (float)Random.Shared.NextDouble(), (float)Random.Shared.NextDouble(), (float)Random.Shared.NextDouble());
|
||||
var range = new ImageSubresourceRange
|
||||
{
|
||||
AspectMask = ImageAspectFlags.ColorBit,
|
||||
BaseMipLevel = 0,
|
||||
LevelCount = 1,
|
||||
BaseArrayLayer = 0,
|
||||
LayerCount = 1
|
||||
};
|
||||
|
||||
var beginInfo = new CommandBufferBeginInfo
|
||||
var commandBufferBeginInfo = new CommandBufferBeginInfo
|
||||
{
|
||||
SType = StructureType.CommandBufferBeginInfo,
|
||||
Flags = CommandBufferUsageFlags.OneTimeSubmitBit
|
||||
};
|
||||
context.Api.BeginCommandBuffer(cmd, &beginInfo).ThrowOnError();
|
||||
context.Api.BeginCommandBuffer(commandBuffers, &commandBufferBeginInfo).ThrowOnError();
|
||||
|
||||
TransitionImageLayout(cmd, image, ImageLayout.Undefined, ImageLayout.TransferDstOptimal);
|
||||
TransitionImageLayout(commandBuffers, importImage, ImageLayout.Undefined, ImageLayout.TransferSrcOptimal);
|
||||
TransitionImageLayout(commandBuffers, exportImage, ImageLayout.Undefined, ImageLayout.TransferDstOptimal);
|
||||
|
||||
context.Api.CmdClearColorImage(cmd, image, ImageLayout.TransferDstOptimal, &clearColor, 1, &range);
|
||||
var region = new ImageCopy
|
||||
{
|
||||
SrcSubresource = new ImageSubresourceLayers
|
||||
{
|
||||
AspectMask = ImageAspectFlags.ColorBit,
|
||||
MipLevel = 0,
|
||||
BaseArrayLayer = 0,
|
||||
LayerCount = 1
|
||||
},
|
||||
SrcOffset = new Offset3D(0, 0, 0),
|
||||
DstSubresource = new ImageSubresourceLayers
|
||||
{
|
||||
AspectMask = ImageAspectFlags.ColorBit,
|
||||
MipLevel = 0,
|
||||
BaseArrayLayer = 0,
|
||||
LayerCount = 1
|
||||
},
|
||||
DstOffset = new Offset3D(0, 0, 0),
|
||||
Extent = new Extent3D((uint)width, (uint)height, 1)
|
||||
};
|
||||
context.Api.CmdCopyImage(commandBuffers, importImage, ImageLayout.Undefined, exportImage, ImageLayout.Undefined, [region]);
|
||||
|
||||
TransitionImageLayout(cmd, image, ImageLayout.TransferDstOptimal, ImageLayout.General);
|
||||
TransitionImageLayout(commandBuffers, exportImage, ImageLayout.TransferDstOptimal, ImageLayout.General);
|
||||
|
||||
context.Api.EndCommandBuffer(cmd).ThrowOnError();
|
||||
context.Api.EndCommandBuffer(commandBuffers).ThrowOnError();
|
||||
|
||||
if (context.Api.TryGetDeviceExtension<KhrExternalMemoryFd>(context.Instance, context.Device, out var khrExternalMemoryFd))
|
||||
Console.WriteLine("KhrExternalMemoryFd import success");
|
||||
else
|
||||
throw new Exception("KhrExternalMemoryFd import error");
|
||||
var MemoryGetFdInfoKHR = new MemoryGetFdInfoKHR
|
||||
{
|
||||
SType = StructureType.MemoryGetFDInfoKhr,
|
||||
Memory = exportMemory,
|
||||
HandleType = ExternalMemoryHandleTypeFlags.OpaqueFDBit
|
||||
};
|
||||
khrExternalMemoryFd.GetMemoryF(context.Device, &MemoryGetFdInfoKHR, out var vulkanFd).ThrowOnError();
|
||||
Console.WriteLine($"Image export success {vulkanFd}");
|
||||
|
||||
var renderFinished = context.RenderFinishedSemaphore;
|
||||
|
||||
var submitInfo = new SubmitInfo
|
||||
{
|
||||
SType = StructureType.SubmitInfo,
|
||||
CommandBufferCount = 1,
|
||||
PCommandBuffers = &cmd,
|
||||
PCommandBuffers = &commandBuffers,
|
||||
PSignalSemaphores = &renderFinished,
|
||||
SignalSemaphoreCount = 1
|
||||
};
|
||||
|
||||
context.Api.QueueSubmit(context.Queue, 1, &submitInfo, default).ThrowOnError();
|
||||
|
||||
var getFdInfo = new MemoryGetFdInfoKHR
|
||||
{
|
||||
SType = StructureType.MemoryGetFDInfoKhr,
|
||||
Memory = memory,
|
||||
HandleType = ExternalMemoryHandleTypeFlags.OpaqueFDBit
|
||||
};
|
||||
if (context.Api.TryGetDeviceExtension<KhrExternalMemoryFd>(context.Instance, context.Device, out var khrExternalMemoryFd))
|
||||
Console.WriteLine("KhrExternalMemoryFd import success");
|
||||
else
|
||||
throw new Exception("KhrExternalMemoryFd import error");
|
||||
khrExternalMemoryFd.GetMemoryF(context.Device, &getFdInfo, out var fd1).ThrowOnError();
|
||||
Console.WriteLine($"Image export success {fd1}");
|
||||
|
||||
return new VkImage()
|
||||
{
|
||||
Width = width,
|
||||
Height = height,
|
||||
Fd = fd1,
|
||||
MemorySize = memReq.Size
|
||||
Fd = vulkanFd,
|
||||
MemorySize = exportMemoryReqirements.Size
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -199,6 +162,109 @@ class VkRenderer
|
||||
}
|
||||
}
|
||||
|
||||
unsafe public (Image, MemoryRequirements, DeviceMemory) ImportImage(int fd, int width, int height, int stride)
|
||||
{
|
||||
var subresourceLayout = new SubresourceLayout
|
||||
{
|
||||
Offset = 0,
|
||||
RowPitch = checked((ulong)stride),
|
||||
};
|
||||
var imageDrmFormatModifierExplicitCreateInfoEXT = new ImageDrmFormatModifierExplicitCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.ImageDrmFormatModifierExplicitCreateInfoExt,
|
||||
DrmFormatModifier = 0,
|
||||
DrmFormatModifierPlaneCount = 1,
|
||||
PPlaneLayouts = &subresourceLayout,
|
||||
};
|
||||
var imageCreateInfo = new ImageCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageCreateInfo,
|
||||
PNext = &imageDrmFormatModifierExplicitCreateInfoEXT,
|
||||
ImageType = ImageType.Type2D,
|
||||
Format = Format.B8G8R8A8Unorm,
|
||||
Extent = new Extent3D
|
||||
{
|
||||
Width = checked((uint)width),
|
||||
Height = checked((uint)height),
|
||||
Depth = 1
|
||||
},
|
||||
MipLevels = 1,
|
||||
ArrayLayers = 1,
|
||||
Samples = SampleCountFlags.Count1Bit,
|
||||
Tiling = ImageTiling.DrmFormatModifierExt,
|
||||
Usage = ImageUsageFlags.TransferSrcBit | ImageUsageFlags.SampledBit,
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
InitialLayout = ImageLayout.Undefined,
|
||||
};
|
||||
context.Api.CreateImage(context.Device, &imageCreateInfo, null, out var image).ThrowOnError();
|
||||
context.Api.GetImageMemoryRequirements(context.Device, image, out var memoryReqirements);
|
||||
|
||||
var importMemoryFdInfoKHR = new ImportMemoryFdInfoKHR
|
||||
{
|
||||
SType = StructureType.ImportMemoryFDInfoKhr,
|
||||
HandleType = ExternalMemoryHandleTypeFlags.DmaBufBitExt,
|
||||
Fd = fd,
|
||||
};
|
||||
var memoryAllocateInfo = new MemoryAllocateInfo
|
||||
{
|
||||
SType = StructureType.MemoryAllocateInfo,
|
||||
AllocationSize = memoryReqirements.Size,
|
||||
MemoryTypeIndex = checked((uint)FindMemoryType(memoryReqirements.MemoryTypeBits, MemoryPropertyFlags.DeviceLocalBit)),
|
||||
PNext = &importMemoryFdInfoKHR,
|
||||
};
|
||||
context.Api.AllocateMemory(context.Device, &memoryAllocateInfo, null, out var memory).ThrowOnError();
|
||||
context.Api.BindImageMemory(context.Device, image, memory, 0).ThrowOnError();
|
||||
|
||||
return (image, memoryReqirements, memory);
|
||||
}
|
||||
unsafe public (Image, MemoryRequirements, DeviceMemory) CreateExportImage(int width, int height)
|
||||
{
|
||||
var externalMemoryImageCreateInfo = new ExternalMemoryImageCreateInfo
|
||||
{
|
||||
SType = StructureType.ExternalMemoryImageCreateInfo,
|
||||
HandleTypes = ExternalMemoryHandleTypeFlags.OpaqueFDBit
|
||||
};
|
||||
var imageCreateInfo = new ImageCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageCreateInfo,
|
||||
PNext = &externalMemoryImageCreateInfo,
|
||||
ImageType = ImageType.Type2D,
|
||||
Format = Format.B8G8R8A8Unorm,
|
||||
Extent = new Extent3D
|
||||
{
|
||||
Width = checked((uint)width),
|
||||
Height = checked((uint)height),
|
||||
Depth = 1
|
||||
},
|
||||
MipLevels = 1,
|
||||
ArrayLayers = 1,
|
||||
Samples = SampleCountFlags.Count1Bit,
|
||||
Tiling = ImageTiling.Optimal,
|
||||
Usage = ImageUsageFlags.TransferDstBit | ImageUsageFlags.SampledBit,
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
InitialLayout = ImageLayout.Undefined,
|
||||
};
|
||||
context.Api.CreateImage(context.Device, &imageCreateInfo, null, out var image).ThrowOnError();
|
||||
context.Api.GetImageMemoryRequirements(context.Device, image, out var memoryReqirements);
|
||||
|
||||
var exportMemoryFdInfoKHR = new ExportMemoryAllocateInfoKHR
|
||||
{
|
||||
SType = StructureType.ExportMemoryAllocateInfoKhr,
|
||||
HandleTypes = ExternalMemoryHandleTypeFlags.DmaBufBitExt
|
||||
};
|
||||
var exportAllocateInfo = new MemoryAllocateInfo
|
||||
{
|
||||
SType = StructureType.MemoryAllocateInfo,
|
||||
AllocationSize = memoryReqirements.Size,
|
||||
MemoryTypeIndex = checked((uint)FindMemoryType(memoryReqirements.MemoryTypeBits, MemoryPropertyFlags.DeviceLocalBit)),
|
||||
PNext = &exportMemoryFdInfoKHR,
|
||||
};
|
||||
context.Api.AllocateMemory(context.Device, &exportAllocateInfo, null, out var memory).ThrowOnError();
|
||||
context.Api.BindImageMemory(context.Device, image, memory, 0).ThrowOnError();
|
||||
|
||||
return (image, memoryReqirements, memory);
|
||||
}
|
||||
|
||||
private int FindMemoryType(uint typeFilter, MemoryPropertyFlags properties)
|
||||
{
|
||||
context!.Api.GetPhysicalDeviceMemoryProperties(context.PhysicalDevice, out var memProps);
|
||||
@@ -207,15 +273,15 @@ class VkRenderer
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
unsafe private void TransitionImageLayout(CommandBuffer cmd, Silk.NET.Vulkan.Image image, ImageLayout oldLayout, ImageLayout newLayout)
|
||||
unsafe private void TransitionImageLayout(CommandBuffer cmd, Image image, ImageLayout oldLayout, ImageLayout newLayout)
|
||||
{
|
||||
var barrier = new ImageMemoryBarrier
|
||||
{
|
||||
SType = StructureType.ImageMemoryBarrier,
|
||||
OldLayout = oldLayout,
|
||||
NewLayout = newLayout,
|
||||
SrcQueueFamilyIndex = 0,
|
||||
DstQueueFamilyIndex = 0,
|
||||
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
Image = image,
|
||||
SubresourceRange = new ImageSubresourceRange
|
||||
{
|
||||
@@ -227,37 +293,70 @@ class VkRenderer
|
||||
}
|
||||
};
|
||||
|
||||
PipelineStageFlags srcStage;
|
||||
PipelineStageFlags dstStage;
|
||||
|
||||
if (oldLayout == ImageLayout.Undefined && newLayout == ImageLayout.TransferDstOptimal)
|
||||
{
|
||||
barrier.SrcAccessMask = 0;
|
||||
barrier.DstAccessMask = AccessFlags.TransferWriteBit;
|
||||
|
||||
srcStage = PipelineStageFlags.TopOfPipeBit;
|
||||
dstStage = PipelineStageFlags.TransferBit;
|
||||
|
||||
}
|
||||
else if (oldLayout == ImageLayout.TransferDstOptimal && newLayout == ImageLayout.ShaderReadOnlyOptimal)
|
||||
{
|
||||
|
||||
barrier.SrcAccessMask = AccessFlags.TransferWriteBit;
|
||||
barrier.DstAccessMask = AccessFlags.ShaderReadBit;
|
||||
|
||||
srcStage = PipelineStageFlags.TransferBit;
|
||||
dstStage = PipelineStageFlags.FragmentShaderBit;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
srcStage = PipelineStageFlags.AllCommandsBit;
|
||||
dstStage = PipelineStageFlags.AllCommandsBit;
|
||||
}
|
||||
|
||||
context!.Api.CmdPipelineBarrier(cmd, srcStage, dstStage, 0, 0, null, 0, null, 1, &barrier);
|
||||
context.Api.CmdPipelineBarrier(
|
||||
cmd,
|
||||
PipelineStageFlags.TopOfPipeBit,
|
||||
PipelineStageFlags.TransferBit,
|
||||
0,
|
||||
0, null,
|
||||
0, null,
|
||||
1, &barrier);
|
||||
}
|
||||
// unsafe private void TransitionImageLayout(CommandBuffer cmd, Silk.NET.Vulkan.Image image, ImageLayout oldLayout, ImageLayout newLayout)
|
||||
// {
|
||||
// var barrier = new ImageMemoryBarrier
|
||||
// {
|
||||
// SType = StructureType.ImageMemoryBarrier,
|
||||
// OldLayout = oldLayout,
|
||||
// NewLayout = newLayout,
|
||||
// SrcQueueFamilyIndex = 0,
|
||||
// DstQueueFamilyIndex = 0,
|
||||
// Image = image,
|
||||
// SubresourceRange = new ImageSubresourceRange
|
||||
// {
|
||||
// AspectMask = ImageAspectFlags.ColorBit,
|
||||
// BaseMipLevel = 0,
|
||||
// LevelCount = 1,
|
||||
// BaseArrayLayer = 0,
|
||||
// LayerCount = 1
|
||||
// }
|
||||
// };
|
||||
|
||||
// PipelineStageFlags srcStage;
|
||||
// PipelineStageFlags dstStage;
|
||||
|
||||
// if (oldLayout == ImageLayout.Undefined && newLayout == ImageLayout.TransferDstOptimal)
|
||||
// {
|
||||
// barrier.SrcAccessMask = 0;
|
||||
// barrier.DstAccessMask = AccessFlags.TransferWriteBit;
|
||||
|
||||
// srcStage = PipelineStageFlags.TopOfPipeBit;
|
||||
// dstStage = PipelineStageFlags.TransferBit;
|
||||
// }
|
||||
// else if (oldLayout == ImageLayout.Undefined && newLayout == ImageLayout.ShaderReadOnlyOptimal)
|
||||
// {
|
||||
// barrier.SrcAccessMask = 0;
|
||||
// barrier.DstAccessMask = AccessFlags.ShaderReadBit;
|
||||
|
||||
// srcStage = PipelineStageFlags.TopOfPipeBit;
|
||||
// dstStage = PipelineStageFlags.FragmentShaderBit;
|
||||
// }
|
||||
// else if (oldLayout == ImageLayout.TransferDstOptimal && newLayout == ImageLayout.ShaderReadOnlyOptimal)
|
||||
// {
|
||||
// barrier.SrcAccessMask = AccessFlags.TransferWriteBit;
|
||||
// barrier.DstAccessMask = AccessFlags.ShaderReadBit;
|
||||
|
||||
// srcStage = PipelineStageFlags.TransferBit;
|
||||
// dstStage = PipelineStageFlags.FragmentShaderBit;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// srcStage = PipelineStageFlags.AllCommandsBit;
|
||||
// dstStage = PipelineStageFlags.AllCommandsBit;
|
||||
// }
|
||||
|
||||
// context!.Api.CmdPipelineBarrier(cmd, srcStage, dstStage, 0, 0, null, 0, null, 1, &barrier);
|
||||
// }
|
||||
}
|
||||
|
||||
public partial class CameraView : Control
|
||||
@@ -327,16 +426,56 @@ public partial class CameraView : Control
|
||||
var (handle, properties, semaphore) = image.Export();
|
||||
|
||||
var imageRenderedSemaphore = _gpuInterop!.ImportSemaphore(_renerer!.ExportSemaphore(false));
|
||||
imageRenderedSemaphore.ImportCompleted.ContinueWith(t =>
|
||||
{
|
||||
Console.WriteLine($"imageRenderedSemaphore.ImportCompleted {t.Status}");
|
||||
if (t.Exception is not null)
|
||||
{
|
||||
Console.WriteLine($"Error: \n{t.Exception.Message}\n{t.Exception.StackTrace} ");
|
||||
foreach (var e in t.Exception.InnerExceptions)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
Console.WriteLine(e.StackTrace);
|
||||
}
|
||||
}
|
||||
});
|
||||
var renderCompletedSemaphore = _gpuInterop!.ImportSemaphore(_renerer!.ExportSemaphore(true));
|
||||
renderCompletedSemaphore.ImportCompleted.ContinueWith(t =>
|
||||
{
|
||||
Console.WriteLine($"renderCompletedSemaphore.ImportCompleted {t.Status}");
|
||||
if (t.Exception is not null)
|
||||
{
|
||||
Console.WriteLine($"Error: \n{t.Exception.Message}\n{t.Exception.StackTrace} ");
|
||||
foreach (var e in t.Exception.InnerExceptions)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
Console.WriteLine(e.StackTrace);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Console.WriteLine("ImportImage");
|
||||
var importedImage = _gpuInterop!.ImportImage(handle, properties);
|
||||
importedImage.ImportCompleted.ContinueWith(t =>
|
||||
{
|
||||
Console.WriteLine($"importedImage.ImportCompleted {t.Status}");
|
||||
if (t.Exception is not null)
|
||||
{
|
||||
Console.WriteLine($"Error: \n{t.Exception.Message}\n{t.Exception.StackTrace} ");
|
||||
foreach (var e in t.Exception.InnerExceptions)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
Console.WriteLine(e.StackTrace);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Dispatcher.UIThread.Invoke(async () =>
|
||||
{
|
||||
await importedImage.ImportCompleted;
|
||||
await Surface!.UpdateWithSemaphoresAsync(importedImage, renderCompletedSemaphore, imageRenderedSemaphore)
|
||||
.ContinueWith((t) =>
|
||||
{
|
||||
Console.WriteLine($"UpdateWithSemaphoresAsync {t.Status}");
|
||||
if (t.Exception is not null)
|
||||
{
|
||||
Console.WriteLine($"Error while surface update: \n{t.Exception.Message}\n{t.Exception.StackTrace} ");
|
||||
@@ -367,7 +506,7 @@ public partial class CameraView : Control
|
||||
|
||||
if (frameBuffer is not null && streamConfiguration is not null && _renerer is not null)
|
||||
{
|
||||
var image = _renerer.ImportOrUpdate(frameBuffer.Planes.First().Fd.Get(), checked((int)streamConfiguration.Size.Width), checked((int)streamConfiguration.Size.Height));
|
||||
var image = _renerer.ImportOrUpdate(frameBuffer.Planes.First().Fd.Get(), checked((int)streamConfiguration.Size.Width), checked((int)streamConfiguration.Size.Height), checked((int)streamConfiguration.Stride));
|
||||
_latestImage = image;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user