mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
Import vkd3d pages from MediaWiki.
commit
52846c72fc
362
Building-a-MinGW-WoW64-Wine-with-a-custom-vkd3d-build.md
Normal file
362
Building-a-MinGW-WoW64-Wine-with-a-custom-vkd3d-build.md
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
As of version 7.4, Wine comes with a bundled version of vkd3d.
|
||||||
|
|
||||||
|
However, if you want to use a more modern version of vkd3d, apply
|
||||||
|
certain patches to it, or test fixes of your own, you will need Wine to
|
||||||
|
work with a custom version of vkd3d.
|
||||||
|
|
||||||
|
For this purpose, it is necessary to build both projects and link them
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
Compiling a Windows on Windows (WoW) version of Wine, so that it
|
||||||
|
supports both 32-bits and 64-bits Windows applications – which is often
|
||||||
|
desired – adds a layer of complexity to the build process.
|
||||||
|
|
||||||
|
Furthermore, you may want to use MinGW to cross-compile the Wine
|
||||||
|
executables and DLLs in the Windows PE format. This is because various
|
||||||
|
programs expect the on-disk DLLs to look like real PE DLLs.
|
||||||
|
|
||||||
|
This guide aims to help you through that process.
|
||||||
|
|
||||||
|
# Preliminaries
|
||||||
|
|
||||||
|
## Install Wine dependencies
|
||||||
|
|
||||||
|
First, install the dependencies listed in the [Building
|
||||||
|
Wine](https://gitlab.winehq.org/wine/wine/-/wikis/Building-Wine#satisfying-build-dependencies) article.
|
||||||
|
|
||||||
|
Remember to install the `:i386` version of the required packages too (if
|
||||||
|
your system has multi-lib support).
|
||||||
|
|
||||||
|
The **mingw** and **vulkan** packages are of particular importance.
|
||||||
|
|
||||||
|
It is also recommended that you install `ccache`, as it may save us a
|
||||||
|
considerable amount of time during the builds.
|
||||||
|
|
||||||
|
If you have a system-wide installation of vkd3d, it may be good to
|
||||||
|
uninstall it using `make uninstall`. To ensure that the correct version
|
||||||
|
of vkd3d is linked in this tutorial.
|
||||||
|
|
||||||
|
## Directory organization
|
||||||
|
|
||||||
|
For this tutorial we will need to create several build directories and
|
||||||
|
have several git repositories. For this reason, we will start by
|
||||||
|
creating a common directory for them:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ mkdir -p $HOME/wine-dirs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cloning `wine` and `vkd3d` repositories
|
||||||
|
|
||||||
|
First, we clone the `wine` repository if we haven't already:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ git clone https://gitlab.winehq.org/wine/wine.git $HOME/wine-dirs/wine-git
|
||||||
|
```
|
||||||
|
|
||||||
|
We also need to clone `vkd3d` repository if we haven't already:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ git clone https://gitlab.winehq.org/wine/vkd3d.git $HOME/wine-dirs/vkd3d-git
|
||||||
|
```
|
||||||
|
|
||||||
|
In case you already have these repositories somewhere else, you can
|
||||||
|
create symbolic links inside `wine-dirs` instead:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd $HOME/wine-dirs
|
||||||
|
$ ln -s <relative-path-to-wine-repo> wine-git
|
||||||
|
$ ln -s <relative-path-to-vkd3d-repo> vkd3d-git
|
||||||
|
```
|
||||||
|
|
||||||
|
Now it is a good time to pick a particular branch or apply the desired
|
||||||
|
patches to these repositories.
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
## Build WIDL
|
||||||
|
|
||||||
|
If the distribution provides a recent enough version (3.21 or later as
|
||||||
|
of this writing) of WIDL, we can skip this step. On Debian that's
|
||||||
|
provided by the `mingw-w64-tools` package. We can also skip this step if
|
||||||
|
we already have 64-bit Wine available and built.
|
||||||
|
|
||||||
|
Vkd3d uses WIDL to compile its IDL files, and if the distribution
|
||||||
|
doesn't provide a package, we'll have to build it from the Wine
|
||||||
|
repository to get it. We start by creating the build directory:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd $HOME/wine-dirs
|
||||||
|
$ mkdir wine64p
|
||||||
|
```
|
||||||
|
|
||||||
|
We run the Wine `configure` script from the installation folder
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd wine64p
|
||||||
|
$ ../wine-git/configure --enable-win64 CC='ccache gcc' x86_64_CC='ccache x86_64-w64-mingw32-gcc'
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that we use `x86_64_CC` to indicate the compiler used for
|
||||||
|
cross-compilation, in this case we need the 64-bit mingw32 compiler. We
|
||||||
|
prepend `ccache` which works as a wrapper for the compiler. The same is
|
||||||
|
done for the regular C compiler, `gcc`, passed with the `CC` variable.
|
||||||
|
|
||||||
|
Note that to know about other parameters for the `configure` script we
|
||||||
|
can use:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ ../wine-git/configure --help
|
||||||
|
```
|
||||||
|
|
||||||
|
Also, if something from the configure command fails, it is useful to
|
||||||
|
search in `config.log` for the line that contains the pertinent error,
|
||||||
|
and the lines before and after it.
|
||||||
|
|
||||||
|
Once the configure script has finished, we use `make tools/widl/widl` to
|
||||||
|
only compile WIDL. We can pass `-j`<n> to use <n> threads.
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ make -j8 tools/widl/widl
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build a 64-bit vkd3d installation
|
||||||
|
|
||||||
|
Now we need to build 64-bit vkd3d. For that purpose we will also need
|
||||||
|
the Vulkan and SPIR-V headers. One way of getting them is downloading
|
||||||
|
the [Vulkan SDK](https://vulkan.lunarg.com).
|
||||||
|
|
||||||
|
Alternativelly, you can get them from the official
|
||||||
|
[Vulkan-Headers](https://github.com/KhronosGroup/Vulkan-Headers) and
|
||||||
|
[SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers)
|
||||||
|
repositories.
|
||||||
|
|
||||||
|
Another alternative is to copy them from your distribution. Usually the
|
||||||
|
host headers will be installed in `/usr/include/vulkan/` and
|
||||||
|
`/usr/include/spirv/`.
|
||||||
|
|
||||||
|
Assuming you downloaded and extracted the SDK, move it to the common
|
||||||
|
directory:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ mv <vulkan sdk path> $HOME/wine-dirs/vulkan-sdk
|
||||||
|
```
|
||||||
|
|
||||||
|
You must change the first argument of the `mv` command depending on
|
||||||
|
where you downloaded and extracted the SDK. e.g.
|
||||||
|
`~/Downloads/vulkansdk-linux-x86_64-1.3.204.1/1.3.204.1`.
|
||||||
|
|
||||||
|
We have to run `autogen.sh` in `vkd3d-git` to generate vkd3d's
|
||||||
|
`configure` script
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd $HOME/wine-dirs/vkd3d-git
|
||||||
|
$ ./autogen.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we create a folder for the 64-bit vkd3d build
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd $HOME/wine-dirs
|
||||||
|
$ mkdir vkd3d64
|
||||||
|
```
|
||||||
|
|
||||||
|
We run the configure script in the installation folder:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd vkd3d64
|
||||||
|
$ ../vkd3d-git/configure \
|
||||||
|
--host=x86_64-w64-mingw32 \
|
||||||
|
--prefix="$HOME/wine-dirs/vkd3d64-prefix" \
|
||||||
|
WIDL="$HOME/wine-dirs/wine64p/tools/widl/widl" \
|
||||||
|
SONAME_LIBVULKAN="vulkan-1.dll" \
|
||||||
|
CPPFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include" \
|
||||||
|
LDFLAGS="-static-libgcc"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--host=x86_64-w64-mingw32` indicates that we want to cross-compile
|
||||||
|
the programs and libraries using the 64-bit MinGW compiler.
|
||||||
|
- `--prefix="$HOME/wine-dirs/vkd3d64-prefix"` is used to set this
|
||||||
|
build's installation directory. In this case, we will create a new
|
||||||
|
folder inside `wine-dirs`. We have to keep in mind that the other
|
||||||
|
programs will expect the vkd3d libraries to be in this directory at
|
||||||
|
run-time.
|
||||||
|
- We set the `WIDL` variable to point to our provisional 64-bit Wine's
|
||||||
|
WIDL. When using the distribution's WIDL, `configure` should generally
|
||||||
|
be able to find WIDL on its own and this variable can be omitted; if
|
||||||
|
not, point it to the location of the distribution's WIDL.
|
||||||
|
- `SONAME_LIBVULKAN` indicates the name of the Vulkan library to load at
|
||||||
|
run-time.
|
||||||
|
- We use `CPPFLAGS` so that the compiler knows to search in the
|
||||||
|
`vulkan-sdk` folder for the vulkan headers (`-I` flag). Note that you
|
||||||
|
cannot pass `-I/usr/include/` here to use the host headers; this will
|
||||||
|
result in incorrect detection of headers like `dlfcn.h`. You will need
|
||||||
|
to copy or link host headers to a separate directory.
|
||||||
|
- We use `LDFLAGS="-static-libgcc"` because MinGW gcc depends on
|
||||||
|
`libgcc_s_sjlj-1.dll`; this links a static version. Alternatively, you
|
||||||
|
can add the correct path to `--with-system-dllpath` as described
|
||||||
|
below.
|
||||||
|
|
||||||
|
Then we run
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
Append `-j$(nproc)` to parallelize.
|
||||||
|
|
||||||
|
And if the build succeeds, then we run
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ make install
|
||||||
|
```
|
||||||
|
|
||||||
|
to install 64-bit vkd3d in `$HOME/wine-dirs/vkd3d64-prefix`.
|
||||||
|
|
||||||
|
## Build 64-bit wine
|
||||||
|
|
||||||
|
Now with the 64-bit `vkd3d` installation, we can compile a 64-bit Wine
|
||||||
|
linked to it.
|
||||||
|
|
||||||
|
If you do not have a 64-bit wine tree already, create a new one:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd $HOME/wine-dirs
|
||||||
|
$ mkdir wine64
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can reuse the same "provisional" Wine tree.
|
||||||
|
|
||||||
|
We run the Wine `configure` script again, but now specifying the
|
||||||
|
parameters to link Wine to the 64-bit vkd3d prefix we just created. We
|
||||||
|
will also need to include the vulkan headers:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd wine64
|
||||||
|
$ ../wine-git/configure --enable-win64 \
|
||||||
|
CC='ccache gcc' x86_64_CC='ccache x86_64-w64-mingw32-gcc' \
|
||||||
|
--with-system-dllpath="$HOME/wine-dirs/vkd3d64-prefix/bin:<mingw 64-bit gcc dynamic dependencies>" \
|
||||||
|
VKD3D_PE_CFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include -I$HOME/wine-dirs/vkd3d64-prefix/include/vkd3d" \
|
||||||
|
VKD3D_PE_LIBS="-L$HOME/wine-dirs/vkd3d64-prefix/lib -lvkd3d -lvkd3d-shader"
|
||||||
|
```
|
||||||
|
|
||||||
|
- We use `--with-system-dllpath` so that wine knows to search our vkd3d
|
||||||
|
prefix for the vkd3d DLLs. If you did not use `-static-libgcc` to
|
||||||
|
compile vkd3d, you should also add the libgcc path here. Depending on
|
||||||
|
distribution it may be `/usr/x86_64-w64-mingw32/bin/` (Arch),
|
||||||
|
`/usr/x86_64-w64-mingw32/sys-root/mingw/bin/` (Fedora), or
|
||||||
|
`/usr/lib/gcc/x86_64-w64-mingw32/##-win32/`, where `##` depends on the
|
||||||
|
gcc version (Debian).
|
||||||
|
- Notice that multiple paths should be separated with a colon.
|
||||||
|
- We set `VKD3D_PE_CFLAGS` and `VKD3D_PE_LIBS` to indicate that we will
|
||||||
|
use a custom version of vkd3d. We use `VKD3D_PE_CFLAGS` to include the
|
||||||
|
vulkan headers and the vkd3d headers and `VKD3D_PE_LIBS` to load
|
||||||
|
vkd3d's dynamic libraries.
|
||||||
|
- Alternatively, you can install MinGW pkg-config, and pass
|
||||||
|
`PKG_CONFIG_PATH="$HOME/wine-dirs/vkd3d64-prefix/lib/pkgconfig"`.
|
||||||
|
|
||||||
|
If you get the following message around the last lines:
|
||||||
|
|
||||||
|
```
|
||||||
|
configure: libvkd3d 64-bit MinGW development files not found; using bundled version.
|
||||||
|
```
|
||||||
|
|
||||||
|
Wine was **not** correctly linked to your custom version of vkd3d. Check
|
||||||
|
the `config.log`.
|
||||||
|
|
||||||
|
Clean ntdll to make sure that the new system DLL path is picked up, and
|
||||||
|
then rebuild wine:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ make dlls/ntdll/clean
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
Append "-j\$(nproc)" to make commands to parallelize.
|
||||||
|
|
||||||
|
## Build a 32-bit vkd3d installation
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd $HOME/wine-dirs
|
||||||
|
$ mkdir vkd3d32
|
||||||
|
```
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd vkd3d32
|
||||||
|
$ ../vkd3d-git/configure \
|
||||||
|
--host=i686-w64-mingw32 \
|
||||||
|
--prefix="$HOME/wine-dirs/vkd3d32-prefix" \
|
||||||
|
WIDL="$HOME/wine-dirs/wine64p/tools/widl/widl" \
|
||||||
|
SONAME_LIBVULKAN="vulkan-1.dll" \
|
||||||
|
CPPFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include" \
|
||||||
|
LDFLAGS="-static-libgcc"
|
||||||
|
```
|
||||||
|
|
||||||
|
- We now use `--host=i686-w64-mingw32` to indicate that we will use the
|
||||||
|
32-bit MinGW compiler.
|
||||||
|
- We are changing the prefix so that this 32-bit vkd3d is installed in
|
||||||
|
the `vkd3d32-prefix` folder instead of `vkd3d64-prefix`.
|
||||||
|
- We're using 64-bit WIDL like before; this is fine.
|
||||||
|
- We can also still use the Vulkan headers from our 64-bit vulkan-sdk.
|
||||||
|
|
||||||
|
We then run:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ make
|
||||||
|
$ make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build 32-bit Wine
|
||||||
|
|
||||||
|
We can now build our 32-bit Wine, linking it to our 32-bit vkd3d.
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd $HOME/wine-dirs
|
||||||
|
$ mkdir wine32
|
||||||
|
```
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ cd wine32
|
||||||
|
$ ../wine-git/configure --with-wine64=../wine64/ \
|
||||||
|
CC='ccache gcc' i386_CC='ccache i686-w64-mingw32-gcc' \
|
||||||
|
--with-system-dllpath="$HOME/wine-dirs/vkd3d32-prefix/bin:<mingw 32-bit dynamic dependencies>" \
|
||||||
|
VKD3D_PE_CFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include -I$HOME/wine-dirs/vkd3d32-prefix/include/vkd3d" \
|
||||||
|
VKD3D_PE_LIBS="-L$HOME/wine-dirs/vkd3d32-prefix/lib -lvkd3d -lvkd3d-shader"
|
||||||
|
```
|
||||||
|
|
||||||
|
- We now point `--with-system-dllpath` and `VKD3D_PE_LIBS` to the
|
||||||
|
directories inside `vkd3d32-prefix`.
|
||||||
|
|
||||||
|
As above, clean ntdll to make sure that the new system DLL path is
|
||||||
|
picked up, and then rebuild wine:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
$ make dlls/ntdll/clean
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
# Updating your build
|
||||||
|
|
||||||
|
If you want to update either wine or vkd3d's source code, we can execute
|
||||||
|
the following commands in order. `ccache` should help reducing the
|
||||||
|
compilations times.
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
# Recompile 64-bit vkd3d
|
||||||
|
cd $HOME/wine-dirs/vkd3d64
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
# Recompile 64-bit wine
|
||||||
|
cd $HOME/wine-dirs/wine64
|
||||||
|
make
|
||||||
|
|
||||||
|
# Recompile 32-bit vkd3d
|
||||||
|
cd $HOME/wine-dirs/vkd3d32
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
# Recompile 32-bit wine
|
||||||
|
cd $HOME/wine-dirs/wine32
|
||||||
|
make
|
||||||
|
```
|
248
Known-Issues.md
Normal file
248
Known-Issues.md
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
Vkd3d is considered as work-in-progress, there are known issues that
|
||||||
|
have to be resolved. Moreover, there are some incompatibilities between
|
||||||
|
Vulkan and Direct3D 12.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr class="header">
|
||||||
|
<th><p>Issue</p></th>
|
||||||
|
<th><p>Description</p></th>
|
||||||
|
<th><p>Current implementation</p></th>
|
||||||
|
<th><p>Possible solutions</p></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="odd">
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>NULL descriptors</p></td>
|
||||||
|
<td><p>Vulkan doesn't support NULL descriptors.</p></td>
|
||||||
|
<td><p>NULL descriptors are currently emulated using dummy resources.
|
||||||
|
Sparse resources are used when
|
||||||
|
`residencyNonResidentStrict` is supported. The current
|
||||||
|
solution doesn't handle `resinfo` and
|
||||||
|
`bufinfo` instructions correctly.</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Indirect draws</p></td>
|
||||||
|
<td><p>In Direct3D 12 indirect draws can update vertex buffer views,
|
||||||
|
index buffer views, root constants and root descriptors.</p></td>
|
||||||
|
<td><p>Not supported in Vulkan.</p></td>
|
||||||
|
<td><ul>
|
||||||
|
<li>A Vulkan extension.</li>
|
||||||
|
<li>It could be emulated in an inefficient way.</li>
|
||||||
|
</ul></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Memory object residency</p></td>
|
||||||
|
<td><p>Memory object residency management doesn't exist in Vulkan. In
|
||||||
|
Direct3D 12 resources and heaps can be evicted. Resource descriptors are
|
||||||
|
still valid after a resource is made resident again.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td><p>We can try to evict memory manually (e.g. using sparse
|
||||||
|
bindings).</p></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Queries initial state</p></td>
|
||||||
|
<td><p>Queries are initially in the available state in Direct3D 12.
|
||||||
|
Results are all equal to zero.</p></td>
|
||||||
|
<td><p>We track the query state, and fill buffer with zeroes when a
|
||||||
|
query wasn't issued. The current implementation doesn't handle command
|
||||||
|
lists executed out-of-order.</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Texture array views</p></td>
|
||||||
|
<td><p>Texture array views and textures views are incompatible in
|
||||||
|
Vulkan.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Descriptor heaps</p></td>
|
||||||
|
<td><p>Direct3D 12 and Vulkan binding models are largely different. It
|
||||||
|
seems to be implied that Direct3D 12 CBV/SRV/UAV descriptor heaps exist
|
||||||
|
in GPU memory, but there's no real equivalent for that in Vulkan. Vulkan
|
||||||
|
descriptor sets are probably the closest match, but among others have
|
||||||
|
the issue that the descriptor type (CBV, SRV or UAV) would need to be
|
||||||
|
declared in advance, while in Direct3D 12 these can be mixed freely
|
||||||
|
within the descriptor heap. Run-time translation from Direct3D 12
|
||||||
|
binding model to Vulkan binding model is expected to introduce a
|
||||||
|
noticeable overhead.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>CPU descriptor heaps</p></td>
|
||||||
|
<td><p>Direct3D 12 allows to create and prepare descriptors in CPU
|
||||||
|
heaps. Descriptors from CPU descriptor heaps can be copied to
|
||||||
|
shader-visible descriptor heaps. In Vulkan, there are only
|
||||||
|
shared-visibile descriptor sets, and
|
||||||
|
`VkCopyDescriptorSet` is implemented very inefficiently
|
||||||
|
on some drivers.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Descriptor heaps concurrency</p></td>
|
||||||
|
<td><p>Some apps appear to concurrently overwrite descriptors in
|
||||||
|
descriptor heaps. We need to confirm that this works reliably on
|
||||||
|
Windows. It might not be a problem on Windows because implementations
|
||||||
|
might simply write or copy descriptors data in memory. However, in our
|
||||||
|
translation layer we have to manage VkImageView objects and potentially
|
||||||
|
reference count them.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Descriptors for destroyed resources</p></td>
|
||||||
|
<td><p>Apps keep descriptors for destroyed resources in descriptor
|
||||||
|
heaps. This is problematic and may lead to invalid usage in
|
||||||
|
Vulkan.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>ID3D12Fence</p></td>
|
||||||
|
<td><p>ID3D12Fence have an associated UINT64 value (see also timeline
|
||||||
|
semaphores). In addition, ID3D12Fence can be signaled by GPU or CPU, and
|
||||||
|
can also be waited for on CPU or ID3D12CommandQueue. Moreover, it's
|
||||||
|
possible to signal native Win32 events when a fence reaches a certain
|
||||||
|
value. In Vulkan, there is no way to signal native synchronization
|
||||||
|
objects (e.g. HANDLEs to Win32 events or file descriptors) when, e.g.
|
||||||
|
VkFence is signaled.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td><p>Timeline semaphores.</p></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Sampler border color</p></td>
|
||||||
|
<td><p>In Direct3D 12 the sampler border color is defined as a float4
|
||||||
|
vector. In Vulkan the border color is constrained by the values of the
|
||||||
|
VkBorderColor enum. (It might not be that important because we haven't
|
||||||
|
encountered application which needs this yet).</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Separate resource state for depth-stencil</p></td>
|
||||||
|
<td><p>In Direct3D, the depth aspect and the stencil aspect of an image
|
||||||
|
can be in different image layouts.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td><p>Vulkan extension.</p></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Out-of-bounds resource access</p></td>
|
||||||
|
<td><p>Vulkan doesn't give the same guarantees as Direct3D 12 when it
|
||||||
|
comes to out-of-bounds resource access.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT</p></td>
|
||||||
|
<td><p>On radv with AMD Polaris GPUs, the required alignment for
|
||||||
|
textures may be higher than 0x10000
|
||||||
|
(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), e.g. 0x20000 or 0x40000.
|
||||||
|
World of Warcraft aligns only to
|
||||||
|
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT and ignores the alignment
|
||||||
|
returned from `GetResourceAllocationInfo()`.</p></td>
|
||||||
|
<td><p>We currently allocate additional device memory when the heap
|
||||||
|
offset is misaligned.</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Swapchain</p></td>
|
||||||
|
<td><ul>
|
||||||
|
<li>sRGB views.</li>
|
||||||
|
<li>Scaling.</li>
|
||||||
|
<li>Present mode without recreating.</li>
|
||||||
|
</ul></td>
|
||||||
|
<td><p>We currently use additional set of images and blit from them to
|
||||||
|
the real swapchain.</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Conditional rendering</p></td>
|
||||||
|
<td><p>In D3D12, 64-bit values are used.
|
||||||
|
`VK_EXT_conditional_rendering` uses 32-bit values. In
|
||||||
|
D3D12, conditional rendering affects copy commands.</p></td>
|
||||||
|
<td><p>We do what the `VK_EXT_conditional_rendering`
|
||||||
|
extension does.</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Binary occlusion queries</p></td>
|
||||||
|
<td><p>D3D12 guarantees binary occlusion queries result in only 0 and
|
||||||
|
1.</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Strip cut value</p></td>
|
||||||
|
<td><p>In Vulkan the strip cut value is derived from the index format.
|
||||||
|
In Direct3D 12 0xffff or 0xffffffff can be used as the strip cut value
|
||||||
|
with 16-bit and 32-bit index buffer formats.</p></td>
|
||||||
|
<td><p>Not supported in Vulkan.</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>GPU virtual addresses</p></td>
|
||||||
|
<td><p>In Direct3D 12, vertex buffers, index buffers, stream output
|
||||||
|
buffers and root descriptors are bound using GPU virtual addresses. In
|
||||||
|
Vulkan, VkBuffer objects with an offset are used instead.</p></td>
|
||||||
|
<td><p>Fake virtual addresses are allocated for buffers. Virtual
|
||||||
|
addresses have to be resolved to VkBuffer and an offset. The resolving
|
||||||
|
of GPU virtual address introduces unnecessary overhead.</p></td>
|
||||||
|
<td><ul>
|
||||||
|
<li>`VK_EXT_device_buffer_address` can be used for root
|
||||||
|
descriptors. Unfortunately, the extension doesn't help with vertex,
|
||||||
|
index and stream output buffers. The extension also introduces some
|
||||||
|
complications, e.g. multiple buffers can be bound to the same virtual
|
||||||
|
memory address.</li>
|
||||||
|
<li>Ideally, we could bind vertex, index and stream output buffers using
|
||||||
|
`VkDeviceAddress` in Vulkan.</li>
|
||||||
|
</ul></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>`GetResourceAllocationInfo()`</p></td>
|
||||||
|
<td><p>In Vulkan, a resource needs to be created to get allocation
|
||||||
|
info.</p></td>
|
||||||
|
<td><p>We create temporary resources to get allocation info.</p></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>`SetEventOnCompletion()` /
|
||||||
|
`SetEventOnMultipleFenceCompletion()`</p></td>
|
||||||
|
<td></td>
|
||||||
|
<td><p>We have a separate thread that signals Win32 events.</p></td>
|
||||||
|
<td><p>Timeline semaphores.</p></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="odd">
|
||||||
|
<td><p>Copy between depth-stencil and color formats</p></td>
|
||||||
|
<td><p>In Direct3D 12 it is possible to copy data between compatible
|
||||||
|
color and depth-stencil resources.</p></td>
|
||||||
|
<td><p>We currently use a temporary buffer to perform the copy
|
||||||
|
operation.</p></td>
|
||||||
|
<td><p>We should implement the copy operation in shaders for graphics
|
||||||
|
and compute queues.</p></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="even">
|
||||||
|
<td><p>Dynamic states</p></td>
|
||||||
|
<td><p>In Direct3D 12 the following states are dynamic: vertex buffer
|
||||||
|
strides, the primitive topology and viewport/scissor counts. In Vulkan,
|
||||||
|
those states require compiling a new pipeline. The primitive topology
|
||||||
|
type is still specified when Direct3D 12 pipeline states are created
|
||||||
|
(one of points, lines, triangles, or patches).</p></td>
|
||||||
|
<td><p>Vulkan pipelines are created on draw call time when we know all
|
||||||
|
parameters to compile the pipeline.</p></td>
|
||||||
|
<td><ul>
|
||||||
|
<li>Add pipeline cache.</li>
|
||||||
|
<li>Compile pipelines speculatively.</li>
|
||||||
|
</ul></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
134
Todo.md
Normal file
134
Todo.md
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
## libvkd3d
|
||||||
|
|
||||||
|
- Try to use VK_EXT_buffer_device_address for GPU addresses (partially
|
||||||
|
done - jkucia).
|
||||||
|
- Add tests for out-of-bounds access with vertex buffers.
|
||||||
|
- Improve multi-queue support.
|
||||||
|
- Queue family ownership transfer.
|
||||||
|
- Fix all Vulkan validation errors.
|
||||||
|
- Fix clears for A8_UNORM.
|
||||||
|
- Implement UAVs in vertex processing shader stages.
|
||||||
|
- Implement support for multiple viewports.
|
||||||
|
- Test and fix copying between BC and other compatible formats.
|
||||||
|
- State decay for resources and queue ownership transfer for resources.
|
||||||
|
- Reduce the number of queue submits. Queue submits are generally
|
||||||
|
expensive, especially on recent kernels with amdgpu (mostly done -
|
||||||
|
jkucia).
|
||||||
|
- Merge vkCmdPipelineBarrier() calls.
|
||||||
|
- Try to avoid fence worker thread when possible.
|
||||||
|
- Implement stencil aspect resource state transitions.
|
||||||
|
- Implement cache for SPIR-V shaders?
|
||||||
|
- Implement disk pipeline/shader cache?
|
||||||
|
- Implement sparse resources?
|
||||||
|
- Optimize barriers (render passes, ClearUnorderedAccessView, transform
|
||||||
|
feedback).
|
||||||
|
- Memory residency.
|
||||||
|
- Raytracing?
|
||||||
|
- DirectML?
|
||||||
|
- Add support for sRGB swapchain views (VK_KHR_image_format_list).
|
||||||
|
- Add tests for validation of view format compatibility (RTV, SRV, UAV,
|
||||||
|
DSV).
|
||||||
|
|
||||||
|
## libvkd3d-shader
|
||||||
|
|
||||||
|
- Add support for capturing components with stream output.
|
||||||
|
- Finish the DXIL work (Conor).
|
||||||
|
- Add tests for OpenGL atomic counters.
|
||||||
|
- Import SM4 to GLSL shader translation from wined3d (Henri).
|
||||||
|
- Allow ignoring checking the checksum when parsing DXBC, both from the
|
||||||
|
API and from the command line.
|
||||||
|
- Always check that memory allocation didn't fail; for example, calls to
|
||||||
|
vkd3d_string_buffer_printf() usually are not checked.
|
||||||
|
- Finish API for scanning/gathering info from shaders (registers used,
|
||||||
|
bindings used, parameters used, required limits, extensions).
|
||||||
|
- Implement ID3D11ShaderReflection et al.
|
||||||
|
- Should we put everything into the same (chained)
|
||||||
|
vkd3d_shader_scan_dxbc_info struct, or split them up? (Split up the
|
||||||
|
DXBC-specific ones from the rest?)
|
||||||
|
- I guess HLSL compile flags should be preserved verbatim...? I don't
|
||||||
|
like the disparity we currently have.
|
||||||
|
- How to do things like constant table types?
|
||||||
|
- Add support for SSBO.
|
||||||
|
- Support HLSL -\> sm6 compilation.
|
||||||
|
- Support direct HLSL -\> spirv compilation. This will be easier as
|
||||||
|
things are refactored to account for vsir.
|
||||||
|
- Consider adding a CUDA frontend.
|
||||||
|
|
||||||
|
#### TPF validation
|
||||||
|
|
||||||
|
Vkd3d-shader generally assumes that Direct3D shader bytecode is valid
|
||||||
|
and doesn't do much validation. We should introduce some kind of
|
||||||
|
validation pass. The validation potentially could be optional, e.g. used
|
||||||
|
only in debug builds.
|
||||||
|
|
||||||
|
- Interpolation mode is the same for all variables in the input
|
||||||
|
register.
|
||||||
|
- Number of indices for resources (SM5 vs SM5.1).
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
- Make it possible to run all reasonable test combinations mixing these
|
||||||
|
factors:
|
||||||
|
- the library used to compile the shaders: vkd3d-shader,
|
||||||
|
d3dcompiler_xx.dll or dxcompiler.dll;
|
||||||
|
- the Shader Model to target;
|
||||||
|
- the API to use to run the shader (d3d8, d3d9, d3d10, d3d11, d3d12,
|
||||||
|
Vulkan, GL);
|
||||||
|
- when running on Windows, the actual library to use to run the
|
||||||
|
shader: vkd3d or a native implementation;
|
||||||
|
- possibly, one day, the library to use to recompile the shaders (it
|
||||||
|
currently only makes sense on macOS once we support the Apple shader
|
||||||
|
compiler for Metal; in all the other cases the choice is forced).
|
||||||
|
- Run a decent subsets of those combinations in the CI.
|
||||||
|
- Need more shader runners: OpenGL + GLSL (Henri has WIP), d3d10core,
|
||||||
|
d3d8
|
||||||
|
|
||||||
|
- Some HLSL functionality was accepted despite a lack of tests. We need
|
||||||
|
tests for:
|
||||||
|
- all tex\*() variants
|
||||||
|
- D3DCOLORtoUBYTE4() different results on sm1
|
||||||
|
- min()
|
||||||
|
- texture arrays
|
||||||
|
- centroid interpolation
|
||||||
|
- "linear centroid" keywords
|
||||||
|
- noperspective interpolation
|
||||||
|
- precise?
|
||||||
|
- texture types other than 2D
|
||||||
|
- nontrivial tests for 2D multisample textures
|
||||||
|
- GetDimensions()
|
||||||
|
- SampleCmp(), SampleCmpLevelZero()
|
||||||
|
- depth output
|
||||||
|
- GS SV_PrimitiveID
|
||||||
|
- For the sake of sm1 and its weird disjoint instruction sets, a lot
|
||||||
|
of tests probably deserve VS variants as well.
|
||||||
|
- Uniform reflection, which depends on uniform reflection API design
|
||||||
|
- SM1 semantic matching (Zeb has this)
|
||||||
|
- Test that all of the SM1 input semantics work
|
||||||
|
- tbuffer
|
||||||
|
- We should properly gate features based on profile version, and test
|
||||||
|
that we are correctly doing this.
|
||||||
|
|
||||||
|
|
||||||
|
None of this necessarily needs to be extensions to the shader runner; we
|
||||||
|
can find a way to write C tests for these.
|
||||||
|
|
||||||
|
- We would also like a way to invoke shader runner logic from C. It's a
|
||||||
|
bit unfortunate that the tests in hlsl_d3d12.c are d3d12-specific.
|
||||||
|
- Untested sm4 -\> spirv paths:
|
||||||
|
- "lod" shader instruction
|
||||||
|
- bufinfo and resinfo with NULL SRV and UAV descriptors
|
||||||
|
- D3D discard semantics
|
||||||
|
|
||||||
|
## DXGI
|
||||||
|
|
||||||
|
- Fix adapter LUIDs in Wine.
|
||||||
|
- Reimplement IDXGIAdapter3::QueryVideoMemoryInfo() on top of
|
||||||
|
VK_EXT_memory_budget. Ideally, Vulkan implementations should return
|
||||||
|
the memory budget based on total system load (memory used by all
|
||||||
|
graphics APIs).
|
||||||
|
|
||||||
|
## Vulkan
|
||||||
|
|
||||||
|
- Try to fix detached WSI surfaces after D3D9/D3D11 swapchain (OpenGL)
|
||||||
|
is created for a window with D3D12 swapchain (Vulkan).
|
||||||
|
- Fix child window rendering for D3D12 RenderDoc.
|
134
home.md
Normal file
134
home.md
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
---
|
||||||
|
title: Vkd3d
|
||||||
|
---
|
||||||
|
|
||||||
|
Vkd3d is a 3D graphics library built on top of Vulkan. It has an API
|
||||||
|
very similar, but not identical, to Direct3D 12. Wine uses vkd3d
|
||||||
|
libraries for its implementation of Direct3D 12.
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
## Getting the vkd3d source
|
||||||
|
|
||||||
|
You can download the Vkd3d source code as a
|
||||||
|
[tarball](https://dl.winehq.org/vkd3d/source/), but if you plan to do
|
||||||
|
any actual testing or developing, you'll want to use
|
||||||
|
[git](https://gitlab.winehq.org/wine/vkd3d).
|
||||||
|
|
||||||
|
To grab the source code, just enter the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ git clone https://gitlab.winehq.org/wine/vkd3d.git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compiling
|
||||||
|
|
||||||
|
Enter the following commands:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ./autogen.sh
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
See also the [README
|
||||||
|
file](https://gitlab.winehq.org/wine/vkd3d/-/raw/master/README).
|
||||||
|
|
||||||
|
In order to build 32-bit libraries:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ../vkd3d/configure --build=i686-pc-linux-gnu "CPPFLAGS=-m32" "LDFLAGS=-m32"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building a MinGW WoW64 Wine with a custom vkd3d build
|
||||||
|
|
||||||
|
If you want your Wine build to use a custom vkd3d build and make it
|
||||||
|
compatible with a wider range of applications, check [Building a MinGW
|
||||||
|
WoW64 Wine with a custom vkd3d
|
||||||
|
build](Building-a-MinGW-WoW64-Wine-with-a-custom-vkd3d-build).
|
||||||
|
|
||||||
|
## Building Wine with Direct3D 12 support
|
||||||
|
|
||||||
|
Wine uses **pkg-config** to find vkd3d libraries. If vkd3d libraries are
|
||||||
|
installed system-wide, the Wine configure script should find the vkd3d
|
||||||
|
libraries automatically. You can also use **PKG_CONFIG_PATH**,
|
||||||
|
**VKD3D_CFLAGS** or **VKD3D_LIBS** to override **pkg-config** search
|
||||||
|
path, C compiler flags for **libvkd3d**, or linker flags for
|
||||||
|
**libvkd3d**, e.g.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ../wine-git/configure PKG_CONFIG_PATH=$HOME/src/vulkan/install/lib/pkgconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
# Debugging
|
||||||
|
|
||||||
|
## Debug output
|
||||||
|
|
||||||
|
Vkd3d provides **VKD3D_DEBUG** and **VKD3D_SHADER_DEBUG** environment
|
||||||
|
variables to control debug log messages. The debug variables can be set
|
||||||
|
to one of the following debug log levels: **none**, **err**, **fixme**,
|
||||||
|
**warn**, **trace**.
|
||||||
|
|
||||||
|
See the [README
|
||||||
|
file](https://gitlab.winehq.org/wine/vkd3d/-/raw/master/README) for
|
||||||
|
description of all debug environment variables.
|
||||||
|
|
||||||
|
## Vulkan validation layers
|
||||||
|
|
||||||
|
Enable validation layers in a standard way:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation
|
||||||
|
```
|
||||||
|
|
||||||
|
You may also want to enable Vulkan debug extensions in vkd3d:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
VKD3D_CONFIG=vk_debug
|
||||||
|
```
|
||||||
|
|
||||||
|
## Other tools
|
||||||
|
|
||||||
|
- [RenderDoc](https://renderdoc.org/) is a frame-capture based debugger.
|
||||||
|
It supports Vulkan and Direct3D 12.
|
||||||
|
- VK_LAYER_LUNARG_api_dump is useful to dump Vulkan commands produced by
|
||||||
|
libvkd3d.
|
||||||
|
- [Fossilize](https://github.com/ValveSoftware/Fossilize) might be
|
||||||
|
useful for debugging crashes in driver shader compiler. Just capture
|
||||||
|
pipelines using VK_LAYER_fossilize and use fossilize-replay to
|
||||||
|
reproduce the crash.
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
|
||||||
|
Use the following command to run tests:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ make check
|
||||||
|
```
|
||||||
|
|
||||||
|
Tests can also be run individually, for example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ make tests/d3d12 && ./tests/d3d12
|
||||||
|
$ VKD3D_TEST_FILTER=clear_render_target ./tests/d3d12
|
||||||
|
```
|
||||||
|
|
||||||
|
To cross-compile tests for Windows run the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ make crosstest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shader bytecode in tests
|
||||||
|
|
||||||
|
Some tests include compiled shader bytecode. Shader bytecode should be
|
||||||
|
generated with `/Qstrip_debug /Qstrip_reflect` options. For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ fxc /Qstrip_debug /Qstrip_reflect /T ps_5_0 source.hlsl /Fo output.dxbc
|
||||||
|
```
|
||||||
|
|
||||||
|
# See also
|
||||||
|
|
||||||
|
- [Todo](Todo)
|
||||||
|
- [Known Issues](Known-Issues)
|
Loading…
Reference in New Issue
Block a user