mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
Update Skia Rust Bindings
See https://github.com/rust-skia/rust-skia/releases/tag/0.70.0 for a list of changes. The main change for us is that the D3D API was ported to the modern windows rust crate. (cherry picked from commitf809b3ff41
) The previous attempt at merging this surfaced build issue for source builds with Skia, due to the use of an old git version that doesn't understand the new --path-format=relative option the git-sync-deps.py script uses with git rev-parse, as well as the new permission checking that breaks with docker volumes where ~/.cargo is mapped to /cargo and the skia-bindings build performs additional git clones in there, where the resulting user ids will differ. Work around the former by upgrading git, and the latter by adding a wildcard - sadly there's no recursive sub-directory option. This new version also removes ureq from the dependency tree, which means we can revert commit212e28071c
This commit is contained in:
parent
46dd8b1060
commit
e4c087c5b0
7 changed files with 132 additions and 165 deletions
14
.github/workflows/ci.yaml
vendored
14
.github/workflows/ci.yaml
vendored
|
@ -68,13 +68,13 @@ jobs:
|
|||
with:
|
||||
toolchain: ${{ matrix.rust_version }}
|
||||
key: x-v2
|
||||
- name: Pin dependencies to make it build with our MSRV
|
||||
if: matrix.rust_version == '1.70'
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ! -f ./Cargo.lock ]; then
|
||||
cargo update -p ureq --precise 2.9.1
|
||||
fi
|
||||
# - name: Pin dependencies to make it build with our MSRV
|
||||
# if: matrix.rust_version == '1.70'
|
||||
# shell: bash
|
||||
# run: |
|
||||
# if [ ! -f ./Cargo.lock ]; then
|
||||
# cargo update -p ureq --precise 2.9.1
|
||||
# fi
|
||||
- name: Run tests
|
||||
run: DYLD_FRAMEWORK_PATH=$Qt5_DIR/lib cargo test --verbose --all-features --workspace ${{ matrix.extra_args }} --exclude slint-node --exclude pyslint --exclude test-driver-node --exclude slint-node --exclude test-driver-nodejs --exclude test-driver-cpp --exclude mcu-board-support --exclude printerdemo_mcu --exclude uefi-demo --exclude slint-cpp
|
||||
env:
|
||||
|
|
|
@ -11,4 +11,12 @@ RUN dpkg --add-architecture arm64 && \
|
|||
libfontconfig1-dev \
|
||||
clang libstdc++-10-dev:arm64
|
||||
|
||||
# Work around the Skia source build requiring a newer git version (that supports --path-format=relative with rev-parse, as needed by git-sync-deps.py),
|
||||
# as well as a disabling of the directory safety checks (https://github.blog/2022-04-12-git-security-vulnerability-announced/#cve-2022-24765) as
|
||||
# /cargo comes from ~/.cargo and may have differing user ids, which breaks when the skia-bindings build clones additional git repos (skia/third_party/external/*)
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes software-properties-common && \
|
||||
add-apt-repository -y ppa:git-core/ppa && \
|
||||
apt-get install --assume-yes git && \
|
||||
git config --global safe.directory '*'
|
||||
|
||||
ENV PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig
|
||||
|
|
|
@ -11,4 +11,12 @@ RUN dpkg --add-architecture armhf && \
|
|||
libfontconfig1-dev \
|
||||
clang libstdc++-10-dev:armhf
|
||||
|
||||
# Work around the Skia source build requiring a newer git version (that supports --path-format=relative with rev-parse, as needed by git-sync-deps.py),
|
||||
# as well as a disabling of the directory safety checks (https://github.blog/2022-04-12-git-security-vulnerability-announced/#cve-2022-24765) as
|
||||
# /cargo comes from ~/.cargo and may have differing user ids, which breaks when the skia-bindings build clones additional git repos (skia/third_party/external/*)
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes software-properties-common && \
|
||||
add-apt-repository -y ppa:git-core/ppa && \
|
||||
apt-get install --assume-yes git && \
|
||||
git config --global safe.directory '*'
|
||||
|
||||
ENV PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig
|
||||
|
|
|
@ -11,4 +11,12 @@ RUN dpkg --add-architecture riscv64 && \
|
|||
libfontconfig1-dev \
|
||||
clang libstdc++-10-dev:riscv64
|
||||
|
||||
# Work around the Skia source build requiring a newer git version (that supports --path-format=relative with rev-parse, as needed by git-sync-deps.py),
|
||||
# as well as a disabling of the directory safety checks (https://github.blog/2022-04-12-git-security-vulnerability-announced/#cve-2022-24765) as
|
||||
# /cargo comes from ~/.cargo and may have differing user ids, which breaks when the skia-bindings build clones additional git repos (skia/third_party/external/*)
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes software-properties-common && \
|
||||
add-apt-repository -y ppa:git-core/ppa && \
|
||||
apt-get install --assume-yes git && \
|
||||
git config --global safe.directory '*'
|
||||
|
||||
ENV PKG_CONFIG_PATH=/usr/lib/riscv64-linux-gnu/pkgconfig
|
||||
|
|
|
@ -9,3 +9,11 @@ RUN apt-get update && \
|
|||
DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes libfontconfig1-dev libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libinput-dev libgbm-dev python3 \
|
||||
libfontconfig1-dev \
|
||||
clang libstdc++-10-dev
|
||||
|
||||
# Work around the Skia source build requiring a newer git version (that supports --path-format=relative with rev-parse, as needed by git-sync-deps.py),
|
||||
# as well as a disabling of the directory safety checks (https://github.blog/2022-04-12-git-security-vulnerability-announced/#cve-2022-24765) as
|
||||
# /cargo comes from ~/.cargo and may have differing user ids, which breaks when the skia-bindings build clones additional git repos (skia/third_party/external/*)
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes software-properties-common && \
|
||||
add-apt-repository -y ppa:git-core/ppa && \
|
||||
apt-get install --assume-yes git && \
|
||||
git config --global safe.directory '*'
|
||||
|
|
|
@ -42,7 +42,7 @@ pin-weak = "1"
|
|||
scoped-tls-hkt = "0.1"
|
||||
raw-window-handle = { version = "0.5", features = ["std"] }
|
||||
|
||||
skia-safe = { version = "0.69.0", features = ["textlayout", "gl"] }
|
||||
skia-safe = { version = "0.70.0", features = ["textlayout", "gl"] }
|
||||
glow = { version = "0.13" }
|
||||
unicode-segmentation = { version = "1.8.0" }
|
||||
|
||||
|
@ -57,9 +57,8 @@ softbuffer = { workspace = true, default-features = false }
|
|||
bytemuck = { workspace = true }
|
||||
|
||||
[target.'cfg(target_family = "windows")'.dependencies]
|
||||
winapi = { version = "0.3", features = ["impl-default", "dwrite", "d3d12", "dxgi", "dxgi1_2", "dxgi1_3", "dxgi1_4", "d3d12sdklayers", "synchapi", "winbase"] }
|
||||
skia-safe = { version = "0.69.0", features = ["d3d"] }
|
||||
wio = { version = "0.2.2" }
|
||||
windows = { version = "0.52.0", features = ["Win32", "Win32_System_Com", "Win32_Graphics", "Win32_Graphics_Dxgi", "Win32_Graphics_Direct3D12", "Win32_Graphics_Direct3D", "Win32_Foundation", "Win32_Graphics_Dxgi_Common", "Win32_System_Threading", "Win32_Security"] }
|
||||
skia-safe = { version = "0.70.0", features = ["d3d"] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = { version = "0.25.0" }
|
||||
|
@ -69,10 +68,10 @@ metal = { version = "0.27.0" }
|
|||
foreign-types = { version = "0.5.0" }
|
||||
objc = { version = "0.2.7" }
|
||||
core-graphics-types = { version = "0.1.1" }
|
||||
skia-safe = { version = "0.69.0", features = ["metal"] }
|
||||
skia-safe = { version = "0.70.0", features = ["metal"] }
|
||||
|
||||
[target.'cfg(not(any(target_os = "macos", target_family = "windows")))'.dependencies]
|
||||
skia-safe = { version = "0.69.0", features = ["gl"] }
|
||||
skia-safe = { version = "0.70.0", features = ["gl"] }
|
||||
|
||||
[build-dependencies]
|
||||
cfg_aliases = { workspace = true }
|
||||
|
|
|
@ -4,88 +4,69 @@
|
|||
use i_slint_core::api::PhysicalSize as PhysicalWindowSize;
|
||||
use i_slint_core::platform::PlatformError;
|
||||
use std::cell::RefCell;
|
||||
use windows::core::ComInterface;
|
||||
use windows::Win32::Graphics::Direct3D::D3D_FEATURE_LEVEL_11_0;
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
|
||||
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
|
||||
use winapi::{
|
||||
shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgiformat},
|
||||
shared::{
|
||||
dxgitype,
|
||||
guiddef::GUID,
|
||||
winerror::{DXGI_STATUS_OCCLUDED, HRESULT, S_OK},
|
||||
},
|
||||
um::{d3d12, d3dcommon},
|
||||
Interface,
|
||||
use windows::Win32::Foundation::{DXGI_STATUS_OCCLUDED, HANDLE, HWND, S_OK};
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
D3D12CreateDevice, ID3D12CommandQueue, ID3D12Device, ID3D12Fence, ID3D12Resource,
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_DESC, D3D12_FENCE_FLAG_NONE,
|
||||
D3D12_RESOURCE_STATE_PRESENT,
|
||||
};
|
||||
use wio::com::ComPtr;
|
||||
|
||||
fn resolve_interface<T: Interface>(
|
||||
f: impl FnOnce(&GUID, &mut *mut std::ffi::c_void) -> HRESULT,
|
||||
) -> Result<ComPtr<T>, HRESULT> {
|
||||
let mut ptr: *mut std::ffi::c_void = std::ptr::null_mut();
|
||||
let r = f(&T::uuidof(), &mut ptr);
|
||||
if r == S_OK {
|
||||
Ok(unsafe { ComPtr::from_raw(ptr as *mut T) })
|
||||
} else {
|
||||
Err(r)
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_specific<T: Interface>(
|
||||
f: impl FnOnce(&mut *mut T) -> HRESULT,
|
||||
) -> Result<ComPtr<T>, HRESULT> {
|
||||
let mut ptr: *mut T = std::ptr::null_mut();
|
||||
let r = f(&mut ptr);
|
||||
if r == S_OK {
|
||||
Ok(unsafe { ComPtr::from_raw(ptr) })
|
||||
} else {
|
||||
Err(r)
|
||||
}
|
||||
}
|
||||
use windows::Win32::Graphics::Dxgi::{
|
||||
Common::{DXGI_FORMAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC},
|
||||
CreateDXGIFactory2, IDXGIFactory4, IDXGISwapChain3, DXGI_ADAPTER_DESC1, DXGI_ADAPTER_FLAG,
|
||||
DXGI_ADAPTER_FLAG_NONE, DXGI_ADAPTER_FLAG_SOFTWARE, DXGI_SWAP_CHAIN_DESC,
|
||||
DXGI_SWAP_CHAIN_DESC1, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
};
|
||||
use windows::Win32::System::Threading::{CreateEventW, WaitForSingleObjectEx, INFINITE};
|
||||
|
||||
trait MapToPlatformError<T> {
|
||||
fn map_platform_error(self, msg: &str) -> Result<T, PlatformError>;
|
||||
fn map_platform_error(self, msg: &str) -> std::result::Result<T, PlatformError>;
|
||||
}
|
||||
|
||||
impl<T> MapToPlatformError<T> for Result<T, HRESULT> {
|
||||
fn map_platform_error(self, msg: &str) -> Result<T, PlatformError> {
|
||||
impl<T> MapToPlatformError<T> for windows::core::Result<T> {
|
||||
fn map_platform_error(self, msg: &str) -> std::result::Result<T, PlatformError> {
|
||||
match self {
|
||||
Ok(r) => Ok(r),
|
||||
Err(hr) => Err(format!("{} failed. {:x}", msg, hr).into()),
|
||||
Err(hr) => Err(format!("{} failed. {:x}", msg, hr.code().0).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_SURFACE_FORMAT: dxgiformat::DXGI_FORMAT = dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
const DEFAULT_SURFACE_FORMAT: DXGI_FORMAT = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
struct SwapChain {
|
||||
command_queue: ComPtr<d3d12::ID3D12CommandQueue>,
|
||||
swap_chain: ComPtr<dxgi1_4::IDXGISwapChain3>,
|
||||
command_queue: ID3D12CommandQueue,
|
||||
swap_chain: IDXGISwapChain3,
|
||||
surfaces: Option<[skia_safe::Surface; 2]>,
|
||||
current_buffer_index: usize,
|
||||
fence: ComPtr<d3d12::ID3D12Fence>,
|
||||
fence: ID3D12Fence,
|
||||
fence_values: [u64; 2],
|
||||
fence_event: *mut std::ffi::c_void,
|
||||
fence_event: HANDLE,
|
||||
gr_context: skia_safe::gpu::DirectContext,
|
||||
}
|
||||
|
||||
impl SwapChain {
|
||||
fn new(
|
||||
command_queue: ComPtr<d3d12::ID3D12CommandQueue>,
|
||||
device: &ComPtr<d3d12::ID3D12Device>,
|
||||
command_queue: ID3D12CommandQueue,
|
||||
device: &ID3D12Device,
|
||||
mut gr_context: skia_safe::gpu::DirectContext,
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
size: PhysicalWindowSize,
|
||||
dxgi_factory: &ComPtr<dxgi1_4::IDXGIFactory4>,
|
||||
dxgi_factory: &IDXGIFactory4,
|
||||
) -> Result<Self, PlatformError> {
|
||||
let swap_chain_desc = dxgi1_2::DXGI_SWAP_CHAIN_DESC1 {
|
||||
let swap_chain_desc = DXGI_SWAP_CHAIN_DESC1 {
|
||||
Width: size.width,
|
||||
Height: size.height,
|
||||
Format: DEFAULT_SURFACE_FORMAT,
|
||||
BufferCount: 2,
|
||||
BufferUsage: dxgitype::DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
SwapEffect: dxgi::DXGI_SWAP_EFFECT_FLIP_DISCARD,
|
||||
SampleDesc: dxgitype::DXGI_SAMPLE_DESC { Count: 1, ..Default::default() },
|
||||
BufferUsage: DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
SwapEffect: DXGI_SWAP_EFFECT_FLIP_DISCARD,
|
||||
SampleDesc: DXGI_SAMPLE_DESC { Count: 1, ..Default::default() },
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -93,37 +74,27 @@ impl SwapChain {
|
|||
raw_window_handle::RawWindowHandle::Win32(raw_window_handle::Win32WindowHandle {
|
||||
hwnd,
|
||||
..
|
||||
}) => hwnd,
|
||||
}) => HWND(hwnd as _),
|
||||
_ => {
|
||||
return Err(format!("Metal surface is only supported with Win32WindowHandle").into())
|
||||
}
|
||||
};
|
||||
|
||||
let swap_chain1 = resolve_specific(|ptr| unsafe {
|
||||
dxgi_factory.CreateSwapChainForHwnd(
|
||||
command_queue.as_raw() as _,
|
||||
hwnd as _,
|
||||
&swap_chain_desc,
|
||||
std::ptr::null(),
|
||||
std::ptr::null_mut(),
|
||||
ptr,
|
||||
)
|
||||
})
|
||||
let swap_chain1 = unsafe {
|
||||
dxgi_factory.CreateSwapChainForHwnd(&command_queue, hwnd, &swap_chain_desc, None, None)
|
||||
}
|
||||
.map_platform_error("unable to create D3D swap chain")?;
|
||||
|
||||
let swap_chain: ComPtr<dxgi1_4::IDXGISwapChain3> =
|
||||
let swap_chain: IDXGISwapChain3 =
|
||||
swap_chain1.cast().map_platform_error("unable to cast swap chain 1 to v3")?;
|
||||
|
||||
let fence = resolve_interface(|iid, ptr| unsafe {
|
||||
device.CreateFence(0, d3d12::D3D12_FENCE_FLAG_NONE, iid, ptr)
|
||||
})
|
||||
.map_platform_error("unable to create D3D12 fence")?;
|
||||
let fence = unsafe { device.CreateFence(0, D3D12_FENCE_FLAG_NONE) }
|
||||
.map_platform_error("unable to create D3D12 fence")?;
|
||||
|
||||
let fence_values = [0, 0];
|
||||
|
||||
let fence_event = unsafe {
|
||||
winapi::um::synchapi::CreateEventW(std::ptr::null_mut(), 0, 0, std::ptr::null())
|
||||
};
|
||||
let fence_event = unsafe { CreateEventW(None, false, false, None) }
|
||||
.map_platform_error("error creating fence event")?;
|
||||
|
||||
let current_buffer_index = unsafe { swap_chain.GetCurrentBackBufferIndex() } as usize;
|
||||
|
||||
|
@ -176,35 +147,26 @@ impl SwapChain {
|
|||
|
||||
let present_result = unsafe { self.swap_chain.Present(1, 0) };
|
||||
if present_result != S_OK && present_result != DXGI_STATUS_OCCLUDED {
|
||||
return Err(format!("Error presenting d3d swap chain: {:x}", present_result).into());
|
||||
return Err(format!("Error presenting d3d swap chain: {:x}", present_result.0).into());
|
||||
}
|
||||
|
||||
let signal_result = unsafe {
|
||||
self.command_queue
|
||||
.Signal(self.fence.as_raw() as _, self.fence_values[self.current_buffer_index])
|
||||
};
|
||||
if signal_result != S_OK {
|
||||
return Err(format!(
|
||||
"error setting up completion signal for d3d12 command queue: {:x}",
|
||||
signal_result
|
||||
)
|
||||
.into());
|
||||
unsafe {
|
||||
self.command_queue.Signal(&self.fence, self.fence_values[self.current_buffer_index])
|
||||
}
|
||||
.map_platform_error("error setting up completion signal for d3d12 command queue")?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn create_surfaces(
|
||||
swap_chain: &ComPtr<dxgi1_4::IDXGISwapChain3>,
|
||||
swap_chain: &IDXGISwapChain3,
|
||||
gr_context: &mut skia_safe::gpu::DirectContext,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) -> Result<[skia_safe::Surface; 2], PlatformError> {
|
||||
let mut make_surface = |buffer_index| {
|
||||
let buffer: ComPtr<d3d12::ID3D12Resource> = resolve_interface(|iid, ptr| unsafe {
|
||||
swap_chain.GetBuffer(buffer_index, iid, ptr)
|
||||
})
|
||||
.map_err(|hr| format!("unable to retrieve swap chain back buffer: {hr}"))?;
|
||||
let buffer: ID3D12Resource = unsafe { swap_chain.GetBuffer(buffer_index) }
|
||||
.map_err(|hr| format!("unable to retrieve swap chain back buffer: {hr}"))?;
|
||||
|
||||
debug_assert_eq!(unsafe { buffer.GetDesc().Width }, width as u64);
|
||||
debug_assert_eq!(unsafe { buffer.GetDesc().Height }, height as u32);
|
||||
|
@ -212,11 +174,11 @@ impl SwapChain {
|
|||
let texture_info = skia_safe::gpu::d3d::TextureResourceInfo {
|
||||
resource: buffer,
|
||||
alloc: None,
|
||||
resource_state: d3d12::D3D12_RESOURCE_STATE_PRESENT,
|
||||
resource_state: D3D12_RESOURCE_STATE_PRESENT,
|
||||
format: DEFAULT_SURFACE_FORMAT,
|
||||
sample_count: 1,
|
||||
level_count: 1,
|
||||
sample_quality_pattern: dxgitype::DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN,
|
||||
sample_quality_pattern: DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN,
|
||||
protected: skia_safe::gpu::Protected::No,
|
||||
};
|
||||
let backend_texture =
|
||||
|
@ -248,15 +210,8 @@ impl SwapChain {
|
|||
|
||||
drop(self.surfaces.take());
|
||||
|
||||
unsafe {
|
||||
let resize_result =
|
||||
self.swap_chain.ResizeBuffers(0, width, height, DEFAULT_SURFACE_FORMAT, 0);
|
||||
if resize_result != S_OK {
|
||||
return Err(
|
||||
format!("Error resizing swap chain buffers: {:x}", resize_result).into()
|
||||
);
|
||||
}
|
||||
}
|
||||
unsafe { self.swap_chain.ResizeBuffers(0, width, height, DEFAULT_SURFACE_FORMAT, 0) }
|
||||
.map_platform_error("Error resizing swap chain buffers")?;
|
||||
|
||||
self.surfaces = Some(Self::create_surfaces(
|
||||
&self.swap_chain,
|
||||
|
@ -269,22 +224,13 @@ impl SwapChain {
|
|||
|
||||
fn wait_for_buffer(&mut self, buffer_index: usize) -> Result<(), PlatformError> {
|
||||
if unsafe { self.fence.GetCompletedValue() } < self.fence_values[buffer_index] {
|
||||
let set_completion_result = unsafe {
|
||||
self.fence.SetEventOnCompletion(self.fence_values[buffer_index], self.fence_event)
|
||||
};
|
||||
if set_completion_result != S_OK {
|
||||
return Err(format!(
|
||||
"error setting event on command queue completion: {:x}",
|
||||
set_completion_result
|
||||
)
|
||||
.into());
|
||||
}
|
||||
unsafe {
|
||||
winapi::um::synchapi::WaitForSingleObjectEx(
|
||||
self.fence_event,
|
||||
winapi::um::winbase::INFINITE,
|
||||
0,
|
||||
);
|
||||
self.fence.SetEventOnCompletion(self.fence_values[buffer_index], self.fence_event)
|
||||
}
|
||||
.map_platform_error("error setting event on command queue completion")?;
|
||||
|
||||
unsafe {
|
||||
WaitForSingleObjectEx(self.fence_event, INFINITE, false);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -318,10 +264,8 @@ impl super::Surface for D3DSurface {
|
|||
}
|
||||
*/
|
||||
|
||||
let dxgi_factory: ComPtr<dxgi1_4::IDXGIFactory4> = resolve_interface(|iid, ptr| unsafe {
|
||||
dxgi1_3::CreateDXGIFactory2(factory_flags, iid, ptr)
|
||||
})
|
||||
.map_err(|hr| format!("unable to create DXGIFactory4: {hr}"))?;
|
||||
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(factory_flags) }
|
||||
.map_platform_error("unable to create DXGIFactory4")?;
|
||||
|
||||
let mut software_adapter_index = None;
|
||||
let use_warp = std::env::var("SLINT_D3D_USE_WARP").is_ok();
|
||||
|
@ -329,17 +273,17 @@ impl super::Surface for D3DSurface {
|
|||
let adapter = {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
let adapter =
|
||||
match resolve_specific(|ptr| unsafe { dxgi_factory.EnumAdapters1(i, ptr) }) {
|
||||
Ok(adapter) => adapter,
|
||||
Err(_) => break None,
|
||||
};
|
||||
let adapter = match unsafe { dxgi_factory.EnumAdapters1(i) } {
|
||||
Ok(adapter) => adapter,
|
||||
Err(_) => break None,
|
||||
};
|
||||
|
||||
let mut desc = dxgi::DXGI_ADAPTER_DESC1::default();
|
||||
unsafe { adapter.GetDesc1(&mut desc) };
|
||||
let mut desc = DXGI_ADAPTER_DESC1::default();
|
||||
let _ = unsafe { adapter.GetDesc1(&mut desc) };
|
||||
|
||||
let adapter_is_warp =
|
||||
(desc.Flags & dxgi::DXGI_ADAPTER_FLAG_SOFTWARE) != dxgi::DXGI_ADAPTER_FLAG_NONE;
|
||||
let adapter_is_warp = (DXGI_ADAPTER_FLAG(desc.Flags as i32)
|
||||
& DXGI_ADAPTER_FLAG_SOFTWARE)
|
||||
!= DXGI_ADAPTER_FLAG_NONE;
|
||||
|
||||
if adapter_is_warp {
|
||||
if software_adapter_index.is_none() {
|
||||
|
@ -362,13 +306,13 @@ impl super::Surface for D3DSurface {
|
|||
// Check to see whether the adapter supports Direct3D 12, but don't
|
||||
// create the actual device yet.
|
||||
if unsafe {
|
||||
d3d12::D3D12CreateDevice(
|
||||
adapter.as_raw() as _,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_11_0,
|
||||
&d3d12::ID3D12Device::uuidof(),
|
||||
std::ptr::null_mut(),
|
||||
D3D12CreateDevice(
|
||||
&adapter,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
std::ptr::null_mut::<Option<ID3D12Device>>(),
|
||||
)
|
||||
} == S_OK
|
||||
}
|
||||
.is_ok()
|
||||
{
|
||||
break Some(adapter);
|
||||
}
|
||||
|
@ -381,33 +325,24 @@ impl super::Surface for D3DSurface {
|
|||
|| {
|
||||
let software_adapter_index = software_adapter_index
|
||||
.ok_or_else(|| format!("unable to locate D3D software adapter"))?;
|
||||
resolve_specific(|ptr| unsafe {
|
||||
dxgi_factory.EnumAdapters1(software_adapter_index, ptr)
|
||||
})
|
||||
.map_err(|hr| format!("unable to create D3D software adapter: {hr}"))
|
||||
unsafe { dxgi_factory.EnumAdapters1(software_adapter_index) }
|
||||
.map_err(|hr| format!("unable to create D3D software adapter: {hr}"))
|
||||
},
|
||||
|adapter| Ok(adapter),
|
||||
)?;
|
||||
|
||||
let device: ComPtr<d3d12::ID3D12Device> = resolve_interface(|iid, ptr| unsafe {
|
||||
d3d12::D3D12CreateDevice(
|
||||
adapter.as_raw() as _,
|
||||
d3dcommon::D3D_FEATURE_LEVEL_11_0,
|
||||
iid,
|
||||
ptr,
|
||||
)
|
||||
})
|
||||
.map_platform_error("error calling D3D12CreateDevice")?;
|
||||
let mut device: Option<ID3D12Device> = None;
|
||||
unsafe { D3D12CreateDevice(&adapter, D3D_FEATURE_LEVEL_11_0, &mut device) }
|
||||
.map_platform_error("error calling D3D12CreateDevice")?;
|
||||
let device = device.unwrap();
|
||||
|
||||
let queue: ComPtr<d3d12::ID3D12CommandQueue> = {
|
||||
let desc = d3d12::D3D12_COMMAND_QUEUE_DESC {
|
||||
Type: d3d12::D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
Priority: d3d12::D3D12_COMMAND_QUEUE_PRIORITY_NORMAL as _,
|
||||
Flags: d3d12::D3D12_COMMAND_QUEUE_FLAG_NONE,
|
||||
NodeMask: 0,
|
||||
let queue: ID3D12CommandQueue = {
|
||||
let desc = D3D12_COMMAND_QUEUE_DESC {
|
||||
Type: D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
resolve_interface(|iid, ptr| unsafe { device.CreateCommandQueue(&desc, iid, ptr) })
|
||||
unsafe { device.CreateCommandQueue(&desc) }
|
||||
.map_platform_error("Creating command queue")?
|
||||
};
|
||||
|
||||
|
@ -458,8 +393,9 @@ impl super::Surface for D3DSurface {
|
|||
}
|
||||
|
||||
fn bits_per_pixel(&self) -> Result<u8, i_slint_core::platform::PlatformError> {
|
||||
let mut desc = dxgi::DXGI_SWAP_CHAIN_DESC::default();
|
||||
unsafe { self.swap_chain.borrow().swap_chain.GetDesc(&mut desc) };
|
||||
let mut desc = DXGI_SWAP_CHAIN_DESC::default();
|
||||
unsafe { self.swap_chain.borrow().swap_chain.GetDesc(&mut desc) }
|
||||
.map_platform_error("error getting swap chain description")?;
|
||||
Ok(match desc.BufferDesc.Format {
|
||||
DEFAULT_SURFACE_FORMAT => 32,
|
||||
fmt @ _ => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue