Skip to content

Commit 9893a38

Browse files
committed
MS Windows support
- Add support for Windows: surface creation and DLL loading. - Add Getting Started documentation for Windows. - Test Getting Started docs for both platforms in fresh VMs. - Tidy README and add badges.
1 parent 135f054 commit 9893a38

File tree

13 files changed

+251
-120
lines changed

13 files changed

+251
-120
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ${{ matrix.os }}
1313
strategy:
1414
matrix:
15-
os: [macOS-latest] # ubuntu-latest, windows-latest
15+
os: [macOS-latest, windows-latest] # ubuntu-latest
1616
cabal: ["3.2"]
1717
ghc:
1818
- "8.10.5"

GettingStarted.md

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Getting Started
2+
3+
Please see the platform-specific guides below:
4+
- [Apple macOS](#macOS)
5+
- [Microsoft Windows](#windows)
6+
7+
## Apple macOS
8+
9+
These instructions are only a suggestion. Other setup options are possible.
10+
These instructions were tested manually in a fresh Virtual Machine installation
11+
of macOS Big Sur (11.5.2) on 2021-08-21.
12+
13+
### Toolchain Installation
14+
15+
1. Install the
16+
[Rust toolchain](https://www.rust-lang.org/tools/install) using `rustup`.
17+
18+
1. Install the [Haskell toolchain](https://www.haskell.org/ghcup/) using
19+
`ghcup`. You may need to run the install command twice, the second time
20+
after being prompted to install the XCode command line tools. Instructions
21+
will be displayed in the terminal. You may need to use `ghcup tui` to
22+
select an appropriate GHC version (GHC 8.10.5).
23+
24+
### Build and Run an Example
25+
26+
1. Clone the repository. In a terminal:
27+
28+
```sh
29+
git clone https://github.com/lancelet/wgpu-hs.git
30+
cd wgpu-hs
31+
git submodule update --init --recursive
32+
```
33+
34+
1. Build the Rust library `libwgpu_native.dylib`:
35+
36+
```sh
37+
pushd wgpu-raw-hs-codegen/wgpu-native
38+
WGPU_NATIVE_VERSION='v0.9.2.2' make lib-native
39+
popd
40+
```
41+
42+
1. Set `LD_LIBRARY_PATH` to include the Rust dynamic library that was just
43+
built:
44+
45+
```sh
46+
export LD_LIBRARY_PATH=$(pwd)/wgpu-raw-hs-codegen/wgpu-native/target/debug/:$LD_LIBRARY_PATH
47+
```
48+
49+
1. Build and run the `triangle` example:
50+
51+
```sh
52+
cabal run triangle
53+
```
54+
55+
![triangle demo](triangle-demo.png)
56+
57+
## Microsoft Windows
58+
59+
These instructions are only a suggestion. Other setup options are possible.
60+
These instructions were tested manually in a fresh Virtual Machine installation
61+
of Windows 10 on 2021-08-21.
62+
63+
### Toolchain Installation
64+
65+
1. Install the
66+
[Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/).
67+
Select the "Desktop development with C++" option as a minimum.
68+
69+
1. Install the [Rust toolchain](https://www.rust-lang.org/tools/install) using
70+
`rustup` (ie. `RUSTUP-INIT.EXE` - 64 bit).
71+
72+
1. Install the [Haskell toolchain](https://www.haskell.org/ghcup/) using
73+
`ghcup`. `HLS` and `Stack` are optional installations, but make sure to
74+
install `MSys2`. You may need to use `ghcup tui` to select an appropriate
75+
GHC version (GHC 8.10.5).
76+
77+
1. Install the [Chocolatey](https://chocolatey.org/) package manager.
78+
79+
1. Install the required Chocolatey packages. In an Administrator PowerShell:
80+
81+
```powershell
82+
choco install git make llvm -y
83+
```
84+
85+
### Build and Run an Example
86+
87+
1. Clone the repository. In PowerShell:
88+
89+
```powershell
90+
git clone https://github.com/lancelet/wgpu-hs.git
91+
cd wgpu-hs
92+
git submodule update --init --recursive
93+
```
94+
95+
1. Build the Rust library `wgpu-native.dll`:
96+
97+
```powershell
98+
pushd wgpu-raw-hs-codegen/wgpu-native
99+
set WGPU_NATIVE_VERSION='v0.9.2.2'
100+
make lib-native
101+
popd
102+
```
103+
104+
1. Copy the DLL file so that it can be found when running the example:
105+
106+
```powershell
107+
cp wgpu-raw-hs-codegen/wgpu-native/target/debug/wgpu_native.dll wgpu_native.dll
108+
```
109+
110+
1. Build and run the `triangle` example:
111+
112+
```powershell
113+
cabal run triangle
114+
```

README.md

+4-52
Original file line numberDiff line numberDiff line change
@@ -13,57 +13,9 @@
1313

1414
This repository contains Haskell bindings for
1515
[wgpu-native](https://github.com/gfx-rs/wgpu-native).
16-
These bindings are in an early stage of development and are not yet stable.
1716

18-
Currently, only macOS is supported by these Haskell bindings. Adding other
19-
platforms should be relatively trivial but requires testing.
20-
21-
## Building and Running
22-
23-
You will need a working Rust toolchain.
24-
25-
To build and run an example:
26-
27-
1. Clone the repository and make sure that all git submodules are checked
28-
out:
29-
30-
```
31-
git clone https://github.com/lancelet/wgpu-hs.git
32-
cd wgpu-hs
33-
git submodule update --init --recursive
34-
```
35-
36-
2. Build the Rust libraries. The `WGPU_NATIVE_VERSION` environment variable
37-
is optional, but if it is supplied, it bakes the specified version number
38-
into the dynamic library binary.
39-
40-
```
41-
pushd wgpu-raw-hs-codegen/wgpu-native
42-
WGPU_NATIVE_VERSION='v0.9.2.2' make lib-native
43-
popd
44-
```
45-
46-
3. Set `LD_LIBRARY_PATH` to include the Rust libraries that were just built.
47-
The Rust build steps will have produced a dynamic library, called
48-
`libwgpu_native.dylib` on macOS. The example code loads this library at
49-
runtime. `LD_LIBRARY_PATH` is a standard environment variable that allows
50-
the system dynamic loader to find the library.
51-
52-
```
53-
export LD_LIBRARY_PATH=$(pwd)/wgpu-raw-hs-codegen/wgpu-native/target/debug/:$LD_LIBRARY_PATH
54-
```
55-
56-
4. Build and run the `triangle` example:
57-
58-
```
59-
export METAL_DEVICE_WRAPPER_TYPE=1
60-
cabal run triangle
61-
```
62-
63-
The environment variable `METAL_DEVICE_WRAPPER_TYPE` enables Metal API
64-
validation.
65-
66-
If everything went well, you should see the initial triangle demo:
67-
68-
![triangle demo](triangle-demo.png)
17+
Currently, only macOS and Windows are supported by these Haskell bindings.
18+
Adding Linux is on the roadmap.
6919

20+
To get started, please read the [Getting Started](GettingStarted.md)
21+
instructions.

wgpu-hs/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Revision history for wgpu-hs
22

3+
## 0.2.0.0 -- 2021-08-22
4+
5+
- Added MS Windows support for surfaces and DLL loading.
6+
- Added `withPlatformInstance`: select dynamic library name based on platform.
7+
38
## 0.1.0.0 -- 2021-08-20
49

510
- Initial (incomplete) API bindings started.

wgpu-hs/examples/triangle/Main.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ main = do
4040
TextIO.putStrLn "Failed to create GLFW window"
4141
exitFailure
4242

43-
WGPU.withInstance "libwgpu_native.dylib" (Just WGPU.logStdout) $ \inst -> do
43+
WGPU.withPlatformInstance (Just WGPU.logStdout) $ \inst -> do
4444
-- set the logging level
4545
WGPU.setLogLevel inst WGPU.Warn
4646

wgpu-hs/src-internal/WGPU/Internal/Instance.hs

+46-11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module WGPU.Internal.Instance
1313
--
1414
-- $instance
1515
Instance (..),
16+
withPlatformInstance,
1617
withInstance,
1718

1819
-- * Logging
@@ -36,6 +37,7 @@ import qualified Data.Text.IO as TextIO
3637
import Data.Word (Word32, Word8)
3738
import Foreign (Ptr, freeHaskellFunPtr, nullFunPtr)
3839
import Foreign.C (CChar, peekCString)
40+
import qualified System.Info
3941
import WGPU.Internal.Memory (ToRaw, raw)
4042
import WGPU.Raw.Dynamic (withWGPU)
4143
import WGPU.Raw.Generated.Enum.WGPULogLevel (WGPULogLevel (WGPULogLevel))
@@ -78,17 +80,23 @@ instance ToRaw Instance WGPUHsInstance where
7880

7981
-------------------------------------------------------------------------------
8082

81-
-- | Logging level.
82-
data LogLevel
83-
= Trace
84-
| Debug
85-
| Info
86-
| Warn
87-
| Error
88-
deriving (Eq, Show)
89-
90-
-- | Logging callback function.
91-
type LogCallback = LogLevel -> Text -> IO ()
83+
-- | Load the WGPU API from a dynamic library and supply an 'Instance' to a
84+
-- program.
85+
--
86+
-- This is the same as 'withInstance', except that it uses a default,
87+
-- per-platform name for the library, based on the value returned by
88+
-- 'System.Info.os'.
89+
withPlatformInstance ::
90+
-- | Optional logging callback. @'Just' 'logStdout'@ can be supplied here to
91+
-- print log messages to @stdout@ for debugging purposes.
92+
Maybe LogCallback ->
93+
-- | The Program. A function which takes an 'Instance' and returns an IO
94+
-- action that uses the instance.
95+
(Instance -> IO a) ->
96+
-- | IO action which loads the WGPU 'Instance', passes it to the program, and
97+
-- returns the result of running the program.
98+
IO a
99+
withPlatformInstance = withInstance platformDylibName
92100

93101
-- | Load the WGPU API from a dynamic library and supply an 'Instance' to a
94102
-- program.
@@ -125,6 +133,33 @@ withInstance dylibPath mLog program =
125133

126134
pure result
127135

136+
-- | Return the dynamic library name for a given platform.
137+
--
138+
-- This is the dynamic library name that should be passed to the 'withInstance'
139+
-- function to load the dynamic library.
140+
platformDylibName :: FilePath
141+
platformDylibName =
142+
case System.Info.os of
143+
"darwin" -> "libwgpu_native.dylib"
144+
"mingw32" -> "wgpu_native.dll"
145+
"linux" -> "libwgpu_native.dylib"
146+
other ->
147+
error $ "platformDylibName: unknown / unhandled platform: " <> other
148+
149+
-------------------------------------------------------------------------------
150+
151+
-- | Logging level.
152+
data LogLevel
153+
= Trace
154+
| Debug
155+
| Info
156+
| Warn
157+
| Error
158+
deriving (Eq, Show)
159+
160+
-- | Logging callback function.
161+
type LogCallback = LogLevel -> Text -> IO ()
162+
128163
-- | Set the current logging level for the instance.
129164
setLogLevel :: Instance -> LogLevel -> IO ()
130165
setLogLevel inst lvl =

0 commit comments

Comments
 (0)