[vulkan] Move both alias color maps into the one layer

This cuts down on the memory requirements for skins by 25%, and
simplifies the shader a bit more, too. While at it, I made alias skins
nominally compatible with bsp textures: layer 0 is color, 1 is emissive,
and 2 is the color map (emissive was on 3).
This commit is contained in:
Bill Currie 2022-11-15 13:09:41 +09:00
parent 668f7f2cd2
commit a28488d2e1
4 changed files with 64 additions and 49 deletions

View file

@ -109,8 +109,10 @@ void Skin_Free (skin_t *skin);
skin_t *Skin_SetColormap (skin_t *skin, int cmap);
skin_t *Skin_SetSkin (skin_t *skin, int cmap, const char *skinname);
void Skin_SetTranslation (int cmap, int top, int bottom);
int Skin_CalcTopColors (byte *out, const byte *in, size_t pixels);
int Skin_CalcBottomColors (byte *out, const byte *in, size_t pixels);
int Skin_CalcTopColors (byte *out, const byte *in, size_t pixels, int stride);
int Skin_CalcTopMask (byte *out, const byte *in, size_t pixels, int stride);
int Skin_CalcBottomColors(byte *out, const byte *in, size_t pixels, int stride);
int Skin_CalcBottomMask (byte *out, const byte *in, size_t pixels, int stride);
int Skin_ClearTopColors (byte *out, const byte *in, size_t pixels);
int Skin_ClearBottomColors (byte *out, const byte *in, size_t pixels);

View file

@ -111,6 +111,8 @@ vulkan_alias_clear (model_t *m, void *data)
}
}
#define SKIN_LAYERS 3
static void *
Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
int snum, int gnum, qboolean group,
@ -138,7 +140,7 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
VkExtent3D extent = { w, h, 1 };
skin->image = QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,
VK_FORMAT_R8G8B8A8_UNORM, extent,
mipLevels, 4, VK_SAMPLE_COUNT_1_BIT,
mipLevels, 3, VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_USAGE_SAMPLED_BIT
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
@ -161,45 +163,23 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
alias_ctx->mod->name, snum, gnum));
qfv_stagebuf_t *stage = QFV_CreateStagingBuffer (device, "alias stage",
4 * skinsize * 4,
SKIN_LAYERS * 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);
byte *cmap_data = QFV_PacketExtend (packet, skinsize * 4);
Mod_CalcFullbright (tskin + skinsize, tskin, skinsize);
Vulkan_ExpandPalette (glow_data, tskin + skinsize, vid.palette, 1,
skinsize);
Mod_ClearFullbright (tskin, tskin, skinsize);
static byte map_palette[] = {
0x08, 0x00, 0x00,
0x18, 0xff, 0x00,
0x28, 0xff, 0x00,
0x38, 0xff, 0x00,
0x48, 0xff, 0x00,
0x58, 0xff, 0x00,
0x68, 0xff, 0x00,
0x78, 0xff, 0x00,
0x88, 0xff, 0x00,
0x98, 0xff, 0x00,
0xa8, 0xff, 0x00,
0xb8, 0xff, 0x00,
0xc8, 0xff, 0x00,
0xd8, 0xff, 0x00,
0xe8, 0xff, 0x00,
0xf8, 0xff, 0x00,
};
Skin_CalcTopColors (tskin + skinsize, tskin, skinsize);
Vulkan_ExpandPalette (cola_data, tskin + skinsize, map_palette, 1,
skinsize);
Skin_CalcTopColors (cmap_data + 0, tskin, skinsize, 4);
Skin_CalcTopMask (cmap_data + 1, tskin, skinsize, 4);
Skin_CalcBottomColors (cmap_data + 2, tskin, skinsize, 4);
Skin_CalcBottomMask (cmap_data + 3, tskin, skinsize, 4);
Skin_ClearTopColors (tskin, tskin, skinsize);
Skin_CalcBottomColors (tskin + skinsize, tskin, skinsize);
Vulkan_ExpandPalette (colb_data, tskin + skinsize, map_palette, 1,
skinsize);
Skin_ClearBottomColors (tskin, tskin, skinsize);
Vulkan_ExpandPalette (base_data, tskin, vid.palette, 1, skinsize);
@ -214,7 +194,7 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
VkBufferImageCopy copy = {
packet->offset, 0, 0,
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 4},
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, SKIN_LAYERS},
{0, 0, 0}, {w, h, 1},
};
dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer,
@ -232,7 +212,7 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
1, &ib.barrier);
} else {
QFV_GenerateMipMaps (device, packet->cmd, skin->image,
mipLevels, w, h, 4);
mipLevels, w, h, SKIN_LAYERS);
}
QFV_PacketSubmit (packet);
QFV_DestroyStagingBuffer (stage);

View file

@ -256,7 +256,7 @@ Skin_Init (void)
}
VISIBLE int
Skin_CalcTopColors (byte *out, const byte *in, size_t pixels)
Skin_CalcTopColors (byte *out, const byte *in, size_t pixels, int stride)
{
byte tc = 0;
@ -264,16 +264,35 @@ Skin_CalcTopColors (byte *out, const byte *in, size_t pixels)
byte pix = *in++;
if (pix >= TOP_RANGE && pix < TOP_RANGE + 16) {
tc = 1;
*out++ = pix - TOP_RANGE;
*out = (pix - TOP_RANGE) * 16 + 8;
} else {
*out++ = 0;
*out = 0;
}
out += stride;
}
return tc;
}
VISIBLE int
Skin_CalcBottomColors (byte *out, const byte *in, size_t pixels)
Skin_CalcTopMask (byte *out, const byte *in, size_t pixels, int stride)
{
byte tc = 0;
while (pixels-- > 0) {
byte pix = *in++;
if (pix >= TOP_RANGE && pix < TOP_RANGE + 16) {
tc = 1;
*out = 0xff;
} else {
*out = 0;
}
out += stride;
}
return tc;
}
VISIBLE int
Skin_CalcBottomColors (byte *out, const byte *in, size_t pixels, int stride)
{
byte bc = 0;
@ -281,10 +300,29 @@ Skin_CalcBottomColors (byte *out, const byte *in, size_t pixels)
byte pix = *in++;
if (pix >= BOTTOM_RANGE && pix < BOTTOM_RANGE + 16) {
bc = 1;
*out++ = pix - BOTTOM_RANGE;
*out = (pix - BOTTOM_RANGE) * 16 + 8;
} else {
*out++ = 0;
*out = 0;
}
out += stride;
}
return bc;
}
VISIBLE int
Skin_CalcBottomMask (byte *out, const byte *in, size_t pixels, int stride)
{
byte bc = 0;
while (pixels-- > 0) {
byte pix = *in++;
if (pix >= BOTTOM_RANGE && pix < BOTTOM_RANGE + 16) {
bc = 1;
*out = 0xff;
} else {
*out = 0;
}
out += stride;
}
return bc;
}

View file

@ -24,17 +24,12 @@ main (void)
{
vec4 c;
vec4 e;
int i;
vec3 light = vec3 (0);
vec4 rows = unpackUnorm4x8(colors);
vec2 cols = vec2 (texture (Skin, vec3 (st, 1)).r,
texture (Skin, vec3 (st, 2)).r);
vec2 mask = vec2 (texture (Skin, vec3 (st, 1)).g,
texture (Skin, vec3 (st, 2)).g);
c = texture (Skin, vec3 (st, 0)) * base_color;
c += texture (Palette, vec2 (cols.x, rows.x)) * mask.x;
c += texture (Palette, vec2 (cols.y, rows.y)) * mask.y;
e = texture (Skin, vec3 (st, 3));
e = texture (Skin, vec3 (st, 1));
vec4 rows = unpackUnorm4x8(colors);
vec4 cmap = texture (Skin, vec3 (st, 2));
c += texture (Palette, vec2 (cmap.x, rows.x)) * cmap.y;
c += texture (Palette, vec2 (cmap.z, rows.y)) * cmap.w;
frag_color = c;
frag_emission = e;