Limited support for dynamic states

This commit is contained in:
Dzmitry Malyshau 2018-03-30 00:18:10 -04:00
parent cd5f32bcf1
commit 1bc260fb25
3 changed files with 111 additions and 61 deletions

View file

@ -25,19 +25,19 @@ optional = true
[dependencies.gfx-hal] [dependencies.gfx-hal]
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
rev = "eda7f3c570d09f2fd0bf942c3d945a1b62d72af8" rev = "df0563493a0ce4baab2767c461ccc5c1ebc265ca"
[target.'cfg(not(target_os = "macos"))'.dependencies.gfx-backend-vulkan] [target.'cfg(not(target_os = "macos"))'.dependencies.gfx-backend-vulkan]
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
rev = "eda7f3c570d09f2fd0bf942c3d945a1b62d72af8" rev = "df0563493a0ce4baab2767c461ccc5c1ebc265ca"
optional = true optional = true
[target.'cfg(windows)'.dependencies.gfx-backend-dx12] [target.'cfg(windows)'.dependencies.gfx-backend-dx12]
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
rev = "eda7f3c570d09f2fd0bf942c3d945a1b62d72af8" rev = "df0563493a0ce4baab2767c461ccc5c1ebc265ca"
optional = true optional = true
[target.'cfg(target_os = "macos")'.dependencies.gfx-backend-metal] [target.'cfg(target_os = "macos")'.dependencies.gfx-backend-metal]
git = "https://github.com/gfx-rs/gfx" git = "https://github.com/gfx-rs/gfx"
rev = "eda7f3c570d09f2fd0bf942c3d945a1b62d72af8" rev = "df0563493a0ce4baab2767c461ccc5c1ebc265ca"
optional = true optional = true

View file

@ -623,3 +623,24 @@ pub fn map_extent(extent: VkExtent3D) -> image::Extent {
depth: extent.depth, depth: extent.depth,
} }
} }
pub fn map_rect(rect: &VkRect2D) -> pso::Rect {
pso::Rect {
x: rect.offset.x as _,
y: rect.offset.y as _,
w: rect.extent.width as _,
h: rect.extent.height as _,
}
}
pub fn map_viewport(vp: &VkViewport) -> pso::Viewport {
pso::Viewport {
rect: pso::Rect {
x: vp.x as _,
y: vp.y as _,
w: vp.width as _,
h: vp.height as _,
},
depth: vp.minDepth .. vp.maxDepth,
}
}

View file

@ -684,7 +684,8 @@ pub extern "C" fn gfxQueueSubmit(
} }
#[inline] #[inline]
pub extern "C" fn gfxQueueWaitIdle(queue: VkQueue) -> VkResult { pub extern "C" fn gfxQueueWaitIdle(queue: VkQueue) -> VkResult {
unimplemented!() let _ = queue.wait_idle();
VkResult::VK_SUCCESS
} }
#[inline] #[inline]
pub extern "C" fn gfxDeviceWaitIdle(device: VkDevice) -> VkResult { pub extern "C" fn gfxDeviceWaitIdle(device: VkDevice) -> VkResult {
@ -715,7 +716,7 @@ pub extern "C" fn gfxAllocateMemory(
pub extern "C" fn gfxFreeMemory( pub extern "C" fn gfxFreeMemory(
gpu: VkDevice, gpu: VkDevice,
memory: VkDeviceMemory, memory: VkDeviceMemory,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
gpu.device.free_memory(*memory.unwrap()); gpu.device.free_memory(*memory.unwrap());
} }
@ -985,7 +986,7 @@ pub extern "C" fn gfxDestroySemaphore(
pub extern "C" fn gfxCreateEvent( pub extern "C" fn gfxCreateEvent(
device: VkDevice, device: VkDevice,
pCreateInfo: *const VkEventCreateInfo, pCreateInfo: *const VkEventCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pEvent: *mut VkEvent, pEvent: *mut VkEvent,
) -> VkResult { ) -> VkResult {
unimplemented!() unimplemented!()
@ -994,7 +995,7 @@ pub extern "C" fn gfxCreateEvent(
pub extern "C" fn gfxDestroyEvent( pub extern "C" fn gfxDestroyEvent(
device: VkDevice, device: VkDevice,
event: VkEvent, event: VkEvent,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
unimplemented!() unimplemented!()
} }
@ -1014,7 +1015,7 @@ pub extern "C" fn gfxResetEvent(device: VkDevice, event: VkEvent) -> VkResult {
pub extern "C" fn gfxCreateQueryPool( pub extern "C" fn gfxCreateQueryPool(
device: VkDevice, device: VkDevice,
pCreateInfo: *const VkQueryPoolCreateInfo, pCreateInfo: *const VkQueryPoolCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pQueryPool: *mut VkQueryPool, pQueryPool: *mut VkQueryPool,
) -> VkResult { ) -> VkResult {
unimplemented!() unimplemented!()
@ -1023,7 +1024,7 @@ pub extern "C" fn gfxCreateQueryPool(
pub extern "C" fn gfxDestroyQueryPool( pub extern "C" fn gfxDestroyQueryPool(
device: VkDevice, device: VkDevice,
queryPool: VkQueryPool, queryPool: VkQueryPool,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
unimplemented!() unimplemented!()
} }
@ -1044,7 +1045,7 @@ pub extern "C" fn gfxGetQueryPoolResults(
pub extern "C" fn gfxCreateBuffer( pub extern "C" fn gfxCreateBuffer(
gpu: VkDevice, gpu: VkDevice,
pCreateInfo: *const VkBufferCreateInfo, pCreateInfo: *const VkBufferCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pBuffer: *mut VkBuffer, pBuffer: *mut VkBuffer,
) -> VkResult { ) -> VkResult {
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
@ -1064,37 +1065,55 @@ pub extern "C" fn gfxCreateBuffer(
pub extern "C" fn gfxDestroyBuffer( pub extern "C" fn gfxDestroyBuffer(
gpu: VkDevice, gpu: VkDevice,
buffer: VkBuffer, buffer: VkBuffer,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
if !buffer.is_null() { if !buffer.is_null() {
match *buffer.unwrap() { match *buffer.unwrap() {
Buffer::Buffer(buffer) => gpu.device.destroy_buffer(buffer), Buffer::Buffer(buffer) => gpu.device.destroy_buffer(buffer),
Buffer::Unbound(_) => unimplemented!(), Buffer::Unbound(_) => () //TODO? drop for now
} }
} }
} }
#[inline] #[inline]
pub extern "C" fn gfxCreateBufferView( pub extern "C" fn gfxCreateBufferView(
device: VkDevice, gpu: VkDevice,
pCreateInfo: *const VkBufferViewCreateInfo, pCreateInfo: *const VkBufferViewCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pView: *mut VkBufferView, pView: *mut VkBufferView,
) -> VkResult { ) -> VkResult {
unimplemented!() let info = unsafe { &*pCreateInfo };
let view = gpu.device
.create_buffer_view(
match *info.buffer {
Buffer::Buffer(ref buffer) => buffer,
Buffer::Unbound(_) => unimplemented!(),
},
conv::map_format(info.format),
info.offset .. info.offset + info.range,
)
.expect("Error creating buffer view");
unsafe {
*pView = Handle::new(view);
}
VkResult::VK_SUCCESS
} }
#[inline] #[inline]
pub extern "C" fn gfxDestroyBufferView( pub extern "C" fn gfxDestroyBufferView(
device: VkDevice, gpu: VkDevice,
bufferView: VkBufferView, view: VkBufferView,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
unimplemented!() if !view.is_null() {
gpu.device.destroy_buffer_view(*view.unwrap());
}
} }
#[inline] #[inline]
pub extern "C" fn gfxCreateImage( pub extern "C" fn gfxCreateImage(
gpu: VkDevice, gpu: VkDevice,
pCreateInfo: *const VkImageCreateInfo, pCreateInfo: *const VkImageCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pImage: *mut VkImage, pImage: *mut VkImage,
) -> VkResult { ) -> VkResult {
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
@ -1126,7 +1145,7 @@ pub extern "C" fn gfxCreateImage(
pub extern "C" fn gfxDestroyImage( pub extern "C" fn gfxDestroyImage(
gpu: VkDevice, gpu: VkDevice,
image: VkImage, image: VkImage,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
if !image.is_null() { if !image.is_null() {
match *image.unwrap() { match *image.unwrap() {
@ -1148,7 +1167,7 @@ pub extern "C" fn gfxGetImageSubresourceLayout(
pub extern "C" fn gfxCreateImageView( pub extern "C" fn gfxCreateImageView(
gpu: VkDevice, gpu: VkDevice,
pCreateInfo: *const VkImageViewCreateInfo, pCreateInfo: *const VkImageViewCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pView: *mut VkImageView, pView: *mut VkImageView,
) -> VkResult { ) -> VkResult {
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
@ -1181,7 +1200,7 @@ pub extern "C" fn gfxCreateImageView(
pub extern "C" fn gfxDestroyImageView( pub extern "C" fn gfxDestroyImageView(
gpu: VkDevice, gpu: VkDevice,
imageView: VkImageView, imageView: VkImageView,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
gpu.device.destroy_image_view(*imageView.unwrap()) gpu.device.destroy_image_view(*imageView.unwrap())
} }
@ -1219,7 +1238,7 @@ pub extern "C" fn gfxDestroyShaderModule(
pub extern "C" fn gfxCreatePipelineCache( pub extern "C" fn gfxCreatePipelineCache(
device: VkDevice, device: VkDevice,
pCreateInfo: *const VkPipelineCacheCreateInfo, pCreateInfo: *const VkPipelineCacheCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pPipelineCache: *mut VkPipelineCache, pPipelineCache: *mut VkPipelineCache,
) -> VkResult { ) -> VkResult {
// unimplemented!() // unimplemented!()
@ -1231,7 +1250,7 @@ pub extern "C" fn gfxCreatePipelineCache(
pub extern "C" fn gfxDestroyPipelineCache( pub extern "C" fn gfxDestroyPipelineCache(
device: VkDevice, device: VkDevice,
pipelineCache: VkPipelineCache, pipelineCache: VkPipelineCache,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
unimplemented!() unimplemented!()
} }
@ -1315,8 +1334,6 @@ pub extern "C" fn gfxCreateGraphicsPipelines(
let mut cur_shader_stage = 0; let mut cur_shader_stage = 0;
let descs = infos.into_iter().map(|info| { let descs = infos.into_iter().map(|info| {
// TODO: handle dynamic states and viewports
let shaders = { let shaders = {
let mut set: pso::GraphicsShaderSet<_> = unsafe { mem::zeroed() }; let mut set: pso::GraphicsShaderSet<_> = unsafe { mem::zeroed() };
@ -1530,6 +1547,35 @@ pub extern "C" fn gfxCreateGraphicsPipelines(
}) })
}; };
let vp_state = unsafe { &*info.pViewportState };
let empty_dyn_states = [];
let dyn_states = match unsafe { info.pDynamicState.as_ref() } {
Some(state) => unsafe {
slice::from_raw_parts(state.pDynamicStates, state.dynamicStateCount as _)
},
None => &empty_dyn_states,
};
let baked_states = pso::BakedStates {
viewport: if dyn_states.iter().any(|&ds| ds == VkDynamicState::VK_DYNAMIC_STATE_VIEWPORT) {
None
} else {
unsafe { vp_state.pViewports.as_ref() }
.map(conv::map_viewport)
},
scissor: if dyn_states.iter().any(|&ds| ds == VkDynamicState::VK_DYNAMIC_STATE_SCISSOR) {
None
} else {
unsafe { vp_state.pScissors.as_ref() }
.map(conv::map_rect)
},
blend_color: if dyn_states.iter().any(|&ds| ds == VkDynamicState::VK_DYNAMIC_STATE_BLEND_CONSTANTS) {
None
} else {
unsafe { info.pColorBlendState.as_ref() }
.map(|cbs| cbs.blendConstants)
},
};
let layout = &*info.layout; let layout = &*info.layout;
let subpass = pass::Subpass { let subpass = pass::Subpass {
index: info.subpass as _, index: info.subpass as _,
@ -1572,6 +1618,7 @@ pub extern "C" fn gfxCreateGraphicsPipelines(
input_assembler, input_assembler,
blender, blender,
depth_stencil, depth_stencil,
baked_states,
layout, layout,
subpass, subpass,
flags, flags,
@ -1601,7 +1648,7 @@ pub extern "C" fn gfxCreateComputePipelines(
pipelineCache: VkPipelineCache, pipelineCache: VkPipelineCache,
createInfoCount: u32, createInfoCount: u32,
pCreateInfos: *const VkComputePipelineCreateInfo, pCreateInfos: *const VkComputePipelineCreateInfo,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pPipelines: *mut VkPipeline, pPipelines: *mut VkPipeline,
) -> VkResult { ) -> VkResult {
unimplemented!() unimplemented!()
@ -1610,7 +1657,7 @@ pub extern "C" fn gfxCreateComputePipelines(
pub extern "C" fn gfxDestroyPipeline( pub extern "C" fn gfxDestroyPipeline(
gpu: VkDevice, gpu: VkDevice,
pipeline: VkPipeline, pipeline: VkPipeline,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
if !pipeline.is_null() { if !pipeline.is_null() {
match *pipeline.unwrap() { match *pipeline.unwrap() {
@ -2233,7 +2280,7 @@ pub extern "C" fn gfxAllocateCommandBuffers(
#[inline] #[inline]
pub extern "C" fn gfxFreeCommandBuffers( pub extern "C" fn gfxFreeCommandBuffers(
_gpu: VkDevice, _gpu: VkDevice,
mut commandPool: VkCommandPool, commandPool: VkCommandPool,
commandBufferCount: u32, commandBufferCount: u32,
pCommandBuffers: *const VkCommandBuffer, pCommandBuffers: *const VkCommandBuffer,
) { ) {
@ -2291,17 +2338,7 @@ pub extern "C" fn gfxCmdSetViewport(
let viewports = unsafe { let viewports = unsafe {
slice::from_raw_parts(pViewports, viewportCount as _) slice::from_raw_parts(pViewports, viewportCount as _)
.into_iter() .into_iter()
.map(|viewport| { .map(conv::map_viewport)
com::Viewport {
rect: com::Rect {
x: viewport.x as _,
y: viewport.y as _,
w: viewport.width as _,
h: viewport.height as _,
},
depth: viewport.minDepth .. viewport.maxDepth,
}
})
}; };
commandBuffer.set_viewports(viewports); commandBuffer.set_viewports(viewports);
@ -2318,14 +2355,7 @@ pub extern "C" fn gfxCmdSetScissor(
let scissors = unsafe { let scissors = unsafe {
slice::from_raw_parts(pScissors, scissorCount as _) slice::from_raw_parts(pScissors, scissorCount as _)
.into_iter() .into_iter()
.map(|scissor| { .map(conv::map_rect)
com::Rect {
x: scissor.offset.x as _,
y: scissor.offset.y as _,
w: scissor.extent.width as _,
h: scissor.extent.height as _,
}
})
}; };
commandBuffer.set_scissors(scissors); commandBuffer.set_scissors(scissors);
@ -2855,7 +2885,7 @@ pub extern "C" fn gfxCmdBeginRenderPass(
) { ) {
let info = unsafe { &*pRenderPassBegin }; let info = unsafe { &*pRenderPassBegin };
let render_area = com::Rect { let render_area = pso::Rect {
x: info.renderArea.offset.x as _, x: info.renderArea.offset.x as _,
y: info.renderArea.offset.y as _, y: info.renderArea.offset.y as _,
w: info.renderArea.extent.width as _, w: info.renderArea.extent.width as _,
@ -3049,7 +3079,7 @@ pub extern "C" fn gfxCreateSwapchainKHR(
pub extern "C" fn gfxDestroySwapchainKHR( pub extern "C" fn gfxDestroySwapchainKHR(
device: VkDevice, device: VkDevice,
mut swapchain: VkSwapchainKHR, mut swapchain: VkSwapchainKHR,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
for image in &mut swapchain.images { for image in &mut swapchain.images {
let _ = image.unwrap(); let _ = image.unwrap();
@ -3106,7 +3136,7 @@ pub extern "C" fn gfxCmdReserveSpaceForCommandsNVX(
pub extern "C" fn gfxCreateIndirectCommandsLayoutNVX( pub extern "C" fn gfxCreateIndirectCommandsLayoutNVX(
device: VkDevice, device: VkDevice,
pCreateInfo: *const VkIndirectCommandsLayoutCreateInfoNVX, pCreateInfo: *const VkIndirectCommandsLayoutCreateInfoNVX,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pIndirectCommandsLayout: *mut VkIndirectCommandsLayoutNVX, pIndirectCommandsLayout: *mut VkIndirectCommandsLayoutNVX,
) -> VkResult { ) -> VkResult {
unimplemented!() unimplemented!()
@ -3115,7 +3145,7 @@ pub extern "C" fn gfxCreateIndirectCommandsLayoutNVX(
pub extern "C" fn gfxDestroyIndirectCommandsLayoutNVX( pub extern "C" fn gfxDestroyIndirectCommandsLayoutNVX(
device: VkDevice, device: VkDevice,
indirectCommandsLayout: VkIndirectCommandsLayoutNVX, indirectCommandsLayout: VkIndirectCommandsLayoutNVX,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
unimplemented!() unimplemented!()
} }
@ -3123,7 +3153,7 @@ pub extern "C" fn gfxDestroyIndirectCommandsLayoutNVX(
pub extern "C" fn gfxCreateObjectTableNVX( pub extern "C" fn gfxCreateObjectTableNVX(
device: VkDevice, device: VkDevice,
pCreateInfo: *const VkObjectTableCreateInfoNVX, pCreateInfo: *const VkObjectTableCreateInfoNVX,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pObjectTable: *mut VkObjectTableNVX, pObjectTable: *mut VkObjectTableNVX,
) -> VkResult { ) -> VkResult {
unimplemented!() unimplemented!()
@ -3132,7 +3162,7 @@ pub extern "C" fn gfxCreateObjectTableNVX(
pub extern "C" fn gfxDestroyObjectTableNVX( pub extern "C" fn gfxDestroyObjectTableNVX(
device: VkDevice, device: VkDevice,
objectTable: VkObjectTableNVX, objectTable: VkObjectTableNVX,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
unimplemented!() unimplemented!()
} }
@ -3200,7 +3230,7 @@ pub extern "C" fn gfxDisplayPowerControlEXT(
pub extern "C" fn gfxRegisterDeviceEventEXT( pub extern "C" fn gfxRegisterDeviceEventEXT(
device: VkDevice, device: VkDevice,
pDeviceEventInfo: *const VkDeviceEventInfoEXT, pDeviceEventInfo: *const VkDeviceEventInfoEXT,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pFence: *mut VkFence, pFence: *mut VkFence,
) -> VkResult { ) -> VkResult {
unimplemented!() unimplemented!()
@ -3210,7 +3240,7 @@ pub extern "C" fn gfxRegisterDisplayEventEXT(
device: VkDevice, device: VkDevice,
display: VkDisplayKHR, display: VkDisplayKHR,
pDisplayEventInfo: *const VkDisplayEventInfoEXT, pDisplayEventInfo: *const VkDisplayEventInfoEXT,
pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pFence: *mut VkFence, pFence: *mut VkFence,
) -> VkResult { ) -> VkResult {
unimplemented!() unimplemented!()
@ -3240,12 +3270,12 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR(
pAllocator: *const VkAllocationCallbacks, pAllocator: *const VkAllocationCallbacks,
pSurface: *mut VkSurfaceKHR, pSurface: *mut VkSurfaceKHR,
) -> VkResult { ) -> VkResult {
assert!(pAllocator.is_null());
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
#[cfg(all(feature = "gfx-backend-vulkan", target_os = "windows"))] #[cfg(all(feature = "gfx-backend-vulkan", target_os = "windows"))]
{ {
unsafe { unsafe {
assert_eq!(info.flags, 0); assert_eq!(info.flags, 0);
assert!(pAllocator.is_null());
*pSurface = Handle::new( *pSurface = Handle::new(
instance.backend.create_surface_from_hwnd(info.hinstance, info.hwnd), instance.backend.create_surface_from_hwnd(info.hinstance, info.hwnd),
); );
@ -3256,7 +3286,6 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR(
{ {
unsafe { unsafe {
assert_eq!(info.flags, 0); assert_eq!(info.flags, 0);
assert!(pAllocator.is_null());
*pSurface = Handle::new(instance.backend.create_surface_from_hwnd(info.hwnd)); *pSurface = Handle::new(instance.backend.create_surface_from_hwnd(info.hwnd));
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -3270,12 +3299,12 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR(
pAllocator: *const VkAllocationCallbacks, pAllocator: *const VkAllocationCallbacks,
pSurface: *mut VkSurfaceKHR, pSurface: *mut VkSurfaceKHR,
) -> VkResult { ) -> VkResult {
assert!(pAllocator.is_null());
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
#[cfg(all(feature = "gfx-backend-vulkan", target_os = "linux"))] #[cfg(all(feature = "gfx-backend-vulkan", target_os = "linux"))]
{ {
unsafe { unsafe {
assert_eq!(info.flags, 0); assert_eq!(info.flags, 0);
assert!(pAllocator.is_null());
*pSurface = Handle::new( *pSurface = Handle::new(
instance.backend.create_surface_from_xcb(info.connection as _, info.window), instance.backend.create_surface_from_xcb(info.connection as _, info.window),
); );