Fix up some vulkan+openxr issues.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6123 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-11-14 00:35:08 +00:00
parent 99f20e7b80
commit d332496ed4
7 changed files with 108 additions and 30 deletions

View file

@ -1113,16 +1113,27 @@ qboolean R_RegisterRenderer(void *module, rendererinfo_t *ri)
}
static plugvrfuncs_t *vrfuncs;
static void *vrmodule;
qboolean R_RegisterVRDriver(void *module, plugvrfuncs_t *vr)
{
if (!vrfuncs)
if (!vr)
{
vrfuncs = vr;
return true;
if (vrmodule == module)
{
vrfuncs = NULL;
vrmodule = NULL;
}
return false;
}
Sys_Printf("unable to register renderer %s\n", vr->description);
return false;
if (vrfuncs && vrfuncs!=vr)
{
Con_Printf("unable to register renderer %s (%s already registered)\n", vr->description, vrfuncs->description);
return false;
}
vrfuncs = vr;
vrmodule = module;
return true;
}

View file

@ -1538,6 +1538,7 @@ void Plug_Close(plugin_t *plug)
#endif
#ifdef HAVE_CLIENT
S_UnregisterSoundInputModule(plug);
R_RegisterVRDriver(plug, NULL);
Image_RegisterLoader(plug, NULL);
Material_RegisterLoader(plug, NULL);
#endif

View file

@ -24,6 +24,8 @@
SDL_Surface *sdlsurf;
#endif
#include "vr.h"
extern cvar_t vid_vsync;
extern cvar_t vid_hardwaregamma;
extern cvar_t gl_lateswap;
@ -318,12 +320,20 @@ static qboolean SDLVID_Init (rendererstate_t *info, unsigned char *palette, r_qr
SDL_SetVideoMode(0, 0, 0, 0); //to get around some SDL bugs
#endif
#ifdef OPENGL_SDL
if (qrenderer == QR_OPENGL)
{
#if SDL_MAJOR_VERSION >= 2
switch(qrenderer)
{
default:
return false;
#ifdef OPENGL_SDL
case QR_OPENGL:
if (info->vr)
Con_Printf(CON_ERROR"%s support is not available with SDL-OpenGL\n", info->vr->description);
info->vr = NULL;
#if SDL_MAJOR_VERSION >= 2
SDL_GL_LoadLibrary(NULL);
#endif
#endif
if (info->bpp >= 32)
{
@ -347,7 +357,7 @@ static qboolean SDLVID_Init (rendererstate_t *info, unsigned char *palette, r_qr
if (info->stereo)
SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
#if SDL_MAJOR_VERSION >= 2
#if SDL_MAJOR_VERSION >= 2
if (info->srgb)
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
@ -379,27 +389,18 @@ static qboolean SDLVID_Init (rendererstate_t *info, unsigned char *palette, r_qr
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
#endif
#endif
if (info->multisample)
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, info->multisample);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
}
}
#endif
#if SDL_MAJOR_VERSION >= 2
switch(qrenderer)
{
default:
break;
#ifdef OPENGL_SDL
case QR_OPENGL:
flags |= SDL_WINDOW_OPENGL;
break;
#endif
#ifdef VULKAN_SDL
case QR_VULKAN:
case QR_VULKAN:
flags |= SDL_WINDOW_VULKAN;
break;
#endif
@ -591,6 +592,7 @@ void GLVID_DeInit (void)
#endif
#ifdef VULKAN_SDL
case QR_VULKAN:
VK_Shutdown();
break;
#endif
default:

View file

@ -8,6 +8,7 @@
//FIXME: instead of switching rendertargets and back, we should be using an alternative queue.
#define PERMUTATION_BEM_VR (1u<<11)
#define PERMUTATION_BEM_FP16 (1u<<12)
#define PERMUTATION_BEM_MULTISAMPLE (1u<<13)
#define PERMUTATION_BEM_DEPTHONLY (1u<<14)
@ -2501,6 +2502,8 @@ static void BE_CreatePipeline(program_t *p, unsigned int shaderflags, unsigned i
i |= RP_MULTISAMPLE;
if (permu&PERMUTATION_BEM_FP16)
i |= RP_FP16;
if (permu&PERMUTATION_BEM_VR)
i |= RP_VR;
pipeCreateInfo.renderPass = VK_GetRenderPass(i);
pipeCreateInfo.subpass = 0;
pipeCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
@ -3217,6 +3220,8 @@ void VKBE_SelectMode(backendmode_t mode)
shaderstate.modepermutation |= PERMUTATION_BEM_MULTISAMPLE;
if (vk.rendertarg->rpassflags & RP_FP16)
shaderstate.modepermutation |= PERMUTATION_BEM_FP16;
if (vk.rendertarg->rpassflags & RP_VR)
shaderstate.modepermutation |= PERMUTATION_BEM_VR;
switch(mode)
{
@ -4170,7 +4175,7 @@ void VKBE_RT_Gen(struct vk_rendertarg *targ, vk_image_t *colour, uint32_t width,
}
}
if (targ->framebuffer)
if (targ->framebuffer || targ->externalimage)
{ //schedule the old one to be destroyed at the end of the current frame. DIE OLD ONE, DIE!
purge = VK_AtFrameEnd(VKBE_RT_Purge, NULL, sizeof(*purge));
purge->framebuffer = targ->framebuffer;
@ -4201,10 +4206,22 @@ void VKBE_RT_Gen(struct vk_rendertarg *targ, vk_image_t *colour, uint32_t width,
targ->restartinfo.renderPass = VK_NULL_HANDLE;
return; //destroyed
}
targ->restartinfo.renderPass = VK_GetRenderPass(RP_FULLCLEAR|targ->rpassflags);
if (targ->externalimage)
{
VkFormat old = vk.backbufformat;
colour_imginfo.format = vk.backbufformat = colour->vkformat;
targ->rpassflags |= RP_VR;
targ->restartinfo.renderPass = VK_GetRenderPass(RP_FULLCLEAR|targ->rpassflags);
//colour buffer is always 1 sample. if multisampling then we have a hidden 'mscolour' image that is paired with the depth, resolvnig to the 'colour' image.
colour_imginfo.format = (targ->rpassflags&RP_FP16)?VK_FORMAT_R16G16B16A16_SFLOAT:vk.backbufformat;
vk.backbufformat = old;
}
else
{
targ->rpassflags &= ~RP_VR;
targ->restartinfo.renderPass = VK_GetRenderPass(RP_FULLCLEAR|targ->rpassflags);
colour_imginfo.format = (targ->rpassflags&RP_FP16)?VK_FORMAT_R16G16B16A16_SFLOAT:vk.backbufformat;
}
colour_imginfo.flags = 0;
colour_imginfo.imageType = VK_IMAGE_TYPE_2D;
colour_imginfo.extent.width = width;
@ -4212,6 +4229,7 @@ void VKBE_RT_Gen(struct vk_rendertarg *targ, vk_image_t *colour, uint32_t width,
colour_imginfo.extent.depth = 1;
colour_imginfo.mipLevels = 1;
colour_imginfo.arrayLayers = 1;
//colour buffer is always 1 sample. if multisampling then we have a hidden 'mscolour' image that is paired with the depth, resolving to the 'colour' image.
colour_imginfo.samples = VK_SAMPLE_COUNT_1_BIT;
colour_imginfo.tiling = VK_IMAGE_TILING_OPTIMAL;
colour_imginfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT;
@ -4220,7 +4238,9 @@ void VKBE_RT_Gen(struct vk_rendertarg *targ, vk_image_t *colour, uint32_t width,
colour_imginfo.pQueueFamilyIndices = NULL;
colour_imginfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
if (targ->externalimage)
{
targ->colour.image = colour->image;
}
else
{
VkAssert(vkCreateImage(vk.device, &colour_imginfo, vkallocationcb, &targ->colour.image));
@ -4296,10 +4316,10 @@ void VKBE_RT_Gen(struct vk_rendertarg *targ, vk_image_t *colour, uint32_t width,
lmsampinfo.unnormalizedCoordinates = VK_FALSE;
lmsampinfo.compareEnable = VK_FALSE;
VkAssert(vkCreateSampler(vk.device, &lmsampinfo, NULL, &targ->colour.sampler));
VK_CreateSamplerInfo(&lmsampinfo, &targ->colour);
lmsampinfo.compareEnable = VK_TRUE;
VkAssert(vkCreateSampler(vk.device, &lmsampinfo, NULL, &targ->depth.sampler));
VK_CreateSamplerInfo(&lmsampinfo, &targ->depth);
}
targ->colour.layout = VK_IMAGE_LAYOUT_UNDEFINED;
@ -5710,7 +5730,7 @@ void VKBE_BeginShadowmapFace(void)
vkCmdSetScissor(vk.rendertarg->cbuf, 0, 1, &wrekt);
//shadowmaps never multisample...
shaderstate.modepermutation &= ~(PERMUTATION_BEM_MULTISAMPLE|PERMUTATION_BEM_FP16);
shaderstate.modepermutation &= ~(PERMUTATION_BEM_MULTISAMPLE|PERMUTATION_BEM_FP16|PERMUTATION_BEM_VR);
}
#endif

View file

@ -1177,6 +1177,35 @@ static void VK_DestroySampler_FrameEnd(void *w)
VK_DestroySampler(*(VkSampler*)w);
}
void VK_CreateSamplerInfo(VkSamplerCreateInfo *info, vk_image_t *img)
{
unsigned int flags = IF_RENDERTARGET;
struct vksamplers_s *ref;
if (img->sampler)
VK_DestroySampler(img->sampler);
for (ref = vk.samplers; ref; ref = ref->next)
if (ref->flags == flags)
if (!memcmp(&ref->props, info, sizeof(*info)))
break;
if (!ref)
{
ref = Z_Malloc(sizeof(*ref));
ref->flags = flags;
ref->props = *info;
ref->next = vk.samplers;
ref->link = &vk.samplers;
if (vk.samplers)
vk.samplers->link = &ref->next;
vk.samplers = ref;
VkAssert(vkCreateSampler(vk.device, &ref->props, NULL, &ref->samp));
}
ref->usages++;
img->sampler = ref->samp;
}
void VK_CreateSampler(unsigned int flags, vk_image_t *img)
{
struct vksamplers_s *ref;
@ -2726,6 +2755,7 @@ void VK_R_RenderEye(texid_t image, vec4_t fovoverride, vec3_t eyeangorg[2])
VK_SetupViewPortProjection(false);
rt = &postproc[postproc_buf++%countof(postproc)];
rt->rpassflags |= RP_VR;
VKBE_RT_Gen(rt, image?image->vkimage:NULL, 320, 200, false, RT_IMAGEFLAGS);
VKBE_RT_Begin(rt);
@ -2763,6 +2793,7 @@ void VK_R_RenderEye(texid_t image, vec4_t fovoverride, vec3_t eyeangorg[2])
vk.rendertarg->depthcleared = false;
VKBE_RT_End(rt);
rt->rpassflags &= ~RP_VR;
}
void VK_R_RenderView (void)
@ -3995,7 +4026,12 @@ VkRenderPass VK_GetRenderPass(int pass)
if (color_reference.attachment != ~(uint32_t)0)
{
attachments[color_reference.attachment].format = (pass&RP_FP16)?VK_FORMAT_R16G16B16A16_SFLOAT:vk.backbufformat;
if (pass&RP_FP16)
attachments[color_reference.attachment].format = VK_FORMAT_R16G16B16A16_SFLOAT;
else if (pass&RP_VR)
attachments[color_reference.attachment].format = vk.backbufformat; //FIXME
else
attachments[color_reference.attachment].format = vk.backbufformat;
attachments[color_reference.attachment].samples = (pass & RP_MULTISAMPLE)?vk.multisamplebits:VK_SAMPLE_COUNT_1_BIT;
// attachments[color_reference.attachment].loadOp = pass?VK_ATTACHMENT_LOAD_OP_LOAD:VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[color_reference.attachment].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@ -5367,6 +5403,7 @@ void VK_Shutdown(void)
Z_Free(ptr);
}
vkDestroyPipelineCache(vk.device, vk.pipelinecache, vkallocationcb);
vk.pipelinecache = VK_NULL_HANDLE;
}
while(vk.mempools)

View file

@ -219,6 +219,7 @@ typedef struct vk_image_s
VkSampler sampler;
VkImageLayout layout;
VkFormat vkformat;
uint32_t width;
uint32_t height;
uint32_t layers;
@ -383,7 +384,8 @@ extern struct vulkaninfo_s
#define RP_MULTISAMPLE (1u<<2)
#define RP_PRESENTABLE (1u<<3)
#define RP_FP16 (1u<<4)
VkRenderPass renderpass[1u<<5];
#define RP_VR (1u<<5) //potentially a different colour format.
VkRenderPass renderpass[1u<<6];
VkSwapchainKHR swapchain;
uint32_t bufferidx;
@ -517,6 +519,7 @@ struct stagingbuf
vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t layers, uint32_t mips, uploadfmt_t encoding, unsigned int type, qboolean rendertarget, const char *debugname);
void set_image_layout(VkCommandBuffer cmd, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout, VkAccessFlags srcaccess, VkPipelineStageFlagBits srcstagemask, VkImageLayout new_image_layout, VkAccessFlags dstaccess, VkPipelineStageFlagBits dststagemask);
void VK_CreateSampler(unsigned int flags, vk_image_t *img);
void VK_CreateSamplerInfo(VkSamplerCreateInfo *info, vk_image_t *img);
void *VKBE_CreateStagingBuffer(struct stagingbuf *n, size_t size, VkBufferUsageFlags usage);
VkBuffer VKBE_FinishStaging(struct stagingbuf *n, vk_poolmem_t *memptr);
void *VK_FencedBegin(void (*passed)(void *work), size_t worksize);

View file

@ -240,6 +240,7 @@ static struct
XrFrameState framestate;
qboolean needrender; //we MUST call xrBegin before the next xrWait
int srgb; //<0 = gamma-only. 0 = no srgb at all, >0 full srgb, including textures and stuff
int colourformat;
unsigned int numactions;
struct
@ -1346,6 +1347,7 @@ static qboolean XR_Begin(void)
for (u = 0; u < swapfmts; u++) switch(fmts[u])
{
case VK_FORMAT_R16G16B16A16_SFLOAT: Con_DPrintf("OpenXr fmt%u: %s\n", u, "VK_FORMAT_R16G16B16A16_SFLOAT"); if (xr.srgb) fmttouse = fmts[u],u=swapfmts; break;
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:Con_DPrintf("OpenXr fmt%u: %s\n", u, "VK_FORMAT_A2B10G10R10_UNORM_PACK32"); if (!xr.srgb) fmttouse = fmts[u],u=swapfmts; break;
case VK_FORMAT_B8G8R8A8_UNORM: Con_DPrintf("OpenXr fmt%u: %s\n", u, "VK_FORMAT_B8G8R8A8_UNORM"); if (!xr.srgb) fmttouse = fmts[u],u=swapfmts; break;
case VK_FORMAT_R8G8B8A8_UNORM: Con_DPrintf("OpenXr fmt%u: %s\n", u, "VK_FORMAT_R8G8B8A8_UNORM"); if (!xr.srgb) fmttouse = fmts[u],u=swapfmts; break;
case VK_FORMAT_B8G8R8A8_SRGB: Con_DPrintf("OpenXr fmt%u: %s\n", u, "VK_FORMAT_B8G8R8A8_SRGB"); if (xr.srgb) fmttouse = fmts[u],u=swapfmts; break;
@ -1382,6 +1384,7 @@ static qboolean XR_Begin(void)
Con_Printf("fmt%u: %u / %x\n", u, (unsigned)fmts[u], (unsigned)fmts[u]);
}
xr.colourformat = fmttouse;
for (u = 0; u < xr.viewcount; u++)
{
XrSwapchainCreateInfo swapinfo = {XR_TYPE_SWAPCHAIN_CREATE_INFO};
@ -1462,6 +1465,7 @@ static qboolean XR_Begin(void)
for (i = 0; i < xr.eye[u].numswapimages; i++)
{
xr.eye[u].swapimages[i].vkimage = &vkimg[i];
vkimg[i].vkformat = fmttouse;
vkimg[i].image = xrimg[i].image;
//vkimg[i].mem.* = 0;
vkimg[i].view = VK_NULL_HANDLE;