mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 09:51:41 +00:00
[vulkan] Start work on the alias pipeline
This commit is contained in:
parent
3bbe33844a
commit
57968249fe
10 changed files with 695 additions and 18 deletions
84
include/QF/Vulkan/qf_alias.h
Normal file
84
include/QF/Vulkan/qf_alias.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
qf_alias.h
|
||||
|
||||
Vulkan specific brush model stuff
|
||||
|
||||
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
||||
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2012/1/7
|
||||
Date: 2021/1/18
|
||||
|
||||
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_qf_alias_h
|
||||
#define __QF_Vulkan_qf_alias_h
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/model.h"
|
||||
#include "QF/modelgen.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
|
||||
typedef struct aliasvrt_s {
|
||||
float vertex[4];
|
||||
float normal[4];
|
||||
} aliasvrt_t;
|
||||
|
||||
typedef struct aliasuv_s {
|
||||
float u, v;
|
||||
} aliasuv_t;
|
||||
|
||||
typedef struct qfv_alias_mesh_s {
|
||||
VkBuffer vertex_buffer;
|
||||
VkBuffer uv_buffer;
|
||||
VkBuffer index_buffer;
|
||||
VkDeviceMemory memory;
|
||||
} qfv_alias_mesh_t;
|
||||
|
||||
typedef struct qfv_light_s {
|
||||
vec3_t color;
|
||||
float dist;
|
||||
vec3_t position;
|
||||
int type;
|
||||
vec3_t direction;
|
||||
float cone;
|
||||
} qfv_light_t;
|
||||
|
||||
typedef struct qfv_light_buffer_s {
|
||||
int light_count;
|
||||
qfv_light_t lights[] __attribute__((aligned(16)));
|
||||
} qfv_light_buffer_t;
|
||||
|
||||
typedef struct alias_ctx_s {
|
||||
} alias_ctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
void *Vulkan_Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum,
|
||||
qboolean group, maliasskindesc_t *skindesc,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Mod_FinalizeAliasModel (model_t *m, aliashdr_t *hdr,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Mod_LoadExternalSkins (model_t *mod, struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr,
|
||||
void *_m, int _s, int extra,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
|
||||
#endif//__QF_Vulkan_qf_alias_h
|
|
@ -277,10 +277,15 @@ typedef struct {
|
|||
} maliasframedesc_t;
|
||||
|
||||
typedef struct {
|
||||
aliasskintype_t type;
|
||||
int skin;
|
||||
int texnum;
|
||||
int fb_texnum;
|
||||
aliasskintype_t type;
|
||||
int skin;
|
||||
union {
|
||||
struct {
|
||||
int texnum;
|
||||
int fb_texnum;
|
||||
};
|
||||
void *tex;
|
||||
};
|
||||
} maliasskindesc_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
vulkan_model_alais.c
|
||||
|
||||
Alias model processing for Vulkan
|
||||
|
||||
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2021/1/24
|
||||
|
||||
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 <stdlib.h>
|
||||
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/modelgen.h"
|
||||
#include "QF/vid.h"
|
||||
#include "QF/Vulkan/qf_alias.h"
|
||||
#include "QF/Vulkan/qf_texture.h"
|
||||
#include "QF/Vulkan/buffer.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
#include "QF/Vulkan/staging.h"
|
||||
|
||||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
static vec3_t vertex_normals[NUMVERTEXNORMALS] = {
|
||||
#include "anorms.h"
|
||||
};
|
||||
|
||||
static void
|
||||
vulkan_alias_clear (model_t *m, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
void *
|
||||
Vulkan_Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum,
|
||||
qboolean group, maliasskindesc_t *skindesc,
|
||||
vulkan_ctx_t *ctx)
|
||||
{
|
||||
byte *tskin;
|
||||
int w, h;
|
||||
|
||||
w = pheader->mdl.skinwidth;
|
||||
h = pheader->mdl.skinheight;
|
||||
tskin = malloc (skinsize);
|
||||
memcpy (tskin, skin, skinsize);
|
||||
Mod_FloodFillSkin (tskin, w, h);
|
||||
tex_t skin_tex = {w, h, tex_palette, 1, vid.palette, tskin};
|
||||
skindesc->tex = Vulkan_LoadTex (ctx, &skin_tex, 1);
|
||||
free (tskin);
|
||||
return skin + skinsize;
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Mod_FinalizeAliasModel (model_t *m, aliashdr_t *hdr, vulkan_ctx_t *ctx)
|
||||
{
|
||||
if (hdr->mdl.ident == HEADER_MDL16)
|
||||
VectorScale (hdr->mdl.scale, 1/256.0, hdr->mdl.scale);
|
||||
m->clear = vulkan_alias_clear;
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Mod_LoadExternalSkins (model_t *mod, vulkan_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m,
|
||||
int _s, int extra, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
aliasvrt_t *verts;
|
||||
aliasuv_t *uv;
|
||||
trivertx_t *pv;
|
||||
int *indexmap;
|
||||
uint32_t *indices;
|
||||
int numverts;
|
||||
int numtris;
|
||||
int i, j;
|
||||
int pose;
|
||||
vec3_t pos;
|
||||
|
||||
numverts = hdr->mdl.numverts;
|
||||
numtris = hdr->mdl.numtris;
|
||||
|
||||
// initialize indexmap to -1 (unduplicated). any other value indicates
|
||||
// both that the vertex has been duplicated and the index of the
|
||||
// duplicate vertex.
|
||||
indexmap = malloc (numverts * sizeof (int));
|
||||
memset (indexmap, -1, numverts * sizeof (int));
|
||||
|
||||
// check for onseam verts, and duplicate any that are associated with
|
||||
// back-facing triangles
|
||||
for (i = 0; i < numtris; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
int vind = triangles.a[i].vertindex[j];
|
||||
if (stverts.a[vind].onseam && !triangles.a[i].facesfront) {
|
||||
// duplicate the vertex if it has not alreaddy been
|
||||
// duplicated
|
||||
if (indexmap[vind] == -1) {
|
||||
indexmap[vind] = numverts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we now know exactly how many vertices we need, so built the vertex
|
||||
// and index data arrays
|
||||
// The layout is:
|
||||
// vbuf:{vertex, normal} * (numposes * numverts)
|
||||
// uvbuf:{uv} * (numverts)
|
||||
// ibuf:{index} * (numtris * 3)
|
||||
// numverts includes the duplicated seam vertices.
|
||||
// The vertex buffer will be bound with various offsets based on the
|
||||
// current and previous pose, uvbuff "statically" bound as uvs are not
|
||||
// animated by pose, and the same for ibuf: indices will never change for
|
||||
// the mesh
|
||||
size_t atom = device->physDev->properties.limits.nonCoherentAtomSize;
|
||||
size_t atom_mask = atom - 1;
|
||||
size_t vert_count = numverts * hdr->numposes;
|
||||
size_t vert_size = vert_count * sizeof (aliasvrt_t);
|
||||
size_t uv_size = numverts * sizeof (aliasuv_t);
|
||||
size_t ind_size = numverts * sizeof (uint32_t);
|
||||
vert_size = (vert_size + atom_mask) & ~atom_mask;
|
||||
uv_size = (uv_size + atom_mask) & ~atom_mask;
|
||||
ind_size = (ind_size + atom_mask) & ~atom_mask;
|
||||
size_t buff_size = vert_size + ind_size + uv_size;
|
||||
|
||||
VkBuffer vbuff = QFV_CreateBuffer (device, buff_size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
VkBuffer uvbuff = QFV_CreateBuffer (device, buff_size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
VkBuffer ibuff = QFV_CreateBuffer (device, buff_size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
||||
VkDeviceMemory mem;
|
||||
mem = QFV_AllocBufferMemory (device, vbuff,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
buff_size, 0);
|
||||
QFV_BindBufferMemory (device, vbuff, mem, 0);
|
||||
QFV_BindBufferMemory (device, uvbuff, mem, vert_size);
|
||||
QFV_BindBufferMemory (device, ibuff, mem, vert_size + uv_size);
|
||||
|
||||
qfv_stagebuf_t *stage = QFV_CreateStagingBuffer (device, buff_size,
|
||||
ctx->cmdpool);
|
||||
qfv_packet_t *packet = QFV_PacketAcquire (stage);
|
||||
verts = QFV_PacketExtend (packet, vert_size);
|
||||
uv = QFV_PacketExtend (packet, uv_size);
|
||||
indices = QFV_PacketExtend (packet, ind_size);
|
||||
|
||||
// populate the uvs, duplicating and shifting any that are on the seam
|
||||
// and associated with back-facing triangles (marked by non-negative
|
||||
// indexmap entry).
|
||||
// the s coordinate is shifted right by half the skin width.
|
||||
for (i = 0; i < hdr->mdl.numverts; i++) {
|
||||
int vind = indexmap[i];
|
||||
uv[i].u = (float) stverts.a[i].s / hdr->mdl.skinwidth;
|
||||
uv[i].v = (float) stverts.a[i].t / hdr->mdl.skinheight;
|
||||
if (vind != -1) {
|
||||
uv[vind] = uv[i];
|
||||
uv[vind].u += 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
// poputlate the vertex position and normal data, duplicating for
|
||||
// back-facing on-seam verts (indicated by non-negative indexmap entry)
|
||||
for (i = 0, pose = 0; i < hdr->numposes; i++, pose += numverts) {
|
||||
for (j = 0; j < hdr->mdl.numverts; j++) {
|
||||
pv = &poseverts.a[i][j];
|
||||
if (extra) {
|
||||
VectorMultAdd (pv[hdr->mdl.numverts].v, 256, pv->v, pos);
|
||||
} else {
|
||||
VectorCopy (pv->v, pos);
|
||||
}
|
||||
VectorCompMultAdd (hdr->mdl.scale_origin, hdr->mdl.scale,
|
||||
pos, verts[pose + j].vertex);
|
||||
VectorCopy (vertex_normals[pv->lightnormalindex],
|
||||
verts[pose + j].normal);
|
||||
// duplicate on-seam vert associated with back-facing triangle
|
||||
if (indexmap[j] != -1) {
|
||||
verts[pose + indexmap[j]] = verts[pose + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now build the indices for DrawElements
|
||||
for (i = 0; i < numverts; i++) {
|
||||
indexmap[i] = indexmap[i] != -1 ? indexmap[i] : i;
|
||||
}
|
||||
for (i = 0; i < numtris; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
indices[3 * i + j] = indexmap[triangles.a[i].vertindex[j]];
|
||||
}
|
||||
}
|
||||
// finished with indexmap
|
||||
free (indexmap);
|
||||
|
||||
hdr->poseverts = numverts;
|
||||
|
||||
VkBufferMemoryBarrier wr_barriers[] = {
|
||||
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
|
||||
0, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
vbuff, 0, vert_size},
|
||||
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
|
||||
0, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
uvbuff, 0, uv_size},
|
||||
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
|
||||
0, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
ibuff, 0, ind_size},
|
||||
};
|
||||
dfunc->vkCmdPipelineBarrier (packet->cmd,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, 0, 0, 3, wr_barriers, 0, 0);
|
||||
VkBufferCopy copy_region[] = {
|
||||
{ packet->offset, 0, vert_size },
|
||||
{ packet->offset + vert_size, 0, uv_size },
|
||||
{ packet->offset + vert_size + uv_size, 0, ind_size },
|
||||
};
|
||||
dfunc->vkCmdCopyBuffer (packet->cmd, stage->buffer,
|
||||
vbuff, 1, ©_region[0]);
|
||||
dfunc->vkCmdCopyBuffer (packet->cmd, stage->buffer,
|
||||
uvbuff, 1, ©_region[1]);
|
||||
dfunc->vkCmdCopyBuffer (packet->cmd, stage->buffer,
|
||||
ibuff, 1, ©_region[2]);
|
||||
VkBufferMemoryBarrier rd_barriers[] = {
|
||||
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
vbuff, 0, vert_size },
|
||||
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
uvbuff, 0, uv_size },
|
||||
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
ibuff, 0, ind_size },
|
||||
};
|
||||
dfunc->vkCmdPipelineBarrier (packet->cmd,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
||||
0, 0, 0, 1, rd_barriers, 0, 0);
|
||||
QFV_PacketSubmit (packet);
|
||||
QFV_DestroyStagingBuffer (stage);
|
||||
|
||||
qfv_alias_mesh_t *mesh = Hunk_Alloc (sizeof (qfv_alias_mesh_t));
|
||||
mesh->vertex_buffer = vbuff;
|
||||
mesh->uv_buffer = uvbuff;
|
||||
mesh->index_buffer = ibuff;
|
||||
mesh->memory = mem;
|
||||
hdr->commands = (byte *) mesh - (byte *) hdr;
|
||||
}
|
|
@ -269,6 +269,10 @@ quakebspv_src = libs/video/renderer/vulkan/quakebsp.vert
|
|||
quakebspv_c = libs/video/renderer/vulkan/quakebsp.vert.spvc
|
||||
quakebspf_src = libs/video/renderer/vulkan/quakebsp.frag
|
||||
quakebspf_c = libs/video/renderer/vulkan/quakebsp.frag.spvc
|
||||
aliasv_src = libs/video/renderer/vulkan/alias.vert
|
||||
aliasv_c = libs/video/renderer/vulkan/alias.vert.spvc
|
||||
aliasf_src = libs/video/renderer/vulkan/alias.frag
|
||||
aliasf_c = libs/video/renderer/vulkan/alias.frag.spvc
|
||||
passthrough_src = libs/video/renderer/vulkan/passthrough.vert
|
||||
passthrough_c = libs/video/renderer/vulkan/passthrough.vert.spvc
|
||||
pushcolor_src = libs/video/renderer/vulkan/pushcolor.frag
|
||||
|
@ -282,6 +286,10 @@ $(quakebspv_c): $(quakebspv_src)
|
|||
|
||||
$(quakebspf_c): $(quakebspf_src)
|
||||
|
||||
$(aliasv_c): $(aliasv_src)
|
||||
|
||||
$(aliasf_c): $(aliasf_src)
|
||||
|
||||
$(passthrough_c): $(passthrough_src)
|
||||
|
||||
$(pushcolor_c): $(pushcolor_src)
|
||||
|
@ -291,6 +299,8 @@ vkshader_c = \
|
|||
$(twodf_c) \
|
||||
$(quakebspv_c) \
|
||||
$(quakebspf_c) \
|
||||
$(aliasv_c) \
|
||||
$(aliasf_c) \
|
||||
$(passthrough_c) \
|
||||
$(pushcolor_c)
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "QF/plugin/general.h"
|
||||
#include "QF/plugin/vid_render.h"
|
||||
|
||||
#include "QF/Vulkan/qf_alias.h"
|
||||
#include "QF/Vulkan/qf_bsp.h"
|
||||
#include "QF/Vulkan/qf_draw.h"
|
||||
#include "QF/Vulkan/qf_lightmap.h"
|
||||
|
@ -419,18 +420,21 @@ static void
|
|||
vulkan_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr,
|
||||
void *_m, int _s, int extra)
|
||||
{
|
||||
Vulkan_Mod_MakeAliasModelDisplayLists (m, hdr, _m, _s, extra, vulkan_ctx);
|
||||
}
|
||||
|
||||
static void *
|
||||
vulkan_Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum,
|
||||
qboolean group, maliasskindesc_t *skindesc)
|
||||
{
|
||||
return skin + skinsize;
|
||||
return Vulkan_Mod_LoadSkin (skin, skinsize, snum, gnum, group, skindesc,
|
||||
vulkan_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
vulkan_Mod_FinalizeAliasModel (model_t *m, aliashdr_t *hdr)
|
||||
{
|
||||
Vulkan_Mod_FinalizeAliasModel (m, hdr, vulkan_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
55
libs/video/renderer/vulkan/alias.frag
Normal file
55
libs/video/renderer/vulkan/alias.frag
Normal file
|
@ -0,0 +1,55 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D Texture;
|
||||
layout (set = 0, binding = 2) uniform sampler2D GlowMap;
|
||||
layout (set = 0, binding = 3) uniform sampler2D ColorA;
|
||||
layout (set = 0, binding = 4) uniform sampler2D ColorB;
|
||||
|
||||
struct LightData {
|
||||
vec3 color;
|
||||
float dist;
|
||||
vec3 position;
|
||||
int type;
|
||||
vec3 direction;
|
||||
float cone;
|
||||
};
|
||||
|
||||
layout (constant_id = 0) const int MaxLights = 8;
|
||||
layout (set = 1, binding = 0) uniform Lights {
|
||||
int light_count;
|
||||
LightData lights[MaxLights];
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 80)
|
||||
vec4 fog;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 st;
|
||||
layout (location = 1) in vec3 position;
|
||||
layout (location = 2) in vec3 normal;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 c;
|
||||
int i;
|
||||
vec3 light = vec3 (0);
|
||||
|
||||
c = texture (Texture, st);
|
||||
c += texture (ColorA, st);
|
||||
c += texture (ColorB, st);
|
||||
c += texture (GlowMap, st);
|
||||
if (MaxLights > 0) {
|
||||
for (i = 0; i < light_count; i++) {
|
||||
vec3 dist = lights[i].position - position;
|
||||
float dd = dot (dist, dist);
|
||||
float mag = max (0.0, dot (dist, normal));
|
||||
light += lights[i].color * mag * lights[i].dist / dd;
|
||||
}
|
||||
}
|
||||
frag_color = c * vec4(light, 1);//fogBlend (c);
|
||||
}
|
38
libs/video/renderer/vulkan/alias.vert
Normal file
38
libs/video/renderer/vulkan/alias.vert
Normal file
|
@ -0,0 +1,38 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 Projection;
|
||||
mat4 View;
|
||||
mat4 Sky;
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
mat4 Model;
|
||||
float blend;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 vertexa;
|
||||
layout (location = 1) in vec3 normala;
|
||||
layout (location = 2) in vec4 vertexb;
|
||||
layout (location = 3) in vec3 normalb;
|
||||
layout (location = 4) in vec2 uv;
|
||||
|
||||
layout (location = 0) out vec2 st;
|
||||
layout (location = 1) out vec3 position;
|
||||
layout (location = 2) out vec3 normal;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 vertex;
|
||||
vec3 norm;
|
||||
vec4 pos;
|
||||
|
||||
vertex = mix (vertexa, vertexb, blend);
|
||||
norm = mix (normala, normalb, blend);
|
||||
pos = (Model * vertex);
|
||||
gl_Position = Projection * (View * pos);
|
||||
position = pos.xyz;
|
||||
normal = mat3 (Model) * norm;
|
||||
st = uv;
|
||||
}
|
|
@ -11,6 +11,8 @@
|
|||
twodf = $builtin/twod.frag;
|
||||
quakebspv = $builtin/quakebsp.vert;
|
||||
quakebspf = $builtin/quakebsp.frag;
|
||||
aliasv = $builtin/alias.vert;
|
||||
aliasf = $builtin/alias.frag;
|
||||
};
|
||||
samplers = {
|
||||
quakepic = {
|
||||
|
@ -30,7 +32,7 @@
|
|||
borderColor = float_transparent_black;
|
||||
unnormalizedCoordinates = false;
|
||||
};
|
||||
quakebsp = {
|
||||
quakebsp.sampler = {
|
||||
magFilter = linear;
|
||||
minFilter = linear;
|
||||
mipmapMode = linear;
|
||||
|
@ -81,7 +83,7 @@
|
|||
},
|
||||
);
|
||||
};
|
||||
quakebsp = {
|
||||
quakebsp.textures = {
|
||||
flags = push_descriptor;
|
||||
bindings = (
|
||||
{
|
||||
|
@ -122,6 +124,51 @@
|
|||
},
|
||||
);
|
||||
};
|
||||
alias.textures = {
|
||||
flags = push_descriptor;
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
descriptorType = uniform_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = vertex;
|
||||
},
|
||||
{
|
||||
binding = 1;
|
||||
descriptorType = combined_image_sampler;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 2;
|
||||
descriptorType = combined_image_sampler;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 3;
|
||||
descriptorType = combined_image_sampler;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 4;
|
||||
descriptorType = combined_image_sampler;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
);
|
||||
};
|
||||
alias.lights = {
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
descriptorType = uniform_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
);
|
||||
};
|
||||
something = {
|
||||
flags = 0;
|
||||
bindings = (
|
||||
|
@ -144,8 +191,8 @@
|
|||
twod = {
|
||||
setLayouts = (twod);
|
||||
};
|
||||
quakebsp = {
|
||||
setLayouts = (quakebsp);
|
||||
quakebsp.layout = {
|
||||
setLayouts = (quakebsp.textures);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
|
@ -159,6 +206,21 @@
|
|||
},
|
||||
);
|
||||
};
|
||||
alias.layout = {
|
||||
setLayouts = (alias.textures, alias.lights);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
offset = 0;
|
||||
size = "16 * 4 + 4";
|
||||
},
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 80;
|
||||
size = "2 * 4 * 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
something = {
|
||||
setLayouts = (something);
|
||||
pushConstantRanges = (
|
||||
|
@ -171,6 +233,133 @@
|
|||
};
|
||||
};
|
||||
pipelines = {
|
||||
alias = {
|
||||
stages = (
|
||||
{ stage = vertex; name = main; module = aliasv; },
|
||||
{
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = aliasf;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
);
|
||||
data = <00000000>;
|
||||
};
|
||||
},
|
||||
);
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
stride = "2 * 4 * 4";
|
||||
inputRate = vertex;
|
||||
},
|
||||
{
|
||||
binding = 1;
|
||||
stride = "2 * 4 * 4";
|
||||
inputRate = vertex;
|
||||
},
|
||||
{
|
||||
binding = 2;
|
||||
stride = "2 * 4";
|
||||
inputRate = vertex;
|
||||
},
|
||||
);
|
||||
attributes = (
|
||||
{
|
||||
location = 0;
|
||||
binding = 0;
|
||||
format = r32g32b32a32_sfloat;
|
||||
offset = 0;
|
||||
},
|
||||
{
|
||||
location = 1;
|
||||
binding = 0;
|
||||
format = r32g32b32a32_sfloat;
|
||||
offset = 16;
|
||||
},
|
||||
{
|
||||
location = 2;
|
||||
binding = 1;
|
||||
format = r32g32b32a32_sfloat;
|
||||
offset = 0;
|
||||
},
|
||||
{
|
||||
location = 3;
|
||||
binding = 1;
|
||||
format = r32g32b32a32_sfloat;
|
||||
offset = 16;
|
||||
},
|
||||
{
|
||||
location = 4;
|
||||
binding = 2;
|
||||
format = r32g32_sfloat;
|
||||
offset = 0;
|
||||
},
|
||||
);
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = triangle;
|
||||
primitiveRestartEnable = false;
|
||||
};
|
||||
viewport = {
|
||||
viewports = (
|
||||
{
|
||||
x = 0; y = 0;
|
||||
width = 640; height = 480;
|
||||
minDepth = 0; maxDepth = 1;
|
||||
}
|
||||
);
|
||||
scissors = (
|
||||
{
|
||||
offset = { x = 0; y = 0 };
|
||||
extent = { width = 640; height = 480; };
|
||||
},
|
||||
);
|
||||
};
|
||||
rasterization = {
|
||||
depthClampEnable = false;
|
||||
rasterizerDiscardEnable = false;
|
||||
polygonMode = fill;
|
||||
cullMode = back;
|
||||
frontFace = clockwise;
|
||||
depthBiasEnable = false;
|
||||
lineWidth = 1;
|
||||
};
|
||||
multisample = {
|
||||
rasterizationSamples = $msaaSamples;
|
||||
sampleShadingEnable = false;
|
||||
minSampleShading = 0.5f;
|
||||
alphaToCoverageEnable = false;
|
||||
alphaToOneEnable = false;
|
||||
};
|
||||
depthStencil = {
|
||||
depthTestEnable = true;
|
||||
depthWriteEnable = true;
|
||||
depthCompareOp = less_or_equal;
|
||||
depthBoundsTestEnable = false;
|
||||
stencilTestEnable = false;
|
||||
};
|
||||
colorBlend = {
|
||||
logicOpEnable = false;
|
||||
attachments = ({
|
||||
blendEnable = true;
|
||||
srcColorBlendFactor = src_alpha;
|
||||
dstColorBlendFactor = one_minus_src_alpha;
|
||||
colorBlendOp = add;
|
||||
srcAlphaBlendFactor = src_alpha;
|
||||
dstAlphaBlendFactor = one_minus_src_alpha;
|
||||
alphaBlendOp = add;
|
||||
colorWriteMask = r|g|b|a;
|
||||
});
|
||||
};
|
||||
dynamic = {
|
||||
dynamicState = ( viewport, scissor, blend_constants );
|
||||
};
|
||||
layout = alias;
|
||||
//renderPass = renderpass;
|
||||
};
|
||||
quakebsp.main = {
|
||||
stages = (
|
||||
{ stage = vertex; name = main; module = quakebspv; },
|
||||
|
@ -257,7 +446,7 @@
|
|||
dynamic = {
|
||||
dynamicState = ( viewport, scissor, blend_constants );
|
||||
};
|
||||
layout = quakebsp;
|
||||
layout = quakebsp.layout;
|
||||
//renderPass = renderpass;
|
||||
};
|
||||
quakebsp.skysheet = {
|
||||
|
@ -359,7 +548,7 @@
|
|||
dynamic = {
|
||||
dynamicState = ( viewport, scissor, blend_constants );
|
||||
};
|
||||
layout = quakebsp;
|
||||
layout = quakebsp.layout;
|
||||
//renderPass = renderpass;
|
||||
};
|
||||
twod = {
|
||||
|
|
|
@ -63,6 +63,10 @@ static
|
|||
static
|
||||
#include "libs/video/renderer/vulkan/quakebsp.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/alias.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/alias.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/passthrough.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/pushcolor.frag.spvc"
|
||||
|
@ -78,6 +82,8 @@ static shaderdata_t builtin_shaders[] = {
|
|||
{ "twod.frag", twod_frag, sizeof (twod_frag) },
|
||||
{ "quakebsp.vert", quakebsp_vert, sizeof (quakebsp_vert) },
|
||||
{ "quakebsp.frag", quakebsp_frag, sizeof (quakebsp_frag) },
|
||||
{ "alias.vert", alias_vert, sizeof (alias_vert) },
|
||||
{ "alias.frag", alias_frag, sizeof (alias_frag) },
|
||||
{ "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) },
|
||||
{ "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) },
|
||||
{}
|
||||
|
|
|
@ -1420,13 +1420,8 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx)
|
|||
|
||||
bctx->main = Vulkan_CreatePipeline (ctx, "quakebsp.main");
|
||||
bctx->sky = Vulkan_CreatePipeline (ctx, "quakebsp.skysheet");
|
||||
bctx->layout = QFV_GetPipelineLayout (ctx, "quakebsp");
|
||||
bctx->sampler = QFV_GetSampler (ctx, "quakebsp");
|
||||
|
||||
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (frames, alloca);
|
||||
for (size_t i = 0; i < layouts->size; i++) {
|
||||
layouts->a[i] = QFV_GetDescriptorSetLayout (ctx, "quakebsp");
|
||||
}
|
||||
bctx->layout = QFV_GetPipelineLayout (ctx, "quakebsp.layout");
|
||||
bctx->sampler = QFV_GetSampler (ctx, "quakebsp.sampler");
|
||||
|
||||
__auto_type cmdBuffers = QFV_AllocCommandBufferSet (3 * frames, alloca);
|
||||
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, cmdBuffers);
|
||||
|
|
Loading…
Reference in a new issue