3 Commits

Author SHA1 Message Date
Giovanni Mascellani
154acd2c2b Release 1.7.1. 2023-05-03 21:46:28 +02:00
Henri Verbeet
cb2acc35f2 vkd3d-utils: Export D3D12CreateDevice() once again.
Commit d27fee64ab inadvertently stopped
exporting D3D12CreateDevice().
2023-05-03 21:46:27 +02:00
Conor McCarthy
7b9b0179ec vkd3d: Leave the command queue op mutex locked after a partial flush.
All return paths in d3d12_command_queue_flush_ops_locked() must
leave the op mutex locked.
2023-05-03 21:46:25 +02:00
426 changed files with 26189 additions and 154467 deletions

View File

@@ -1,16 +0,0 @@
# https://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
tab_width = 8
trim_trailing_whitespace = true
max_line_length = 120
insert_final_newline = true
[Makefile*]
indent_style = tab
indent_size = 8

2
.gitignore vendored
View File

@@ -10,7 +10,6 @@ Makefile
Makefile.in Makefile.in
test-suite.log test-suite.log
/vkd3d-compiler /vkd3d-compiler
/vkd3d-dxbc
vkd3d-*.tar.xz vkd3d-*.tar.xz
@@ -23,7 +22,6 @@ vkd3d-*.tar.xz
*.tab.c *.tab.c
*.tab.h *.tab.h
*.trs *.trs
*.txt
*.yy.c *.yy.c
*~ *~

View File

@@ -1,11 +0,0 @@
stages:
- image
- build
- test
- deploy
include:
- local: "/gitlab/image.yml"
- local: "/gitlab/build.yml"
- local: "/gitlab/test.yml"
- local: "/gitlab/release.yml"

View File

@@ -1,2 +0,0 @@
Elizabeth Figura <z.figura12@gmail.com>
Elizabeth Figura <zfigura@codeweavers.com>

513
ANNOUNCE

File diff suppressed because it is too large Load Diff

16
AUTHORS
View File

@@ -1,10 +1,6 @@
Akihiro Sagawa
Alexandre Julliard Alexandre Julliard
Alistair Leslie-Hughes
Andrew Eikum Andrew Eikum
Andrey Gusev Andrey Gusev
Anna (navi) Figueiredo Gomes
Arkadiusz Hiler
Atharva Nimbalkar Atharva Nimbalkar
Biswapriyo Nath Biswapriyo Nath
Brendan Shanks Brendan Shanks
@@ -12,34 +8,24 @@ Chip Davis
Conor McCarthy Conor McCarthy
David Gow David Gow
Derek Lesho Derek Lesho
Elizabeth Figura
Ethan Lee
Evan Tang
Fabian Maurer Fabian Maurer
Feifan He
Florian Weimer
Francisco Casas Francisco Casas
Francois Gouget Francois Gouget
Giovanni Mascellani Giovanni Mascellani
Hans-Kristian Arntzen Hans-Kristian Arntzen
Henri Verbeet Henri Verbeet
Isabella Bosia Isabella Bosia
Jacek Caban
Jactry Zeng Jactry Zeng
Jan Sikorski
Joshua Ashton Joshua Ashton
JĂłzef Kucia JĂłzef Kucia
Martin Storsjö Martin Storsjö
Matteo Bruni Matteo Bruni
Nikolay Sivov Nikolay Sivov
Petrichor Park
Philip Rebohle Philip Rebohle
Rémi Bernon Rémi Bernon
Robin Kertels Robin Kertels
Shaun Ren
Stefan Dösinger Stefan Dösinger
Sven Hesse Sven Hesse
Victor Chiletto
Vinson Lee Vinson Lee
Yuxuan Shui Zebediah Figura
Zhiyi Zhang Zhiyi Zhang

View File

@@ -1,4 +1,4 @@
Copyright 2016-2025 the Vkd3d project authors (see the file AUTHORS for a Copyright 2016-2023 the Vkd3d project authors (see the file AUTHORS for a
complete list) complete list)
Vkd3d is free software; you can redistribute it and/or modify it under Vkd3d is free software; you can redistribute it and/or modify it under

File diff suppressed because it is too large Load Diff

View File

@@ -8,10 +8,6 @@ OUTPUT_DIRECTORY = doc
JAVADOC_AUTOBRIEF = YES JAVADOC_AUTOBRIEF = YES
OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_STATIC = YES EXTRACT_STATIC = YES
QUIET = YES
WARN_IF_UNDOCUMENTED = NO
WARN_IF_INCOMPLETE_DOC = NO
LATEX_BATCHMODE = YES
INPUT = @srcdir@/include/vkd3d.h \ INPUT = @srcdir@/include/vkd3d.h \
@srcdir@/include/vkd3d_shader.h \ @srcdir@/include/vkd3d_shader.h \

File diff suppressed because it is too large Load Diff

151
README
View File

@@ -9,31 +9,20 @@ similar, but not identical, to Direct3D 12.
Building vkd3d Building vkd3d
============== ==============
Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.3.228), as well as Perl Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.2.139).
and libjson-perl.
Vkd3d generates some of its headers from IDL files. If you are using the Vkd3d generates some of its headers from IDL files. If you are using the
release tarballs, then these headers are pre-generated and are included. If release tarballs, then these headers are pre-generated and are included. If
you are building from git, then they will be generated at build-time using you are building from git, then they will be generated at build-time using
widl. By default, vkd3d will use the widl found in `PATH'. If widl is not widl. By default, vkd3d will use the widl found in `PATH'. If widl is not
available or is not recent (>= 3.21), then you can build Wine with `make available or is not recent (>= 3.20), then you can build Wine with `make
tools/widl/widl' to avoid building all of Wine. You can then point vkd3d's tools/widl' to avoid building all of Wine. You can then point vkd3d's
configure at that widl binary with `WIDL="/path/to/widl"'. configure at that widl binary with `WIDL="/path/to/widl"'.
For release builds, you may want to disable debug log messages defining For release builds, you may want to define NDEBUG. If you do not need debug log
preprocessor macros VKD3D_NO_TRACE_MESSAGES and VKD3D_NO_DEBUG_MESSAGES. messages, you may also consider VKD3D_NO_TRACE_MESSAGES and
See the `Preprocessor definitions' section below for more details. VKD3D_NO_DEBUG_MESSAGES. For example, you can pass `CPPFLAGS="-DNDEBUG
-DVKD3D_NO_TRACE_MESSAGES"' to configure.
================
Developing vkd3d
================
Development of vkd3d happens on the Wine GitLab instance
(https://gitlab.winehq.org/wine/vkd3d/). Contributors are encouraged
to submit their patches using the merge request tool.
Each merge request is automatically tested with the GitLab CI
system. See gitlab/README in the Git tree for more details.
=========== ===========
Using vkd3d Using vkd3d
@@ -50,16 +39,16 @@ Environment variables
===================== =====================
Most of the environment variables used by vkd3d are for debugging purposes. The Most of the environment variables used by vkd3d are for debugging purposes. The
environment variables are not considered a stable interface and might be changed environment variables are not considered a part of API and might be changed or
or removed in future versions of vkd3d. removed in the future versions of vkd3d.
Some of debug variables are lists of elements. Elements must be separated by Some of debug variables are lists of elements. Elements must be separated by
commas or semicolons. commas or semicolons.
* NO_COLOR - this is an alias of NO_COLOUR. * NO_COLOR - this is an alias of NO_COLOUR.
* NO_COLOUR - when set, vkd3d-compiler and vkd3d-dxbc will default to * NO_COLOUR - when set, vkd3d-compiler will default to monochrome output,
monochrome output, even when the output supports colour. even when the output supports colour.
* VKD3D_CONFIG - a list of options that change the behavior of libvkd3d. * VKD3D_CONFIG - a list of options that change the behavior of libvkd3d.
* virtual_heaps - Create descriptors for each D3D12 root signature * virtual_heaps - Create descriptors for each D3D12 root signature
@@ -76,19 +65,6 @@ commas or semicolons.
* VKD3D_DISABLE_EXTENSIONS - a list of Vulkan extensions that libvkd3d should * VKD3D_DISABLE_EXTENSIONS - a list of Vulkan extensions that libvkd3d should
not use even if available. not use even if available.
* VKD3D_CAPS_OVERRIDE - a list of Direct3D 12 capabilities for which the
default value detected by vkd3d should be overridden, in the form
`capability1=value1,capability2=value2'. This doesn't change the vkd3d
behaviour, only the information reported to the application. The following
capabilities can currently be overridden:
* feature_level (allowed values: 11.0, 11.1, 12.0, 12.1, 12.2)
* resource_binding_tier (allowed values: 1, 2, 3)
* VKD3D_SHADER_CONFIG - a list of options that change the behavior of
libvkd3d-shader.
* force_validation - Enable (additional) validation of libvkd3d-shader's
internal representation of shaders.
* VKD3D_SHADER_DEBUG - controls the debug level for log messages produced by * VKD3D_SHADER_DEBUG - controls the debug level for log messages produced by
libvkd3d-shader. See VKD3D_DEBUG for accepted values. libvkd3d-shader. See VKD3D_DEBUG for accepted values.
@@ -97,10 +73,6 @@ commas or semicolons.
* VKD3D_TEST_DEBUG - enables additional debug messages in tests. Set to 0, 1 * VKD3D_TEST_DEBUG - enables additional debug messages in tests. Set to 0, 1
or 2. or 2.
* VKD3D_TEST_DETAILED - enables printing detailed output when running the test
suite, reporting specific shader_test lines that trigger XFAIL and SKIP even
on tests that overall PASS. Set to 0, or 1.
* VKD3D_TEST_FILTER - a filter string. Only the tests whose names matches the * VKD3D_TEST_FILTER - a filter string. Only the tests whose names matches the
filter string will be run, e.g. VKD3D_TEST_FILTER=clear_render_target. filter string will be run, e.g. VKD3D_TEST_FILTER=clear_render_target.
Useful for debugging or developing new tests. Useful for debugging or developing new tests.
@@ -109,105 +81,4 @@ commas or semicolons.
platform controls the behavior of todo(), todo_if(), bug_if() and broken() platform controls the behavior of todo(), todo_if(), bug_if() and broken()
conditions in tests. conditions in tests.
* VKD3D_TEST_SKIP_DXC - when set, tests requiring the dxcompiler library will
be skipped.
* VKD3D_TEST_BUG - set to 0 to disable bug_if() conditions in tests. * VKD3D_TEST_BUG - set to 0 to disable bug_if() conditions in tests.
If the configuration defines 'DXCOMPILER_LIBS=-L/path/to/dxcompiler', Shader
Runner attempts to load libdxcompiler.so or dxcompiler.dll to compile test
shaders in Shader Model 6. LD_LIBRARY_PATH (linux), WINEPATH (wine) or PATH
(native windows) should include the location of dxcompiler if SM 6 shader
tests are desired. If dxcompiler is not found, Shader Runner will compile the
test shaders only in earlier shader models. The DXC source does not contain
code for adding DXBC checksums, so the official release should be installed
from:
https://github.com/microsoft/DirectXShaderCompiler/releases
========================
Preprocessor definitions
========================
A number of preprocessor definitions can be used at compilation time to control
the behaviour of the generated binary. You can pass something like
`CPPFLAGS="-DVKD3D_VAR1 -DVKD3D_VAR2"' to the configure script. The preprocessor
variables are not considered a stable interface and might be changed or removed
in future versions of vkd3d.
* VKD3D_NO_TRACE_MESSAGES - do not emit trace messages in the debug log; this
can be useful in release builds to reduce the size of the binary and make it
slightly faster.
* VKD3D_NO_DEBUG_MESSAGES - do not emit warn and fixme messages in the debug
log; this will further optimise the binary, but may omit messages that could
help debug problems with vkd3d.
* VKD3D_NO_ERROR_MESSAGES - do not emit error messages; this will optimise the
binary even more, but may omit very important messages, so it is not
recommended in most circumstances.
* VKD3D_ABORT_ON_ERR - abort the process as soon as an error message is
emitted; this can be useful for developers to make error conditions as
conspicuous as possible.
* VKD3D_SHADER_UNSUPPORTED_GLSL - enable GLSL (GL Shading Language) support in
vkd3d-shader, which is disabled by default because it is not considered ready
for release yet. Please note that this feature is not currently supported,
and it might change in a non-compatible way before it is released.
* VKD3D_SHADER_UNSUPPORTED_MSL - enable MSL (Metal Shading Language) support in
vkd3d-shader, which is disabled by default because it is not considered ready
for release yet. Please note that this feature is not currently supported,
and it might change in a non-compatible way before it is released.
* VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER - enable SPIR-V parser support in
vkd3d-shader, which is disabled by default because it is not considered ready
for release yet. Please note that this feature is not currently supported,
and it might change in a non-compatible way before it is released.
============================
Testing with the Agility SDK
============================
Traditionally Microsoft have released the Direct3D 12 development files,
including the debug layer runtime, as part of the larger Windows SDK.
In 2021 the DirectX 12 Agility SDK was introduced, which may be updated
independently of the Windows SDK. If you plan to run the vkd3d
crosstests with Microsoft's debug layer you might want to get it from
the Agility SDK, both because it's probably going to be more up-to-date
and because the Agility SDK is a couple dozens of megabytes versus the
gigabytes of the Windows SDK.
In order to build the vkd3d crosstests with Agility SDK support, follow
these steps:
* The Agility SDK is distributed at [1]: select your preferred
version (likely the most recent one) and note the number in column
D3D12SDKVersion, which you're going to need later.
[1] https://devblogs.microsoft.com/directx/directx12agility/
* You also need to enable the "Graphics Tools" optional feature in Windows.
Open the "Settings" applications, then look for "Apps", "Optional features",
"View features" and install "Graphics Tools".
* Configure vkd3d with something like:
'CROSSCC64="x86_64-w64-mingw32-gcc -DVKD3D_AGILITY_SDK_VERSION=<version>"',
as well as the equivalent CROSSCC32 variable for the 32-bit
crosstests. You'll have to replace '<version>' with the
D3D12SDKVersion number you noted above. Then build the crosstests
with 'make crosstest' as usual.
* Download the Agility SDK NuGet package, which is essentially a ZIP
file with a .nupkg extension. Extract d3d12core.dll and
d3d12sdklayers.dll for your architecture, and put them in the
directory containing the crosstest executables.
* Now you can run the crosstests, possibly with arguments
'--validate' and '--gbv' to enable the debug layers. They will use
the runtime from the Agility SDK.
* It's also possible to use '-DVKD3D_AGILITY_SDK_PATH=/path/to/sdk/' to
specify the directory to load the Agility SDK DLLs from at runtime.
If relative, the path is intended to be relative to the executable
path. If unspecified the path defaults to './'.

View File

@@ -1,17 +1,14 @@
AC_PREREQ([2.69]) AC_PREREQ([2.69])
AC_INIT([vkd3d],[1.16]) AC_INIT([vkd3d],[1.7.1])
AC_CONFIG_AUX_DIR([bin]) AC_CONFIG_AUX_DIR([bin])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS(include/config.h) AC_CONFIG_HEADERS(include/config.h)
AC_ARG_VAR([PERL], [The Perl 5 language interpreter])
AC_ARG_VAR([WIDL], [widl IDL compiler]) AC_ARG_VAR([WIDL], [widl IDL compiler])
AC_ARG_VAR([CROSSCC32], [32-bit Windows cross compiler]) AC_ARG_VAR([CROSSCC32], [32-bit Windows cross compiler])
AC_ARG_VAR([CROSSCC64], [64-bit Windows cross compiler]) AC_ARG_VAR([CROSSCC64], [64-bit Windows cross compiler])
AC_ARG_WITH([metal], AS_HELP_STRING([--with-metal], [Build with the Metal library (default: test)]))
AC_ARG_WITH([ncurses], AS_HELP_STRING([--with-ncurses], [Build with the ncurses library (default: test)])) AC_ARG_WITH([ncurses], AS_HELP_STRING([--with-ncurses], [Build with the ncurses library (default: test)]))
AC_ARG_WITH([opengl], AS_HELP_STRING([--with-opengl], [Build with the OpenGL library (default: test)]))
AC_ARG_WITH([spirv-tools], AS_HELP_STRING([--with-spirv-tools], AC_ARG_WITH([spirv-tools], AS_HELP_STRING([--with-spirv-tools],
[Build with SPIRV-Tools library (default: disabled)])) [Build with SPIRV-Tools library (default: disabled)]))
AC_ARG_WITH([xcb], AS_HELP_STRING([--with-xcb], [Build with XCB library (default: test)])) AC_ARG_WITH([xcb], AS_HELP_STRING([--with-xcb], [Build with XCB library (default: test)]))
@@ -30,14 +27,9 @@ AC_PROG_CC
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_PROG_SED AC_PROG_SED
AC_PROG_MKDIR_P AC_PROG_MKDIR_P
VKD3D_PROG_WIDL(3, 21) VKD3D_PROG_WIDL(3, 20)
AS_IF([test "x$WIDL" = "xno"], [AC_MSG_WARN([widl is required to build header files.])]) AS_IF([test "x$WIDL" = "xno"], [AC_MSG_WARN([widl is required to build header files.])])
AC_CHECK_PROGS([PERL], [perl], [none])
AS_IF([test "$PERL" = "none"], [AC_MSG_ERROR([no suitable perl found. Please install the 'perl-base' package.])])
VKD3D_CHECK_PERL_MODULE([JSON],
[AC_MSG_ERROR([perl module 'JSON' not found. Please install the 'libjson-perl' package.])])
AC_CHECK_PROGS([FLEX], [flex], [none]) AC_CHECK_PROGS([FLEX], [flex], [none])
AS_IF([test "$FLEX" = "none"], [AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])]) AS_IF([test "$FLEX" = "none"], [AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])])
AC_ARG_VAR([LFLAGS], [extra flags for flex]) AC_ARG_VAR([LFLAGS], [extra flags for flex])
@@ -62,23 +54,16 @@ gl_LD_VERSION_SCRIPT
dnl Check compiler specific flags dnl Check compiler specific flags
AC_SUBST([VKD3D_CFLAGS]) AC_SUBST([VKD3D_CFLAGS])
AS_IF([test "x${GCC}" = "xyes"], AS_IF([test "x${GCC}" = "xyes"],
[VKD3D_CFLAGS="-Wall -pipe -D_WIN32_WINNT=0x0600" [VKD3D_CFLAGS="-Wall -pipe"
VKD3D_CHECK_CFLAGS([-std=c99]) VKD3D_CHECK_CFLAGS([-std=c99])
VKD3D_CHECK_CFLAGS([-flto=auto])
VKD3D_CHECK_CFLAGS([-fvisibility=hidden]) VKD3D_CHECK_CFLAGS([-fvisibility=hidden])
VKD3D_CHECK_CFLAGS([-Wdeclaration-after-statement]) VKD3D_CHECK_CFLAGS([-Wdeclaration-after-statement])
VKD3D_CHECK_CFLAGS([-Wempty-body])
VKD3D_CHECK_CFLAGS([-Wenum-conversion])
VKD3D_CHECK_CFLAGS([-Wimplicit-fallthrough]) VKD3D_CHECK_CFLAGS([-Wimplicit-fallthrough])
VKD3D_CHECK_CFLAGS([-Winit-self]) VKD3D_CHECK_CFLAGS([-Winit-self])
VKD3D_CHECK_CFLAGS([-Wmissing-prototypes]) VKD3D_CHECK_CFLAGS([-Wmissing-prototypes])
VKD3D_CHECK_CFLAGS([-Wpointer-arith])
VKD3D_CHECK_CFLAGS([-Wshadow])
VKD3D_CHECK_CFLAGS([-Wshift-overflow=2])
VKD3D_CHECK_CFLAGS([-Wtype-limits])
VKD3D_CHECK_CFLAGS([-Wunused-but-set-parameter]) VKD3D_CHECK_CFLAGS([-Wunused-but-set-parameter])
VKD3D_CHECK_CFLAGS([-Wvla]) VKD3D_CHECK_CFLAGS([-Wvla])
VKD3D_CHECK_CFLAGS([-Wwrite-strings]) VKD3D_CHECK_CFLAGS([-Wpointer-arith])
VKD3D_CHECK_CFLAGS([-Wl,--no-undefined])]) VKD3D_CHECK_CFLAGS([-Wl,--no-undefined])])
dnl Check for cross compilers dnl Check for cross compilers
@@ -98,7 +83,7 @@ AS_IF([test "x$ac_cv_header_spirv_unified1_GLSL_std_450_h" != "xyes" \
-a "x$ac_cv_header_vulkan_GLSL_std_450_h" != "xyes"], -a "x$ac_cv_header_vulkan_GLSL_std_450_h" != "xyes"],
[AC_MSG_ERROR([GLSL.std.450.h not found.])]) [AC_MSG_ERROR([GLSL.std.450.h not found.])])
VKD3D_CHECK_VULKAN_HEADER_VERSION([228], [AC_MSG_ERROR([Vulkan headers are too old, 1.3.228 is required.])]) VKD3D_CHECK_VULKAN_HEADER_VERSION([139], [AC_MSG_ERROR([Vulkan headers are too old, 1.2.139 is required.])])
AC_CHECK_DECL([SpvCapabilityDemoteToHelperInvocationEXT],, [AC_MSG_ERROR([SPIR-V headers are too old.])], [ AC_CHECK_DECL([SpvCapabilityDemoteToHelperInvocationEXT],, [AC_MSG_ERROR([SPIR-V headers are too old.])], [
#ifdef HAVE_SPIRV_UNIFIED1_SPIRV_H #ifdef HAVE_SPIRV_UNIFIED1_SPIRV_H
@@ -135,30 +120,10 @@ AS_IF([test "x$SONAME_LIBVULKAN" = "x"],
[VKD3D_CHECK_VULKAN], [VKD3D_CHECK_VULKAN],
[AC_DEFINE_UNQUOTED([SONAME_LIBVULKAN],["$SONAME_LIBVULKAN"],[Define to the shared object name of the Vulkan library.])]) [AC_DEFINE_UNQUOTED([SONAME_LIBVULKAN],["$SONAME_LIBVULKAN"],[Define to the shared object name of the Vulkan library.])])
AC_ARG_VAR([SONAME_LIBDXCOMPILER], [shared object name for the dxcompiler library])
AC_ARG_VAR([DXCOMPILER_LIBS], [linker flags for the dxcompiler library])
AS_IF([test "x$SONAME_LIBDXCOMPILER" = "x"],
[VKD3D_CHECK_SONAME([dxcompiler], [DxcCreateInstance], [HAVE_DXCOMPILER=yes], [HAVE_DXCOMPILER=no], [$DXCOMPILER_LIBS])],
[AC_DEFINE_UNQUOTED([SONAME_LIBDXCOMPILER],["$SONAME_LIBDXCOMPILER"],[Define to the shared object name of the dxcompiler library.])])
AS_IF([test "x$with_metal" != "xno"],
[AC_MSG_CHECKING([for Metal])]
[AC_PREPROC_IFELSE([AC_LANG_PROGRAM([#include <Metal/Metal.h>])],
[AC_MSG_RESULT([yes])
AC_PROG_OBJC
AC_DEFINE([HAVE_METAL], [1], [Define to 1 if you have Metal.])
with_metal=yes],
[AC_MSG_RESULT([no])
AM_CONDITIONAL([am__fastdepOBJC], [false])
with_metal=no])])
AS_IF([test "x$with_ncurses" != "xno"], AS_IF([test "x$with_ncurses" != "xno"],
[PKG_CHECK_MODULES([NCURSES], [ncurses], [PKG_CHECK_MODULES([NCURSES], [ncurses],
[AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if you have ncurses.]) with_ncurses=yes], [AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if you have ncurses.]) with_ncurses=yes],
[with_ncurses=no])]) [with_ncurses=no])])
AS_IF([test "x$with_opengl" != "xno"],
[PKG_CHECK_MODULES([OPENGL], [egl opengl],
[AC_DEFINE([HAVE_OPENGL], [1], [Define to 1 if you have OpenGL.]) with_opengl=yes],
[with_opengl=no])])
AS_IF([test "x$with_spirv_tools" = "xyes"], AS_IF([test "x$with_spirv_tools" = "xyes"],
[PKG_CHECK_MODULES([SPIRV_TOOLS], [SPIRV-Tools-shared], [PKG_CHECK_MODULES([SPIRV_TOOLS], [SPIRV-Tools-shared],
[AC_DEFINE([HAVE_SPIRV_TOOLS], [1], [Define to 1 if you have SPIRV-Tools.])])], [AC_DEFINE([HAVE_SPIRV_TOOLS], [1], [Define to 1 if you have SPIRV-Tools.])])],
@@ -176,35 +141,26 @@ VKD3D_CHECK_FUNC([HAVE_BUILTIN_CLZ], [__builtin_clz], [__builtin_clz(0)])
VKD3D_CHECK_FUNC([HAVE_BUILTIN_POPCOUNT], [__builtin_popcount], [__builtin_popcount(0)]) VKD3D_CHECK_FUNC([HAVE_BUILTIN_POPCOUNT], [__builtin_popcount], [__builtin_popcount(0)])
VKD3D_CHECK_FUNC([HAVE_BUILTIN_ADD_OVERFLOW], [__builtin_add_overflow], [__builtin_add_overflow(0, 0, (int *)0)]) VKD3D_CHECK_FUNC([HAVE_BUILTIN_ADD_OVERFLOW], [__builtin_add_overflow], [__builtin_add_overflow(0, 0, (int *)0)])
VKD3D_CHECK_FUNC([HAVE_SYNC_ADD_AND_FETCH], [__sync_add_and_fetch], [__sync_add_and_fetch((int *)0, 0)]) VKD3D_CHECK_FUNC([HAVE_SYNC_ADD_AND_FETCH], [__sync_add_and_fetch], [__sync_add_and_fetch((int *)0, 0)])
VKD3D_CHECK_FUNC([HAVE_SYNC_BOOL_COMPARE_AND_SWAP], [__sync_bool_compare_and_swap], [__sync_bool_compare_and_swap((int *)0, 0, 0)]) VKD3D_CHECK_FUNC([HAVE_SYNC_SUB_AND_FETCH], [__sync_sub_and_fetch], [__sync_sub_and_fetch((int *)0, 0)])
VKD3D_CHECK_FUNC([HAVE_ATOMIC_EXCHANGE_N], [__atomic_exchange_n], [__atomic_exchange_n((int *)0, 0, 0)])
AC_CHECK_FUNCS([gettid])
AC_CHECK_FUNCS([pthread_threadid_np])
dnl Makefiles dnl Makefiles
case $host_os in case $host_os in
mingw32*) mingw32*)
AC_SUBST([DEMO_LIBS],["-lgdi32"]) AC_SUBST([DEMO_LIBS],["-ld3d12 -ldxgi -lgdi32"])
AC_SUBST([DEMO_CFLAGS],["-municode"]) AC_SUBST([DEMO_CFLAGS],["-municode"])
;; ;;
darwin*)
AC_SUBST([DEMO_LIBS],["-framework Foundation -framework AppKit -framework QuartzCore"])
AC_SUBST([DEMO_CFLAGS],[""])
;;
*) AS_IF([test "x$enable_demos" = "xyes" -a "x$HAVE_XCB" != "xyes"], *) AS_IF([test "x$enable_demos" = "xyes" -a "x$HAVE_XCB" != "xyes"],
[AC_MSG_ERROR([libxcb is required for demos.])]) [AC_MSG_ERROR([libxcb is required for demos.])])
AC_SUBST([DEMO_LIBS],[$XCB_LIBS]) AC_SUBST([DEMO_LIBS],[$XCB_LIBS])
AC_SUBST([DEMO_CFLAGS],[$XCB_CFLAGS]) AC_SUBST([DEMO_CFLAGS],[$XCB_CFLAGS])
;; ;;
esac esac
VKD3D_CHECK_CFLAGS([-fno-lto], [DEMO_CFLAGS="$DEMO_CFLAGS -fno-lto"])
AM_CONDITIONAL([BUILD_DEMOS], [test "x$enable_demos" = "xyes"]) AM_CONDITIONAL([BUILD_DEMOS], [test "x$enable_demos" = "xyes"])
AM_CONDITIONAL([BUILD_DOC], [test $DX_FLAG_doc = 1]) AM_CONDITIONAL([BUILD_DOC], [test $DX_FLAG_doc = 1])
AM_CONDITIONAL([BUILD_TESTS], [test "x$enable_tests" != "xno"]) AM_CONDITIONAL([BUILD_TESTS], [test "x$enable_tests" != "xno"])
AM_CONDITIONAL([HAVE_WIDL], [test "x$WIDL" != "xno"]) AM_CONDITIONAL([HAVE_WIDL], [test "x$WIDL" != "xno"])
AM_CONDITIONAL([HAVE_CROSSTARGET32], [test "x$CROSSTARGET32" != "xno"]) AM_CONDITIONAL([HAVE_CROSSTARGET32], [test "x$CROSSTARGET32" != "xno"])
AM_CONDITIONAL([HAVE_CROSSTARGET64], [test "x$CROSSTARGET64" != "xno"]) AM_CONDITIONAL([HAVE_CROSSTARGET64], [test "x$CROSSTARGET64" != "xno"])
AM_CONDITIONAL([HAVE_METAL], [test "${host_os#darwin}" != "$host_os"])
AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([Makefile])
AC_OUTPUT AC_OUTPUT
@@ -221,10 +177,7 @@ AS_ECHO(["
widl: ${WIDL} widl: ${WIDL}
Have dxcompiler: ${HAVE_DXCOMPILER}
Have Metal: ${with_metal}
Have ncurses: ${with_ncurses} Have ncurses: ${with_ncurses}
Have OpenGL: ${with_opengl}
Have SPIRV-Tools: ${with_spirv_tools} Have SPIRV-Tools: ${with_spirv_tools}
Have xcb: ${HAVE_XCB} Have xcb: ${HAVE_XCB}

View File

@@ -39,46 +39,6 @@
#include <vkd3d_d3d12.h> #include <vkd3d_d3d12.h>
#include <inttypes.h> #include <inttypes.h>
#ifdef __WIN32__
#define DEMO_ASM_PUSHSECTION ".section rdata\n\t"
#define DEMO_ASM_POPSECTION ".text\n\t"
#define DEMO_ASM_OBJECT_TYPE(name)
#elif defined(__APPLE__)
#define DEMO_ASM_PUSHSECTION ".pushsection __TEXT,__const\n\t"
#define DEMO_ASM_POPSECTION ".popsection\n\t"
#define DEMO_ASM_OBJECT_TYPE(name)
#else
#define DEMO_ASM_PUSHSECTION ".pushsection .rodata\n\t"
#define DEMO_ASM_POPSECTION ".popsection\n\t"
#define DEMO_ASM_OBJECT_TYPE(name) ".type "name", @object\n\t"
#endif
#if (defined(__WIN32__) && defined(__i386__)) || defined(__APPLE__)
#define DEMO_ASM_NAME(name) "_"#name
#else
#define DEMO_ASM_NAME(name) #name
#endif
#define DEMO_EMBED_ASM(name, file) \
DEMO_ASM_PUSHSECTION \
".global "name"\n\t" \
DEMO_ASM_OBJECT_TYPE(name) \
".balign 8\n\t" \
name":\n\t" \
".incbin \""file"\"\n\t" \
name"_end:\n\t" \
".global "name"_size\n\t" \
DEMO_ASM_OBJECT_TYPE(name"_size") \
".balign 8\n\t" \
name"_size:\n\t" \
".int "name"_end - "name"\n\t" \
DEMO_ASM_POPSECTION
#define DEMO_EMBED(name, file) \
extern const unsigned int name##_size; \
extern const uint8_t name[]; \
__asm__(DEMO_EMBED_ASM(DEMO_ASM_NAME(name), file))
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
#define DEMO_KEY_UNKNOWN 0x0000 #define DEMO_KEY_UNKNOWN 0x0000
@@ -178,11 +138,9 @@ static inline HRESULT demo_create_root_signature(ID3D12Device *device,
return hr; return hr;
} }
#ifdef VKD3D_CROSSTEST #ifdef _WIN32
#include "demo_d3d12.h" #include "demo_win32.h"
#else #else
# ifndef _WIN32 #define INFINITE VKD3D_INFINITE
# define INFINITE VKD3D_INFINITE #include "demo_xcb.h"
# endif
#include "demo_vkd3d.h"
#endif #endif

View File

@@ -1,217 +0,0 @@
/*
* Copyright 2016 JĂłzef Kucia for CodeWeavers
* Copyright 2016 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <vkd3d_dxgi1_4.h>
#include <vkd3d_d3dcompiler.h>
#include <stdbool.h>
#include <stdio.h>
struct demo_win32
{
UINT (*GetDpiForSystem)(void);
};
struct demo
{
union
{
struct demo_win32 win32;
} u;
size_t window_count;
void *user_data;
void (*idle_func)(struct demo *demo, void *user_data);
};
struct demo_window
{
struct demo *demo;
void *user_data;
void (*expose_func)(struct demo_window *window, void *user_data);
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data);
};
static inline bool demo_window_init(struct demo_window *window, struct demo *demo, void *user_data)
{
window->demo = demo;
window->user_data = user_data;
window->expose_func = NULL;
window->key_press_func = NULL;
++demo->window_count;
return true;
}
static inline void demo_window_cleanup(struct demo_window *window)
{
--window->demo->window_count;
}
#include "demo_win32.h"
struct demo_swapchain
{
IDXGISwapChain3 *swapchain;
};
static inline void demo_cleanup(struct demo *demo)
{
demo_win32_cleanup(demo);
}
static inline bool demo_init(struct demo *demo, void *user_data)
{
if (!demo_win32_init(&demo->u.win32))
{
fprintf(stderr, "Failed to initialise demo.\n");
return false;
}
demo->window_count = 0;
demo->user_data = user_data;
demo->idle_func = NULL;
return true;
}
static inline void demo_get_dpi(struct demo *demo, double *dpi_x, double *dpi_y)
{
demo_win32_get_dpi(demo, dpi_x, dpi_y);
}
static inline void demo_process_events(struct demo *demo)
{
demo_win32_process_events(demo);
}
static inline void demo_set_idle_func(struct demo *demo,
void (*idle_func)(struct demo *demo, void *user_data))
{
demo->idle_func = idle_func;
}
static inline void demo_window_destroy(struct demo_window *window)
{
demo_window_win32_destroy(window);
}
static inline struct demo_window *demo_window_create(struct demo *demo, const char *title,
unsigned int width, unsigned int height, void *user_data)
{
return demo_window_win32_create(demo, title, width, height, user_data);
}
static inline void demo_window_set_expose_func(struct demo_window *window,
void (*expose_func)(struct demo_window *window, void *user_data))
{
window->expose_func = expose_func;
}
static inline void demo_window_set_key_press_func(struct demo_window *window,
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data))
{
window->key_press_func = key_press_func;
}
static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *command_queue,
struct demo_window *window, const struct demo_swapchain_desc *desc)
{
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w);
DXGI_SWAP_CHAIN_DESC1 swapchain_desc;
struct demo_swapchain *swapchain;
IDXGISwapChain1 *swapchain1;
IDXGIFactory2 *factory;
HRESULT hr;
if (!(swapchain = malloc(sizeof(*swapchain))))
return NULL;
if (FAILED(CreateDXGIFactory1(&IID_IDXGIFactory2, (void **)&factory)))
goto fail;
memset(&swapchain_desc, 0, sizeof(swapchain_desc));
swapchain_desc.BufferCount = desc->buffer_count;
swapchain_desc.Width = desc->width;
swapchain_desc.Height = desc->height;
swapchain_desc.Format = desc->format;
swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapchain_desc.SampleDesc.Count = 1;
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)command_queue,
window_win32->window, &swapchain_desc, NULL, NULL, &swapchain1);
IDXGIFactory2_Release(factory);
if (FAILED(hr))
goto fail;
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain->swapchain);
IDXGISwapChain1_Release(swapchain1);
if (FAILED(hr))
goto fail;
return swapchain;
fail:
free(swapchain);
return NULL;
}
static inline unsigned int demo_swapchain_get_current_back_buffer_index(struct demo_swapchain *swapchain)
{
return IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain->swapchain);
}
static inline ID3D12Resource *demo_swapchain_get_back_buffer(struct demo_swapchain *swapchain, unsigned int index)
{
ID3D12Resource *buffer;
if (FAILED(IDXGISwapChain3_GetBuffer(swapchain->swapchain, index,
&IID_ID3D12Resource, (void **)&buffer)))
return NULL;
return buffer;
}
static inline void demo_swapchain_present(struct demo_swapchain *swapchain)
{
IDXGISwapChain3_Present(swapchain->swapchain, 1, 0);
}
static inline void demo_swapchain_destroy(struct demo_swapchain *swapchain)
{
IDXGISwapChain3_Release(swapchain->swapchain);
free(swapchain);
}
static inline HANDLE demo_create_event(void)
{
return CreateEventA(NULL, FALSE, FALSE, NULL);
}
static inline unsigned int demo_wait_event(HANDLE event, unsigned int ms)
{
return WaitForSingleObject(event, ms);
}
static inline void demo_destroy_event(HANDLE event)
{
CloseHandle(event);
}

View File

@@ -1,310 +0,0 @@
/*
* Copyright 2025 Henri Verbeet
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
typedef long NSInteger;
typedef unsigned long NSUInteger;
typedef struct NSPoint
{
double x, y;
} NSPoint;
typedef struct NSRect
{
double x, y;
double w, h;
} NSRect;
#define BOOL OBJC_BOOL
#include "private/appkit.h"
#include "private/foundation.h"
#include "private/quartzcore.h"
#undef BOOL
extern const id NSDefaultRunLoopMode;
enum NSBackingStoreType
{
NSBackingStoreBuffered = 2,
};
enum NSEventType
{
NSEventTypeKeyDown = 0xa,
NSEventTypeApplicationDefined = 0xf,
};
enum NSWindowStyleMask
{
NSWindowStyleMaskBorderless = 0x0000,
NSWindowStyleMaskTitled = 0x0001,
NSWindowStyleMaskClosable = 0x0002,
NSWindowStyleMaskMiniaturizable = 0x0004,
NSWindowStyleMaskResizable = 0x0008,
NSWindowStyleMaskUtilityWindow = 0x0010,
NSWindowStyleMaskDocModalWindow = 0x0040,
NSWindowStyleMaskNonactivatingPanel = 0x0080,
NSWindowStyleMaskUnifiedTitleAndToolbar = 0x1000,
NSWindowStyleMaskHUDWindow = 0x2000,
NSWindowStyleMaskFullScreen = 0x4000,
NSWindowStyleMaskFullSizeContentView = 0x8000,
};
enum
{
DemoWindowDestroyed,
};
struct demo_window_macos
{
struct demo_window w;
id window;
id layer;
};
static struct demo_window_macos *demo_macos_find_macos_window(struct demo *demo, id window)
{
size_t i;
for (i = 0; i < demo->window_count; ++i)
{
struct demo_window_macos *window_macos = CONTAINING_RECORD(demo->windows[i], struct demo_window_macos, w);
if (window_macos->window == window)
return window_macos;
}
return NULL;
}
static VkSurfaceKHR demo_window_macos_create_vk_surface(struct demo_window *window, VkInstance vk_instance)
{
struct demo_window_macos *window_macos = CONTAINING_RECORD(window, struct demo_window_macos, w);
struct VkMetalSurfaceCreateInfoEXT surface_desc;
VkSurfaceKHR vk_surface;
id l, v;
l = window_macos->layer = CAMetalLayer_layer();
CAMetalLayer_setContentsScale(l, NSScreen_backingScaleFactor(NSScreen_mainScreen()));
v = NSWindow_contentView(window_macos->window);
NSView_setLayer(v, l);
NSView_setWantsLayer(v, true);
surface_desc.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
surface_desc.pNext = NULL;
surface_desc.flags = 0;
surface_desc.pLayer = l;
if (vkCreateMetalSurfaceEXT(vk_instance, &surface_desc, NULL, &vk_surface) < 0)
return VK_NULL_HANDLE;
return vk_surface;
}
static void demo_window_macos_destroy(struct demo_window *window)
{
struct demo_window_macos *window_macos = CONTAINING_RECORD(window, struct demo_window_macos, w);
NSWindow_close(window_macos->window);
}
static void demo_window_macos_destroyed(struct demo_window_macos *window_macos)
{
CAMetalLayer_release(window_macos->layer);
NSWindow_release(window_macos->window);
demo_window_cleanup(&window_macos->w);
free(window_macos);
}
static struct demo_window *demo_window_macos_create(struct demo *demo,
const char *title, unsigned int width, unsigned int height, void *user_data)
{
unsigned long style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable;
struct demo_window_macos *window_macos;
NSRect r = {0, 0, width, height};
double scale;
id w, s;
if (!(window_macos = malloc(sizeof(*window_macos))))
return NULL;
if (!demo_window_init(&window_macos->w, demo, user_data,
demo_window_macos_create_vk_surface, demo_window_macos_destroy))
{
free(window_macos);
return NULL;
}
s = NSScreen_mainScreen();
scale = NSScreen_backingScaleFactor(s);
r.w /= scale;
r.h /= scale;
w = window_macos->window = class_createInstance(objc_getClass("DemoWindow"), 0);
NSWindow_initWithContentRect(w, r, style, NSBackingStoreBuffered, true, s);
NSWindow_setReleasedWhenClosed(w, false);
NSWindow_setDelegate(w, w);
NSWindow_center(w);
NSWindow_setTitle(w, NSString_stringWithUTF8String(title));
NSWindow_makeKeyAndOrderFront(w, nil);
window_macos->layer = nil;
return &window_macos->w;
}
static void demo_macos_get_dpi(struct demo *demo, double *dpi_x, double *dpi_y)
{
*dpi_x = *dpi_y = 96.0 * NSScreen_backingScaleFactor(NSScreen_mainScreen());
}
static demo_key demo_key_from_nsevent(id event)
{
enum vkey
{
kVK_ANSI_A = 0x00,
kVK_Escape = 0x35,
kVK_LeftArrow = 0x7b,
kVK_RightArrow = 0x7c,
kVK_DownArrow = 0x7d,
kVK_UpArrow = 0x7e,
} vkey;
size_t i;
static const struct
{
enum vkey vkey;
demo_key demo_key;
}
lookup[] =
{
{kVK_ANSI_A, 'a'},
{kVK_Escape, DEMO_KEY_ESCAPE},
{kVK_LeftArrow, DEMO_KEY_LEFT},
{kVK_RightArrow, DEMO_KEY_RIGHT},
{kVK_UpArrow, DEMO_KEY_UP},
{kVK_DownArrow, DEMO_KEY_DOWN},
};
vkey = NSEvent_keyCode(event);
for (i = 0; i < ARRAY_SIZE(lookup); ++i)
{
if (lookup[i].vkey == vkey)
return lookup[i].demo_key;
}
return DEMO_KEY_UNKNOWN;
}
static void demo_macos_process_events(struct demo *demo)
{
struct demo_window_macos *window_macos;
struct demo_window *window;
id a, event;
size_t i;
for (i = 0; i < demo->window_count; ++i)
{
if ((window = demo->windows[i])->expose_func)
window->expose_func(window, window->user_data);
}
a = NSApplication_sharedApplication();
while (demo->window_count)
{
if (!demo->idle_func)
{
if (!(event = NSApplication_nextEventMatchingMask(a, ~(uint64_t)0,
NSDate_distantFuture(), NSDefaultRunLoopMode, true)))
break;
}
else if (!(event = NSApplication_nextEventMatchingMask(a, ~(uint64_t)0, nil, NSDefaultRunLoopMode, true)))
{
demo->idle_func(demo, demo->user_data);
continue;
}
switch (NSEvent_type(event))
{
case NSEventTypeKeyDown:
if (NSMenu_performKeyEquivalent(NSApplication_mainMenu(a), event))
continue;
if (!(window_macos = demo_macos_find_macos_window(demo, NSEvent_window(event)))
|| !window_macos->w.key_press_func)
break;
window_macos->w.key_press_func(&window_macos->w,
demo_key_from_nsevent(event), window_macos->w.user_data);
continue;
case NSEventTypeApplicationDefined:
if (NSEvent_subtype(event) != DemoWindowDestroyed
|| !(window_macos = demo_macos_find_macos_window(demo, NSEvent_window(event))))
break;
demo_window_macos_destroyed(window_macos);
continue;
}
NSApplication_sendEvent(a, event);
}
}
static void DemoWindow_windowWillClose(id window, SEL sel, id notification)
{
id event;
event = NSEvent_otherEventWithType(NSEventTypeApplicationDefined, (NSPoint){0.0, 0.0},
0, 0.0, NSWindow_windowNumber(window), nil, DemoWindowDestroyed, 0, 0);
NSApplication_postEvent(NSApplication_sharedApplication(), event, true);
}
static void demo_macos_cleanup(struct demo *demo)
{
}
static bool demo_macos_init(struct demo_macos *macos)
{
id application, item, menu, submenu;
Class c;
if ((c = objc_allocateClassPair(objc_getClass("NSWindow"), "DemoWindow", 0)))
{
class_addMethod(c, sel_registerName("windowWillClose:"), (IMP)DemoWindow_windowWillClose, "v@:@");
objc_registerClassPair(c);
}
application = NSApplication_sharedApplication();
NSApplication_setActivationPolicy(application, 0);
menu = NSMenu_new();
submenu = NSMenu_new();
NSMenu_addItemWithTitle(submenu, NSString_stringWithUTF8String("Quit"),
sel_registerName("terminate:"), NSString_stringWithUTF8String("q"));
item = NSMenuItem_new();
NSMenuItem_setSubmenu(item, submenu);
NSMenu_release(submenu);
NSMenu_addItem(menu, item);
NSMenuItem_release(item);
NSApplication_setMainMenu(application, menu);
NSMenu_release(menu);
NSApplication_finishLaunching(application);
return true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -17,108 +17,85 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#define DEMO_WIN32_WINDOW_CLASS_NAME L"demo_wc" #include <vkd3d_dxgi1_4.h>
#include <vkd3d_d3dcompiler.h>
#include <stdbool.h>
#include <stdio.h>
struct demo_window_win32 #define DEMO_WINDOW_CLASS_NAME L"demo_wc"
struct demo
{ {
struct demo_window w; size_t window_count;
bool quit;
HINSTANCE instance; void *user_data;
HWND window; void (*idle_func)(struct demo *demo, void *user_data);
}; };
#ifndef VKD3D_CROSSTEST struct demo_window
static VkSurfaceKHR demo_window_win32_create_vk_surface(struct demo_window *window, VkInstance vk_instance)
{ {
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w); HINSTANCE instance;
struct VkWin32SurfaceCreateInfoKHR surface_desc; HWND hwnd;
VkSurfaceKHR vk_surface; struct demo *demo;
void *user_data;
void (*expose_func)(struct demo_window *window, void *user_data);
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data);
};
surface_desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; struct demo_swapchain
surface_desc.pNext = NULL;
surface_desc.flags = 0;
surface_desc.hinstance = window_win32->instance;
surface_desc.hwnd = window_win32->window;
if (vkCreateWin32SurfaceKHR(vk_instance, &surface_desc, NULL, &vk_surface) < 0)
return VK_NULL_HANDLE;
return vk_surface;
}
#endif
static void demo_window_win32_destroy(struct demo_window *window)
{ {
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w); IDXGISwapChain3 *swapchain;
};
DestroyWindow(window_win32->window); static inline struct demo_window *demo_window_create(struct demo *demo, const char *title,
}
static void demo_window_win32_destroyed(struct demo_window *window)
{
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w);
demo_window_cleanup(&window_win32->w);
free(window_win32);
}
static struct demo_window *demo_window_win32_create(struct demo *demo, const char *title,
unsigned int width, unsigned int height, void *user_data) unsigned int width, unsigned int height, void *user_data)
{ {
struct demo_window_win32 *window_win32;
RECT rect = {0, 0, width, height}; RECT rect = {0, 0, width, height};
struct demo_window *window;
int title_size; int title_size;
WCHAR *title_w; WCHAR *title_w;
DWORD style; DWORD style;
if (!(window_win32 = malloc(sizeof(*window_win32)))) if (!(window = malloc(sizeof(*window))))
return NULL; return NULL;
#ifdef VKD3D_CROSSTEST
if (!demo_window_init(&window_win32->w, demo, user_data))
#else
if (!demo_window_init(&window_win32->w, demo, user_data,
demo_window_win32_create_vk_surface, demo_window_win32_destroy))
#endif
{
free(window_win32);
return NULL;
}
title_size = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); title_size = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
if (!(title_w = calloc(title_size, sizeof(*title_w)))) if (!(title_w = calloc(title_size, sizeof(*title_w))))
{ {
demo_window_cleanup(&window_win32->w); free(window);
free(window_win32);
return NULL; return NULL;
} }
MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, title_size); MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, title_size);
window_win32->instance = GetModuleHandle(NULL); window->instance = GetModuleHandle(NULL);
window->user_data = user_data;
window->expose_func = NULL;
window->key_press_func = NULL;
style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE; style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE;
AdjustWindowRect(&rect, style, FALSE); AdjustWindowRect(&rect, style, FALSE);
window_win32->window = CreateWindowExW(0, DEMO_WIN32_WINDOW_CLASS_NAME, title_w, style, CW_USEDEFAULT, window->hwnd = CreateWindowExW(0, DEMO_WINDOW_CLASS_NAME, title_w, style, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, window_win32->instance, NULL); rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, window->instance, NULL);
free(title_w); free(title_w);
if (!window_win32->window) if (!window->hwnd)
{ {
demo_window_cleanup(&window_win32->w); free(window);
free(window_win32);
return NULL; return NULL;
} }
SetWindowLongPtrW(window_win32->window, GWLP_USERDATA, (LONG_PTR)window_win32); SetWindowLongPtrW(window->hwnd, GWLP_USERDATA, (LONG_PTR)window);
window->demo = demo;
++demo->window_count;
return &window_win32->w; return window;
} }
static void demo_win32_get_dpi(struct demo *demo, double *dpi_x, double *dpi_y) static inline void demo_window_destroy(struct demo_window *window)
{ {
struct demo_win32 *win32 = &demo->u.win32; DestroyWindow(window->hwnd);
*dpi_x = *dpi_y = win32->GetDpiForSystem();
} }
static demo_key demo_key_from_win32_vkey(DWORD vkey) static inline demo_key demo_key_from_vkey(DWORD vkey)
{ {
static const struct static const struct
{ {
@@ -149,33 +126,46 @@ static demo_key demo_key_from_win32_vkey(DWORD vkey)
return DEMO_KEY_UNKNOWN; return DEMO_KEY_UNKNOWN;
} }
static LRESULT CALLBACK demo_win32_window_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) static inline LRESULT CALLBACK demo_window_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{ {
struct demo_window_win32 *window_win32 = (void *)GetWindowLongPtrW(window, GWLP_USERDATA); struct demo_window *window = (void *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
switch (message) switch (message)
{ {
case WM_PAINT: case WM_PAINT:
if (window_win32 && window_win32->w.expose_func) if (window && window->expose_func)
window_win32->w.expose_func(&window_win32->w, window_win32->w.user_data); window->expose_func(window, window->user_data);
return 0; return 0;
case WM_KEYDOWN: case WM_KEYDOWN:
if (!window_win32->w.key_press_func) if (!window->key_press_func)
break; break;
window_win32->w.key_press_func(&window_win32->w, window->key_press_func(window, demo_key_from_vkey(wparam), window->user_data);
demo_key_from_win32_vkey(wparam), window_win32->w.user_data);
return 0; return 0;
case WM_DESTROY: case WM_DESTROY:
demo_window_win32_destroyed(&window_win32->w); if (!--window->demo->window_count)
window->demo->quit = true;
free(window);
return 0; return 0;
} }
return DefWindowProcW(window, message, wparam, lparam); return DefWindowProcW(hwnd, message, wparam, lparam);
} }
static void demo_win32_process_events(struct demo *demo) static inline void demo_window_set_key_press_func(struct demo_window *window,
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data))
{
window->key_press_func = key_press_func;
}
static inline void demo_window_set_expose_func(struct demo_window *window,
void (*expose_func)(struct demo_window *window, void *user_data))
{
window->expose_func = expose_func;
}
static inline void demo_process_events(struct demo *demo)
{ {
MSG msg = {0}; MSG msg = {0};
@@ -196,28 +186,18 @@ static void demo_win32_process_events(struct demo *demo)
break; break;
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessageW(&msg); DispatchMessageW(&msg);
if (!demo->window_count) if (demo->quit)
PostQuitMessage(0); PostQuitMessage(0);
} }
} }
static void demo_win32_cleanup(struct demo *demo) static inline bool demo_init(struct demo *demo, void *user_data)
{
UnregisterClassW(DEMO_WIN32_WINDOW_CLASS_NAME, GetModuleHandle(NULL));
}
static inline UINT demo_win32_GetDpiForSystem(void)
{
return 96;
}
static bool demo_win32_init(struct demo_win32 *win32)
{ {
WNDCLASSEXW wc; WNDCLASSEXW wc;
wc.cbSize = sizeof(wc); wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW; wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = demo_win32_window_proc; wc.lpfnWndProc = demo_window_proc;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
wc.cbWndExtra = 0; wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL); wc.hInstance = GetModuleHandle(NULL);
@@ -225,15 +205,110 @@ static bool demo_win32_init(struct demo_win32 *win32)
wc.hCursor = LoadCursorW(NULL, IDC_ARROW); wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.lpszClassName = DEMO_WIN32_WINDOW_CLASS_NAME; wc.lpszClassName = DEMO_WINDOW_CLASS_NAME;
wc.hIconSm = LoadIconW(NULL, IDI_WINLOGO); wc.hIconSm = LoadIconW(NULL, IDI_WINLOGO);
if (!RegisterClassExW(&wc)) if (!RegisterClassExW(&wc))
return false; return false;
if ((win32->GetDpiForSystem = (void *)GetProcAddress(GetModuleHandleA("user32"), "GetDpiForSystem"))) demo->window_count = 0;
SetProcessDPIAware(); demo->quit = false;
else demo->user_data = user_data;
win32->GetDpiForSystem = demo_win32_GetDpiForSystem; demo->idle_func = NULL;
return true; return true;
} }
static inline void demo_cleanup(struct demo *demo)
{
UnregisterClassW(DEMO_WINDOW_CLASS_NAME, GetModuleHandle(NULL));
}
static inline void demo_set_idle_func(struct demo *demo,
void (*idle_func)(struct demo *demo, void *user_data))
{
demo->idle_func = idle_func;
}
static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *command_queue,
struct demo_window *window, const struct demo_swapchain_desc *desc)
{
DXGI_SWAP_CHAIN_DESC1 swapchain_desc;
struct demo_swapchain *swapchain;
IDXGISwapChain1 *swapchain1;
IDXGIFactory2 *factory;
HRESULT hr;
if (!(swapchain = malloc(sizeof(*swapchain))))
return NULL;
if (FAILED(CreateDXGIFactory1(&IID_IDXGIFactory2, (void **)&factory)))
goto fail;
memset(&swapchain_desc, 0, sizeof(swapchain_desc));
swapchain_desc.BufferCount = desc->buffer_count;
swapchain_desc.Width = desc->width;
swapchain_desc.Height = desc->height;
swapchain_desc.Format = desc->format;
swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapchain_desc.SampleDesc.Count = 1;
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)command_queue,
window->hwnd, &swapchain_desc, NULL, NULL, &swapchain1);
IDXGIFactory2_Release(factory);
if (FAILED(hr))
goto fail;
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain->swapchain);
IDXGISwapChain1_Release(swapchain1);
if (FAILED(hr))
goto fail;
return swapchain;
fail:
free(swapchain);
return NULL;
}
static inline unsigned int demo_swapchain_get_current_back_buffer_index(struct demo_swapchain *swapchain)
{
return IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain->swapchain);
}
static inline ID3D12Resource *demo_swapchain_get_back_buffer(struct demo_swapchain *swapchain, unsigned int index)
{
ID3D12Resource *buffer;
if (FAILED(IDXGISwapChain3_GetBuffer(swapchain->swapchain, index,
&IID_ID3D12Resource, (void **)&buffer)))
return NULL;
return buffer;
}
static inline void demo_swapchain_present(struct demo_swapchain *swapchain)
{
IDXGISwapChain3_Present(swapchain->swapchain, 1, 0);
}
static inline void demo_swapchain_destroy(struct demo_swapchain *swapchain)
{
IDXGISwapChain3_Release(swapchain->swapchain);
free(swapchain);
}
static inline HANDLE demo_create_event(void)
{
return CreateEventA(NULL, FALSE, FALSE, NULL);
}
static inline unsigned int demo_wait_event(HANDLE event, unsigned int ms)
{
return WaitForSingleObject(event, ms);
}
static inline void demo_destroy_event(HANDLE event)
{
CloseHandle(event);
}

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,7 @@
#include <math.h> #include <math.h>
#include "demo.h" #include "demo.h"
DEMO_EMBED(gears_hlsl, "gears.hlsl"); #include "gears_hlsl.h"
struct cxg_fence struct cxg_fence
{ {
@@ -681,14 +681,11 @@ static void cxg_load_assets(struct cx_gears *cxg)
hr = demo_create_root_signature(cxg->device, &root_signature_desc, &cxg->root_signature); hr = demo_create_root_signature(cxg->device, &root_signature_desc, &cxg->root_signature);
assert(SUCCEEDED(hr)); assert(SUCCEEDED(hr));
hr = D3DCompile(gears_hlsl, gears_hlsl_size, "gears.hlsl", hr = D3DCompile(gears_hlsl, strlen(gears_hlsl), NULL, NULL, NULL, "vs_main", "vs_5_0", 0, 0, &vs, NULL);
NULL, NULL, "vs_main", "vs_5_0", 0, 0, &vs, NULL);
assert(SUCCEEDED(hr)); assert(SUCCEEDED(hr));
hr = D3DCompile(gears_hlsl, gears_hlsl_size, "gears.hlsl", hr = D3DCompile(gears_hlsl, strlen(gears_hlsl), NULL, NULL, NULL, "ps_main_flat", "ps_5_0", 0, 0, &ps_flat, NULL);
NULL, NULL, "ps_main_flat", "ps_5_0", 0, 0, &ps_flat, NULL);
assert(SUCCEEDED(hr)); assert(SUCCEEDED(hr));
hr = D3DCompile(gears_hlsl, gears_hlsl_size, "gears.hlsl", hr = D3DCompile(gears_hlsl, strlen(gears_hlsl), NULL, NULL, NULL, "ps_main_smooth", "ps_5_0", 0, 0, &ps_smooth, NULL);
NULL, NULL, "ps_main_smooth", "ps_5_0", 0, 0, &ps_smooth, NULL);
assert(SUCCEEDED(hr)); assert(SUCCEEDED(hr));
memset(&pso_desc, 0, sizeof(pso_desc)); memset(&pso_desc, 0, sizeof(pso_desc));
@@ -849,16 +846,12 @@ static int cxg_main(void)
{ {
unsigned int width = 300, height = 300; unsigned int width = 300, height = 300;
struct cx_gears cxg; struct cx_gears cxg;
double dpi_x, dpi_y;
memset(&cxg, 0, sizeof(cxg)); memset(&cxg, 0, sizeof(cxg));
if (!demo_init(&cxg.demo, &cxg)) if (!demo_init(&cxg.demo, &cxg))
return EXIT_FAILURE; return EXIT_FAILURE;
demo_set_idle_func(&cxg.demo, cxg_idle); demo_set_idle_func(&cxg.demo, cxg_idle);
demo_get_dpi(&cxg.demo, &dpi_x, &dpi_y);
width *= dpi_x / 96.0;
height *= dpi_y / 96.0;
cxg.window = demo_window_create(&cxg.demo, "Vkd3d Gears", width, height, &cxg); cxg.window = demo_window_create(&cxg.demo, "Vkd3d Gears", width, height, &cxg);
demo_window_set_key_press_func(cxg.window, cxg_key_press); demo_window_set_key_press_func(cxg.window, cxg_key_press);
demo_window_set_expose_func(cxg.window, cxg_expose); demo_window_set_expose_func(cxg.window, cxg_expose);
@@ -895,9 +888,6 @@ static int cxg_main(void)
} }
#ifdef _WIN32 #ifdef _WIN32
/* Do not trigger -Wmissing-prototypes. */
int wmain(void);
int wmain(void) int wmain(void)
#else #else
int main(void) int main(void)

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2016 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
cbuffer gear_block : register(b0)
{
float4x4 mvp_matrix;
float3x3 normal_matrix;
};
struct vs_in
{
float4 position : POSITION;
float3 normal : NORMAL;
float3 diffuse : DIFFUSE;
float4 transform : TRANSFORM;
};
struct vs_out
{
float4 position : SV_POSITION;
float4 colour : COLOR;
};
struct vs_out vs_main(struct vs_in i)
{
const float3 l_pos = float3(5.0, 5.0, 10.0);
float3 dir, normal;
float4 position;
struct vs_out o;
float att;
position.x = i.transform.x * i.position.x - i.transform.y * i.position.y + i.transform.z;
position.y = i.transform.x * i.position.y + i.transform.y * i.position.x + i.transform.w;
position.zw = i.position.zw;
o.position = mul(mvp_matrix, position);
dir = normalize(l_pos - o.position.xyz / o.position.w);
normal.x = i.transform.x * i.normal.x - i.transform.y * i.normal.y;
normal.y = i.transform.x * i.normal.y + i.transform.y * i.normal.x;
normal.z = i.normal.z;
att = 0.2 + dot(dir, normalize(mul(normal_matrix, normal)));
o.colour.xyz = i.diffuse.xyz * att;
o.colour.w = 1.0;
return o;
}
float4 ps_main_smooth(float4 position : SV_POSITION, float4 colour : COLOR) : SV_TARGET
{
return colour;
}
float4 ps_main_flat(float4 position : SV_POSITION, nointerpolation float4 colour : COLOR) : SV_TARGET
{
return colour;
}

Some files were not shown because too many files have changed in this diff Show More