quakeforge/libs/video/renderer/vulkan/vulkan_vid_common.c
Bill Currie 8f1de6865f [vulkan] Get fisheye working except for translucency
The OIT heads buffer is only a single-layer image, which breaks cube
map rendering, but once this is sorted, it looks like fisheye will work
well.
2023-06-26 14:03:19 +09:00

218 lines
5.8 KiB
C

/*
vid_common_vulkan.c
Common Vulkan video driver functions
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
#include <string.h>
#include "QF/cexpr.h"
#include "QF/cmem.h"
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/heapsort.h"
#include "QF/plist.h"
#include "QF/va.h"
#include "QF/scene/entity.h"
#include "QF/Vulkan/capture.h"
#include "QF/Vulkan/command.h"
#include "QF/Vulkan/debug.h"
#include "QF/Vulkan/device.h"
#include "QF/Vulkan/instance.h"
#include "QF/Vulkan/staging.h"
#include "QF/Vulkan/swapchain.h"
#include "QF/Vulkan/qf_lighting.h"
#include "QF/Vulkan/qf_main.h"
#include "QF/Vulkan/qf_output.h"
#include "QF/Vulkan/qf_particles.h"
#include "QF/Vulkan/qf_translucent.h"
#include "QF/Vulkan/qf_vid.h"
#include "r_internal.h"
#include "vid_vulkan.h"
#include "vkparse.h"
int vulkan_frame_width;
static cvar_t vulkan_frame_width_cvar = {
.name = "vulkan_frame_width",
.description =
"Width of 3D view buffer. Set to 0 for automatic sizing.",
.default_value = "0",
.flags = CVAR_NONE,
.value = { .type = &cexpr_int, .value = &vulkan_frame_width },
};
int vulkan_frame_height;
static cvar_t vulkan_frame_height_cvar = {
.name = "vulkan_frame_height",
.description =
"Height of 3D view buffer. Set to 0 for automatic sizing.",
.default_value = "0",
.flags = CVAR_NONE,
.value = { .type = &cexpr_int, .value = &vulkan_frame_height },
};
int vulkan_oit_fragments;
static cvar_t vulkan_oit_fragments_cvar = {
.name = "vulkan_oit_fragments",
.description =
"Size of fragment buffer (M) for order independent transparency.",
.default_value = "16",
.flags = CVAR_ROM,
.value = { .type = &cexpr_int, .value = &vulkan_oit_fragments },
};
static const char *instance_extensions[] = {
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
0,
};
static const char *device_extensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
0,
};
void
Vulkan_Init_Common (vulkan_ctx_t *ctx)
{
Sys_MaskPrintf (SYS_vulkan, "Vulkan_Init_Common\n");
Cvar_Register (&vulkan_frame_width_cvar, 0, 0);
Cvar_Register (&vulkan_frame_height_cvar, 0, 0);
Cvar_Register (&vulkan_oit_fragments_cvar, 0, 0);
Vulkan_Init_Cvars ();
R_Init_Cvars ();
Vulkan_Script_Init (ctx);
ctx->instance = QFV_CreateInstance (ctx, PACKAGE_STRING, 0x000702ff, 0,
instance_extensions);//FIXME version
DARRAY_INIT (&ctx->renderPasses, 4);
}
void
Vulkan_Shutdown_Common (vulkan_ctx_t *ctx)
{
if (ctx->swapchain) {
QFV_DestroySwapchain (ctx->swapchain);
}
ctx->instance->funcs->vkDestroySurfaceKHR (ctx->instance->instance,
ctx->surface, 0);
Vulkan_Script_Shutdown (ctx);
if (ctx->device) {
QFV_DestroyDevice (ctx->device);
}
if (ctx->instance) {
QFV_DestroyInstance (ctx->instance);
}
ctx->instance = 0;
ctx->unload_vulkan (ctx);
}
void
Vulkan_CreateDevice (vulkan_ctx_t *ctx)
{
ctx->device = QFV_CreateDevice (ctx, device_extensions);
//FIXME msaa and deferred rendering...
//also, location
ctx->msaaSamples = 1;
/*ctx->msaaSamples = min ((VkSampleCountFlagBits) msaaSamples,
QFV_GetMaxSampleCount (device->physDev));
if (ctx->msaaSamples > 1) {
name = "renderpass_msaa";
}*/
}
void
Vulkan_CreateStagingBuffers (vulkan_ctx_t *ctx)
{
// FIXME configurable?
ctx->staging = QFV_CreateStagingBuffer (ctx->device, "vulkan_ctx",
32*1024*1024, ctx->cmdpool);
}
void
Vulkan_CreateSwapchain (vulkan_ctx_t *ctx)
{
VkSwapchainKHR old_swapchain = 0;
if (ctx->swapchain) {
//FIXME this shouldn't be here
qfv_device_t *device = ctx->swapchain->device;
VkDevice dev = device->dev;
qfv_devfuncs_t *dfunc = device->funcs;
old_swapchain = ctx->swapchain->swapchain;
for (size_t i = 0; i < ctx->swapchain->imageViews->size; i++) {
dfunc->vkDestroyImageView(dev, ctx->swapchain->imageViews->a[i], 0);
}
free (ctx->swapchain->images);
free (ctx->swapchain->imageViews);
free (ctx->swapchain);
}
ctx->swapchain = QFV_CreateSwapchain (ctx, old_swapchain);
}
void
Vulkan_BeginEntityLabel (vulkan_ctx_t *ctx, VkCommandBuffer cmd, entity_t ent)
{
qfv_device_t *device = ctx->device;
uint32_t entgen = Ent_Generation (ent.id);
uint32_t entind = Ent_Index (ent.id);
transform_t transform = Entity_Transform (ent);
vec4f_t pos = Transform_GetWorldPosition (transform);
vec4f_t dir = normalf (pos - (vec4f_t) { 0, 0, 0, 1 });
vec4f_t color = 0.5 * dir + (vec4f_t) {0.5, 0.5, 0.5, 1 };
QFV_CmdBeginLabel (device, cmd,
va (ctx->va_ctx, "ent %03x.%05x [%g, %g, %g]",
entgen, entind, VectorExpand (pos)), color);
}
void
Vulkan_ConfigOutput (vulkan_ctx_t *ctx, qfv_output_t *output)
{
*output = (qfv_output_t) {
.extent = ctx->swapchain->extent,
.frames = ctx->swapchain->numImages,
};
if (vulkan_frame_width > 0) {
output->extent.width = vulkan_frame_width;
}
if (vulkan_frame_height > 0) {
output->extent.height = vulkan_frame_height;
}
if (scr_fisheye) {//FIXME
auto w = output->extent.width;
auto h = output->extent.height;
output->extent.width = min (w, h);
output->extent.height = min (w, h);
}
}