mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
[vulkan] Use 4 layer arrays for alias skins
Doesn't seem to make much difference performance-wise, but speed does seem to be fill-rate limited due to the 8x msaa. Still, it does mean fewer bindings to worry about.
This commit is contained in:
parent
0d4ca46923
commit
8e63ab9f94
5 changed files with 112 additions and 78 deletions
|
@ -37,13 +37,6 @@
|
||||||
#include "QF/modelgen.h"
|
#include "QF/modelgen.h"
|
||||||
#include "QF/Vulkan/qf_vid.h"
|
#include "QF/Vulkan/qf_vid.h"
|
||||||
|
|
||||||
typedef struct aliasskin_s {
|
|
||||||
struct qfv_tex_s *tex;
|
|
||||||
struct qfv_tex_s *glow;
|
|
||||||
struct qfv_tex_s *colora;
|
|
||||||
struct qfv_tex_s *colorb;
|
|
||||||
} aliasskin_t;
|
|
||||||
|
|
||||||
typedef struct aliasvrt_s {
|
typedef struct aliasvrt_s {
|
||||||
float vertex[4];
|
float vertex[4];
|
||||||
float normal[4];
|
float normal[4];
|
||||||
|
@ -77,7 +70,7 @@ typedef struct qfv_light_buffer_s {
|
||||||
} qfv_light_buffer_t;
|
} qfv_light_buffer_t;
|
||||||
|
|
||||||
#define ALIAS_BUFFER_INFOS 2
|
#define ALIAS_BUFFER_INFOS 2
|
||||||
#define ALIAS_IMAGE_INFOS 4
|
#define ALIAS_IMAGE_INFOS 1
|
||||||
|
|
||||||
typedef struct aliasframe_s {
|
typedef struct aliasframe_s {
|
||||||
VkCommandBuffer cmd;
|
VkCommandBuffer cmd;
|
||||||
|
|
|
@ -46,9 +46,11 @@
|
||||||
#include "QF/vid.h"
|
#include "QF/vid.h"
|
||||||
#include "QF/Vulkan/qf_alias.h"
|
#include "QF/Vulkan/qf_alias.h"
|
||||||
#include "QF/Vulkan/qf_texture.h"
|
#include "QF/Vulkan/qf_texture.h"
|
||||||
|
#include "QF/Vulkan/barrier.h"
|
||||||
#include "QF/Vulkan/buffer.h"
|
#include "QF/Vulkan/buffer.h"
|
||||||
#include "QF/Vulkan/device.h"
|
#include "QF/Vulkan/device.h"
|
||||||
#include "QF/Vulkan/debug.h"
|
#include "QF/Vulkan/debug.h"
|
||||||
|
#include "QF/Vulkan/image.h"
|
||||||
#include "QF/Vulkan/instance.h"
|
#include "QF/Vulkan/instance.h"
|
||||||
#include "QF/Vulkan/staging.h"
|
#include "QF/Vulkan/staging.h"
|
||||||
|
|
||||||
|
@ -63,17 +65,13 @@ static vec3_t vertex_normals[NUMVERTEXNORMALS] = {
|
||||||
static void
|
static void
|
||||||
skin_clear (int skin_offset, aliashdr_t *hdr, vulkan_ctx_t *ctx)
|
skin_clear (int skin_offset, aliashdr_t *hdr, vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
aliasskin_t *skin = (aliasskin_t *) ((byte *) hdr + skin_offset);
|
qfv_device_t *device = ctx->device;
|
||||||
Vulkan_UnloadTex (ctx, skin->tex);
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
if (skin->glow) {
|
qfv_tex_t *skin = (qfv_tex_t *) ((byte *) hdr + skin_offset);
|
||||||
Vulkan_UnloadTex (ctx, skin->glow);
|
|
||||||
}
|
dfunc->vkDestroyImageView (device->dev, skin->view, 0);
|
||||||
if (skin->colora) {
|
dfunc->vkDestroyImage (device->dev, skin->image, 0);
|
||||||
Vulkan_UnloadTex (ctx, skin->colora);
|
dfunc->vkFreeMemory (device->dev, skin->memory, 0);
|
||||||
}
|
|
||||||
if (skin->colorb) {
|
|
||||||
Vulkan_UnloadTex (ctx, skin->colorb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -114,12 +112,14 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
|
||||||
int snum, int gnum, qboolean group,
|
int snum, int gnum, qboolean group,
|
||||||
maliasskindesc_t *skindesc, vulkan_ctx_t *ctx)
|
maliasskindesc_t *skindesc, vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
aliashdr_t *header = alias_ctx->header;
|
aliashdr_t *header = alias_ctx->header;
|
||||||
aliasskin_t *skin;
|
qfv_tex_t *skin;
|
||||||
byte *tskin;
|
byte *tskin;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
skin = Hunk_Alloc (sizeof (aliasskin_t));
|
skin = Hunk_Alloc (sizeof (qfv_tex_t));
|
||||||
skindesc->skin = (byte *) skin - (byte *) header;
|
skindesc->skin = (byte *) skin - (byte *) header;
|
||||||
//FIXME move all skins into arrays(?)
|
//FIXME move all skins into arrays(?)
|
||||||
w = header->mdl.skinwidth;
|
w = header->mdl.skinwidth;
|
||||||
|
@ -128,30 +128,97 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
|
||||||
memcpy (tskin, skinpix, skinsize);
|
memcpy (tskin, skinpix, skinsize);
|
||||||
Mod_FloodFillSkin (tskin, w, h);
|
Mod_FloodFillSkin (tskin, w, h);
|
||||||
|
|
||||||
tex_t skin_tex = {w, h, tex_palette, 1, vid.palette, tskin + skinsize};
|
int mipLevels = QFV_MipLevels (w, h);
|
||||||
if (Mod_CalcFullbright (tskin, tskin + skinsize, skinsize)) {
|
VkExtent3D extent = { w, h, 1 };
|
||||||
skin->glow = Vulkan_LoadTex (ctx, &skin_tex, 1,
|
skin->offset = 0;
|
||||||
va (ctx->va_ctx, "%s:%d:%d:glow",
|
skin->image = QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,
|
||||||
alias_ctx->mod->name, snum, gnum));
|
VK_FORMAT_R8G8B8A8_UNORM, extent,
|
||||||
Mod_ClearFullbright (tskin, tskin, skinsize);
|
mipLevels, 4, VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
VK_IMAGE_USAGE_SAMPLED_BIT
|
||||||
|
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||||
|
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
|
||||||
|
QFV_duSetObjectName (device, VK_OBJECT_TYPE_IMAGE, skin->image,
|
||||||
|
va (ctx->va_ctx, "image:%s:%d:%d",
|
||||||
|
alias_ctx->mod->name, snum, gnum));
|
||||||
|
skin->memory = QFV_AllocImageMemory (device, skin->image,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
0, 0);
|
||||||
|
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY, skin->memory,
|
||||||
|
va (ctx->va_ctx, "memory:%s:%d:%d",
|
||||||
|
alias_ctx->mod->name, snum, gnum));
|
||||||
|
QFV_BindImageMemory (device, skin->image, skin->memory, 0);
|
||||||
|
skin->view = QFV_CreateImageView (device, skin->image,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||||
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
QFV_duSetObjectName (device, VK_OBJECT_TYPE_IMAGE_VIEW, skin->view,
|
||||||
|
va (ctx->va_ctx, "iview:%s:%d:%d",
|
||||||
|
alias_ctx->mod->name, snum, gnum));
|
||||||
|
|
||||||
|
qfv_stagebuf_t *stage = QFV_CreateStagingBuffer (device, "alias stage",
|
||||||
|
4 * skinsize * 4,
|
||||||
|
ctx->cmdpool);
|
||||||
|
qfv_packet_t *packet = QFV_PacketAcquire (stage);
|
||||||
|
byte *base_data = QFV_PacketExtend (packet, skinsize * 4);
|
||||||
|
byte *cola_data = QFV_PacketExtend (packet, skinsize * 4);
|
||||||
|
byte *colb_data = QFV_PacketExtend (packet, skinsize * 4);
|
||||||
|
byte *glow_data = QFV_PacketExtend (packet, skinsize * 4);
|
||||||
|
|
||||||
|
Mod_CalcFullbright (tskin, tskin + skinsize, skinsize);
|
||||||
|
Vulkan_ExpandPalette (glow_data, tskin + skinsize, vid.palette, 1,
|
||||||
|
skinsize);
|
||||||
|
Mod_ClearFullbright (tskin, tskin, skinsize);
|
||||||
|
|
||||||
|
Skin_CalcTopColors (tskin, tskin + skinsize, skinsize);
|
||||||
|
Vulkan_ExpandPalette (cola_data, tskin + skinsize, vid.palette, 1,
|
||||||
|
skinsize);
|
||||||
|
Skin_ClearTopColors (tskin, tskin, skinsize);
|
||||||
|
|
||||||
|
Skin_CalcBottomColors (tskin, tskin + skinsize, skinsize);
|
||||||
|
Vulkan_ExpandPalette (colb_data, tskin + skinsize, vid.palette, 1,
|
||||||
|
skinsize);
|
||||||
|
Skin_ClearBottomColors (tskin, tskin, skinsize);
|
||||||
|
|
||||||
|
Vulkan_ExpandPalette (base_data, tskin, vid.palette, 1, skinsize);
|
||||||
|
|
||||||
|
VkImageMemoryBarrier barrier;
|
||||||
|
qfv_pipelinestagepair_t stages;
|
||||||
|
|
||||||
|
stages = imageLayoutTransitionStages[qfv_LT_Undefined_to_TransferDst];
|
||||||
|
barrier = imageLayoutTransitionBarriers[qfv_LT_Undefined_to_TransferDst];
|
||||||
|
barrier.image = skin->image;
|
||||||
|
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
1, &barrier);
|
||||||
|
|
||||||
|
VkBufferImageCopy copy = {
|
||||||
|
packet->offset, 0, 0,
|
||||||
|
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 4},
|
||||||
|
{0, 0, 0}, {w, h, 1},
|
||||||
|
};
|
||||||
|
dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer,
|
||||||
|
skin->image,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
1, ©);
|
||||||
|
|
||||||
|
if (mipLevels == 1) {
|
||||||
|
stages = imageLayoutTransitionStages[qfv_LT_TransferDst_to_ShaderReadOnly];
|
||||||
|
barrier=imageLayoutTransitionBarriers[qfv_LT_TransferDst_to_ShaderReadOnly];
|
||||||
|
barrier.image = skin->image;
|
||||||
|
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
1, &barrier);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
QFV_GenerateMipMaps (device, packet->cmd, skin->image,
|
||||||
|
mipLevels, w, h, 4);
|
||||||
}
|
}
|
||||||
if (Skin_CalcTopColors (tskin, tskin + skinsize, skinsize)) {
|
QFV_PacketSubmit (packet);
|
||||||
skin->colora = Vulkan_LoadTex (ctx, &skin_tex, 1,
|
QFV_DestroyStagingBuffer (stage);
|
||||||
va (ctx->va_ctx, "%s:%d:%d:colora",
|
|
||||||
alias_ctx->mod->name, snum, gnum));
|
|
||||||
Skin_ClearTopColors (tskin, tskin, skinsize);
|
|
||||||
}
|
|
||||||
if (Skin_CalcBottomColors (tskin, tskin + skinsize, skinsize)) {
|
|
||||||
skin->colorb = Vulkan_LoadTex (ctx, &skin_tex, 1,
|
|
||||||
va (ctx->va_ctx, "%s:%d:%d:colorb",
|
|
||||||
alias_ctx->mod->name, snum, gnum));
|
|
||||||
Skin_ClearBottomColors (tskin, tskin, skinsize);
|
|
||||||
}
|
|
||||||
skin_tex.data = tskin;
|
|
||||||
skin->tex = Vulkan_LoadTex (ctx, &skin_tex, 1,
|
|
||||||
va (ctx->va_ctx, "%s:%d:%d:tex",
|
|
||||||
alias_ctx->mod->name,
|
|
||||||
snum, gnum));
|
|
||||||
|
|
||||||
free (tskin);
|
free (tskin);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
#version 450
|
#version 450
|
||||||
layout (set = 0, binding = 2) uniform sampler2D Texture;
|
layout (set = 0, binding = 2) uniform sampler2DArray Skin;
|
||||||
layout (set = 0, binding = 3) uniform sampler2D GlowMap;
|
|
||||||
layout (set = 0, binding = 4) uniform sampler2D ColorA;
|
|
||||||
layout (set = 0, binding = 5) uniform sampler2D ColorB;
|
|
||||||
/*
|
/*
|
||||||
layout (set = 2, binding = 0) uniform sampler2D Texture;
|
layout (set = 2, binding = 0) uniform sampler2D Texture;
|
||||||
layout (set = 2, binding = 1) uniform sampler2D GlowMap;
|
layout (set = 2, binding = 1) uniform sampler2D GlowMap;
|
||||||
|
@ -59,9 +56,9 @@ main (void)
|
||||||
vec4 c;
|
vec4 c;
|
||||||
int i;
|
int i;
|
||||||
vec3 light = vec3 (0);
|
vec3 light = vec3 (0);
|
||||||
c = texture (Texture, st);
|
c = texture (Skin, vec3 (st, 0));
|
||||||
c += texture (ColorA, st);
|
c += texture (Skin, vec3 (st, 1));
|
||||||
c += texture (ColorB, st);
|
c += texture (Skin, vec3 (st, 2));
|
||||||
|
|
||||||
if (MaxLights > 0) {
|
if (MaxLights > 0) {
|
||||||
for (i = 0; i < light_count; i++) {
|
for (i = 0; i < light_count; i++) {
|
||||||
|
@ -70,7 +67,7 @@ main (void)
|
||||||
}
|
}
|
||||||
c *= vec4 (light, 1);
|
c *= vec4 (light, 1);
|
||||||
|
|
||||||
c += texture (GlowMap, st);
|
c += texture (Skin, vec3 (st, 3));
|
||||||
//frag_color = vec4((normal + 1)/2, 1);
|
//frag_color = vec4((normal + 1)/2, 1);
|
||||||
frag_color = c;//fogBlend (c);
|
frag_color = c;//fogBlend (c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,24 +172,6 @@
|
||||||
descriptorCount = 1;
|
descriptorCount = 1;
|
||||||
stageFlags = fragment;
|
stageFlags = fragment;
|
||||||
},
|
},
|
||||||
{
|
|
||||||
binding = 3;
|
|
||||||
descriptorType = combined_image_sampler;
|
|
||||||
descriptorCount = 1;
|
|
||||||
stageFlags = fragment;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
binding = 4;
|
|
||||||
descriptorType = combined_image_sampler;
|
|
||||||
descriptorCount = 1;
|
|
||||||
stageFlags = fragment;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
binding = 5;
|
|
||||||
descriptorType = combined_image_sampler;
|
|
||||||
descriptorCount = 1;
|
|
||||||
stageFlags = fragment;
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
alias.matrices = {
|
alias.matrices = {
|
||||||
|
|
|
@ -88,7 +88,7 @@ Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx)
|
||||||
aliashdr_t *hdr;
|
aliashdr_t *hdr;
|
||||||
qfv_alias_mesh_t *mesh;
|
qfv_alias_mesh_t *mesh;
|
||||||
float blend;
|
float blend;
|
||||||
aliasskin_t *skin;
|
qfv_tex_t *skin;
|
||||||
|
|
||||||
if (!(hdr = model->aliashdr)) {
|
if (!(hdr = model->aliashdr)) {
|
||||||
hdr = Cache_Get (&model->cache);
|
hdr = Cache_Get (&model->cache);
|
||||||
|
@ -102,7 +102,7 @@ Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx)
|
||||||
} else {
|
} else {
|
||||||
maliasskindesc_t *skindesc;
|
maliasskindesc_t *skindesc;
|
||||||
skindesc = R_AliasGetSkindesc (ent->skinnum, hdr);
|
skindesc = R_AliasGetSkindesc (ent->skinnum, hdr);
|
||||||
skin = (aliasskin_t *) ((byte *) hdr + skindesc->skin);
|
skin = (qfv_tex_t *) ((byte *) hdr + skindesc->skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDeviceSize offsets[] = {
|
VkDeviceSize offsets[] = {
|
||||||
|
@ -124,12 +124,7 @@ Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx)
|
||||||
dfunc->vkCmdPushConstants (aframe->cmd, actx->layout,
|
dfunc->vkCmdPushConstants (aframe->cmd, actx->layout,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT,
|
VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
64, sizeof (float), &blend);
|
64, sizeof (float), &blend);
|
||||||
aframe->imageInfo[0].imageView = get_view (skin->tex, ctx->default_white);
|
aframe->imageInfo[0].imageView = get_view (skin, 0);
|
||||||
aframe->imageInfo[1].imageView = get_view (skin->glow, ctx->default_black);
|
|
||||||
aframe->imageInfo[2].imageView = get_view (skin->colora,
|
|
||||||
ctx->default_black);
|
|
||||||
aframe->imageInfo[3].imageView = get_view (skin->colorb,
|
|
||||||
ctx->default_black);
|
|
||||||
dfunc->vkCmdPushDescriptorSetKHR (aframe->cmd,
|
dfunc->vkCmdPushDescriptorSetKHR (aframe->cmd,
|
||||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
actx->layout,
|
actx->layout,
|
||||||
|
|
Loading…
Reference in a new issue