Windows 10 [received support](https://devblogs.microsoft.com/commandline/af_unix-comes-to-window… for AF_UNIX sockets in Insider Build 17063. This merge request adds basic support for AF_UNIX sockets to ws2_32 and wineserver.
Of particular note is the difficulty in handling `sun_path`. Most of the functions that allow for translating Windows paths to Unix paths are not accessible from ws2_32. I considered the following options:
* Pass the Windows path to wineserver and do the conversion there.
* This is, as far as I can tell, not possible without major rearchitecting. wineserver does not have functions to translate Windows paths to Unix paths, for obvious reasons.
* Obtain the current working directory of the requesting process and temporarily change directories to there.
* This only handles relative paths and fails for absolute paths, UNC paths, etc.
* Conditionally change directories based on whether the path is relative or not.
* This is error-prone and wineserver does not have the requisite functions to do this cleanly.
I ultimately decided to pass the translated Unix path to wineserver, which changes directories to `dirname(path)`. It then provides `bind` and `connect` with `basename(path)`. This is not threadsafe, but wineserver is not (currently) multithreaded.
Abstract sockets are supported by this patch.
--
v45: ws2_32/tests: Add test for AF_UNIX sockets fix.
server: Fix getsockname() and accept() on AF_UNIX sockets.
server: Introduce error when attempting to create a SOCK_DGRAM AF_UNIX socket.
server: Allow for deletion of socket files.
ws2_32: Add support for AF_UNIX sockets.
ntdll/unix: Add support for AF_UNIX sockets to multiple functions.
ws2_32: Add afunix.h header.
https://gitlab.winehq.org/wine/wine/-/merge_requests/2786
`getpeername()` is currently handled in ntdll. This merge request changes ntdll to forward `getpeername()` to wineserver. The implementation utilises new `peer_addr` and `peer_addr_len` fields in wineserver's `struct sock`.
This fixes multiple `todo_wine`s in `ws2_32/tests` and allows for more accurate peer names to be provided in case the address the socket is bound to on the Unix side does not match what `bind()` was called with on the Windows side.
*This merge request was originally intended to be included in !2786 (Add support for AF_UNIX sockets) but was split into its own merge request because this is not an insignificant change.*
--
v22: server: Move getpeername() implementation from ntdll/unix.
https://gitlab.winehq.org/wine/wine/-/merge_requests/3074
This is probably the most ugly and controversial bit of API. I don't really know
if this is the right approach to solving this.
sm4 registers match by register index, such that shaders can mostly be compiled
in isolation. sm1 does not—registers may be specified in any order in the vertex
and pixel shaders, and will be matched by usage and usage index.
By itself this is not much of a problem. Where it gets hairy is that we want to
do some degree of caching, as well as pre-compilation, and avoid recompiling
either shader every time it's matched with a new one.
Wine currently deals with this problem, for GLSL, by generating a "main" GLSL
shader for the vertex shader, and then an extra function setup_vs_output(), and
linking the two together every time a new pixel shader is used. This could in
theory be used for SPIR-V, but it requires the use of extra, probably external,
code to link SPIR-V shaders together, which I do not particularly anticipate
being well-received.
(I'm not sure how Wine deals with this problem in the ARB backend. It seems to
take the pixel shader signature into account when generating the vertex shader—
cf. init_output_registers()—but it doesn't take it into account when looking up
a vertex shader variant? I didn't look too closely at the code, so maybe I'm
missing something.)
--
The vkd3d parts of this patch are quite straightforward, and looking at them, I
think the design is quite intuitive in isolation. There may be some room for
internal refactoring (in particular with an eye to not so much overloading
the "register_index" field of struct shader_signature_element) but I'm
relatively happy with the way it turned out. In isolation, that is.
The Wine part is worse. I've uploaded branches for vkd3d and Wine that use this
API, and correctly handle shaders with some nontrivial reordering:
https://gitlab.winehq.org/zfigura/vkd3d/-/commits/himavant5https://gitlab.winehq.org/zfigura/wine/-/commits/himavant_cb
The test can be run, as before, like so:
make tests/shader_runner.exe && WINE_D3D_CONFIG=renderer=vulkan wine tests/shader_runner.exe ../vkd3d/tests/hlsl/sm1-interstage-interface.shader_test
The interesting Wine parts are concentrated in a single patch, 5cfb9d930f11e.
The patch takes a few shortcuts, partly because I wanted not to block the vkd3d
API design questions, but also because while writing it I came up with a couple
of problems that I wasn't sure how to fix. There are two main problems I see:
(1) This patch has the user pass the signature from the pixel shader when
compiling the vertex shader, and looks up register indices already
arbitrarily allocated by the pixel shader. This is problematic when trying
to use this signature as a cache key, by virtue of it not being clear (or
even defined) which fields are key elements and which aren't. It's also not
particularly kind to lookup, on account of not being directly comparable
with memcmp(). There are a few options I see:
(a) Provide an internal function to compare key elements. This feels... odd,
like a very special-purpose function, but perhaps workable.
(b) Just make the user deal with it, and assert that all fields are key
elements.
(c) Use some alternative, perhaps shortened structure as a field of
vkd3d_shader_next_stage_info. This has the disadvantage that it is not
as simple for a hypothetical user to retrieve from the pixel shader, but
we would presumably provide a function to generate one from a shader
signature. This would probably also be kinder to cache lookup if it's
shorter.
(d) Make caching vkd3d's responsibility, to some degree. This seems
daunting, but the more we optimize, the more difficult it may be to
design API that allows for nice caching.
(2) Assuming we use signatures, there is a memory management problem that
5cfb9d930f11e spells out. This is probably a matter of "just fix it", but
I suppose another option is to take the GLSL or ARB architecture.
--
April is the cruellest month, breeding
Lilacs out of the dead land, mixing
Memory and desire, stirring
Dull roots with spring rain.
--
https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/280
On Fri Jul 21 01:25:37 2023 +0000, Henri Verbeet wrote:
> > For the d3d12 and shader runner tests I've been using an environment
> variable to specify the path to DXC, HLSL source declarations in
> d3d12.c, and an `[enable]` directive in shader runner. Are those
> acceptable for upstream?
> It's of course not ideal to depend on DXC/dxcompiler for the DXIL shader
> runner tests like that, but I think we can work with that, yes. There's
> some precedent as well, because we can also use d3dcompiler for running
> shader runner tests.
> In terms of the checksum, the most practical way to make that work in
> the shader runner is probably to introduce a flag like
> "VKD3D_SHADER_PARSE_DXBC_IGNORE_CHECKSUM" for vkd3d_shader_parse_dxbc(),
> then use that to parse the DXBCs produced by Linux DXC, and use
> vkd3d_shader_serialize_dxbc() to create a DXBC blob to pass to
> d3d12/vkd3d. Also, would we need to use DXC, or could we use the
> dxcompiler library?
Using dxcompiler would be preferable, but instead of COM interfaces it uses C++ linking, and when I tried using it a while ago I couldn't get the calling conventions to match up, even if the C declaration was explicitly declared the same convention as the dxcompiler function. It worked if I added a wrapper in a C++ source file, but we probably don't want that. I'll take another look and see if they can be made to match up.
--
https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/278#note_39702