Import vkd3d pages from MediaWiki.

Alexandre Julliard 2024-09-02 18:17:49 +02:00
commit 52846c72fc
4 changed files with 878 additions and 0 deletions

@ -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

@ -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

@ -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

@ -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)