Start work on a Vulkan-based renderer

Doesn't do much other than create an instance and enumerate some stuff,
but the build system is working.
This commit is contained in:
Bill Currie 2019-07-06 14:42:53 +09:00
parent c3fa78ef4d
commit 2bc78e7f0a
18 changed files with 1319 additions and 6 deletions

View file

@ -32,6 +32,7 @@
libs/video/renderer/glsl/Makefile
libs/video/renderer/sw/Makefile
libs/video/renderer/sw32/Makefile
libs/video/renderer/vulkan/Makefile
libs/video/targets/Makefile
hw/Makefile

View file

@ -71,7 +71,7 @@ if test "x$HAVE_X" = xyes; then
NQ_DESKTOP_DATA="$NQ_DESKTOP_DATA quakeforge-nq-x11.desktop"
CL_TARGETS="$CL_TARGETS X11"
VID_TARGETS="$VID_TARGETS libQFx11.la"
QF_NEED(vid_render, [sw sw32 gl glsl])
QF_NEED(vid_render, [sw sw32 gl glsl vulkan])
QF_NEED(models, [sw gl glsl])
QF_NEED(alias, [sw gl glsl])
QF_NEED(brush, [sw gl glsl])
@ -95,7 +95,7 @@ if test "x$HAVE_SDL" = xyes; then
NQ_DESKTOP_DATA="$NQ_DESKTOP_DATA quakeforge-nq-sdl.desktop"
CL_TARGETS="$CL_TARGETS SDL"
VID_TARGETS="$VID_TARGETS libQFsdl.la"
QF_NEED(vid_render, [sw sw32 gl glsl])
QF_NEED(vid_render, [sw sw32 gl glsl vulkan])
QF_NEED(models, [sw gl glsl])
QF_NEED(alias, [sw gl glsl])
QF_NEED(brush, [sw gl glsl])
@ -258,7 +258,7 @@ QF_SUBST(progs_gz)
QF_PROCESS_NEED_DIRS(top, [libs hw nq qtv qw tools ruamoko])
QF_PROCESS_NEED_LIBS(swrend, [asm])
QF_PROCESS_NEED_DIRS(vid_render, [gl glsl sw sw32])
QF_PROCESS_NEED_DIRS(vid_render, [gl glsl sw sw32 vulkan])
QF_PROCESS_NEED_LIBS(models, [gl glsl sw])
QF_PROCESS_NEED_LIBS(alias, [gl glsl sw])
QF_PROCESS_NEED_LIBS(brush, [gl glsl sw])
@ -308,7 +308,7 @@ if test "x$static_plugins" = xauto; then
fi
fi
if test "x$static_plugins" = xyes; then
QF_PROCESS_NEED_STATIC_PLUGINS(vid_render, [sw sw32 glsl gl])
QF_PROCESS_NEED_STATIC_PLUGINS(vid_render, [sw sw32 glsl gl vulkan])
QF_PROCESS_NEED_STATIC_PLUGINS(console, [server], [\$(top_builddir)/libs/console], [server])
QF_PROCESS_NEED_STATIC_PLUGINS(console, [client], [\$(top_builddir)/libs/console], [client])
@ -323,7 +323,7 @@ if test "x$static_plugins" = xyes; then
CDTYPE="$CDTYPE (static)"
fi
else
QF_PROCESS_NEED_PLUGINS(vid_render, [sw sw32 glsl gl])
QF_PROCESS_NEED_PLUGINS(vid_render, [sw sw32 glsl gl vulkan])
QF_PROCESS_NEED_PLUGINS(console, [server], [server])
QF_PROCESS_NEED_PLUGINS(console, [client], [client])
QF_PROCESS_NEED_PLUGINS(snd_output, [sdl mme sgi sun win dx oss alsa])

24
config.d/vulkan.m4 Normal file
View file

@ -0,0 +1,24 @@
dnl Check for vulkan support
AC_ARG_ENABLE(vulkan,
[ --disable-vulkan do not use Vulkan],
HAVE_VULKAN=$enable_vulkan, HAVE_VULKAN=auto)
if test "x$HAVE_VULKAN" != xno; then
save_CPPFLAGS="$CPPFLAGS"
AS_IF([test x"$VULKAN_SDK" != x], [
CPPFLAGS="$CPPFLAGS -I$VULKAN_SDK/include"
LDFLAGS="$LDFLAGS -L$VULKAN_SDK/lib"
glslangvalidator="$VULKAN_SDK/bin/glslangValidator"
], [glslangvalidator="glslangValidator"])
AC_CHECK_HEADER(
[vulkan/vulkan.h],
dnl Make sure the library "works"
[AC_CHECK_LIB([vulkan], [vkCreateInstance],
[AC_DEFINE([HAVE_VULKAN], [1], [Define if yhou have the Vulkan libs])
VULKAN_LIBS=-lvulkan],
[AC_MSG_RESULT(no)])
],
[AC_MSG_RESULT(no)]
)
CPPFLAGS="$save_CPPFLAGS"
fi
AC_SUBST(VULKAN_LIBS)

View file

@ -64,6 +64,7 @@ m4_include(config.d/mgl.m4)
m4_include(config.d/fbdev.m4)
m4_include(config.d/svga.m4)
m4_include(config.d/x11.m4)
m4_include(config.d/vulkan.m4)
m4_include(config.d/sdl.m4)
m4_include(config.d/curses.m4)

View file

@ -0,0 +1,7 @@
#ifndef __QF_Vulkan_cvars_h
#define __QF_Vulkan_cvars_h
extern struct cvar_s *vulkan_library_name;
extern struct cvar_s *vulkan_use_validation;
#endif//__QF_Vulkan_cvars_h

View file

@ -0,0 +1,55 @@
#ifndef EXPORTED_VULKAN_FUNCTION
#define EXPORTED_VULKAN_FUNCTION(function)
#endif
EXPORTED_VULKAN_FUNCTION (vkGetInstanceProcAddr)
#undef EXPORTED_VULKAN_FUNCTION
#ifndef GLOBAL_LEVEL_VULKAN_FUNCTION
#define GLOBAL_LEVEL_VULKAN_FUNCTION(function)
#endif
GLOBAL_LEVEL_VULKAN_FUNCTION (vkEnumerateInstanceVersion)
GLOBAL_LEVEL_VULKAN_FUNCTION (vkEnumerateInstanceExtensionProperties)
GLOBAL_LEVEL_VULKAN_FUNCTION (vkEnumerateInstanceLayerProperties)
GLOBAL_LEVEL_VULKAN_FUNCTION (vkCreateInstance)
#undef GLOBAL_LEVEL_VULKAN_FUNCTION
#ifndef INSTANCE_LEVEL_VULKAN_FUNCTION
#define INSTANCE_LEVEL_VULKAN_FUNCTION(function)
#endif
INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumeratePhysicalDevices)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceFeatures)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkCreateDevice)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetDeviceProcAddr)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceLayerProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceExtensionProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceMemoryProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceQueueFamilyProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkDestroyInstance)
#undef INSTANCE_LEVEL_VULKAN_FUNCTION
#ifndef INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION
#define INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION(function)
#endif
INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION (vkCreateDebugUtilsMessengerEXT)
#undef INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION
#ifndef DEVICE_LEVEL_VULKAN_FUNCTION
#define DEVICE_LEVEL_VULKAN_FUNCTION(function)
#endif
#undef DEVICE_LEVEL_VULKAN_FUNCTION
#ifndef DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION
#define DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION(function)
#endif
#undef DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION

View file

@ -0,0 +1,9 @@
#ifndef __QF_Vulkan_funcs_h
#define __QF_Vulkan_funcs_h
#define EXPORTED_VULKAN_FUNCTION(fname) extern PFN_##fname fname;
#define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) extern PFN_##fname fname;
#include "QF/Vulkan/funclist.h"
#endif//__QF_Vulkan_funcs_h

65
include/QF/Vulkan/init.h Normal file
View file

@ -0,0 +1,65 @@
/*
Copyright (C) 2019 Bill Currie <bill@taniwha.org>
Author: Bill Currie
Date: 2019/6/29
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_Vulkan_init_h
#define __QF_Vulkan_init_h
#include <vulkan/vulkan.h>
#include "QF/qtypes.h"
#include "QF/Vulkan/funcs.h"
typedef struct {
VkPhysicalDevice device;
VkPhysicalDeviceProperties properties;
uint32_t numLayers;
VkLayerProperties *layers;
uint32_t numExtensions;
VkExtensionProperties *extensions;
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceMemoryProperties memory;
uint32_t numQueueFamilies;
VkQueueFamilyProperties *queueFamilies;
} VulkanPhysDevice_t;
typedef struct {
VkInstance instance;
VkDebugUtilsMessengerEXT debug_callback;
uint32_t numDevices;
VulkanPhysDevice_t *devices;
#define INSTANCE_LEVEL_VULKAN_FUNCTION(name) PFN_##name name;
#define INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION(name) PFN_##name name;
#include "QF/Vulkan/funclist.h"
} VulkanInstance_t;
void Vulkan_Init_Cvars (void);
VulkanInstance_t *Vulkan_CreateInstance (const char *appName,
uint32_t appVersion,
const char **layers,
const char **extensions);
void Vulkan_DestroyInstance (VulkanInstance_t *instance);
#endif // __QF_Vulkan_init_h

View file

@ -0,0 +1,37 @@
/*
qf_draw.h
vulkan specific draw function
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __gl_draw_h
#define __gl_draw_h
void Vulkan_Set2D (void);
void Vulkan_Set2DScaled (void);
void Vulkan_End2D (void);
void Vulkan_DrawReset (void);
void Vulkan_FlushText (void);
#endif//__gl_draw_h

View file

@ -0,0 +1,36 @@
/*
Vulkan/qf_vid.h
vulkan vid stuff from the renderer.
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_Vulkan_vid_h
#define __QF_Vulkan_vid_h
#include "QF/Vulkan/cvars.h"
void Vulkan_Init_Common (void);
void Vulkan_Shutdown_Common (void);
#endif // __QF_Vulkan_vid_h

View file

@ -16,7 +16,8 @@ noinst_LTLIBRARIES= libQFrenderer.la @vid_render_static_plugins@
EXTRA_LTLIBRARIES= \
vid_render_sw.la vid_render_sw32.la \
vid_render_gl.la vid_render_glsl.la
vid_render_gl.la vid_render_glsl.la \
vid_render_vulkan.la
common_sources= \
crosshair.c noisetextures.c r_alias.c r_bsp.c r_cvar.c r_dyn_textures.c \
@ -63,3 +64,10 @@ vid_render_sw32_la_LDFLAGS= $(plugin_ldflags)
vid_render_sw32_la_LIBADD= $(sw32_libs)
vid_render_sw32_la_DEPENDENCIES=$(sw32_libs)
vid_render_sw32_la_SOURCES= $(common_sources) vid_render_sw32.c
vulkan_libs= \
vulkan/libvulkan.la
vid_render_vulkan_la_LDFLAGS= $(plugin_ldflags)
vid_render_vulkan_la_LIBADD= $(vulkan_libs)
vid_render_vulkan_la_DEPENDENCIES=$(vulkan_libs)
vid_render_vulkan_la_SOURCES= $(common_sources) vid_render_vulkan.c

View file

@ -0,0 +1,193 @@
/*
vid_render_vulkan.c
Vulkan version of the renderer
Copyright (C) 2019 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define NH_DEFINE
#include "vulkan/namehack.h"
#include "QF/plugin/general.h"
#include "QF/plugin/vid_render.h"
#include "QF/Vulkan/qf_vid.h"
#include "mod_internal.h"
#include "r_internal.h"
#include "vulkan/namehack.h"
static vid_model_funcs_t model_funcs = {
/* vulkan_Mod_LoadExternalTextures,
vulkan_Mod_LoadLighting,
vulkan_Mod_SubdivideSurface,
vulkan_Mod_ProcessTexture,
Mod_LoadIQM,
Mod_LoadAliasModel,
Mod_LoadSpriteModel,
vulkan_Mod_MakeAliasModelDisplayLists,
vulkan_Mod_LoadSkin,
vulkan_Mod_FinalizeAliasModel,
vulkan_Mod_LoadExternalSkins,
vulkan_Mod_IQMFinish,
0,
vulkan_Mod_SpriteLoadTexture,
Skin_SetColormap,
Skin_SetSkin,
vulkan_Skin_SetupSkin,
Skin_SetTranslation,
vulkan_Skin_ProcessTranslation,
vulkan_Skin_InitTranslations,*/
};
vid_render_funcs_t vulkan_vid_render_funcs = {
vulkan_Draw_Init,
vulkan_Draw_Character,
vulkan_Draw_String,
vulkan_Draw_nString,
vulkan_Draw_AltString,
vulkan_Draw_ConsoleBackground,
vulkan_Draw_Crosshair,
vulkan_Draw_CrosshairAt,
vulkan_Draw_TileClear,
vulkan_Draw_Fill,
vulkan_Draw_TextBox,
vulkan_Draw_FadeScreen,
vulkan_Draw_BlendScreen,
vulkan_Draw_CachePic,
vulkan_Draw_UncachePic,
vulkan_Draw_MakePic,
vulkan_Draw_DestroyPic,
vulkan_Draw_PicFromWad,
vulkan_Draw_Pic,
vulkan_Draw_Picf,
vulkan_Draw_SubPic,
/* vulkan_SCR_UpdateScreen,
SCR_DrawRam,
SCR_DrawTurtle,
SCR_DrawPause,
vulkan_SCR_CaptureBGR,
vulkan_SCR_ScreenShot,
SCR_DrawStringToSnap,
vulkan_Fog_Update,
vulkan_Fog_ParseWorldspawn,
vulkan_R_Init,
vulkan_R_ClearState,
vulkan_R_LoadSkys,
vulkan_R_NewMap,
R_AddEfrags,
R_RemoveEfrags,
R_EnqueueEntity,
vulkan_R_LineGraph,
R_AllocDlight,
R_AllocEntity,
vulkan_R_RenderView,
R_DecayLights,
vulkan_R_ViewChanged,
vulkan_R_ClearParticles,
vulkan_R_InitParticles,
vulkan_SCR_ScreenShot_f,
vulkan_r_easter_eggs_f,
vulkan_r_particles_style_f,
0,
&model_funcs*/
};
static void
set_palette (const byte *palette)
{
//FIXME really don't want this here: need an application domain
//so Quake can be separated from QuakeForge (ie, Quake itself becomes
//an app using the QuakeForge engine)
}
static void
vulkan_vid_render_init (void)
{
vr_data.vid->set_palette = set_palette;
vr_data.vid->init_gl = Vulkan_Init_Common;
vr_data.vid->load_gl ();
vr_funcs = &vulkan_vid_render_funcs;
m_funcs = &model_funcs;
}
static void
vulkan_vid_render_shutdown (void)
{
Vulkan_Shutdown_Common ();
}
static general_funcs_t plugin_info_general_funcs = {
vulkan_vid_render_init,
vulkan_vid_render_shutdown,
};
static general_data_t plugin_info_general_data;
static plugin_funcs_t plugin_info_funcs = {
&plugin_info_general_funcs,
0,
0,
0,
0,
0,
&vulkan_vid_render_funcs,
};
static plugin_data_t plugin_info_data = {
&plugin_info_general_data,
0,
0,
0,
0,
0,
&vid_render_data,
};
static plugin_t plugin_info = {
qfp_snd_render,
0,
QFPLUGIN_VERSION,
"0.1",
"GLSL Renderer",
"Copyright (C) 1996-1997 Id Software, Inc.\n"
"Copyright (C) 1999-2012 contributors of the QuakeForge project\n"
"Please see the file \"AUTHORS\" for a list of contributors",
&plugin_info_funcs,
&plugin_info_data,
};
PLUGIN_INFO(vid_render, vulkan)
{
return &plugin_info;
}

View file

@ -0,0 +1,26 @@
AUTOMAKE_OPTIONS= foreign
AM_CFLAGS= @PREFER_PIC@
AM_CPPFLAGS= -I$(top_srcdir)/include -DVK_NO_PROTOTYPES
vulkan_src = \
init.c \
vulkan_draw.c \
vulkan_funcs.c \
vulkan_vid_common.c
noinst_LTLIBRARIES= libvulkan.la
BUILT_SOURCES= $(shader_gen)
SUFFICES=.frag .vert .fc .vc .slc .glsl
.glsl.slc:
sed -e 's/^/"/' -e 's/$$/\\n"/' $< > $@
.frag.fc:
sed -e 's/^/"/' -e 's/$$/\\n"/' $< > $@
.vert.vc:
sed -e 's/^/"/' -e 's/$$/\\n"/' $< > $@
libvulkan_la_SOURCES= $(vulkan_src)
EXTRA_DIST = $(vulkan_src) $(shader_src) namehack.h
CLEANFILES= *.vc *.fc *.slc

View file

@ -0,0 +1,390 @@
/*
int.c
Copyright (C) 2019 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/input.h"
#include "QF/qargs.h"
#include "QF/quakefs.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "QF/vid.h"
#include "QF/Vulkan/init.h"
cvar_t *vulkan_library_name;
cvar_t *vulkan_use_validation;
static uint32_t numLayers;
static VkLayerProperties *instanceLayerProperties;
static const char **instanceLayerNames;
static uint32_t numExtensions;
static VkExtensionProperties *instanceExtensionProperties;
static const char **instanceExtensionNames;
static const char *validationLayers[] = {
"VK_LAYER_LUNARG_standard_validation",
0,
};
static const char *debugExtensions[] = {
VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
0,
};
static const char *device_types[] = {
"other",
"integrated gpu",
"discrete gpu",
"virtual gpu",
"cpu",
};
static void
get_instance_layers_and_extensions (void)
{
uint32_t i;
VkLayerProperties *properties;
VkExtensionProperties *extensions;
vkEnumerateInstanceLayerProperties (&numLayers, 0);
properties = malloc (numLayers * sizeof (VkLayerProperties));
vkEnumerateInstanceLayerProperties (&numLayers, properties);
instanceLayerNames = (const char **) malloc ((numLayers + 1)
* sizeof (const char **));
for (i = 0; i < numLayers; i++) {
instanceLayerNames[i] = properties[i].layerName;
}
instanceLayerNames[i] = 0;
vkEnumerateInstanceExtensionProperties (0, &numExtensions, 0);
extensions = malloc (numExtensions * sizeof (VkLayerProperties));
vkEnumerateInstanceExtensionProperties (0, &numExtensions, extensions);
instanceExtensionNames = (const char **) malloc ((numExtensions + 1)
* sizeof (const char **));
for (i = 0; i < numExtensions; i++) {
instanceExtensionNames[i] = extensions[i].extensionName;
}
instanceExtensionNames[i] = 0;
if (developer->int_val & SYS_VID) {
for (i = 0; i < numLayers; i++) {
Sys_Printf ("%s %x %u %s\n",
properties[i].layerName,
properties[i].specVersion,
properties[i].implementationVersion,
properties[i].description);
}
for (i = 0; i < numExtensions; i++) {
Sys_Printf ("%d %s\n",
extensions[i].specVersion,
extensions[i].extensionName);
}
}
instanceLayerProperties = properties;
instanceExtensionProperties = extensions;
}
static void
init_physdev (VulkanInstance_t *instance, VkPhysicalDevice dev, VulkanPhysDevice_t *physdev)
{
physdev->device = dev;
instance->vkGetPhysicalDeviceProperties (dev, &physdev->properties);
instance->vkEnumerateDeviceLayerProperties (dev, &physdev->numLayers, 0);
physdev->layers = malloc (physdev->numLayers * sizeof (VkLayerProperties));
instance->vkEnumerateDeviceLayerProperties (dev, &physdev->numLayers,
physdev->layers);
instance->vkEnumerateDeviceExtensionProperties (dev, 0,
&physdev->numExtensions,
0);
physdev->extensions = malloc (physdev->numExtensions
* sizeof (VkExtensionProperties));
instance->vkEnumerateDeviceExtensionProperties (dev, 0,
&physdev->numExtensions,
physdev->extensions);
instance->vkGetPhysicalDeviceFeatures (dev, &physdev->features);
instance->vkGetPhysicalDeviceMemoryProperties (dev, &physdev->memory);
instance->vkGetPhysicalDeviceQueueFamilyProperties (dev,
&physdev->numQueueFamilies,
0);
physdev->queueFamilies = malloc (physdev->numQueueFamilies
* sizeof (VkQueueFamilyProperties));
instance->vkGetPhysicalDeviceQueueFamilyProperties (dev,
&physdev->numQueueFamilies,
physdev->queueFamilies);
if (developer->int_val & SYS_VID) {
VkPhysicalDeviceProperties *prop = &physdev->properties;
Sys_Printf ("dev: %p\n", dev);
Sys_Printf (" %x %x\n", prop->apiVersion, prop->driverVersion);
Sys_Printf (" %x %x\n", prop->vendorID, prop->deviceID);
Sys_Printf (" %s: %s\n", device_types[prop->deviceType],
prop->deviceName);
for (uint32_t i = 0; i < physdev->numLayers; i++) {
Sys_Printf (" %s %x %u %s\n",
physdev->layers[i].layerName,
physdev->layers[i].specVersion,
physdev->layers[i].implementationVersion,
physdev->layers[i].description);
}
for (uint32_t i = 0; i < physdev->numExtensions; i++) {
Sys_Printf (" %u %s\n",
physdev->extensions[i].specVersion,
physdev->extensions[i].extensionName);
}
Sys_Printf (" memory types:\n");
for (uint32_t i = 0; i < physdev->memory.memoryTypeCount; i++) {
Sys_Printf (" %x %d\n",
physdev->memory.memoryTypes[i].propertyFlags,
physdev->memory.memoryTypes[i].heapIndex);
}
Sys_Printf (" memory heaps:\n");
for (uint32_t i = 0; i < physdev->memory.memoryHeapCount; i++) {
Sys_Printf (" %x %ld\n",
physdev->memory.memoryHeaps[i].flags,
physdev->memory.memoryHeaps[i].size);
}
Sys_Printf (" queue families:\n");
for (uint32_t i = 0; i < physdev->numQueueFamilies; i++) {
VkQueueFamilyProperties *queue = &physdev->queueFamilies[i];
VkExtent3D gran = queue->minImageTransferGranularity;
Sys_Printf (" %x %3d %3d [%d %d %d]\n",
queue->queueFlags,
queue->queueCount,
queue->timestampValidBits,
gran.width, gran.height, gran.depth);
}
}
}
static int
count_strings (const char **str)
{
int count = 0;
if (str) {
while (*str++) {
count++;
}
}
return count;
}
static void
merge_strings (const char **out, const char **in1, const char **in2)
{
if (in1) {
while (*in1) {
*out++ = *in1++;
}
}
if (in2) {
while (*in2) {
*out++ = *in2++;
}
}
}
static void
prune_strings (const char * const *reference, const char **strings,
uint32_t *count)
{
for (int i = *count; i-- > 0; ) {
const char *str = strings[i];
const char * const *ref;
for (ref = reference; *ref; ref++) {
if (!strcmp (*ref, str)) {
break;
}
}
if (!*ref) {
memmove (strings + i, strings + i + 1,
(--(*count) - i) * sizeof (const char **));
}
}
}
static int message_severities =
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
static int message_types =
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
static VKAPI_ATTR VkBool32 VKAPI_CALL
debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* callbackData,
void *data)
{
fprintf (stderr, "validation layer: %s\n", callbackData->pMessage);
return VK_FALSE;
}
static void
setup_debug_callback (VulkanInstance_t *instance)
{
VkDebugUtilsMessengerCreateInfoEXT createInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
.messageSeverity = message_severities,
.messageType = message_types,
.pfnUserCallback = debug_callback,
.pUserData = instance,
};
instance->vkCreateDebugUtilsMessengerEXT(instance->instance, &createInfo,
0, &instance->debug_callback);
}
static void
load_instance_funcs (VulkanInstance_t *instance)
{
#define INSTANCE_LEVEL_VULKAN_FUNCTION(name) \
instance->name = (PFN_##name) vkGetInstanceProcAddr (instance->instance, \
#name); \
if (!instance->name) { \
Sys_Error ("Couldn't find instance level function %s", #name); \
}
#define INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION(name) \
instance->name = (PFN_##name) vkGetInstanceProcAddr (instance->instance,\
#name); \
if (!instance->name) { \
Sys_Printf ("Couldn't find instance level function %s", #name); \
}
#include "QF/Vulkan/funclist.h"
}
VulkanInstance_t *
Vulkan_CreateInstance (const char *appName, uint32_t appVersion,
const char **layers, const char **extensions)
{
VkApplicationInfo appInfo = {
VK_STRUCTURE_TYPE_APPLICATION_INFO, 0,
appName, appVersion,
PACKAGE_STRING, 0x000702ff, //FIXME version
VK_API_VERSION_1_0,
};
VkInstanceCreateInfo createInfo = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 0, 0,
&appInfo,
0, 0,
0, 0,
};
VkResult res;
VkInstance instance;
uint32_t numDev, i;
VkPhysicalDevice *devices;
VulkanInstance_t *inst;
if (!instanceLayerProperties) {
get_instance_layers_and_extensions ();
}
createInfo.enabledLayerCount = count_strings (layers);
createInfo.ppEnabledLayerNames = layers;
createInfo.enabledExtensionCount = count_strings (extensions);
createInfo.ppEnabledExtensionNames = extensions;
if (vulkan_use_validation->int_val) {
createInfo.enabledLayerCount += count_strings (validationLayers);
createInfo.enabledExtensionCount += count_strings (debugExtensions);
}
const char **lay = alloca (createInfo.enabledLayerCount * sizeof (const char *));
const char **ext = alloca (createInfo.enabledExtensionCount * sizeof (const char *));
if (vulkan_use_validation->int_val) {
merge_strings (lay, layers, validationLayers);
merge_strings (ext, extensions, debugExtensions);
} else {
merge_strings (lay, layers, 0);
merge_strings (ext, extensions, 0);
}
prune_strings (instanceLayerNames, lay,
&createInfo.enabledLayerCount);
prune_strings (instanceExtensionNames, ext,
&createInfo.enabledExtensionCount);
createInfo.ppEnabledLayerNames = lay;
createInfo.ppEnabledExtensionNames = ext;
res = vkCreateInstance (&createInfo, 0, &instance);
if (res != VK_SUCCESS) {
Sys_Error ("unable to create vulkan instance\n");
}
inst = malloc (sizeof(VulkanInstance_t));
inst->instance = instance;
load_instance_funcs (inst);
if (vulkan_use_validation->int_val) {
setup_debug_callback (inst);
}
res = inst->vkEnumeratePhysicalDevices (instance, &numDev, 0);
if (res != VK_SUCCESS) {
Sys_Error ("unable to query vulkan device count: %d\n", res);
}
devices = malloc(numDev * sizeof (VkPhysicalDevice));
res = inst->vkEnumeratePhysicalDevices (instance, &numDev, devices);
if (res != VK_SUCCESS) {
Sys_Error ("unable to query vulkan device properties: %d\n", res);
}
inst->numDevices = numDev;
inst->devices = malloc (numDev * sizeof (VulkanPhysDevice_t));
for (i = 0; i < numDev; i++) {
init_physdev (inst, devices[i], &inst->devices[i]);
}
return inst;
}
void
Vulkan_DestroyInstance (VulkanInstance_t *instance)
{
for (uint32_t i = 0; i < instance->numDevices; i++) {
free (instance->devices[i].queueFamilies);
free (instance->devices[i].extensions);
free (instance->devices[i].layers);
}
free (instance->devices);
instance->vkDestroyInstance (instance->instance, 0);
free (instance);
}

View file

@ -0,0 +1,137 @@
#ifdef NH_DEFINE
#undef NH_DEFINE
#define Draw_Init vulkan_Draw_Init
#define Draw_Character vulkan_Draw_Character
#define Draw_String vulkan_Draw_String
#define Draw_nString vulkan_Draw_nString
#define Draw_AltString vulkan_Draw_AltString
#define Draw_ConsoleBackground vulkan_Draw_ConsoleBackground
#define Draw_Crosshair vulkan_Draw_Crosshair
#define Draw_CrosshairAt vulkan_Draw_CrosshairAt
#define Draw_TileClear vulkan_Draw_TileClear
#define Draw_Fill vulkan_Draw_Fill
#define Draw_TextBox vulkan_Draw_TextBox
#define Draw_FadeScreen vulkan_Draw_FadeScreen
#define Draw_BlendScreen vulkan_Draw_BlendScreen
#define Draw_CachePic vulkan_Draw_CachePic
#define Draw_UncachePic vulkan_Draw_UncachePic
#define Draw_MakePic vulkan_Draw_MakePic
#define Draw_DestroyPic vulkan_Draw_DestroyPic
#define Draw_PicFromWad vulkan_Draw_PicFromWad
#define Draw_Pic vulkan_Draw_Pic
#define Draw_Picf vulkan_Draw_Picf
#define Draw_SubPic vulkan_Draw_SubPic
#define Fog_DisableGFog vulkan_Fog_DisableGFog
#define Fog_EnableGFog vulkan_Fog_EnableGFog
#define Fog_GetColor vulkan_Fog_GetColor
#define Fog_GetDensity vulkan_Fog_GetDensity
#define Fog_Init vulkan_Fog_Init
#define Fog_ParseWorldspawn vulkan_Fog_ParseWorldspawn
#define Fog_SetupFrame vulkan_Fog_SetupFrame
#define Fog_StartAdditive vulkan_Fog_StartAdditive
#define Fog_StopAdditive vulkan_Fog_StopAdditive
#define Fog_Update vulkan_Fog_Update
#define R_AddTexture vulkan_R_AddTexture
#define R_BlendLightmaps vulkan_R_BlendLightmaps
#define R_BuildLightMap vulkan_R_BuildLightMap
#define R_CalcLightmaps vulkan_R_CalcLightmaps
#define R_ClearParticles vulkan_R_ClearParticles
#define R_ClearState vulkan_R_ClearState
#define R_ClearTextures vulkan_R_ClearTextures
#define R_DrawAliasModel vulkan_R_DrawAliasModel
#define R_DrawBrushModel vulkan_R_DrawBrushModel
#define R_DrawParticles vulkan_R_DrawParticles
#define R_DrawSky vulkan_R_DrawSky
#define R_DrawSkyChain vulkan_R_DrawSkyChain
#define R_DrawSprite vulkan_R_DrawSprite
#define R_DrawSpriteModel vulkan_R_DrawSpriteModel
#define R_DrawWaterSurfaces vulkan_R_DrawWaterSurfaces
#define R_DrawWorld vulkan_R_DrawWorld
#define R_InitBubble vulkan_R_InitBubble
#define R_InitGraphTextures vulkan_R_InitGraphTextures
#define R_InitParticles vulkan_R_InitParticles
#define R_InitSky vulkan_R_InitSky
#define R_InitSprites vulkan_R_InitSprites
#define R_InitSurfaceChains vulkan_R_InitSurfaceChains
#define R_LineGraph vulkan_R_LineGraph
#define R_LoadSky_f vulkan_R_LoadSky_f
#define R_LoadSkys vulkan_R_LoadSkys
#define R_NewMap vulkan_R_NewMap
#define R_Particle_New vulkan_R_Particle_New
#define R_Particle_NewRandom vulkan_R_Particle_NewRandom
#define R_Particles_Init_Cvars vulkan_R_Particles_Init_Cvars
#define R_ReadPointFile_f vulkan_R_ReadPointFile_f
#define R_RenderDlights vulkan_R_RenderDlights
#define R_RenderView vulkan_R_RenderView
#define R_RotateForEntity vulkan_R_RotateForEntity
#define R_SetupFrame vulkan_R_SetupFrame
#define R_SpriteBegin vulkan_R_SpriteBegin
#define R_SpriteEnd vulkan_R_SpriteEnd
#define R_TimeRefresh_f vulkan_R_TimeRefresh_f
#define R_ViewChanged vulkan_R_ViewChanged
#define SCR_CaptureBGR vulkan_SCR_CaptureBGR
#define SCR_ScreenShot vulkan_SCR_ScreenShot
#define SCR_ScreenShot_f vulkan_SCR_ScreenShot_f
#define SCR_UpdateScreen vulkan_SCR_UpdateScreen
#define c_alias_polys vulkan_c_alias_polys
#define c_brush_polys vulkan_c_brush_polys
#define r_easter_eggs_f vulkan_r_easter_eggs_f
#define r_particles_style_f vulkan_r_particles_style_f
#define r_world_matrix vulkan_r_world_matrix
#else
#undef Fog_DisableGFog
#undef Fog_EnableGFog
#undef Fog_GetColor
#undef Fog_GetDensity
#undef Fog_Init
#undef Fog_ParseWorldspawn
#undef Fog_SetupFrame
#undef Fog_StartAdditive
#undef Fog_StopAdditive
#undef Fog_Update
#undef R_AddTexture
#undef R_BlendLightmaps
#undef R_BuildLightMap
#undef R_CalcLightmaps
#undef R_ClearParticles
#undef R_ClearState
#undef R_ClearTextures
#undef R_DrawAliasModel
#undef R_DrawBrushModel
#undef R_DrawParticles
#undef R_DrawSky
#undef R_DrawSkyChain
#undef R_DrawSpriteModel
#undef R_DrawWaterSurfaces
#undef R_DrawWorld
#undef R_Init
#undef R_InitBubble
#undef R_InitGraphTextures
#undef R_InitParticles
#undef R_InitSky
#undef R_InitSprites
#undef R_InitSurfaceChains
#undef R_LineGraph
#undef R_LoadSky_f
#undef R_LoadSkys
#undef R_NewMap
#undef R_Particle_New
#undef R_Particle_NewRandom
#undef R_Particles_Init_Cvars
#undef R_ReadPointFile_f
#undef R_RenderDlights
#undef R_RenderView
#undef R_RotateForEntity
#undef R_SetupFrame
#undef R_TimeRefresh_f
#undef R_ViewChanged
#undef SCR_CaptureBGR
#undef SCR_ScreenShot
#undef SCR_ScreenShot_f
#undef SCR_UpdateScreen
#undef c_alias_polys
#undef c_brush_polys
#undef r_easter_eggs_f
#undef r_particles_style_f
#undef r_world_matrix
#endif

View file

@ -0,0 +1,189 @@
/*
vulkan_draw.c
2D drawing support for Vulkan
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2011/12/23
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define NH_DEFINE
#include "namehack.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/cvar.h"
#include "QF/draw.h"
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/quakefs.h"
#include "QF/sys.h"
#include "QF/vid.h"
#include "QF/Vulkan/qf_draw.h"
#include "QF/Vulkan/qf_vid.h"
#include "r_internal.h"
qpic_t *
vulkan_Draw_MakePic (int width, int height, const byte *data)
{
return 0;
}
void
vulkan_Draw_DestroyPic (qpic_t *pic)
{
}
qpic_t *
vulkan_Draw_PicFromWad (const char *name)
{
return 0;
}
qpic_t *
vulkan_Draw_CachePic (const char *path, qboolean alpha)
{
return 0;
}
void
vulkan_Draw_UncachePic (const char *path)
{
}
void
vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha)
{
}
void
vulkan_Draw_Init (void)
{
}
void
vulkan_Draw_Character (int x, int y, unsigned int chr)
{
}
void
vulkan_Draw_String (int x, int y, const char *str)
{
}
void
vulkan_Draw_nString (int x, int y, const char *str, int count)
{
}
void
vulkan_Draw_AltString (int x, int y, const char *str)
{
}
void
vulkan_Draw_CrosshairAt (int ch, int x, int y)
{
}
void
vulkan_Draw_Crosshair (void)
{
}
void
vulkan_Draw_Pic (int x, int y, qpic_t *pic)
{
}
void
vulkan_Draw_Picf (float x, float y, qpic_t *pic)
{
}
void
vulkan_Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
int height)
{
}
void
vulkan_Draw_ConsoleBackground (int lines, byte alpha)
{
}
void
vulkan_Draw_TileClear (int x, int y, int w, int h)
{
}
void
vulkan_Draw_Fill (int x, int y, int w, int h, int c)
{
}
void
vulkan_Draw_FadeScreen (void)
{
}
void
Vulkan_Set2D (void)
{
}
void
Vulkan_Set2DScaled (void)
{
}
void
Vulkan_End2D (void)
{
}
void
Vulkan_DrawReset (void)
{
}
void
Vulkan_FlushText (void)
{
}
void
vulkan_Draw_BlendScreen (quat_t color)
{
}

View file

@ -0,0 +1,6 @@
#include <vulkan/vulkan.h>
#define EXPORTED_VULKAN_FUNCTION(fname) PFN_##fname fname;
#define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) PFN_##fname fname;
#include "QF/Vulkan/funclist.h"

View file

@ -0,0 +1,129 @@
/*
vid_common_vulkan.c
Common Vulkan video driver functions
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2019 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_MATH_H
# include <math.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <dlfcn.h>
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/input.h"
#include "QF/qargs.h"
#include "QF/quakefs.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "QF/vid.h"
#include "QF/Vulkan/qf_vid.h"
#include "QF/Vulkan/init.h"
#include "compat.h"
#include "d_iface.h"
#include "r_internal.h"
static void *vulkan_library;
static VulkanInstance_t *vulkan_instance;
static void
load_vulkan_library (void)
{
vulkan_library = dlopen (vulkan_library_name->string, RTLD_NOW);
if (!vulkan_library) {
Sys_Error ("Couldn't load vulkan library %s: %s",
vulkan_library_name->name, dlerror ());
}
#define EXPORTED_VULKAN_FUNCTION(name) \
name = (PFN_##name) dlsym (vulkan_library, #name); \
if (!name) { \
Sys_Error ("Couldn't find exported vulkan function %s", #name); \
}
// Can't use vkGetInstanceProcAddr (0, ...) here because it grabs from
// the whole exe and thus sees the function pointers instead of the actual
// functions. Sure, could rename all the function pointers, but while that
// worked for gl and glsl, it also made it a real pain to work with the
// spec (or man pages, etc). Of course, namespaces would help, too.
#define GLOBAL_LEVEL_VULKAN_FUNCTION(name) \
name = (PFN_##name) dlsym (vulkan_library, #name); \
if (!name) { \
Sys_Error ("Couldn't find global-level function %s", #name); \
}
#include "QF/Vulkan/funclist.h"
}
void
Vulkan_Init_Cvars ()
{
vulkan_library_name = Cvar_Get ("vulkan_library", "libvulkan.so.1",
CVAR_ROM, 0,
"the name of the vulkan shared library");
vulkan_use_validation = Cvar_Get ("vulkan_use_validation", "1", CVAR_NONE,
0,
"enable LunarG Standard Validation "
"Layer if available (requires instance "
"restart).");
}
const char *extensions[] = {
"foo",
0,
};
void
Vulkan_Init_Common (void)
{
Vulkan_Init_Cvars ();
load_vulkan_library ();
vulkan_instance = Vulkan_CreateInstance (PACKAGE_STRING, 0x000702ff, 0, extensions);//FIXME version
Sys_Printf ("Vulkan_Init_Common\n");
if (developer->int_val & SYS_VID) {
Vulkan_DestroyInstance (vulkan_instance);
Sys_Quit();
}
}
void
Vulkan_Shutdown_Common (void)
{
Vulkan_DestroyInstance (vulkan_instance);
}