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
439 changed files with 27297 additions and 165753 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
test-suite.log
/vkd3d-compiler
/vkd3d-dxbc
vkd3d-*.tar.xz
@@ -23,7 +22,6 @@ vkd3d-*.tar.xz
*.tab.c
*.tab.h
*.trs
*.txt
*.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>

684
ANNOUNCE

File diff suppressed because it is too large Load Diff

16
AUTHORS
View File

@@ -1,10 +1,6 @@
Akihiro Sagawa
Alexandre Julliard
Alistair Leslie-Hughes
Andrew Eikum
Andrey Gusev
Anna (navi) Figueiredo Gomes
Arkadiusz Hiler
Atharva Nimbalkar
Biswapriyo Nath
Brendan Shanks
@@ -12,34 +8,24 @@ Chip Davis
Conor McCarthy
David Gow
Derek Lesho
Elizabeth Figura
Ethan Lee
Evan Tang
Fabian Maurer
Feifan He
Florian Weimer
Francisco Casas
Francois Gouget
Giovanni Mascellani
Hans-Kristian Arntzen
Henri Verbeet
Isabella Bosia
Jacek Caban
Jactry Zeng
Jan Sikorski
Joshua Ashton
JĂłzef Kucia
Martin Storsjö
Matteo Bruni
Nikolay Sivov
Petrichor Park
Philip Rebohle
Rémi Bernon
Robin Kertels
Shaun Ren
Stefan Dösinger
Sven Hesse
Victor Chiletto
Vinson Lee
Yuxuan Shui
Zebediah Figura
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)
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
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_STATIC = YES
QUIET = YES
WARN_IF_UNDOCUMENTED = NO
WARN_IF_INCOMPLETE_DOC = NO
LATEX_BATCHMODE = YES
INPUT = @srcdir@/include/vkd3d.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
==============
Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.3.228), as well as Perl
and libjson-perl.
Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.2.139).
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
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
available or is not recent (>= 3.21), then you can build Wine with `make
tools/widl/widl' to avoid building all of Wine. You can then point vkd3d's
available or is not recent (>= 3.20), then you can build Wine with `make
tools/widl' to avoid building all of Wine. You can then point vkd3d's
configure at that widl binary with `WIDL="/path/to/widl"'.
For release builds, you may want to disable debug log messages defining
preprocessor macros VKD3D_NO_TRACE_MESSAGES and VKD3D_NO_DEBUG_MESSAGES.
See the `Preprocessor definitions' section below for more details.
================
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.
For release builds, you may want to define NDEBUG. If you do not need debug log
messages, you may also consider VKD3D_NO_TRACE_MESSAGES and
VKD3D_NO_DEBUG_MESSAGES. For example, you can pass `CPPFLAGS="-DNDEBUG
-DVKD3D_NO_TRACE_MESSAGES"' to configure.
===========
Using vkd3d
@@ -50,16 +39,16 @@ Environment variables
=====================
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
or removed in future versions of vkd3d.
environment variables are not considered a part of API and might be changed or
removed in the future versions of vkd3d.
Some of debug variables are lists of elements. Elements must be separated by
commas or semicolons.
* NO_COLOR - this is an alias of NO_COLOUR.
* NO_COLOUR - when set, vkd3d-compiler and vkd3d-dxbc will default to
monochrome output, even when the output supports colour.
* NO_COLOUR - when set, vkd3d-compiler will default to monochrome output,
even when the output supports colour.
* VKD3D_CONFIG - a list of options that change the behavior of libvkd3d.
* 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
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
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
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
filter string will be run, e.g. VKD3D_TEST_FILTER=clear_render_target.
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()
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.
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_INIT([vkd3d],[1.17])
AC_INIT([vkd3d],[1.7.1])
AC_CONFIG_AUX_DIR([bin])
AC_CONFIG_MACRO_DIR([m4])
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([CROSSCC32], [32-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([opengl], AS_HELP_STRING([--with-opengl], [Build with the OpenGL library (default: test)]))
AC_ARG_WITH([spirv-tools], AS_HELP_STRING([--with-spirv-tools],
[Build with SPIRV-Tools library (default: disabled)]))
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
AC_PROG_SED
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.])])
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])
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])
@@ -62,23 +54,16 @@ gl_LD_VERSION_SCRIPT
dnl Check compiler specific flags
AC_SUBST([VKD3D_CFLAGS])
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([-flto=auto])
VKD3D_CHECK_CFLAGS([-fvisibility=hidden])
VKD3D_CHECK_CFLAGS([-Wdeclaration-after-statement])
VKD3D_CHECK_CFLAGS([-Wempty-body])
VKD3D_CHECK_CFLAGS([-Wenum-conversion])
VKD3D_CHECK_CFLAGS([-Wimplicit-fallthrough])
VKD3D_CHECK_CFLAGS([-Winit-self])
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([-Wvla])
VKD3D_CHECK_CFLAGS([-Wwrite-strings])
VKD3D_CHECK_CFLAGS([-Wpointer-arith])
VKD3D_CHECK_CFLAGS([-Wl,--no-undefined])])
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"],
[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.])], [
#ifdef HAVE_SPIRV_UNIFIED1_SPIRV_H
@@ -135,30 +120,10 @@ AS_IF([test "x$SONAME_LIBVULKAN" = "x"],
[VKD3D_CHECK_VULKAN],
[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"],
[PKG_CHECK_MODULES([NCURSES], [ncurses],
[AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if you have ncurses.]) with_ncurses=yes],
[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"],
[PKG_CHECK_MODULES([SPIRV_TOOLS], [SPIRV-Tools-shared],
[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_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_BOOL_COMPARE_AND_SWAP], [__sync_bool_compare_and_swap], [__sync_bool_compare_and_swap((int *)0, 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])
VKD3D_CHECK_FUNC([HAVE_SYNC_SUB_AND_FETCH], [__sync_sub_and_fetch], [__sync_sub_and_fetch((int *)0, 0)])
dnl Makefiles
case $host_os in
mingw32*)
AC_SUBST([DEMO_LIBS],["-lgdi32"])
AC_SUBST([DEMO_LIBS],["-ld3d12 -ldxgi -lgdi32"])
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"],
[AC_MSG_ERROR([libxcb is required for demos.])])
AC_SUBST([DEMO_LIBS],[$XCB_LIBS])
AC_SUBST([DEMO_CFLAGS],[$XCB_CFLAGS])
;;
esac
VKD3D_CHECK_CFLAGS([-fno-lto], [DEMO_CFLAGS="$DEMO_CFLAGS -fno-lto"])
AM_CONDITIONAL([BUILD_DEMOS], [test "x$enable_demos" = "xyes"])
AM_CONDITIONAL([BUILD_DOC], [test $DX_FLAG_doc = 1])
AM_CONDITIONAL([BUILD_TESTS], [test "x$enable_tests" != "xno"])
AM_CONDITIONAL([HAVE_WIDL], [test "x$WIDL" != "xno"])
AM_CONDITIONAL([HAVE_CROSSTARGET32], [test "x$CROSSTARGET32" != "xno"])
AM_CONDITIONAL([HAVE_CROSSTARGET64], [test "x$CROSSTARGET64" != "xno"])
AM_CONDITIONAL([HAVE_METAL], [test "${host_os#darwin}" != "$host_os"])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
@@ -221,10 +177,7 @@ AS_ECHO(["
widl: ${WIDL}
Have dxcompiler: ${HAVE_DXCOMPILER}
Have Metal: ${with_metal}
Have ncurses: ${with_ncurses}
Have OpenGL: ${with_opengl}
Have SPIRV-Tools: ${with_spirv_tools}
Have xcb: ${HAVE_XCB}

View File

@@ -38,69 +38,15 @@
#define COBJMACROS
#include <vkd3d_d3d12.h>
#include <inttypes.h>
#include <math.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))
#if defined(__GNUC__) || defined(__clang__)
# ifdef __MINGW_PRINTF_FORMAT
# define DEMO_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args)))
# else
# define DEMO_PRINTF_FUNC(fmt, args) __attribute__((format(printf, fmt, args)))
# endif
#else
# define DEMO_PRINTF_FUNC(fmt, args)
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
#define DEMO_KEY_UNKNOWN 0x0000
#define DEMO_KEY_ESCAPE 0xff1b
#define DEMO_KEY_LEFT 0xff51
#define DEMO_KEY_UP 0xff52
#define DEMO_KEY_RIGHT 0xff53
#define DEMO_KEY_DOWN 0xff54
#define DEMO_KEY_KP_ADD 0xffab
#define DEMO_KEY_KP_SUBTRACT 0xffad
#define DEMO_KEY_F1 0xffbe
#define DEMO_KEY_UNKNOWN 0x0000
#define DEMO_KEY_ESCAPE 0xff1b
#define DEMO_KEY_LEFT 0xff51
#define DEMO_KEY_UP 0xff52
#define DEMO_KEY_RIGHT 0xff53
#define DEMO_KEY_DOWN 0xff54
struct demo_vec3
{
@@ -112,26 +58,6 @@ struct demo_vec4
float x, y, z, w;
};
struct demo_uvec2
{
uint32_t x, y;
};
struct demo_uvec4
{
uint32_t x, y, z, w;
};
struct demo_matrix
{
float m[4][4];
};
struct demo_patch
{
uint16_t p[4][4];
};
struct demo_swapchain_desc
{
unsigned int width;
@@ -149,36 +75,6 @@ static inline void demo_vec3_set(struct demo_vec3 *v, float x, float y, float z)
v->z = z;
}
static inline void demo_vec3_subtract(struct demo_vec3 *v, const struct demo_vec3 *a, const struct demo_vec3 *b)
{
demo_vec3_set(v, a->x - b->x, a->y - b->y, a->z - b->z);
}
static inline float demo_vec3_dot(const struct demo_vec3 *a, const struct demo_vec3 *b)
{
return a->x * b->x + a->y * b->y + a->z * b->z;
}
static inline float demo_vec3_length(const struct demo_vec3 *v)
{
return sqrtf(demo_vec3_dot(v, v));
}
static inline void demo_vec3_scale(struct demo_vec3 *v, const struct demo_vec3 *a, float s)
{
demo_vec3_set(v, a->x * s, a->y * s, a->z *s);
}
static inline void demo_vec3_normalise(struct demo_vec3 *v, const struct demo_vec3 *a)
{
demo_vec3_scale(v, a, 1.0f / demo_vec3_length(a));
}
static inline void demo_vec3_cross(struct demo_vec3 *v, const struct demo_vec3 *a, const struct demo_vec3 *b)
{
demo_vec3_set(v, a->y * b->z - a->z * b->y, a->z * b->x - a->x * b->z, a->x * b->y - a->y * b->x);
}
static inline void demo_vec4_set(struct demo_vec4 *v, float x, float y, float z, float w)
{
v->x = x;
@@ -187,60 +83,6 @@ static inline void demo_vec4_set(struct demo_vec4 *v, float x, float y, float z,
v->w = w;
}
static inline void demo_matrix_look_at_rh(struct demo_matrix *m, const struct demo_vec3 *eye,
const struct demo_vec3 *ref, const struct demo_vec3 *up)
{
struct demo_vec3 f, s, t, u;
demo_vec3_subtract(&f, eye, ref);
demo_vec3_normalise(&f, &f);
demo_vec3_cross(&s, up, &f);
demo_vec3_normalise(&s, &s);
demo_vec3_cross(&u, &f, &s);
demo_vec3_set(&t, demo_vec3_dot(&s, eye), demo_vec3_dot(&u, eye), demo_vec3_dot(&f, eye));
*m = (struct demo_matrix)
{{
{ s.x, u.x, f.x, 0.0f},
{ s.y, u.y, f.y, 0.0f},
{ s.z, u.z, f.z, 0.0f},
{-t.x, -t.y, -t.z, 1.0f},
}};
}
static inline void demo_matrix_multiply(struct demo_matrix *out,
const struct demo_matrix *a, const struct demo_matrix *b)
{
unsigned int i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
out->m[i][j] = a->m[i][0] * b->m[0][j]
+ a->m[i][1] * b->m[1][j]
+ a->m[i][2] * b->m[2][j]
+ a->m[i][3] * b->m[3][j];
}
}
}
static inline void demo_matrix_perspective_rh(struct demo_matrix *m, float w, float h, float z_near, float z_far)
{
float sx = 2.0 * z_near / w;
float sy = 2.0 * z_near / h;
float sz = z_far / (z_near - z_far);
float d = z_near * sz;
*m = (struct demo_matrix)
{{
{ sx, 0.0f, 0.0f, 0.0f},
{0.0f, sy, 0.0f, 0.0f},
{0.0f, 0.0f, sz, -1.0f},
{0.0f, 0.0f, d, 0.0f},
}};
}
static inline void demo_rasterizer_desc_init_default(D3D12_RASTERIZER_DESC *desc)
{
desc->FillMode = D3D12_FILL_MODE_SOLID;
@@ -296,11 +138,9 @@ static inline HRESULT demo_create_root_signature(ID3D12Device *device,
return hr;
}
#ifdef VKD3D_CROSSTEST
#include "demo_d3d12.h"
#ifdef _WIN32
#include "demo_win32.h"
#else
# ifndef _WIN32
# define INFINITE VKD3D_INFINITE
# endif
#include "demo_vkd3d.h"
#define INFINITE VKD3D_INFINITE
#include "demo_xcb.h"
#endif

View File

@@ -1,261 +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;
unsigned int buffer_count;
char device_name[128];
};
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 const char *demo_get_platform_name(void)
{
return "Direct3D 12";
}
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;
DXGI_ADAPTER_DESC adapter_desc;
IDXGISwapChain1 *swapchain1;
IDXGIFactory2 *factory;
IDXGIAdapter *adapter;
ID3D12Device *device;
unsigned int i;
HRESULT hr;
LUID luid;
if (!(swapchain = malloc(sizeof(*swapchain))))
return NULL;
if (FAILED(CreateDXGIFactory1(&IID_IDXGIFactory2, (void **)&factory)))
goto fail;
if (FAILED(ID3D12CommandQueue_GetDevice(command_queue, &IID_ID3D12Device, (void **)&device)))
goto fail;
luid = ID3D12Device_GetAdapterLuid(device);
ID3D12Device_Release(device);
sprintf(swapchain->device_name, "Unknown");
for (i = 0; IDXGIFactory2_EnumAdapters(factory, i, &adapter) == S_OK; ++i)
{
hr = IDXGIAdapter_GetDesc(adapter, &adapter_desc);
IDXGIAdapter_Release(adapter);
if (FAILED(hr))
continue;
if (adapter_desc.AdapterLuid.LowPart == luid.LowPart
&& adapter_desc.AdapterLuid.HighPart == luid.HighPart)
{
snprintf(swapchain->device_name, ARRAY_SIZE(swapchain->device_name), "%ls", adapter_desc.Description);
break;
}
}
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;
swapchain->buffer_count = desc->buffer_count;
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 const char *demo_swapchain_get_device_name(struct demo_swapchain *swapchain)
{
return swapchain->device_name;
}
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 unsigned int demo_swapchain_get_back_buffer_count(struct demo_swapchain *swapchain)
{
return swapchain->buffer_count;
}
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,324 +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_ANSI_F = 0x03,
kVK_ANSI_W = 0x0d,
kVK_ANSI_Equal = 0x18,
kVK_ANSI_Minus = 0x1b,
kVK_Escape = 0x35,
kVK_ANSI_KeypadPlus = 0x45,
kVK_ANSI_KeypadMinus = 0x4e,
kVK_F1 = 0x7a,
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_ANSI_F, 'f'},
{kVK_ANSI_W, 'w'},
{kVK_ANSI_Equal, '='},
{kVK_ANSI_Minus, '-'},
{kVK_Escape, DEMO_KEY_ESCAPE},
{kVK_ANSI_KeypadPlus, DEMO_KEY_KP_ADD},
{kVK_ANSI_KeypadMinus, DEMO_KEY_KP_SUBTRACT},
{kVK_F1, DEMO_KEY_F1},
{kVK_LeftArrow, DEMO_KEY_LEFT},
{kVK_RightArrow, DEMO_KEY_RIGHT},
{kVK_DownArrow, DEMO_KEY_DOWN},
{kVK_UpArrow, DEMO_KEY_UP},
};
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
*/
#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;
HWND window;
void *user_data;
void (*idle_func)(struct demo *demo, void *user_data);
};
#ifndef VKD3D_CROSSTEST
static VkSurfaceKHR demo_window_win32_create_vk_surface(struct demo_window *window, VkInstance vk_instance)
struct demo_window
{
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w);
struct VkWin32SurfaceCreateInfoKHR surface_desc;
VkSurfaceKHR vk_surface;
HINSTANCE instance;
HWND hwnd;
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;
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_swapchain
{
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w);
IDXGISwapChain3 *swapchain;
};
DestroyWindow(window_win32->window);
}
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,
static inline struct demo_window *demo_window_create(struct demo *demo, const char *title,
unsigned int width, unsigned int height, void *user_data)
{
struct demo_window_win32 *window_win32;
RECT rect = {0, 0, width, height};
struct demo_window *window;
int title_size;
WCHAR *title_w;
DWORD style;
if (!(window_win32 = malloc(sizeof(*window_win32))))
if (!(window = malloc(sizeof(*window))))
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);
if (!(title_w = calloc(title_size, sizeof(*title_w))))
{
demo_window_cleanup(&window_win32->w);
free(window_win32);
free(window);
return NULL;
}
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;
AdjustWindowRect(&rect, style, FALSE);
window_win32->window = CreateWindowExW(0, DEMO_WIN32_WINDOW_CLASS_NAME, title_w, style, CW_USEDEFAULT,
CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, window_win32->instance, NULL);
window->hwnd = CreateWindowExW(0, DEMO_WINDOW_CLASS_NAME, title_w, style, CW_USEDEFAULT, CW_USEDEFAULT,
rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, window->instance, NULL);
free(title_w);
if (!window_win32->window)
if (!window->hwnd)
{
demo_window_cleanup(&window_win32->w);
free(window_win32);
free(window);
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;
*dpi_x = *dpi_y = win32->GetDpiForSystem();
DestroyWindow(window->hwnd);
}
static demo_key demo_key_from_win32_vkey(DWORD vkey)
static inline demo_key demo_key_from_vkey(DWORD vkey)
{
static const struct
{
@@ -127,23 +104,18 @@ static demo_key demo_key_from_win32_vkey(DWORD vkey)
}
lookup[] =
{
{VK_OEM_MINUS, '-'},
{VK_OEM_PLUS, '='},
{VK_ESCAPE, DEMO_KEY_ESCAPE},
{VK_LEFT, DEMO_KEY_LEFT},
{VK_UP, DEMO_KEY_UP},
{VK_RIGHT, DEMO_KEY_RIGHT},
{VK_DOWN, DEMO_KEY_DOWN},
{VK_ADD, DEMO_KEY_KP_ADD},
{VK_SUBTRACT, DEMO_KEY_KP_SUBTRACT},
{VK_F1, DEMO_KEY_F1},
{VK_ESCAPE, DEMO_KEY_ESCAPE},
{VK_LEFT, DEMO_KEY_LEFT},
{VK_RIGHT, DEMO_KEY_RIGHT},
{VK_UP, DEMO_KEY_UP},
{VK_DOWN, DEMO_KEY_DOWN},
};
unsigned int i;
if (vkey >= '0' && vkey <= '9')
return vkey;
if (vkey >= 'A' && vkey <= 'Z')
return vkey + 0x20;
return vkey;
for (i = 0; i < ARRAY_SIZE(lookup); ++i)
{
@@ -154,33 +126,46 @@ static demo_key demo_key_from_win32_vkey(DWORD vkey)
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)
{
case WM_PAINT:
if (window_win32 && window_win32->w.expose_func)
window_win32->w.expose_func(&window_win32->w, window_win32->w.user_data);
if (window && window->expose_func)
window->expose_func(window, window->user_data);
return 0;
case WM_KEYDOWN:
if (!window_win32->w.key_press_func)
if (!window->key_press_func)
break;
window_win32->w.key_press_func(&window_win32->w,
demo_key_from_win32_vkey(wparam), window_win32->w.user_data);
window->key_press_func(window, demo_key_from_vkey(wparam), window->user_data);
return 0;
case WM_DESTROY:
demo_window_win32_destroyed(&window_win32->w);
if (!--window->demo->window_count)
window->demo->quit = true;
free(window);
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};
@@ -201,28 +186,18 @@ static void demo_win32_process_events(struct demo *demo)
break;
TranslateMessage(&msg);
DispatchMessageW(&msg);
if (!demo->window_count)
if (demo->quit)
PostQuitMessage(0);
}
}
static void demo_win32_cleanup(struct demo *demo)
{
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)
static inline bool demo_init(struct demo *demo, void *user_data)
{
WNDCLASSEXW wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = demo_win32_window_proc;
wc.lpfnWndProc = demo_window_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
@@ -230,15 +205,110 @@ static bool demo_win32_init(struct demo_win32 *win32)
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = DEMO_WIN32_WINDOW_CLASS_NAME;
wc.lpszClassName = DEMO_WINDOW_CLASS_NAME;
wc.hIconSm = LoadIconW(NULL, IDI_WINLOGO);
if (!RegisterClassExW(&wc))
return false;
if ((win32->GetDpiForSystem = (void *)GetProcAddress(GetModuleHandleA("user32"), "GetDpiForSystem")))
SetProcessDPIAware();
else
win32->GetDpiForSystem = demo_win32_GetDpiForSystem;
demo->window_count = 0;
demo->quit = false;
demo->user_data = user_data;
demo->idle_func = NULL;
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

@@ -1,145 +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
*/
/* The glyph data is derived from etl16-unicode.bdf as found on
* ftp://ftp.ring.gr.jp/pub/X/opengroup/contrib/fonts/etl-unicode.tar.gz
* with the following license:
*
* Public domain font. Share and enjoy.
*/
/* Each line in etl16_unicode[] below contains the bitmap data for a single
* 8x16 glyph, starting at ASCII 0x20 (space). Each byte corresponds to a
* single line in the glyph.
*
* The BDF bitmap data is essentially the same format we're using here, so we
* could have extracted the glyphs manually, or perhaps using a small script.
* However, bdf2psf can do most of the work for us, by creating a PSF1 font
* from the BDF.
*
* A PSF1 font has a 4 byte header, followed by at least 256 glyphs.
* For a 8x16 font, each glyph consists of 16 bytes, one byte for each row.
*
* We're not interested in control characters or extended ASCII, so we skip
* the first 0x4 (header) + 0x20 (control characters) * 0x10 = 516 bytes, and
* extract the next (0x80 - 0x20) * 0x10 = 1536 bytes:
*
* bdf2psf etl16-unicode.bdf standard.equivalents ascii.set 256 /dev/stdout | xxd -i -c 16 -s 516 -l 1536
*
* and we're done.
*/
static const uint8_t etl16_unicode[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x66, 0x22, 0x22, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x7e, 0x24, 0x24, 0x7e, 0x48, 0x48, 0x48, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x3e, 0x49, 0x48, 0x38, 0x0e, 0x09, 0x49, 0x3e, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x31, 0x4a, 0x4a, 0x34, 0x08, 0x08, 0x16, 0x29, 0x29, 0x46, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x39, 0x45, 0x42, 0x46, 0x39, 0x00, 0x00,
0x00, 0x00, 0x18, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00,
0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x2a, 0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x0c, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x1c, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x14, 0x24, 0x44, 0x44, 0x7e, 0x04, 0x04, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x4a, 0x56, 0x52, 0x52, 0x52, 0x4e, 0x20, 0x1e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x66, 0x66, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x66, 0x3c, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x44, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x66, 0x66, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00,
0x00, 0x00, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00,
0x00, 0x00, 0x18, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3a, 0x44, 0x44, 0x44, 0x38, 0x20, 0x3c, 0x42, 0x42, 0x3c,
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x48, 0x30,
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x42, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, 0x0c, 0x00,
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0x30, 0x08, 0x08, 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, 0x08, 0x08, 0x30, 0x00,
0x00, 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfc, 0x1b, 0x26, 0xef, 0xc8, 0xe0, 0x43, 0x20, 0x89, 0x58, 0x62, 0x5e, 0x79, 0xba, 0xee, 0x7e,
};

View File

@@ -45,9 +45,10 @@
#include <sys/time.h>
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include "demo.h"
DEMO_EMBED(gears_hlsl, "gears.hlsl");
#include "gears_hlsl.h"
struct cxg_fence
{
@@ -58,7 +59,7 @@ struct cxg_fence
struct cxg_cb_data
{
struct demo_matrix mvp_matrix;
float mvp_matrix[16];
float normal_matrix[12];
};
@@ -119,17 +120,14 @@ struct cx_gears
ID3D12Device *device;
ID3D12CommandQueue *command_queue;
struct demo_swapchain *swapchain;
struct
{
ID3D12Resource *render_target;
ID3D12CommandAllocator *command_allocator;
ID3D12GraphicsCommandList *command_list;
} *swapchain_images;
ID3D12DescriptorHeap *rtv_heap, *dsv_heap;
unsigned int rtv_descriptor_size;
ID3D12Resource *render_targets[3];
ID3D12CommandAllocator *command_allocator[3];
ID3D12RootSignature *root_signature;
ID3D12PipelineState *pipeline_state_smooth, *pipeline_state_flat;
ID3D12GraphicsCommandList *command_list[3];
ID3D12Resource *ds, *cb, *vb[2], *ib;
D3D12_VERTEX_BUFFER_VIEW vbv[2];
D3D12_INDEX_BUFFER_VIEW ibv;
@@ -144,7 +142,7 @@ struct cx_gears
static void cxg_populate_command_list(struct cx_gears *cxg, unsigned int rt_idx)
{
ID3D12GraphicsCommandList *command_list = cxg->swapchain_images[rt_idx].command_list;
ID3D12GraphicsCommandList *command_list = cxg->command_list[rt_idx];
static const float clear_colour[] = {0.0f, 0.0f, 0.0f, 1.0f};
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, dsv_handle;
@@ -152,11 +150,10 @@ static void cxg_populate_command_list(struct cx_gears *cxg, unsigned int rt_idx)
HRESULT hr;
size_t i;
hr = ID3D12CommandAllocator_Reset(cxg->swapchain_images[rt_idx].command_allocator);
hr = ID3D12CommandAllocator_Reset(cxg->command_allocator[rt_idx]);
assert(SUCCEEDED(hr));
hr = ID3D12GraphicsCommandList_Reset(command_list,
cxg->swapchain_images[rt_idx].command_allocator, cxg->pipeline_state_flat);
hr = ID3D12GraphicsCommandList_Reset(command_list, cxg->command_allocator[rt_idx], cxg->pipeline_state_flat);
assert(SUCCEEDED(hr));
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, cxg->root_signature);
@@ -168,7 +165,7 @@ static void cxg_populate_command_list(struct cx_gears *cxg, unsigned int rt_idx)
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.pResource = cxg->swapchain_images[rt_idx].render_target;
barrier.Transition.pResource = cxg->render_targets[rt_idx];
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
@@ -229,24 +226,44 @@ static void cxg_wait_for_previous_frame(struct cx_gears *cxg)
static void cxg_update_mvp(struct cx_gears *cxg)
{
struct demo_matrix projection, world;
float s1 = sinf(cxg->theta);
float c1 = cosf(cxg->theta);
float s2 = sinf(cxg->phi);
float c2 = cosf(cxg->phi);
float z_offset = -40.0f;
float z_max = 60.0f;
float z_min = 5.0f;
float sx = z_min;
float sy = z_min * cxg->aspect_ratio;
float sz = -((z_max + z_min) / (z_max - z_min));
float d = (-2.0f * z_max * z_min) / (z_max - z_min);
unsigned int i, j;
float world[] =
{
c1, s2 * s1, c2 * -s1, 0.0f,
0.0f, c2, s2, 0.0f,
s1, -s2 * c1, c2 * c1, 0.0f,
0.0f, 0.0f, z_offset, 1.0f,
};
float projection[] =
{
sx, 0.0f, 0.0f, 0.0f,
0.0f, sy, 0.0f, 0.0f,
0.0f, 0.0f, sz, -1.0f,
0.0f, 0.0f, d, 0.0f,
};
world = (struct demo_matrix)
{{
{ c1, s2 * s1, c2 * -s1, 0.0f},
{0.0f, c2, s2, 0.0f},
{ s1, -s2 * c1, c2 * c1, 0.0f},
{0.0f, 0.0f, z_offset, 1.0f},
}};
demo_matrix_perspective_rh(&projection, 2.0f, 2.0f / cxg->aspect_ratio, 5.0f, 60.0f);
demo_matrix_multiply(&cxg->cb_data->mvp_matrix, &world, &projection);
memcpy(cxg->cb_data->normal_matrix, &world, sizeof(cxg->cb_data->normal_matrix));
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
cxg->cb_data->mvp_matrix[i * 4 + j] = projection[j] * world[i * 4]
+ projection[j + 4] * world[i * 4 + 1]
+ projection[j + 8] * world[i * 4 + 2]
+ projection[j + 12] * world[i * 4 + 3];
}
}
memcpy(cxg->cb_data->normal_matrix, world, sizeof(cxg->cb_data->normal_matrix));
}
static void cxg_render_frame(struct cx_gears *cxg)
@@ -278,7 +295,7 @@ static void cxg_render_frame(struct cx_gears *cxg)
demo_vec4_set(&cxg->instance_data[2].transform, cosf(a), sinf(a), -3.1f, 4.2f);
ID3D12CommandQueue_ExecuteCommandLists(cxg->command_queue, 1,
(ID3D12CommandList **)&cxg->swapchain_images[cxg->rt_idx].command_list);
(ID3D12CommandList **)&cxg->command_list[cxg->rt_idx]);
demo_swapchain_present(cxg->swapchain);
cxg_wait_for_previous_frame(cxg);
}
@@ -287,14 +304,16 @@ static void cxg_destroy_pipeline(struct cx_gears *cxg)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(cxg->command_allocator); ++i)
{
ID3D12CommandAllocator_Release(cxg->command_allocator[i]);
}
for (i = 0; i < ARRAY_SIZE(cxg->render_targets); ++i)
{
ID3D12Resource_Release(cxg->render_targets[i]);
}
ID3D12DescriptorHeap_Release(cxg->dsv_heap);
ID3D12DescriptorHeap_Release(cxg->rtv_heap);
for (i = 0; i < demo_swapchain_get_back_buffer_count(cxg->swapchain); ++i)
{
ID3D12CommandAllocator_Release(cxg->swapchain_images[i].command_allocator);
ID3D12Resource_Release(cxg->swapchain_images[i].render_target);
}
free(cxg->swapchain_images);
demo_swapchain_destroy(cxg->swapchain);
ID3D12CommandQueue_Release(cxg->command_queue);
ID3D12Device_Release(cxg->device);
@@ -306,7 +325,7 @@ static void cxg_load_pipeline(struct cx_gears *cxg)
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
D3D12_COMMAND_QUEUE_DESC queue_desc;
unsigned int i, rt_count;
unsigned int i;
HRESULT hr;
hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&cxg->device);
@@ -319,19 +338,16 @@ static void cxg_load_pipeline(struct cx_gears *cxg)
&IID_ID3D12CommandQueue, (void **)&cxg->command_queue);
assert(SUCCEEDED(hr));
swapchain_desc.buffer_count = 3;
swapchain_desc.buffer_count = ARRAY_SIZE(cxg->render_targets);
swapchain_desc.format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapchain_desc.width = cxg->width;
swapchain_desc.height = cxg->height;
cxg->swapchain = demo_swapchain_create(cxg->command_queue, cxg->window, &swapchain_desc);
assert(cxg->swapchain);
rt_count = demo_swapchain_get_back_buffer_count(cxg->swapchain);
cxg->swapchain_images = calloc(rt_count, sizeof(*cxg->swapchain_images));
assert(cxg->swapchain_images);
cxg->rt_idx = demo_swapchain_get_current_back_buffer_index(cxg->swapchain);
memset(&heap_desc, 0, sizeof(heap_desc));
heap_desc.NumDescriptors = rt_count;
heap_desc.NumDescriptors = ARRAY_SIZE(cxg->render_targets);
heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
hr = ID3D12Device_CreateDescriptorHeap(cxg->device, &heap_desc,
@@ -341,10 +357,10 @@ static void cxg_load_pipeline(struct cx_gears *cxg)
cxg->rtv_descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(cxg->device,
D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
rtv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cxg->rtv_heap);
for (i = 0; i < rt_count; ++i)
for (i = 0; i < ARRAY_SIZE(cxg->render_targets); ++i)
{
cxg->swapchain_images[i].render_target = demo_swapchain_get_back_buffer(cxg->swapchain, i);
ID3D12Device_CreateRenderTargetView(cxg->device, cxg->swapchain_images[i].render_target, NULL, rtv_handle);
cxg->render_targets[i] = demo_swapchain_get_back_buffer(cxg->swapchain, i);
ID3D12Device_CreateRenderTargetView(cxg->device, cxg->render_targets[i], NULL, rtv_handle);
rtv_handle.ptr += cxg->rtv_descriptor_size;
}
@@ -355,10 +371,10 @@ static void cxg_load_pipeline(struct cx_gears *cxg)
&IID_ID3D12DescriptorHeap, (void **)&cxg->dsv_heap);
assert(SUCCEEDED(hr));
for (i = 0; i < rt_count; ++i)
for (i = 0; i < ARRAY_SIZE(cxg->command_allocator); ++i)
{
hr = ID3D12Device_CreateCommandAllocator(cxg->device, D3D12_COMMAND_LIST_TYPE_DIRECT,
&IID_ID3D12CommandAllocator, (void **)&cxg->swapchain_images[i].command_allocator);
&IID_ID3D12CommandAllocator, (void **)&cxg->command_allocator[i]);
assert(SUCCEEDED(hr));
}
}
@@ -381,8 +397,8 @@ static void cxg_destroy_assets(struct cx_gears *cxg)
ID3D12Resource_Unmap(cxg->cb, 0, NULL);
ID3D12Resource_Release(cxg->cb);
ID3D12Resource_Release(cxg->ds);
for (i = 0; i < demo_swapchain_get_back_buffer_count(cxg->swapchain); ++i)
ID3D12GraphicsCommandList_Release(cxg->swapchain_images[i].command_list);
for (i = 0; i < ARRAY_SIZE(cxg->command_list); ++i)
ID3D12GraphicsCommandList_Release(cxg->command_list[i]);
ID3D12PipelineState_Release(cxg->pipeline_state_smooth);
ID3D12PipelineState_Release(cxg->pipeline_state_flat);
ID3D12RootSignature_Release(cxg->root_signature);
@@ -665,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);
assert(SUCCEEDED(hr));
hr = D3DCompile(gears_hlsl, gears_hlsl_size, "gears.hlsl",
NULL, NULL, "vs_main", "vs_5_0", 0, 0, &vs, NULL);
hr = D3DCompile(gears_hlsl, strlen(gears_hlsl), NULL, NULL, NULL, "vs_main", "vs_5_0", 0, 0, &vs, NULL);
assert(SUCCEEDED(hr));
hr = D3DCompile(gears_hlsl, gears_hlsl_size, "gears.hlsl",
NULL, NULL, "ps_main_flat", "ps_5_0", 0, 0, &ps_flat, NULL);
hr = D3DCompile(gears_hlsl, strlen(gears_hlsl), NULL, NULL, NULL, "ps_main_flat", "ps_5_0", 0, 0, &ps_flat, NULL);
assert(SUCCEEDED(hr));
hr = D3DCompile(gears_hlsl, gears_hlsl_size, "gears.hlsl",
NULL, NULL, "ps_main_smooth", "ps_5_0", 0, 0, &ps_smooth, NULL);
hr = D3DCompile(gears_hlsl, strlen(gears_hlsl), NULL, NULL, NULL, "ps_main_smooth", "ps_5_0", 0, 0, &ps_smooth, NULL);
assert(SUCCEEDED(hr));
memset(&pso_desc, 0, sizeof(pso_desc));
@@ -711,13 +724,13 @@ static void cxg_load_assets(struct cx_gears *cxg)
ID3D10Blob_Release(ps_flat);
ID3D10Blob_Release(ps_smooth);
for (i = 0; i < demo_swapchain_get_back_buffer_count(cxg->swapchain); ++i)
for (i = 0; i < ARRAY_SIZE(cxg->command_list); ++i)
{
hr = ID3D12Device_CreateCommandList(cxg->device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
cxg->swapchain_images[i].command_allocator, cxg->pipeline_state_flat,
&IID_ID3D12GraphicsCommandList, (void **)&cxg->swapchain_images[i].command_list);
cxg->command_allocator[i], cxg->pipeline_state_flat,
&IID_ID3D12GraphicsCommandList, (void **)&cxg->command_list[i]);
assert(SUCCEEDED(hr));
hr = ID3D12GraphicsCommandList_Close(cxg->swapchain_images[i].command_list);
hr = ID3D12GraphicsCommandList_Close(cxg->command_list[i]);
assert(SUCCEEDED(hr));
}
@@ -792,6 +805,7 @@ static void cxg_key_press(struct demo_window *window, demo_key key, void *user_d
switch (key)
{
case 'a':
case 'A':
cxg->animate = !cxg->animate;
break;
case DEMO_KEY_ESCAPE:
@@ -832,17 +846,12 @@ static int cxg_main(void)
{
unsigned int width = 300, height = 300;
struct cx_gears cxg;
double dpi_x, dpi_y;
size_t i;
memset(&cxg, 0, sizeof(cxg));
if (!demo_init(&cxg.demo, &cxg))
return EXIT_FAILURE;
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);
demo_window_set_key_press_func(cxg.window, cxg_key_press);
demo_window_set_expose_func(cxg.window, cxg_expose);
@@ -864,13 +873,10 @@ static int cxg_main(void)
cxg_load_pipeline(&cxg);
cxg_load_assets(&cxg);
for (i = 0; i < demo_swapchain_get_back_buffer_count(cxg.swapchain); ++i)
{
cxg_populate_command_list(&cxg, i);
}
cxg_populate_command_list(&cxg, 0);
cxg_populate_command_list(&cxg, 1);
cxg_populate_command_list(&cxg, 2);
printf("vkd3d-gears: Running on \"%s\" using %s.\n",
demo_swapchain_get_device_name(cxg.swapchain), demo_get_platform_name());
demo_process_events(&cxg.demo);
cxg_wait_for_previous_frame(&cxg);
@@ -882,9 +888,6 @@ static int cxg_main(void)
}
#ifdef _WIN32
/* Do not trigger -Wmissing-prototypes. */
int wmain(void);
int wmain(void)
#else
int main(void)

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