Fix: Cycles Metal graphics interop not working
It needs an MTLBuffer instead of a raw pointer.
This commit is contained in:
@@ -633,9 +633,10 @@ GraphicsInteropDevice BlenderDisplayDriver::graphics_interop_get_device()
|
||||
interop_device.type = GraphicsInteropDevice::VULKAN;
|
||||
break;
|
||||
case GPU_BACKEND_METAL:
|
||||
interop_device.type = GraphicsInteropDevice::METAL;
|
||||
break;
|
||||
case GPU_BACKEND_NONE:
|
||||
case GPU_BACKEND_ANY:
|
||||
/* Metal not supported yet by Cycles. */
|
||||
interop_device.type = GraphicsInteropDevice::NONE;
|
||||
break;
|
||||
}
|
||||
@@ -665,9 +666,10 @@ GraphicsInteropBuffer BlenderDisplayDriver::graphics_interop_get_buffer()
|
||||
interop_buffer.type = GraphicsInteropDevice::VULKAN;
|
||||
break;
|
||||
case GPU_BACKEND_METAL:
|
||||
interop_buffer.type = GraphicsInteropDevice::METAL;
|
||||
break;
|
||||
case GPU_BACKEND_NONE:
|
||||
case GPU_BACKEND_ANY:
|
||||
/* Metal not supported yet by Cycles. */
|
||||
interop_buffer.type = GraphicsInteropDevice::NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifdef WITH_METAL
|
||||
|
||||
# include "device/graphics_interop.h"
|
||||
# include "device/metal/device_impl.h"
|
||||
|
||||
# include "session/display_driver.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -34,7 +36,7 @@ class MetalDeviceGraphicsInterop : public DeviceGraphicsInterop {
|
||||
MetalDevice *device_ = nullptr;
|
||||
|
||||
/* Native handle. */
|
||||
void *buffer_ = nullptr;
|
||||
MetalDevice::MetalMem mem_;
|
||||
size_t size_ = 0;
|
||||
|
||||
/* The destination was requested to be cleared. */
|
||||
|
||||
@@ -22,18 +22,19 @@ void MetalDeviceGraphicsInterop::set_buffer(const GraphicsInteropBuffer &interop
|
||||
/* Trivial implementation due to unified memory. */
|
||||
if (interop_buffer.type == GraphicsInteropDevice::METAL) {
|
||||
need_clear_ |= interop_buffer.need_clear;
|
||||
buffer_ = reinterpret_cast<void *>(interop_buffer.handle);
|
||||
mem_.mtlBuffer = reinterpret_cast<id<MTLBuffer>>(interop_buffer.handle);
|
||||
size_ = interop_buffer.width * interop_buffer.height * sizeof(half4);
|
||||
}
|
||||
}
|
||||
|
||||
device_ptr MetalDeviceGraphicsInterop::map()
|
||||
{
|
||||
if (buffer_ && need_clear_) {
|
||||
memset(buffer_, 0, size_);
|
||||
if (mem_.mtlBuffer && need_clear_) {
|
||||
memset([mem_.mtlBuffer contents], 0, size_);
|
||||
need_clear_ = false;
|
||||
}
|
||||
|
||||
return device_ptr(buffer_);
|
||||
return device_ptr(&mem_);
|
||||
}
|
||||
|
||||
void MetalDeviceGraphicsInterop::unmap() {}
|
||||
|
||||
@@ -41,7 +41,7 @@ class GraphicsInteropBuffer {
|
||||
* - OpenGL: pixel buffer object ID.
|
||||
* - Vulkan on Windows: opaque handle for VkBuffer.
|
||||
* - Vulkan on Unix: opaque file descriptor for VkBuffer.
|
||||
* - Metal: pixel buffer unified memory pointer. */
|
||||
* - Metal: MTLBuffer with unified memory. */
|
||||
GraphicsInteropDevice::Type type = GraphicsInteropDevice::NONE;
|
||||
int64_t handle = 0;
|
||||
|
||||
|
||||
@@ -2657,7 +2657,8 @@ GPUPixelBufferNativeHandle MTLPixelBuffer::get_native_handle()
|
||||
}
|
||||
|
||||
/* Just get pointer to unified memory. No need to unmap. */
|
||||
native_handle.handle = reinterpret_cast<int64_t>(map());
|
||||
map();
|
||||
native_handle.handle = reinterpret_cast<int64_t>(buffer_);
|
||||
native_handle.size = size_;
|
||||
|
||||
return native_handle;
|
||||
|
||||
Reference in New Issue
Block a user