Add experemental vulkan render

This commit is contained in:
Denis Pauk 2020-01-11 15:55:45 +02:00 committed by Yamagi
parent 4c3853ca56
commit 823e0eb915
16 changed files with 531 additions and 579 deletions

103
Makefile
View file

@ -56,6 +56,9 @@ WITH_SYSTEMDIR:=""
# Contents/Resources
OSX_APP:=yes
# Build vulkan render
WITH_REFVK:=no
# This is an optional configuration file, it'll be used in
# case of presence.
CONFIG_FILE:=config.mk
@ -164,6 +167,20 @@ endif
# ----------
# Base CPPFLAGS.
#
# -O2 are enough optimizations.
#
# -g to build always with debug symbols. Please DO NOT
# CHANGE THIS, since it's our only chance to debug this
# crap when random crashes happen!
#
# -fwrapv for defined integer wrapping. MSVC6 did this
# and the game code requires it.
CPPFLAGS := -O2 -pipe -g -fwrapv
# ----------
# Switch of some annoying warnings.
ifeq ($(COMPILER), clang)
# -Wno-missing-braces because otherwise clang complains
@ -337,12 +354,12 @@ endif
# ----------
# Phony targets
.PHONY : all client game icon server ref_gl1 ref_gl3 ref_soft
.PHONY : all client game icon server ref_gl1 ref_gl3 ref_soft ref_vk
# ----------
# Builds everything
all: config client server game ref_gl1 ref_gl3 ref_soft
all: config client server game ref_gl1 ref_gl3 ref_soft ref_vk
# ----------
@ -352,9 +369,10 @@ config:
@echo "============================"
@echo "WITH_CURL = $(WITH_CURL)"
@echo "WITH_OPENAL = $(WITH_OPENAL)"
@echo "WITH_REFVK = $(WITH_REFVK)"
@echo "WITH_RPATH = $(WITH_RPATH)"
@echo "WITH_SYSTEMWIDE = $(WITH_SYSTEMWIDE)"
@echo "WITH_SYSTEMDIR = $(WITH_SYSTEMDIR)"
@echo "WITH_RPATH = $(WITH_RPATH)"
@echo "============================"
@echo ""
@ -430,6 +448,10 @@ ifeq ($(WITH_CURL),yes)
release/quake2 : CFLAGS += -DUSE_CURL
endif
ifeq ($(WITH_REFVK),yes)
release/quake2 : CFLAGS += -DUSE_REFVK
endif
ifeq ($(WITH_OPENAL),yes)
ifeq ($(YQ2_OSTYPE), OpenBSD)
release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.so"'
@ -631,6 +653,37 @@ build/ref_soft/%.o: %.c
# ----------
# The vk renderer lib
ifeq ($(YQ2_OSTYPE), Linux)
ifeq ($(WITH_REFVK),yes)
ref_vk:
@echo "===> Building ref_vk.so"
$(MAKE) release/ref_vk.so
release/ref_vk.so : CFLAGS += -fPIC
release/ref_vk.so : LDFLAGS += -shared -lm -lvulkan -lstdc++
else
ref_vk:
@echo "===> Vulkan render disabled"
endif
else
ref_vk:
@echo "===> Vulkan render unsupported"
endif # OS specific ref_vk stuff
build/ref_vk/%.o: %.c
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(INCLUDE) $(GLAD_INCLUDE) -o $@ $<
build/ref_vk/%.o: %.cpp
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(INCLUDE) $(GLAD_INCLUDE) -o $@ $<
# ----------
# The baseq2 game
ifeq ($(YQ2_OSTYPE), Windows)
game:
@ -915,6 +968,42 @@ endif
# ----------
REFVK_OBJS_ := \
src/client/refresh/vk/vk_mem_alloc.o \
src/client/refresh/vk/vk_buffer.o \
src/client/refresh/vk/vk_cmd.o \
src/client/refresh/vk/vk_common.o \
src/client/refresh/vk/vk_device.o \
src/client/refresh/vk/vk_draw.o \
src/client/refresh/vk/vk_image.o \
src/client/refresh/vk/vk_light.o \
src/client/refresh/vk/vk_mesh.o \
src/client/refresh/vk/vk_model.o \
src/client/refresh/vk/vk_pipeline.o \
src/client/refresh/vk/vk_rmain.o \
src/client/refresh/vk/vk_rmisc.o \
src/client/refresh/vk/vk_rsurf.o \
src/client/refresh/vk/vk_shaders.o \
src/client/refresh/vk/vk_swapchain.o \
src/client/refresh/vk/vk_validation.o \
src/client/refresh/vk/vk_warp.o \
src/client/refresh/files/pcx.o \
src/client/refresh/files/stb.o \
src/client/refresh/files/wal.o \
src/client/refresh/files/pvs.o \
src/common/shared/shared.o \
src/common/md4.o
ifeq ($(YQ2_OSTYPE), Windows)
REFVK_OBJS_ += \
src/backends/windows/shared/hunk.o
else # not Windows
REFVK_OBJS_ += \
src/backends/unix/shared/hunk.o
endif
# ----------
# Used by the server
SERVER_OBJS_ := \
src/backends/generic/misc.o \
@ -971,6 +1060,7 @@ CLIENT_OBJS = $(patsubst %,build/client/%,$(CLIENT_OBJS_))
REFGL1_OBJS = $(patsubst %,build/ref_gl1/%,$(REFGL1_OBJS_))
REFGL3_OBJS = $(patsubst %,build/ref_gl3/%,$(REFGL3_OBJS_))
REFSOFT_OBJS = $(patsubst %,build/ref_soft/%,$(REFSOFT_OBJS_))
REFVK_OBJS = $(patsubst %,build/ref_vk/%,$(REFVK_OBJS_))
SERVER_OBJS = $(patsubst %,build/server/%,$(SERVER_OBJS_))
GAME_OBJS = $(patsubst %,build/baseq2/%,$(GAME_OBJS_))
@ -1068,6 +1158,13 @@ release/ref_soft.so : $(REFSOFT_OBJS)
${Q}$(CC) $(REFSOFT_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
endif
# release/ref_vk.so
ifeq ($(YQ2_OSTYPE), Linux)
release/ref_vk.so : $(REFVK_OBJS)
@echo "===> LD $@"
${Q}$(CC) $(REFVK_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
endif
# release/baseq2/game.so
ifeq ($(YQ2_OSTYPE), Windows)
release/baseq2/game.dll : $(GAME_OBJS)

View file

@ -79,10 +79,21 @@ GetRenderer(void)
{
return 2;
}
#ifdef USE_REFVK
else if (Q_stricmp(vid_renderer->string, "vk") == 0)
{
return 3;
}
else
{
return 4;
}
#else
else
{
return 3;
}
#endif
}
static int
@ -171,6 +182,13 @@ ApplyChanges(void *unused)
Cvar_Set("vid_renderer", "soft");
restart = true;
}
#ifdef USE_REFVK
else if (s_renderer_list.curvalue == 3)
{
Cvar_Set("vid_renderer", "vk");
restart = true;
}
#endif
}
/* auto mode */
@ -260,6 +278,9 @@ VID_MenuInit(void)
"[OpenGL 1.4]",
"[OpenGL 3.2]",
"[Software ]",
#ifdef USE_REFVK
"[Vulkan ]",
#endif
CUSTOM_MODE_NAME,
0
};

View file

@ -9,7 +9,7 @@ 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -29,18 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
** QVk_Shutdown() - unloads libraries, NULLs function pointers
*/
#include <float.h>
#include "../ref_vk/vk_local.h"
#ifdef _WIN32
#include "../win32/vk_win.h"
#endif
#ifdef __linux__
#include "../linux/vk_linux.h"
#endif
#ifdef __APPLE__
#include "../macos/vk_macos.h"
#endif
FILE *vk_logfp = NULL;
#include "vk_local.h"
// Vulkan instance, surface and memory allocator
VkInstance vk_instance = VK_NULL_HANDLE;
@ -414,7 +403,7 @@ static VkResult CreateFramebuffers()
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "CreateFramebuffers(): framebuffer #%d create error: %s\n", j, QVk_GetError(res));
R_Printf(PRINT_ALL, "CreateFramebuffers(): framebuffer #%d create error: %s\n", j, QVk_GetError(res));
DestroyFramebuffers();
return res;
}
@ -692,7 +681,7 @@ static VkResult CreateRenderpasses()
VkResult res = vkCreateRenderPass(vk_device.logical, &rpCreateInfos[i], NULL, &vk_renderpasses[i].rp);
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "CreateRenderpasses(): renderpass #%d create error: %s\n", i, QVk_GetError(res));
R_Printf(PRINT_ALL, "CreateRenderpasses(): renderpass #%d create error: %s\n", i, QVk_GetError(res));
return res;
}
}
@ -708,15 +697,15 @@ static VkResult CreateRenderpasses()
static void CreateDrawBuffers()
{
QVk_CreateDepthBuffer(vk_renderpasses[RP_WORLD].sampleCount, &vk_depthbuffer);
ri.Con_Printf(PRINT_ALL, "...created world depth buffer\n");
R_Printf(PRINT_ALL, "...created world depth buffer\n");
QVk_CreateDepthBuffer(VK_SAMPLE_COUNT_1_BIT, &vk_ui_depthbuffer);
ri.Con_Printf(PRINT_ALL, "...created UI depth buffer\n");
R_Printf(PRINT_ALL, "...created UI depth buffer\n");
QVk_CreateColorBuffer(VK_SAMPLE_COUNT_1_BIT, &vk_colorbuffer, VK_IMAGE_USAGE_SAMPLED_BIT);
ri.Con_Printf(PRINT_ALL, "...created world color buffer\n");
R_Printf(PRINT_ALL, "...created world color buffer\n");
QVk_CreateColorBuffer(VK_SAMPLE_COUNT_1_BIT, &vk_colorbufferWarp, VK_IMAGE_USAGE_SAMPLED_BIT);
ri.Con_Printf(PRINT_ALL, "...created world postpocess color buffer\n");
R_Printf(PRINT_ALL, "...created world postpocess color buffer\n");
QVk_CreateColorBuffer(vk_renderpasses[RP_WORLD].sampleCount, &vk_msaaColorbuffer, 0);
ri.Con_Printf(PRINT_ALL, "...created MSAAx%d color buffer\n", vk_renderpasses[RP_WORLD].sampleCount);
R_Printf(PRINT_ALL, "...created MSAAx%d color buffer\n", vk_renderpasses[RP_WORLD].sampleCount);
QVk_DebugSetObjectName((uint64_t)vk_depthbuffer.image, VK_OBJECT_TYPE_IMAGE, "Depth Buffer: World");
QVk_DebugSetObjectName((uint64_t)vk_depthbuffer.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "Image View: World Depth Buffer");
@ -1130,7 +1119,7 @@ static void CreatePipelines()
VK_VERTINFO(RG_RG, sizeof(float) * 4, VK_INPUTATTR_DESC(0, VK_FORMAT_R32G32_SFLOAT, 0),
VK_INPUTATTR_DESC(1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 2));
VK_VERTINFO(RGB_RG, sizeof(float) * 5, VK_INPUTATTR_DESC(0, VK_FORMAT_R32G32B32_SFLOAT, 0),
VK_VERTINFO(RGB_RG, sizeof(float) * 5, VK_INPUTATTR_DESC(0, VK_FORMAT_R32G32B32_SFLOAT, 0),
VK_INPUTATTR_DESC(1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 3));
VK_VERTINFO(RGB_RGB, sizeof(float) * 6, VK_INPUTATTR_DESC(0, VK_FORMAT_R32G32B32_SFLOAT, 0),
@ -1377,7 +1366,7 @@ void QVk_Shutdown( void )
{
if (vk_instance != VK_NULL_HANDLE)
{
ri.Con_Printf(PRINT_ALL, "Shutting down Vulkan\n");
R_Printf(PRINT_ALL, "Shutting down Vulkan\n");
for (int i = 0; i < 2; ++i)
{
@ -1499,13 +1488,23 @@ void QVk_Shutdown( void )
}
}
# pragma warning (disable : 4113 4133 4047 )
void Vkimp_GetSurfaceExtensions(char **extensions, uint32_t *extCount)
{
if (extensions)
{
extensions[0] = VK_KHR_SURFACE_EXTENSION_NAME;
extensions[1] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
}
if (extCount)
*extCount = 2;
}
/*
** QVk_Init
**
** This is responsible for initializing Vulkan.
**
**
*/
qboolean QVk_Init()
{
@ -1565,13 +1564,13 @@ qboolean QVk_Init()
wantedExtensions[extCount - 1] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
#endif
ri.Con_Printf(PRINT_ALL, "Enabled extensions: ");
R_Printf(PRINT_ALL, "Enabled extensions: ");
for (int i = 0; i < extCount; i++)
{
ri.Con_Printf(PRINT_ALL, "%s ", wantedExtensions[i]);
R_Printf(PRINT_ALL, "%s ", wantedExtensions[i]);
vk_config.extensions[i] = wantedExtensions[i];
}
ri.Con_Printf(PRINT_ALL, "\n");
R_Printf(PRINT_ALL, "\n");
VkInstanceCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
@ -1604,10 +1603,10 @@ qboolean QVk_Init()
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan instance: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan instance: %s\n", QVk_GetError(res));
return false;
}
ri.Con_Printf(PRINT_ALL, "...created Vulkan instance\n");
R_Printf(PRINT_ALL, "...created Vulkan instance\n");
// initialize function pointers
qvkCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(vk_instance, "vkCreateDebugUtilsMessengerEXT");
@ -1624,10 +1623,10 @@ qboolean QVk_Init()
res = Vkimp_CreateSurface();
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan surface: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan surface: %s\n", QVk_GetError(res));
return false;
}
ri.Con_Printf(PRINT_ALL, "...created Vulkan surface\n");
R_Printf(PRINT_ALL, "...created Vulkan surface\n");
// create Vulkan device - see if the user prefers any specific device if there's more than one GPU in the system
QVk_CreateDevice((int)vk_device_idx->value);
@ -1650,19 +1649,19 @@ qboolean QVk_Init()
res = vmaCreateAllocator(&allocInfo, &vk_malloc);
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan memory allocator: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan memory allocator: %s\n", QVk_GetError(res));
return false;
}
ri.Con_Printf(PRINT_ALL, "...created Vulkan memory allocator\n");
R_Printf(PRINT_ALL, "...created Vulkan memory allocator\n");
// setup swapchain
res = QVk_CreateSwapchain();
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan swapchain: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan swapchain: %s\n", QVk_GetError(res));
return false;
}
ri.Con_Printf(PRINT_ALL, "...created Vulkan swapchain\n");
R_Printf(PRINT_ALL, "...created Vulkan swapchain\n");
// set viewport and scissor
vk_viewport.x = 0.f;
@ -1696,7 +1695,7 @@ qboolean QVk_Init()
QVk_DebugSetObjectName((uint64_t)vk_imageAvailableSemaphores[i], VK_OBJECT_TYPE_SEMAPHORE, va("Semaphore: image available #%d", i));
QVk_DebugSetObjectName((uint64_t)vk_renderFinishedSemaphores[i], VK_OBJECT_TYPE_SEMAPHORE, va("Semaphore: render finished #%d", i));
}
ri.Con_Printf(PRINT_ALL, "...created synchronization objects\n");
R_Printf(PRINT_ALL, "...created synchronization objects\n");
// setup render passes
for (int i = 0; i < RP_COUNT; ++i)
@ -1708,7 +1707,7 @@ qboolean QVk_Init()
VkSampleCountFlagBits supportedMsaa = vk_device.properties.limits.framebufferColorSampleCounts;
if (!(supportedMsaa & msaaMode))
{
ri.Con_Printf(PRINT_ALL, "MSAAx%d mode not supported, aborting...\n", msaaMode);
R_Printf(PRINT_ALL, "MSAAx%d mode not supported, aborting...\n", msaaMode);
ri.Cvar_Set("vk_msaa", "0");
msaaMode = VK_SAMPLE_COUNT_1_BIT;
// avoid secondary video reload
@ -1721,28 +1720,28 @@ qboolean QVk_Init()
res = CreateRenderpasses();
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan render passes: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan render passes: %s\n", QVk_GetError(res));
return false;
}
ri.Con_Printf(PRINT_ALL, "...created %d Vulkan render passes\n", RP_COUNT);
R_Printf(PRINT_ALL, "...created %d Vulkan render passes\n", RP_COUNT);
// setup command pools
res = QVk_CreateCommandPool(&vk_commandPool, vk_device.gfxFamilyIndex);
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan command pool for graphics: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan command pool for graphics: %s\n", QVk_GetError(res));
return false;
}
res = QVk_CreateCommandPool(&vk_transferCommandPool, vk_device.transferFamilyIndex);
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan command pool for transfer: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan command pool for transfer: %s\n", QVk_GetError(res));
return false;
}
QVk_DebugSetObjectName((uint64_t)vk_commandPool, VK_OBJECT_TYPE_COMMAND_POOL, "Command Pool: Graphics");
QVk_DebugSetObjectName((uint64_t)vk_transferCommandPool, VK_OBJECT_TYPE_COMMAND_POOL, "Command Pool: Transfer");
ri.Con_Printf(PRINT_ALL, "...created Vulkan command pools\n");
R_Printf(PRINT_ALL, "...created Vulkan command pools\n");
// setup draw buffers
CreateDrawBuffers();
@ -1751,19 +1750,19 @@ qboolean QVk_Init()
res = CreateImageViews();
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan image views: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan image views: %s\n", QVk_GetError(res));
return false;
}
ri.Con_Printf(PRINT_ALL, "...created %d Vulkan image view(s)\n", vk_swapchain.imageCount);
R_Printf(PRINT_ALL, "...created %d Vulkan image view(s)\n", vk_swapchain.imageCount);
// setup framebuffers
res = CreateFramebuffers();
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan framebuffers: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan framebuffers: %s\n", QVk_GetError(res));
return false;
}
ri.Con_Printf(PRINT_ALL, "...created %d Vulkan framebuffers\n", vk_swapchain.imageCount);
R_Printf(PRINT_ALL, "...created %d Vulkan framebuffers\n", vk_swapchain.imageCount);
// setup command buffers (double buffering)
vk_commandbuffers = (VkCommandBuffer *)malloc(NUM_CMDBUFFERS * sizeof(VkCommandBuffer));
@ -1779,12 +1778,12 @@ qboolean QVk_Init()
res = vkAllocateCommandBuffers(vk_device.logical, &cbInfo, vk_commandbuffers);
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan commandbuffers: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "QVk_Init(): Could not create Vulkan commandbuffers: %s\n", QVk_GetError(res));
free(vk_commandbuffers);
vk_commandbuffers = NULL;
return false;
}
ri.Con_Printf(PRINT_ALL, "...created %d Vulkan commandbuffers\n", NUM_CMDBUFFERS);
R_Printf(PRINT_ALL, "...created %d Vulkan commandbuffers\n", NUM_CMDBUFFERS);
// initialize tracker variables
vk_activeCmdbuffer = vk_commandbuffers[vk_activeBufferIdx];
@ -1849,7 +1848,7 @@ VkResult QVk_BeginFrame()
// for VK_OUT_OF_DATE_KHR and VK_SUBOPTIMAL_KHR it'd be fine to just rebuild the swapchain but let's take the easy way out and restart video system
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_SURFACE_LOST_KHR)
{
ri.Con_Printf(PRINT_ALL, "QVk_BeginFrame(): received %s after vkAcquireNextImageKHR - restarting video!\n", QVk_GetError(result));
R_Printf(PRINT_ALL, "QVk_BeginFrame(): received %s after vkAcquireNextImageKHR - restarting video!\n", QVk_GetError(result));
return result;
}
else if (result != VK_SUCCESS)
@ -1885,7 +1884,6 @@ VkResult QVk_EndFrame(qboolean force)
// this may happen if Sys_Error is issued mid-frame, so we need to properly advance the draw pipeline
if (force)
{
extern void R_EndWorldRenderpass(void);
R_EndWorldRenderpass();
}
@ -1929,7 +1927,7 @@ VkResult QVk_EndFrame(qboolean force)
// for VK_OUT_OF_DATE_KHR and VK_SUBOPTIMAL_KHR it'd be fine to just rebuild the swapchain but let's take the easy way out and restart video system
if (renderResult == VK_ERROR_OUT_OF_DATE_KHR || renderResult == VK_SUBOPTIMAL_KHR || renderResult == VK_ERROR_SURFACE_LOST_KHR)
{
ri.Con_Printf(PRINT_ALL, "QVk_EndFrame(): received %s after vkQueuePresentKHR - restarting video!\n", QVk_GetError(renderResult));
R_Printf(PRINT_ALL, "QVk_EndFrame(): received %s after vkQueuePresentKHR - restarting video!\n", QVk_GetError(renderResult));
vid_ref->modified = true;
}
else if (renderResult != VK_SUCCESS)
@ -2022,7 +2020,7 @@ uint8_t *QVk_GetVertexBuffer(VkDeviceSize size, VkBuffer *dstBuffer, VkDeviceSiz
{
vk_config.vertex_buffer_size = max(vk_config.vertex_buffer_size * BUFFER_RESIZE_FACTOR, NextPow2(size));
ri.Con_Printf(PRINT_ALL, "Resizing dynamic vertex buffer to %ukB\n", vk_config.vertex_buffer_size / 1024);
R_Printf(PRINT_ALL, "Resizing dynamic vertex buffer to %ukB\n", vk_config.vertex_buffer_size / 1024);
int swapBufferOffset = vk_swapBuffersCnt[vk_activeSwapBufferIdx];
vk_swapBuffersCnt[vk_activeSwapBufferIdx] += NUM_DYNBUFFERS;
@ -2051,7 +2049,7 @@ uint8_t *QVk_GetVertexBuffer(VkDeviceSize size, VkBuffer *dstBuffer, VkDeviceSiz
vk_config.vertex_buffer_usage = vk_dynVertexBuffers[vk_activeDynBufferIdx].currentOffset;
if (vk_config.vertex_buffer_max_usage < vk_config.vertex_buffer_usage)
vk_config.vertex_buffer_max_usage = vk_config.vertex_buffer_usage;
return (uint8_t *)vk_dynVertexBuffers[vk_activeDynBufferIdx].allocInfo.pMappedData + (*dstOffset);
}
@ -2065,7 +2063,7 @@ uint8_t *QVk_GetIndexBuffer(VkDeviceSize size, VkDeviceSize *dstOffset)
{
vk_config.index_buffer_size = max(vk_config.index_buffer_size * BUFFER_RESIZE_FACTOR, NextPow2(size));
ri.Con_Printf(PRINT_ALL, "Resizing dynamic index buffer to %ukB\n", vk_config.index_buffer_size / 1024);
R_Printf(PRINT_ALL, "Resizing dynamic index buffer to %ukB\n", vk_config.index_buffer_size / 1024);
int swapBufferOffset = vk_swapBuffersCnt[vk_activeSwapBufferIdx];
vk_swapBuffersCnt[vk_activeSwapBufferIdx] += NUM_DYNBUFFERS;
@ -2107,7 +2105,7 @@ uint8_t *QVk_GetUniformBuffer(VkDeviceSize size, uint32_t *dstOffset, VkDescript
{
vk_config.uniform_buffer_size = max(vk_config.uniform_buffer_size * BUFFER_RESIZE_FACTOR, NextPow2(size));
ri.Con_Printf(PRINT_ALL, "Resizing dynamic uniform buffer to %ukB\n", vk_config.uniform_buffer_size / 1024);
R_Printf(PRINT_ALL, "Resizing dynamic uniform buffer to %ukB\n", vk_config.uniform_buffer_size / 1024);
int swapBufferOffset = vk_swapBuffersCnt[vk_activeSwapBufferIdx];
int swapDescSetsOffset = vk_swapDescSetsCnt[vk_activeSwapBufferIdx];
vk_swapBuffersCnt[vk_activeSwapBufferIdx] += NUM_DYNBUFFERS;
@ -2206,7 +2204,7 @@ VkBuffer QVk_GetTriangleFanIbo(VkDeviceSize indexCount)
if (indexCount > vk_config.triangle_fan_index_count)
{
vk_config.triangle_fan_index_count *= BUFFER_RESIZE_FACTOR;
ri.Con_Printf(PRINT_ALL, "Resizing triangle fan index buffer to %u indices.\n", vk_config.triangle_fan_index_count);
R_Printf(PRINT_ALL, "Resizing triangle fan index buffer to %u indices.\n", vk_config.triangle_fan_index_count);
RebuildTriangleFanIndexBuffer();
}
@ -2324,36 +2322,3 @@ const char *QVk_GetError(VkResult errorCode)
#undef ERRSTR
return "UNKNOWN ERROR";
}
void Vkimp_EnableLogging(qboolean enable)
{
if (enable)
{
if (!vkw_state.log_fp)
{
struct tm *newtime;
time_t aclock;
char buffer[1024];
time(&aclock);
newtime = localtime(&aclock);
asctime(newtime);
Com_sprintf(buffer, sizeof(buffer), "%s/vk.log", ri.FS_Gamedir());
vkw_state.log_fp = fopen(buffer, "wt");
fprintf(vkw_state.log_fp, "%s\n", asctime(newtime));
}
vk_logfp = vkw_state.log_fp;
}
else
{
vk_logfp = NULL;
}
}
void Vkimp_LogNewFrame( void )
{
fprintf( vkw_state.log_fp, "*** R_BeginFrame ***\n" );
}

View file

@ -136,11 +136,11 @@ static qboolean selectPhysicalDevice(int preferredDeviceIdx)
if (physicalDeviceCount == 0)
{
ri.Con_Printf(PRINT_ALL, "No Vulkan-capable devices found!\n");
R_Printf(PRINT_ALL, "No Vulkan-capable devices found!\n");
return false;
}
ri.Con_Printf(PRINT_ALL, "...found %d Vulkan-capable device(s)\n", physicalDeviceCount);
R_Printf(PRINT_ALL, "...found %d Vulkan-capable device(s)\n", physicalDeviceCount);
VkPhysicalDevice *physicalDevices = (VkPhysicalDevice *)malloc(physicalDeviceCount * sizeof(VkPhysicalDevice));
VK_VERIFY(vkEnumeratePhysicalDevices(vk_instance, &physicalDeviceCount, physicalDevices));
@ -150,7 +150,7 @@ static qboolean selectPhysicalDevice(int preferredDeviceIdx)
if (vk_device.physical == VK_NULL_HANDLE)
{
ri.Con_Printf(PRINT_ALL, "Could not find a suitable physical device!\n");
R_Printf(PRINT_ALL, "Could not find a suitable physical device!\n");
return false;
}
@ -272,7 +272,7 @@ qboolean QVk_CreateDevice(int preferredDeviceIdx)
VkResult res = createLogicalDevice();
if (res != VK_SUCCESS)
{
ri.Con_Printf(PRINT_ALL, "Could not create Vulkan logical device: %s\n", QVk_GetError(res));
R_Printf(PRINT_ALL, "Could not create Vulkan logical device: %s\n", QVk_GetError(res));
return false;
}

View file

@ -41,17 +41,17 @@ void Draw_InitLocal (void)
/*
================
Draw_Char
Draw_CharScaled
Draws one 8*8 graphics character with 0 being transparent.
It can be clipped to the top of the screen to allow the console to be
smoothly scrolled off.
================
*/
void Draw_Char (int x, int y, int num)
void Draw_CharScaled (int x, int y, int num, float scale)
{
int row, col;
float frow, fcol, size;
int row, col;
float frow, fcol, size;
num &= 255;
@ -61,8 +61,6 @@ void Draw_Char (int x, int y, int num)
if (y <= -8)
return; // totally off screen
cvar_t *scale = ri.Cvar_Get("hudscale", "1", 0);
row = num >> 4;
col = num & 15;
@ -71,7 +69,7 @@ void Draw_Char (int x, int y, int num)
size = 0.0625;
float imgTransform[] = { (float)x / vid.width, (float)y / vid.height,
8.f * scale->value / vid.width, 8.f * scale->value / vid.height,
8.f * scale / vid.width, 8.f * scale / vid.height,
fcol, frow, size, size };
QVk_DrawTexRect(imgTransform, sizeof(imgTransform), &draw_chars->vk_texture);
}
@ -113,10 +111,8 @@ void Draw_GetPicSize (int *w, int *h, char *pic)
return;
}
cvar_t *scale = ri.Cvar_Get("hudscale", "1", 0);
*w = vk->width * scale->value;
*h = vk->height * scale->value;
*w = vk->width;
*h = vk->height;
}
/*
@ -131,7 +127,7 @@ void Draw_StretchPic (int x, int y, int w, int h, char *pic)
vk = Draw_FindPic(pic);
if (!vk)
{
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
R_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
@ -145,22 +141,21 @@ void Draw_StretchPic (int x, int y, int w, int h, char *pic)
/*
=============
Draw_Pic
Draw_PicScaled
=============
*/
void Draw_Pic (int x, int y, char *pic)
void Draw_PicScaled (int x, int y, char *pic, float scale)
{
image_t *vk;
cvar_t *scale = ri.Cvar_Get("hudscale", "1", 0);
vk = Draw_FindPic(pic);
if (!vk)
{
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
R_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
Draw_StretchPic(x, y, vk->width*scale->value, vk->height*scale->value, pic);
Draw_StretchPic(x, y, vk->width*scale, vk->height*scale, pic);
}
/*
@ -178,7 +173,7 @@ void Draw_TileClear (int x, int y, int w, int h, char *pic)
image = Draw_FindPic(pic);
if (!image)
{
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
R_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}

View file

@ -538,7 +538,7 @@ void Vk_ImageList_f (void)
image_t *image;
int texels;
ri.Con_Printf(PRINT_ALL, "------------------\n");
R_Printf(PRINT_ALL, "------------------\n");
texels = 0;
for (i = 0, image = vktextures; i < numvktextures; i++, image++)
@ -549,26 +549,26 @@ void Vk_ImageList_f (void)
switch (image->type)
{
case it_skin:
ri.Con_Printf(PRINT_ALL, "M");
R_Printf(PRINT_ALL, "M");
break;
case it_sprite:
ri.Con_Printf(PRINT_ALL, "S");
R_Printf(PRINT_ALL, "S");
break;
case it_wall:
ri.Con_Printf(PRINT_ALL, "W");
R_Printf(PRINT_ALL, "W");
break;
case it_pic:
ri.Con_Printf(PRINT_ALL, "P");
R_Printf(PRINT_ALL, "P");
break;
default:
ri.Con_Printf(PRINT_ALL, " ");
R_Printf(PRINT_ALL, " ");
break;
}
ri.Con_Printf(PRINT_ALL, " %3i %3i RGB: %s\n",
R_Printf(PRINT_ALL, " %3i %3i RGB: %s\n",
image->upload_width, image->upload_height, image->name);
}
ri.Con_Printf(PRINT_ALL, "Total texel count (not counting mipmaps): %i\n", texels);
R_Printf(PRINT_ALL, "Total texel count (not counting mipmaps): %i\n", texels);
}
@ -668,7 +668,7 @@ void Vk_TextureMode( char *string )
if (i == NUM_VK_MODES)
{
ri.Con_Printf(PRINT_ALL, "bad filter name (valid values: VK_NEAREST, VK_LINEAR, VK_MIPMAP_NEAREST, VK_MIPMAP_LINEAR)\n");
R_Printf(PRINT_ALL, "bad filter name (valid values: VK_NEAREST, VK_LINEAR, VK_MIPMAP_NEAREST, VK_MIPMAP_LINEAR)\n");
ri.Cvar_Set("vk_texturemode", prev_mode);
return;
}
@ -715,7 +715,7 @@ void Vk_LmapTextureMode( char *string )
if (i == NUM_VK_MODES)
{
ri.Con_Printf(PRINT_ALL, "bad filter name (valid values: VK_NEAREST, VK_LINEAR, VK_MIPMAP_NEAREST, VK_MIPMAP_LINEAR)\n");
R_Printf(PRINT_ALL, "bad filter name (valid values: VK_NEAREST, VK_LINEAR, VK_MIPMAP_NEAREST, VK_MIPMAP_LINEAR)\n");
ri.Cvar_Set("vk_lmaptexturemode", prev_mode);
return;
}
@ -734,116 +734,6 @@ void Vk_LmapTextureMode( char *string )
}
}
/*
=================================================================
PCX LOADING
=================================================================
*/
/*
==============
LoadPCX
==============
*/
void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
{
byte *raw;
pcx_t *pcx;
int x, y;
int len;
int dataByte, runLength;
byte *out, *pix;
*pic = NULL;
*palette = NULL;
//
// load the file
//
len = ri.FS_LoadFile (filename, (void **)&raw);
if (!raw)
{
ri.Con_Printf (PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
return;
}
//
// parse the PCX file
//
pcx = (pcx_t *)raw;
pcx->xmin = LittleShort(pcx->xmin);
pcx->ymin = LittleShort(pcx->ymin);
pcx->xmax = LittleShort(pcx->xmax);
pcx->ymax = LittleShort(pcx->ymax);
pcx->hres = LittleShort(pcx->hres);
pcx->vres = LittleShort(pcx->vres);
pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
pcx->palette_type = LittleShort(pcx->palette_type);
raw = &pcx->data;
if (pcx->manufacturer != 0x0a
|| pcx->version != 5
|| pcx->encoding != 1
|| pcx->bits_per_pixel != 8
|| pcx->xmax >= 640
|| pcx->ymax >= 480)
{
ri.Con_Printf (PRINT_ALL, "Bad pcx file %s\n", filename);
return;
}
out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
*pic = out;
pix = out;
if (palette)
{
*palette = malloc(768);
memcpy (*palette, (byte *)pcx + len - 768, 768);
}
if (width)
*width = pcx->xmax+1;
if (height)
*height = pcx->ymax+1;
for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
{
for (x=0 ; x<=pcx->xmax ; )
{
dataByte = *raw++;
if((dataByte & 0xC0) == 0xC0)
{
runLength = dataByte & 0x3F;
dataByte = *raw++;
}
else
runLength = 1;
while(runLength-- > 0)
pix[x++] = dataByte;
}
}
if ( raw - (byte *)pcx > len)
{
ri.Con_Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename);
free (*pic);
*pic = NULL;
}
ri.FS_FreeFile (pcx);
}
/*
=========================================================
@ -886,7 +776,7 @@ void LoadTGA (char *name, byte **pic, int *width, int *height)
length = ri.FS_LoadFile (name, (void **)&buffer);
if (!buffer)
{
ri.Con_Printf (PRINT_DEVELOPER, "Bad tga file %s\n", name);
R_Printf(PRINT_DEVELOPER, "Bad tga file %s\n", name);
return;
}
@ -1483,7 +1373,7 @@ image_t *Vk_LoadWal (char *name)
ri.FS_LoadFile (name, (void **)&mt);
if (!mt)
{
ri.Con_Printf (PRINT_ALL, "Vk_FindImage: can't load %s\n", name);
R_Printf(PRINT_ALL, "Vk_FindImage: can't load %s\n", name);
return r_notexture;
}

View file

@ -9,7 +9,7 @@ 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -39,7 +39,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <vulkan/vulkan.h>
#include <math.h>
#include "../client/ref.h"
#include "../ref_shared.h"
#include "qvk.h"
@ -51,7 +51,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define VK_VERIFY(x) { \
VkResult res = (x); \
if(res != VK_SUCCESS) { \
ri.Con_Printf(PRINT_ALL, "VkResult verification failed: %s in %s:%d\n", QVk_GetError(res), __FILE__, __LINE__); \
R_Printf(PRINT_ALL, "VkResult verification failed: %s in %s:%d\n", QVk_GetError(res), __FILE__, __LINE__); \
assert(res == VK_SUCCESS && "VkResult verification failed!"); \
} \
}
@ -75,36 +75,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
typedef struct
{
unsigned width, height; // coordinates from main game
} viddef_t;
extern viddef_t vid;
/*
skins will be outline flood filled and mip mapped
pics and sprites with alpha will be outline flood filled
pic won't be mip mapped
model skin
sprite frame
wall texture
pic
*/
typedef enum
{
it_skin,
it_sprite,
it_wall,
it_pic,
it_sky
} imagetype_t;
typedef struct image_s
{
char name[MAX_QPATH]; // game path, including extension
@ -234,7 +206,7 @@ extern int registration_sequence;
extern qvksampler_t vk_current_sampler;
extern qvksampler_t vk_current_lmap_sampler;
qboolean R_Init( void *hinstance, void *hWnd );
qboolean R_Init( void );
void R_Shutdown( void );
void R_RenderView (refdef_t *fd);
@ -263,9 +235,9 @@ void R_MarkLights (dlight_t *light, int bit, mnode_t *node);
void COM_StripExtension (char *in, char *out);
void Draw_GetPicSize (int *w, int *h, char *name);
void Draw_Pic (int x, int y, char *name);
void Draw_PicScaled (int x, int y, char *name, float scale);
void Draw_StretchPic (int x, int y, int w, int h, char *name);
void Draw_Char (int x, int y, int c);
void Draw_CharScaled (int x, int y, int c, float scale);
void Draw_TileClear (int x, int y, int w, int h, char *name);
void Draw_Fill (int x, int y, int w, int h, int c);
void Draw_FadeScreen (void);
@ -273,6 +245,7 @@ void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data
void R_BeginFrame( float camera_separation );
void R_EndFrame( void );
void R_EndWorldRenderpass( void );
void R_SetPalette ( const unsigned char *palette);
int Draw_GetPalette (void);
@ -373,10 +346,7 @@ void Vkimp_BeginFrame( float camera_separation );
void Vkimp_EndFrame( void );
int Vkimp_Init( void *hinstance, void *hWnd );
void Vkimp_Shutdown( void );
int Vkimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen );
void Vkimp_AppActivate( qboolean active );
void Vkimp_EnableLogging( qboolean enable );
void Vkimp_LogNewFrame( void );
void Vkimp_GetSurfaceExtensions(char **extensions, uint32_t *extCount);
VkResult Vkimp_CreateSurface(void);

View file

@ -419,13 +419,13 @@ static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
if ( ( e->frame >= paliashdr->num_frames ) || ( e->frame < 0 ) )
{
ri.Con_Printf (PRINT_ALL, "R_CullAliasModel %s: no such frame %d\n",
R_Printf(PRINT_ALL, "R_CullAliasModel %s: no such frame %d\n",
currentmodel->name, e->frame);
e->frame = 0;
}
if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) )
{
ri.Con_Printf (PRINT_ALL, "R_CullAliasModel %s: no such oldframe %d\n",
R_Printf(PRINT_ALL, "R_CullAliasModel %s: no such oldframe %d\n",
currentmodel->name, e->oldframe);
e->oldframe = 0;
}
@ -736,7 +736,7 @@ void R_DrawAliasModel (entity_t *e)
if ( (currententity->frame >= paliashdr->num_frames)
|| (currententity->frame < 0) )
{
ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n",
R_Printf(PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n",
currentmodel->name, currententity->frame);
currententity->frame = 0;
currententity->oldframe = 0;
@ -745,7 +745,7 @@ void R_DrawAliasModel (entity_t *e)
if ( (currententity->oldframe >= paliashdr->num_frames)
|| (currententity->oldframe < 0))
{
ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n",
R_Printf(PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n",
currentmodel->name, currententity->oldframe);
currententity->frame = 0;
currententity->oldframe = 0;

View file

@ -9,7 +9,7 @@ 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -50,7 +50,7 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
mnode_t *node;
float d;
cplane_t *plane;
if (!model || !model->nodes)
ri.Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model");
@ -66,56 +66,11 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
else
node = node->children[1];
}
return NULL; // never reached
}
/*
===================
Mod_DecompressVis
===================
*/
byte *Mod_DecompressVis (byte *in, model_t *model)
{
static byte decompressed[MAX_MAP_LEAFS/8];
int c;
byte *out;
int row;
row = (model->vis->numclusters+7)>>3;
out = decompressed;
if (!in)
{ // no vis info, so make all visible
while (row)
{
*out++ = 0xff;
row--;
}
return decompressed;
}
do
{
if (*in)
{
*out++ = *in++;
continue;
}
c = in[1];
in += 2;
while (c)
{
*out++ = 0;
c--;
}
} while (out - decompressed < row);
return decompressed;
}
/*
==============
Mod_ClusterPVS
@ -125,8 +80,10 @@ byte *Mod_ClusterPVS (int cluster, model_t *model)
{
if (cluster == -1 || !model->vis)
return mod_novis;
return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS],
model);
return Mod_DecompressVis ( (byte *)model->vis +
model->vis->bitofs[cluster][DVIS_PVS],
(model->vis->numclusters+7)>>3);
}
@ -144,15 +101,15 @@ void Mod_Modellist_f (void)
int total;
total = 0;
ri.Con_Printf (PRINT_ALL,"Loaded models:\n");
R_Printf(PRINT_ALL,"Loaded models:\n");
for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
{
if (!mod->name[0])
continue;
ri.Con_Printf (PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);
R_Printf(PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);
total += mod->extradatasize;
}
ri.Con_Printf (PRINT_ALL, "Total resident: %i\n", total);
R_Printf(PRINT_ALL, "Total resident: %i\n", total);
}
/*
@ -179,10 +136,10 @@ model_t *Mod_ForName (char *name, qboolean crash)
model_t *mod;
unsigned *buf;
int i;
if (!name[0])
ri.Sys_Error (ERR_DROP, "Mod_ForName: NULL name");
//
// inline models are grabbed only from worldmodel
//
@ -204,7 +161,7 @@ model_t *Mod_ForName (char *name, qboolean crash)
if (!strcmp (mod->name, name) )
return mod;
}
//
// find a free model slot spot
//
@ -220,7 +177,7 @@ model_t *Mod_ForName (char *name, qboolean crash)
mod_numknown++;
}
strcpy (mod->name, name);
//
// load the file
//
@ -232,7 +189,7 @@ model_t *Mod_ForName (char *name, qboolean crash)
memset (mod->name, 0, sizeof(mod->name));
return NULL;
}
loadmodel = mod;
//
@ -241,19 +198,19 @@ model_t *Mod_ForName (char *name, qboolean crash)
// call the apropriate loader
switch (LittleLong(*(unsigned *)buf))
{
case IDALIASHEADER:
loadmodel->extradata = Hunk_Begin (0x200000);
Mod_LoadAliasModel (mod, buf);
break;
case IDSPRITEHEADER:
loadmodel->extradata = Hunk_Begin (0x10000);
Mod_LoadSpriteModel (mod, buf);
break;
case IDBSPHEADER:
loadmodel->extradata = Hunk_Begin (0x1000000);
Mod_LoadBrushModel (mod, buf);
@ -294,7 +251,7 @@ void Mod_LoadLighting (lump_t *l)
loadmodel->lightdata = NULL;
return;
}
loadmodel->lightdata = Hunk_Alloc ( l->filelen);
loadmodel->lightdata = Hunk_Alloc ( l->filelen);
memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
}
@ -313,7 +270,7 @@ void Mod_LoadVisibility (lump_t *l)
loadmodel->vis = NULL;
return;
}
loadmodel->vis = Hunk_Alloc ( l->filelen);
loadmodel->vis = Hunk_Alloc ( l->filelen);
memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen);
loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters);
@ -340,7 +297,7 @@ void Mod_LoadVertexes (lump_t *l)
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->vertexes = out;
loadmodel->numvertexes = count;
@ -387,7 +344,7 @@ void Mod_LoadSubmodels (lump_t *l)
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->submodels = out;
loadmodel->numsubmodels = count;
@ -422,7 +379,7 @@ void Mod_LoadEdges (lump_t *l)
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( (count + 1) * sizeof(*out));
out = Hunk_Alloc ( (count + 1) * sizeof(*out));
loadmodel->edges = out;
loadmodel->numedges = count;
@ -451,7 +408,7 @@ void Mod_LoadTexinfo (lump_t *l)
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->texinfo = out;
loadmodel->numtexinfo = count;
@ -475,7 +432,7 @@ void Mod_LoadTexinfo (lump_t *l)
out->image = Vk_FindImage (name, it_wall, NULL);
if (!out->image)
{
ri.Con_Printf (PRINT_ALL, "Couldn't load %s\n", name);
R_Printf(PRINT_ALL, "Couldn't load %s\n", name);
out->image = r_notexture;
}
}
@ -509,7 +466,7 @@ void CalcSurfaceExtents (msurface_t *s)
maxs[0] = maxs[1] = -99999;
tex = s->texinfo;
for (i=0 ; i<s->numedges ; i++)
{
e = loadmodel->surfedges[s->firstedge+i];
@ -517,10 +474,10 @@ void CalcSurfaceExtents (msurface_t *s)
v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
else
v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
for (j=0 ; j<2 ; j++)
{
val = v->position[0] * tex->vecs[j][0] +
val = v->position[0] * tex->vecs[j][0] +
v->position[1] * tex->vecs[j][1] +
v->position[2] * tex->vecs[j][2] +
tex->vecs[j][3];
@ -532,7 +489,7 @@ void CalcSurfaceExtents (msurface_t *s)
}
for (i=0 ; i<2 ; i++)
{
{
bmins[i] = floor(mins[i]/16);
bmaxs[i] = ceil(maxs[i]/16);
@ -659,7 +616,7 @@ void Mod_LoadNodes (lump_t *l)
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->nodes = out;
loadmodel->numnodes = count;
@ -671,7 +628,7 @@ void Mod_LoadNodes (lump_t *l)
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->planenum);
out->plane = loadmodel->planes + p;
@ -688,7 +645,7 @@ void Mod_LoadNodes (lump_t *l)
out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
}
}
Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
}
@ -708,7 +665,7 @@ void Mod_LoadLeafs (lump_t *l)
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->leafs = out;
loadmodel->numleafs = count;
@ -730,7 +687,7 @@ void Mod_LoadLeafs (lump_t *l)
out->firstmarksurface = loadmodel->marksurfaces +
LittleShort(in->firstleafface);
out->nummarksurfaces = LittleShort(in->numleaffaces);
// gl underwater warp
#if 0
if (out->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_THINWATER) )
@ -743,7 +700,7 @@ void Mod_LoadLeafs (lump_t *l)
}
}
#endif
}
}
}
/*
@ -752,16 +709,16 @@ Mod_LoadMarksurfaces
=================
*/
void Mod_LoadMarksurfaces (lump_t *l)
{
{
int i, j, count;
short *in;
msurface_t **out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
@ -781,10 +738,10 @@ Mod_LoadSurfedges
=================
*/
void Mod_LoadSurfedges (lump_t *l)
{
{
int i, count;
int *in, *out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
@ -793,7 +750,7 @@ void Mod_LoadSurfedges (lump_t *l)
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: bad surfedges count in %s: %i",
loadmodel->name, count);
out = Hunk_Alloc ( count*sizeof(*out));
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->surfedges = out;
loadmodel->numsurfedges = count;
@ -815,13 +772,13 @@ void Mod_LoadPlanes (lump_t *l)
dplane_t *in;
int count;
int bits;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*2*sizeof(*out));
out = Hunk_Alloc ( count*2*sizeof(*out));
loadmodel->planes = out;
loadmodel->numplanes = count;
@ -851,7 +808,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
int i;
dheader_t *header;
mmodel_t *bm;
loadmodel->type = mod_brush;
if (loadmodel != mod_known)
ri.Sys_Error (ERR_DROP, "Loaded a brush model after the world");
@ -869,7 +826,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
// load into heap
Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
@ -883,7 +840,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
Mod_LoadNodes (&header->lumps[LUMP_NODES]);
Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
mod->numframes = 2; // regular and alternate animation
//
// set up the submodels
//
@ -895,7 +852,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
starmod = &mod_inline[i];
*starmod = *loadmodel;
starmod->firstmodelsurface = bm->firstface;
starmod->nummodelsurfaces = bm->numfaces;
starmod->firstnode = bm->headnode;
@ -905,7 +862,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
VectorCopy (bm->maxs, starmod->maxs);
VectorCopy (bm->mins, starmod->mins);
starmod->radius = bm->radius;
if (i == 0)
*loadmodel = *starmod;
@ -944,7 +901,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
mod->name, version, ALIAS_VERSION);
pheader = Hunk_Alloc (LittleLong(pinmodel->ofs_end));
// byte swap the header fields and sanity check
for (i=0 ; i<sizeof(dmdl_t)/4 ; i++)
((int *)pheader)[i] = LittleLong (((int *)buffer)[i]);
@ -1000,9 +957,9 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
//
for (i=0 ; i<pheader->num_frames ; i++)
{
pinframe = (daliasframe_t *) ((byte *)pinmodel
pinframe = (daliasframe_t *) ((byte *)pinmodel
+ pheader->ofs_frames + i * pheader->framesize);
poutframe = (daliasframe_t *) ((byte *)pheader
poutframe = (daliasframe_t *) ((byte *)pheader
+ pheader->ofs_frames + i * pheader->framesize);
memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
@ -1012,7 +969,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
}
// verts are all 8 bit, so no swapping needed
memcpy (poutframe->verts, pinframe->verts,
memcpy (poutframe->verts, pinframe->verts,
pheader->num_xyz*sizeof(dtrivertx_t));
}
@ -1096,11 +1053,11 @@ void Mod_LoadSpriteModel (model_t *mod, void *buffer)
//=============================================================================
/*
@@@@@@@@@@@@@@@@@@@@@
=====================
R_BeginRegistration
Specifies the model that will be used as the world
@@@@@@@@@@@@@@@@@@@@@
=====================
*/
void R_BeginRegistration (char *model)
{
@ -1124,10 +1081,10 @@ void R_BeginRegistration (char *model)
/*
@@@@@@@@@@@@@@@@@@@@@
=====================
R_RegisterModel
@@@@@@@@@@@@@@@@@@@@@
=====================
*/
struct model_s *R_RegisterModel (char *name)
{
@ -1168,10 +1125,10 @@ struct model_s *R_RegisterModel (char *name)
/*
@@@@@@@@@@@@@@@@@@@@@
=====================
R_EndRegistration
@@@@@@@@@@@@@@@@@@@@@
=====================
*/
void R_EndRegistration (void)
{

View file

@ -170,8 +170,6 @@ typedef struct mleaf_s
// Whole model
//
typedef enum {mod_bad, mod_brush, mod_sprite, mod_alias } modtype_t;
typedef struct model_s
{
char name[MAX_QPATH];

View file

@ -9,7 +9,7 @@ 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -19,6 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// vk_rmain.c
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
#include "vk_local.h"
viddef_t vid;
@ -90,7 +94,6 @@ cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level
cvar_t *vk_validation;
cvar_t *vk_mode;
cvar_t *vk_bitdepth;
cvar_t *vk_log;
cvar_t *vk_picmip;
cvar_t *vk_skymip;
cvar_t *vk_round_down;
@ -121,6 +124,7 @@ cvar_t *vk_sampleshading;
cvar_t *vk_vsync;
cvar_t *vk_device_idx;
cvar_t *r_vsync;
cvar_t *vid_fullscreen;
cvar_t *vid_gamma;
cvar_t *vid_ref;
@ -219,7 +223,7 @@ void R_DrawSpriteModel (entity_t *e)
VkDeviceSize vboOffset;
uint8_t *vertData = QVk_GetVertexBuffer(sizeof(quadVerts), &vbo, &vboOffset);
memcpy(vertData, quadVerts, sizeof(quadVerts));
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset);
vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawSpritePipeline.layout, 0, 1, &currentmodel->skins[e->frame]->vk_texture.descriptorSet, 0, NULL);
vkCmdDraw(vk_activeCmdbuffer, 6, 1, 0, 0);
@ -408,7 +412,7 @@ void Vk_DrawParticles( int num_particles, const particle_t particles[], const un
typedef struct {
float x,y,z,r,g,b,a,u,v;
} pvertex;
static pvertex visibleParticles[MAX_PARTICLES*3];
for (p = particles, i = 0; i < num_particles; i++, p++)
@ -914,7 +918,7 @@ void R_RenderView (refdef_t *fd)
if (r_speeds->value)
{
ri.Con_Printf(PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n",
R_Printf(PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n",
c_brush_polys,
c_alias_polys,
c_visible_textures,
@ -1004,10 +1008,10 @@ void R_SetLightLevel (void)
}
/*
@@@@@@@@@@@@@@@@@@@@@
=====================
R_RenderFrame
@@@@@@@@@@@@@@@@@@@@@
=====================
*/
void R_RenderFrame (refdef_t *fd)
{
@ -1036,7 +1040,6 @@ void R_Register( void )
#endif
vk_mode = ri.Cvar_Get("vk_mode", "11", CVAR_ARCHIVE);
vk_bitdepth = ri.Cvar_Get("vk_bitdepth", "0", 0);
vk_log = ri.Cvar_Get("vk_log", "0", 0);
vk_picmip = ri.Cvar_Get("vk_picmip", "0", 0);
vk_skymip = ri.Cvar_Get("vk_skymip", "0", 0);
vk_round_down = ri.Cvar_Get("vk_round_down", "1", 0);
@ -1072,6 +1075,7 @@ void R_Register( void )
else if (vk_msaa->value > 4)
ri.Cvar_Set("vk_msaa", "4");
r_vsync = ri.Cvar_Get("r_vsync", "1", CVAR_ARCHIVE);
vid_fullscreen = ri.Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
vid_gamma = ri.Cvar_Get("vid_gamma", "1.0", CVAR_ARCHIVE);
vid_ref = ri.Cvar_Get("vid_ref", "soft", CVAR_ARCHIVE);
@ -1083,6 +1087,40 @@ void R_Register( void )
ri.Cmd_AddCommand("screenshot", Vk_ScreenShot_f);
}
static int
Vkimp_SetMode(int *pwidth, int *pheight, int mode, int fullscreen)
{
R_Printf(PRINT_ALL, "setting mode %d:", mode);
/* mode -1 is not in the vid mode table - so we keep the values in pwidth
and pheight and don't even try to look up the mode info */
if ((mode >= 0) && !ri.Vid_GetModeInfo(pwidth, pheight, mode))
{
R_Printf(PRINT_ALL, " invalid mode\n");
return rserr_invalid_mode;
}
/* We trying to get resolution from desktop */
if (mode == -2)
{
if(!ri.GLimp_GetDesktopMode(pwidth, pheight))
{
R_Printf( PRINT_ALL, " can't detect mode\n" );
return rserr_invalid_mode;
}
}
R_Printf(PRINT_ALL, " %d %d\n", *pwidth, *pheight);
if (!ri.GLimp_InitGraphics(fullscreen, pwidth, pheight))
{
return rserr_invalid_mode;
}
return rserr_ok;
}
/*
==================
R_SetMode
@ -1091,9 +1129,12 @@ R_SetMode
qboolean R_SetMode (void)
{
rserr_t err;
qboolean fullscreen;
int fullscreen;
fullscreen = vid_fullscreen->value;
fullscreen = (int)vid_fullscreen->value;
vid_fullscreen->modified = false;
vk_mode->modified = false;
vid_gamma->modified = false;
vid_fullscreen->modified = false;
@ -1120,7 +1161,7 @@ qboolean R_SetMode (void)
{
ri.Cvar_SetValue("vid_fullscreen", 0);
vid_fullscreen->modified = false;
ri.Con_Printf(PRINT_ALL, "ref_vk::R_SetMode() - fullscreen unavailable in this mode\n");
R_Printf(PRINT_ALL, "ref_vk::R_SetMode() - fullscreen unavailable in this mode\n");
if ((err = Vkimp_SetMode((int*)&vid.width, (int*)&vid.height, vk_mode->value, false)) == rserr_ok)
return true;
}
@ -1128,13 +1169,13 @@ qboolean R_SetMode (void)
{
ri.Cvar_SetValue("vk_mode", vk_state.prev_mode);
vk_mode->modified = false;
ri.Con_Printf(PRINT_ALL, "ref_vk::R_SetMode() - invalid mode\n");
R_Printf(PRINT_ALL, "ref_vk::R_SetMode() - invalid mode\n");
}
// try setting it back to something safe
if ((err = Vkimp_SetMode((int*)&vid.width, (int*)&vid.height, vk_state.prev_mode, false)) != rserr_ok)
{
ri.Con_Printf(PRINT_ALL, "ref_vk::R_SetMode() - could not revert to safe mode\n");
R_Printf(PRINT_ALL, "ref_vk::R_SetMode() - could not revert to safe mode\n");
return false;
}
}
@ -1146,24 +1187,19 @@ qboolean R_SetMode (void)
R_Init
===============
*/
qboolean R_Init( void *hinstance, void *hWnd )
qboolean R_Init( void )
{
ri.Con_Printf(PRINT_ALL, "ref_vk version: "REF_VERSION"\n");
R_Printf(PRINT_ALL, "ref_vk version: "REF_VERSION"\n");
R_Register();
// create the window (OS-specific)
if (!Vkimp_Init(hinstance, hWnd))
{
return false;
}
// set our "safe" modes
vk_state.prev_mode = 6;
// set video mode/screen resolution
if (!R_SetMode())
{
ri.Con_Printf(PRINT_ALL, "ref_vk::R_Init() - could not R_SetMode()\n");
R_Printf(PRINT_ALL, "ref_vk::R_Init() - could not R_SetMode()\n");
return false;
}
ri.Vid_MenuInit();
@ -1171,11 +1207,11 @@ qboolean R_Init( void *hinstance, void *hWnd )
// window is ready, initialize Vulkan now
if (!QVk_Init())
{
ri.Con_Printf(PRINT_ALL, "ref_vk::R_Init() - could not initialize Vulkan!\n");
R_Printf(PRINT_ALL, "ref_vk::R_Init() - could not initialize Vulkan!\n");
return false;
}
ri.Con_Printf(PRINT_ALL, "Successfully initialized Vulkan!\n");
R_Printf(PRINT_ALL, "Successfully initialized Vulkan!\n");
// print device information during startup
Vk_Strings_f();
@ -1210,12 +1246,17 @@ void R_Shutdown (void)
Vkimp_Shutdown();
}
/*
** Vkimp_BeginFrame
*/
void Vkimp_BeginFrame( float camera_seperation )
{
}
/*
@@@@@@@@@@@@@@@@@@@@@
=====================
R_BeginFrame
@@@@@@@@@@@@@@@@@@@@@
=====================
*/
void R_BeginFrame( float camera_separation )
{
@ -1250,17 +1291,6 @@ void R_BeginFrame( float camera_separation )
}
}
if (vk_log->modified)
{
Vkimp_EnableLogging(vk_log->value);
vk_log->modified = false;
}
if (vk_log->value)
{
Vkimp_LogNewFrame();
}
Vkimp_BeginFrame(camera_separation);
VkResult swapChainValid = QVk_BeginFrame();
@ -1275,12 +1305,17 @@ void R_BeginFrame( float camera_separation )
{
QVk_BeginRenderpass(RP_WORLD);
}
if (!r_worldmodel && !(r_newrefdef.rdflags & RDF_NOWORLDMODEL))
{
R_EndWorldRenderpass();
}
}
/*
@@@@@@@@@@@@@@@@@@@@@
=====================
R_EndFrame
@@@@@@@@@@@@@@@@@@@@@
=====================
*/
void R_EndFrame( void )
{
@ -1431,79 +1466,156 @@ void Draw_TileClear (int x, int y, int w, int h, char *name);
void Draw_Fill (int x, int y, int w, int h, int c);
void Draw_FadeScreen (void);
/*
@@@@@@@@@@@@@@@@@@@@@
GetRefAPI
static SDL_Window *window = NULL;
@@@@@@@@@@@@@@@@@@@@@
*/
refexport_t GetRefAPI (refimport_t rimp )
static int
R_InitContext(void *win)
{
refexport_t re;
char title[40] = {0};
ri = rimp;
if(win == NULL)
{
ri.Sys_Error(ERR_FATAL, "%s() must not be called with NULL argument!", __func__);
return false;
}
re.api_version = API_VERSION;
window = (SDL_Window *)win;
re.BeginRegistration = R_BeginRegistration;
re.RegisterModel = R_RegisterModel;
re.RegisterSkin = R_RegisterSkin;
re.RegisterPic = Draw_FindPic;
re.SetSky = R_SetSky;
re.EndRegistration = R_EndRegistration;
/* Window title - set here so we can display renderer name in it */
snprintf(title, sizeof(title), "Yamagi Quake II %s - Vulkan Render", YQ2VERSION);
SDL_SetWindowTitle(window, title);
re.RenderFrame = R_RenderFrame;
return true;
}
re.DrawGetPicSize = Draw_GetPicSize;
re.DrawPic = Draw_Pic;
re.DrawStretchPic = Draw_StretchPic;
re.DrawChar = Draw_Char;
re.DrawTileClear = Draw_TileClear;
re.DrawFill = Draw_Fill;
re.DrawFadeScreen= Draw_FadeScreen;
/*
** Vkimp_Shutdown
**
** This routine does all OS specific shutdown procedures for the Vulkan
** subsystem.
**
*/
void Vkimp_Shutdown( void )
{
window = NULL;
}
re.DrawStretchRaw = Draw_StretchRaw;
VkResult Vkimp_CreateSurface()
{
if (!SDL_Vulkan_CreateSurface(window, vk_instance, &vk_surface))
{
ri.Sys_Error(ERR_FATAL, "%s() SDL_Vulkan_CreateSurface failed", __func__);
return VK_ERROR_SURFACE_LOST_KHR;
}
return VK_SUCCESS;
}
re.Init = R_Init;
re.Shutdown = R_Shutdown;
static void
R_ShutdownContext(void)
{
}
re.CinematicSetPalette = R_SetPalette;
re.BeginFrame = R_BeginFrame;
re.EndFrame = R_EndFrame;
re.EndWorldRenderpass = R_EndWorldRenderpass;
static qboolean
R_IsVsyncActive(void)
{
if (r_vsync->value)
{
return true;
}
else
{
return false;
}
}
re.AppActivate = Vkimp_AppActivate;
static int R_PrepareForWindow(void)
{
return SDL_WINDOW_VULKAN;
}
/*
===============
GetRefAPI
===============
*/
Q2_DLL_EXPORTED refexport_t
GetRefAPI(refimport_t imp)
{
// struct for save refexport callbacks, copy of re struct from main file
// used different variable name for prevent confusion and cppcheck warnings
refexport_t refexport;
memset(&refexport, 0, sizeof(refexport_t));
ri = imp;
refexport.api_version = API_VERSION;
refexport.BeginRegistration = R_BeginRegistration;
refexport.RegisterModel = R_RegisterModel;
refexport.RegisterSkin = R_RegisterSkin;
refexport.DrawFindPic = Draw_FindPic;
refexport.SetSky = R_SetSky;
refexport.EndRegistration = R_EndRegistration;
refexport.RenderFrame = R_RenderFrame;
refexport.DrawGetPicSize = Draw_GetPicSize;
refexport.DrawPicScaled = Draw_PicScaled;
refexport.DrawStretchPic = Draw_StretchPic;
refexport.DrawCharScaled = Draw_CharScaled;
refexport.DrawTileClear = Draw_TileClear;
refexport.DrawFill = Draw_Fill;
refexport.DrawFadeScreen= Draw_FadeScreen;
refexport.DrawStretchRaw = Draw_StretchRaw;
refexport.Init = R_Init;
refexport.IsVSyncActive = R_IsVsyncActive;
refexport.Shutdown = R_Shutdown;
refexport.InitContext = R_InitContext;
refexport.ShutdownContext = R_ShutdownContext;
refexport.PrepareForWindow = R_PrepareForWindow;
refexport.SetPalette = R_SetPalette;
refexport.BeginFrame = R_BeginFrame;
refexport.EndFrame = R_EndFrame;
Swap_Init ();
return re;
return refexport;
}
#ifndef REF_HARD_LINKED
// this is only here so the functions in q_shared.c and q_shwin.c can link
void Sys_Error (char *error, ...)
void R_Printf(int level, const char* msg, ...)
{
va_list argptr;
va_start(argptr, msg);
ri.Com_VPrintf(level, msg, argptr);
va_end(argptr);
}
void
Sys_Error (char *error, ...)
{
va_list argptr;
char text[1024];
va_start (argptr, error);
vsnprintf (text, 1024, error, argptr);
vsprintf (text, error, argptr);
va_end (argptr);
ri.Sys_Error (ERR_FATAL, "%s", text);
}
void Com_Printf (char *fmt, ...)
void
Com_Printf (char *fmt, ...)
{
va_list argptr;
char text[1024];
va_start (argptr, fmt);
vsnprintf (text, 1024, fmt, argptr);
vsprintf (text, fmt, argptr);
va_end (argptr);
ri.Con_Printf (PRINT_ALL, "%s", text);
R_Printf(PRINT_ALL, "%s", text);
}
#endif

View file

@ -9,7 +9,7 @@ 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -76,78 +76,35 @@ void R_InitParticleTexture (void)
}
/*
==============================================================================
SCREEN SHOTS
==============================================================================
*/
/*
==============================================================================
typedef struct _TargaHeader {
unsigned char id_length, colormap_type, image_type;
unsigned short colormap_index, colormap_length;
unsigned char colormap_size;
unsigned short x_origin, y_origin, width, height;
unsigned char pixel_size, attributes;
} TargaHeader;
SCREEN SHOTS
==============================================================================
*/
/*
==================
/*
==================
Vk_ScreenShot_f
==================
*/
void Vk_ScreenShot_f (void)
==================
*/
void Vk_ScreenShot_f (void)
{
byte *buffer;
char picname[80];
char checkname[MAX_OSPATH];
int i, temp;
FILE *f;
size_t buffSize = vid.width * vid.height * 4 + 18;
// create the scrnshots directory if it doesn't exist
Com_sprintf(checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir());
Sys_Mkdir(checkname);
//
// find a file name to save it to
//
strcpy(picname, "quake00.tga");
for (i = 0; i <= 99; i++)
{
picname[5] = i / 10 + '0';
picname[6] = i % 10 + '0';
Com_sprintf(checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), picname);
f = fopen(checkname, "rb");
if (!f)
break; // file doesn't exist
fclose(f);
}
if (i == 100)
{
ri.Con_Printf(PRINT_ALL, "SCR_ScreenShot_f: Couldn't create a file\n");
return;
}
size_t buffSize = vid.width * vid.height * 4;
buffer = malloc(buffSize);
memset(buffer, 0, 18);
buffer[2] = 2; // uncompressed type
buffer[12] = vid.width & 255;
buffer[13] = vid.width >> 8;
buffer[14] = vid.height & 255;
buffer[15] = vid.height >> 8;
buffer[16] = 32; // pixel size
buffer[17] = 0x20; // image is upside-down
QVk_ReadPixels(buffer + 18, vid.width, vid.height);
QVk_ReadPixels(buffer, vid.width, vid.height);
// swap rgb to bgr
if (vk_swapchain.format == VK_FORMAT_R8G8B8A8_UNORM || vk_swapchain.format == VK_FORMAT_R8G8B8A8_SRGB)
{
for (i = 18; i < buffSize; i += 4)
for (i = 0; i < buffSize; i += 4)
{
temp = buffer[i];
buffer[i] = buffer[i + 2];
@ -157,19 +114,16 @@ void Vk_ScreenShot_f (void)
}
else
{
for (i = 18; i < buffSize; i += 4)
for (i = 0; i < buffSize; i += 4)
{
buffer[i + 3] = 255;
}
}
f = fopen(checkname, "wb");
fwrite(buffer, 1, buffSize, f);
fclose(f);
ri.Vid_WriteScreenshot(vid.width, vid.height, 3, buffer);
free(buffer);
ri.Con_Printf(PRINT_ALL, "Wrote %s\n", picname);
}
}
/*
** Vk_Strings_f
@ -209,67 +163,67 @@ void Vk_Strings_f(void)
if (preferredDevice >= numDevices) preferredDevice = -1;
ri.Con_Printf(PRINT_ALL, "\n%s\n", ver);
ri.Con_Printf(PRINT_ALL, "------------------------------------\n");
ri.Con_Printf(PRINT_ALL, "Vulkan API: %d.%d\n", VK_VERSION_MAJOR(vk_config.vk_version),
R_Printf(PRINT_ALL, "\n%s\n", ver);
R_Printf(PRINT_ALL, "------------------------------------\n");
R_Printf(PRINT_ALL, "Vulkan API: %d.%d\n", VK_VERSION_MAJOR(vk_config.vk_version),
VK_VERSION_MINOR(vk_config.vk_version));
ri.Con_Printf(PRINT_ALL, "Header version: %d\n", VK_HEADER_VERSION);
ri.Con_Printf(PRINT_ALL, "Devices found:\n");
R_Printf(PRINT_ALL, "Header version: %d\n", VK_HEADER_VERSION);
R_Printf(PRINT_ALL, "Devices found:\n");
for (i = 0; i < numDevices; ++i)
{
vkGetPhysicalDeviceProperties(physicalDevices[i], &deviceProperties);
isPreferred = (preferredDevice == i) || (preferredDevice < 0 && deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
if (isPreferred) usedDevice = i;
ri.Con_Printf(PRINT_ALL, "%s#%d: %s\n", isPreferred && numDevices > 1 ? "* " : " ", i, deviceProperties.deviceName);
R_Printf(PRINT_ALL, "%s#%d: %s\n", isPreferred && numDevices > 1 ? "* " : " ", i, deviceProperties.deviceName);
}
ri.Con_Printf(PRINT_ALL, "Using device #%d:\n", usedDevice);
ri.Con_Printf(PRINT_ALL, " deviceName: %s\n", vk_device.properties.deviceName);
ri.Con_Printf(PRINT_ALL, " resolution: %dx%d", vid.width, vid.height);
R_Printf(PRINT_ALL, "Using device #%d:\n", usedDevice);
R_Printf(PRINT_ALL, " deviceName: %s\n", vk_device.properties.deviceName);
R_Printf(PRINT_ALL, " resolution: %dx%d", vid.width, vid.height);
if (msaa > 0)
ri.Con_Printf(PRINT_ALL, " (MSAAx%d)\n", 2 << (msaa - 1));
R_Printf(PRINT_ALL, " (MSAAx%d)\n", 2 << (msaa - 1));
else
ri.Con_Printf(PRINT_ALL, "\n");
R_Printf(PRINT_ALL, "\n");
#ifndef __linux__
// Intel on Windows and MacOS (Linux uses semver for Mesa drivers)
if (vk_device.properties.vendorID == 0x8086)
ri.Con_Printf(PRINT_ALL, " driverVersion: %d (0x%X)\n", vk_device.properties.driverVersion, vk_device.properties.driverVersion);
R_Printf(PRINT_ALL, " driverVersion: %d (0x%X)\n", vk_device.properties.driverVersion, vk_device.properties.driverVersion);
else
#endif
ri.Con_Printf(PRINT_ALL, " driverVersion: %d.%d.%d (0x%X)\n", driverMajor, driverMinor, driverPatch, vk_device.properties.driverVersion);
R_Printf(PRINT_ALL, " driverVersion: %d.%d.%d (0x%X)\n", driverMajor, driverMinor, driverPatch, vk_device.properties.driverVersion);
ri.Con_Printf(PRINT_ALL, " apiVersion: %d.%d.%d\n", VK_VERSION_MAJOR(vk_device.properties.apiVersion),
R_Printf(PRINT_ALL, " apiVersion: %d.%d.%d\n", VK_VERSION_MAJOR(vk_device.properties.apiVersion),
VK_VERSION_MINOR(vk_device.properties.apiVersion),
VK_VERSION_PATCH(vk_device.properties.apiVersion));
ri.Con_Printf(PRINT_ALL, " deviceID: %d\n", vk_device.properties.deviceID);
ri.Con_Printf(PRINT_ALL, " vendorID: 0x%X (%s)\n", vk_device.properties.vendorID, vk_config.vendor_name);
ri.Con_Printf(PRINT_ALL, " deviceType: %s\n", vk_config.device_type);
ri.Con_Printf(PRINT_ALL, " gfx/present/transfer: %d/%d/%d\n", vk_device.gfxFamilyIndex,
R_Printf(PRINT_ALL, " deviceID: %d\n", vk_device.properties.deviceID);
R_Printf(PRINT_ALL, " vendorID: 0x%X (%s)\n", vk_device.properties.vendorID, vk_config.vendor_name);
R_Printf(PRINT_ALL, " deviceType: %s\n", vk_config.device_type);
R_Printf(PRINT_ALL, " gfx/present/transfer: %d/%d/%d\n", vk_device.gfxFamilyIndex,
vk_device.presentFamilyIndex,
vk_device.transferFamilyIndex);
ri.Con_Printf(PRINT_ALL, "Present mode: %s\n", vk_config.present_mode);
ri.Con_Printf(PRINT_ALL, "Swapchain image format: %d\n", vk_swapchain.format);
ri.Con_Printf(PRINT_ALL, "Supported present modes: ");
R_Printf(PRINT_ALL, "Present mode: %s\n", vk_config.present_mode);
R_Printf(PRINT_ALL, "Swapchain image format: %d\n", vk_swapchain.format);
R_Printf(PRINT_ALL, "Supported present modes: ");
i = 0;
while(vk_config.supported_present_modes[i])
{
ri.Con_Printf(PRINT_ALL, "%s ", vk_config.supported_present_modes[i++]);
R_Printf(PRINT_ALL, "%s ", vk_config.supported_present_modes[i++]);
}
ri.Con_Printf(PRINT_ALL, "\nEnabled extensions: ");
R_Printf(PRINT_ALL, "\nEnabled extensions: ");
i = 0;
while(vk_config.extensions[i])
{
ri.Con_Printf(PRINT_ALL, "%s ", vk_config.extensions[i++]);
R_Printf(PRINT_ALL, "%s ", vk_config.extensions[i++]);
}
ri.Con_Printf(PRINT_ALL, "\nEnabled layers: ");
R_Printf(PRINT_ALL, "\nEnabled layers: ");
i = 0;
while(vk_config.layers[i])
{
ri.Con_Printf(PRINT_ALL, "%s ", vk_config.layers[i++]);
R_Printf(PRINT_ALL, "%s ", vk_config.layers[i++]);
}
ri.Con_Printf(PRINT_ALL, "\n");
R_Printf(PRINT_ALL, "\n");
}
/*
@ -277,20 +231,20 @@ void Vk_Strings_f(void)
*/
void Vk_Mem_f(void)
{
ri.Con_Printf(PRINT_ALL, "\nDynamic buffer stats: \n");
ri.Con_Printf(PRINT_ALL, "Vertex : %u/%ukB (%.1f%% max: %ukB)\n", vk_config.vertex_buffer_usage / 1024,
R_Printf(PRINT_ALL, "\nDynamic buffer stats: \n");
R_Printf(PRINT_ALL, "Vertex : %u/%ukB (%.1f%% max: %ukB)\n", vk_config.vertex_buffer_usage / 1024,
vk_config.vertex_buffer_size / 1024,
100.f * vk_config.vertex_buffer_usage / vk_config.vertex_buffer_size,
vk_config.vertex_buffer_max_usage / 1024);
ri.Con_Printf(PRINT_ALL, "Index : %u/%uB (%.1f%% max: %uB)\n", vk_config.index_buffer_usage,
R_Printf(PRINT_ALL, "Index : %u/%uB (%.1f%% max: %uB)\n", vk_config.index_buffer_usage,
vk_config.index_buffer_size,
100.f * vk_config.index_buffer_usage / vk_config.index_buffer_size,
vk_config.index_buffer_max_usage);
ri.Con_Printf(PRINT_ALL, "Uniform: %u/%ukB (%.1f%% max: %ukB)\n", vk_config.uniform_buffer_usage / 1024,
R_Printf(PRINT_ALL, "Uniform: %u/%ukB (%.1f%% max: %ukB)\n", vk_config.uniform_buffer_usage / 1024,
vk_config.uniform_buffer_size / 1024,
100.f * vk_config.uniform_buffer_usage / vk_config.uniform_buffer_size,
vk_config.uniform_buffer_max_usage / 1024);
ri.Con_Printf(PRINT_ALL, "Tri fan: %u/%u (%.1f%% max: %u)\n", vk_config.triangle_fan_index_usage,
R_Printf(PRINT_ALL, "Tri fan: %u/%u (%.1f%% max: %u)\n", vk_config.triangle_fan_index_usage,
vk_config.triangle_fan_index_count,
100.f * vk_config.triangle_fan_index_usage / vk_config.triangle_fan_index_count,
vk_config.triangle_fan_index_max_usage);

View file

@ -68,7 +68,7 @@ static VkPresentModeKHR getSwapPresentMode(const VkPresentModeKHR *presentModes,
if (presentModes[i] == desiredMode)
{
vk_config.present_mode = presentModeString(desiredMode);
ri.Con_Printf(PRINT_ALL, "...using present mode: %s\n", vk_config.present_mode);
R_Printf(PRINT_ALL, "...using present mode: %s\n", vk_config.present_mode);
return desiredMode;
}
}
@ -91,7 +91,7 @@ static VkPresentModeKHR getSwapPresentMode(const VkPresentModeKHR *presentModes,
}
vk_config.present_mode = presentModeString(usedPresentMode);
ri.Con_Printf(PRINT_ALL, "...present mode %s not supported, using present mode: %s\n", presentModeString(desiredMode), vk_config.present_mode);
R_Printf(PRINT_ALL, "...present mode %s not supported, using present mode: %s\n", presentModeString(desiredMode), vk_config.present_mode);
return usedPresentMode;
}
@ -135,13 +135,13 @@ VkResult QVk_CreateSwapchain()
presentModes = (VkPresentModeKHR *)malloc(presentModesCount * sizeof(VkPresentModeKHR));
VK_VERIFY(vkGetPhysicalDeviceSurfacePresentModesKHR(vk_device.physical, vk_surface, &presentModesCount, presentModes));
ri.Con_Printf(PRINT_ALL, "Supported present modes: ");
R_Printf(PRINT_ALL, "Supported present modes: ");
for (int i = 0; i < presentModesCount; i++)
{
ri.Con_Printf(PRINT_ALL, "%s ", presentModeString(presentModes[i]));
R_Printf(PRINT_ALL, "%s ", presentModeString(presentModes[i]));
vk_config.supported_present_modes[i] = presentModeString(presentModes[i]);
}
ri.Con_Printf(PRINT_ALL, "\n");
R_Printf(PRINT_ALL, "\n");
}
VkSurfaceFormatKHR swapSurfaceFormat = getSwapSurfaceFormat(surfaceFormats, formatCount);
@ -196,8 +196,8 @@ VkResult QVk_CreateSwapchain()
vk_swapchain.format = swapSurfaceFormat.format;
vk_swapchain.extent = extent;
ri.Con_Printf(PRINT_ALL, "...trying swapchain extent: %dx%d\n", vk_swapchain.extent.width, vk_swapchain.extent.height);
ri.Con_Printf(PRINT_ALL, "...trying swapchain image format: %d\n", vk_swapchain.format);
R_Printf(PRINT_ALL, "...trying swapchain extent: %dx%d\n", vk_swapchain.extent.width, vk_swapchain.extent.height);
R_Printf(PRINT_ALL, "...trying swapchain image format: %d\n", vk_swapchain.format);
VkResult res = vkCreateSwapchainKHR(vk_device.logical, &scCreateInfo, NULL, &vk_swapchain.sc);
if (res != VK_SUCCESS)

View file

@ -21,11 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "vk_local.h"
static VkDebugUtilsMessengerEXT validationMessenger = VK_NULL_HANDLE;
extern FILE *vk_logfp;
#define VK_FILELOG(msg, ...) if(vk_log->value && vk_logfp) { \
fprintf(vk_logfp, msg, __VA_ARGS__); \
}
// layer message to string
static const char* msgToString(VkDebugUtilsMessageTypeFlagsEXT type)
@ -51,21 +46,17 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsCallback(VkDebugUtilsMessageSeve
switch (msgSeverity)
{
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
ri.Con_Printf(PRINT_ALL, "VK_INFO: %s %s\n", callbackData->pMessage, msgToString(msgType));
VK_FILELOG("VK_INFO: %s %s\n", callbackData->pMessage, msgToString(msgType));
R_Printf(PRINT_ALL, "VK_INFO: %s %s\n", callbackData->pMessage, msgToString(msgType));
break;
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
ri.Con_Printf(PRINT_ALL, "VK_VERBOSE: %s %s\n", callbackData->pMessage, msgToString(msgType));
VK_FILELOG("VK_VERBOSE: %s %s\n", callbackData->pMessage, msgToString(msgType));
R_Printf(PRINT_ALL, "VK_VERBOSE: %s %s\n", callbackData->pMessage, msgToString(msgType));
break;
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
ri.Con_Printf(PRINT_ALL, "VK_WARNING: %s %s\n", callbackData->pMessage, msgToString(msgType));
VK_FILELOG("VK_WARNING: %s %s\n", callbackData->pMessage, msgToString(msgType));
R_Printf(PRINT_ALL, "VK_WARNING: %s %s\n", callbackData->pMessage, msgToString(msgType));
assert(!"Vulkan warning occured!");
break;
default:
ri.Con_Printf(PRINT_ALL, "VK_ERROR: %s %s\n", callbackData->pMessage, msgToString(msgType));
VK_FILELOG("VK_ERROR: %s %s\n", callbackData->pMessage, msgToString(msgType));
R_Printf(PRINT_ALL, "VK_ERROR: %s %s\n", callbackData->pMessage, msgToString(msgType));
assert(!"Vulkan error occured!");
}
return VK_FALSE;
@ -93,7 +84,7 @@ void QVk_CreateValidationLayers()
}
VK_VERIFY(qvkCreateDebugUtilsMessengerEXT(vk_instance, &callbackInfo, NULL, &validationMessenger));
ri.Con_Printf(PRINT_ALL, "...Vulkan validation layers enabled\n");
R_Printf(PRINT_ALL, "...Vulkan validation layers enabled\n");
}
void QVk_DestroyValidationLayers()

View file

@ -31,7 +31,6 @@ image_t *sky_images[6];
msurface_t *warpface;
#define SUBDIVIDE_SIZE 64
//#define SUBDIVIDE_SIZE 1024
void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
{

View file

@ -239,6 +239,9 @@ static qboolean checkForHelp(int argc, char **argv)
printf(" 'gl1' (the OpenGL 1.x renderer),\n");
printf(" 'gl3' (the OpenGL 3.2 renderer),\n");
printf(" 'soft' (the software renderer)\n");
#ifdef USE_REFVK
printf(" 'vulkan' (the experimental Vulkan renderer)\n");
#endif
#endif // DEDICATED_ONLY
printf("\nSee https://github.com/yquake2/yquake2/blob/master/doc/04_cvarlist.md\nfor some more cvars\n");