mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-07 08:21:59 +00:00
[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:
parent
668f7f2cd2
commit
a28488d2e1
4 changed files with 64 additions and 49 deletions
|
@ -109,8 +109,10 @@ void Skin_Free (skin_t *skin);
|
||||||
skin_t *Skin_SetColormap (skin_t *skin, int cmap);
|
skin_t *Skin_SetColormap (skin_t *skin, int cmap);
|
||||||
skin_t *Skin_SetSkin (skin_t *skin, int cmap, const char *skinname);
|
skin_t *Skin_SetSkin (skin_t *skin, int cmap, const char *skinname);
|
||||||
void Skin_SetTranslation (int cmap, int top, int bottom);
|
void Skin_SetTranslation (int cmap, int top, int bottom);
|
||||||
int Skin_CalcTopColors (byte *out, const byte *in, size_t pixels);
|
int Skin_CalcTopColors (byte *out, const byte *in, size_t pixels, int stride);
|
||||||
int Skin_CalcBottomColors (byte *out, const byte *in, size_t pixels);
|
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_ClearTopColors (byte *out, const byte *in, size_t pixels);
|
||||||
int Skin_ClearBottomColors (byte *out, const byte *in, size_t pixels);
|
int Skin_ClearBottomColors (byte *out, const byte *in, size_t pixels);
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,8 @@ vulkan_alias_clear (model_t *m, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SKIN_LAYERS 3
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
|
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,
|
||||||
|
@ -138,7 +140,7 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
|
||||||
VkExtent3D extent = { w, h, 1 };
|
VkExtent3D extent = { w, h, 1 };
|
||||||
skin->image = QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,
|
skin->image = QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM, extent,
|
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_SAMPLED_BIT
|
||||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||||
| VK_IMAGE_USAGE_TRANSFER_SRC_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));
|
alias_ctx->mod->name, snum, gnum));
|
||||||
|
|
||||||
qfv_stagebuf_t *stage = QFV_CreateStagingBuffer (device, "alias stage",
|
qfv_stagebuf_t *stage = QFV_CreateStagingBuffer (device, "alias stage",
|
||||||
4 * skinsize * 4,
|
SKIN_LAYERS * skinsize * 4,
|
||||||
ctx->cmdpool);
|
ctx->cmdpool);
|
||||||
qfv_packet_t *packet = QFV_PacketAcquire (stage);
|
qfv_packet_t *packet = QFV_PacketAcquire (stage);
|
||||||
byte *base_data = QFV_PacketExtend (packet, skinsize * 4);
|
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 *glow_data = QFV_PacketExtend (packet, skinsize * 4);
|
||||||
|
byte *cmap_data = QFV_PacketExtend (packet, skinsize * 4);
|
||||||
|
|
||||||
Mod_CalcFullbright (tskin + skinsize, tskin, skinsize);
|
Mod_CalcFullbright (tskin + skinsize, tskin, skinsize);
|
||||||
Vulkan_ExpandPalette (glow_data, tskin + skinsize, vid.palette, 1,
|
Vulkan_ExpandPalette (glow_data, tskin + skinsize, vid.palette, 1,
|
||||||
skinsize);
|
skinsize);
|
||||||
Mod_ClearFullbright (tskin, tskin, skinsize);
|
Mod_ClearFullbright (tskin, tskin, skinsize);
|
||||||
|
|
||||||
static byte map_palette[] = {
|
Skin_CalcTopColors (cmap_data + 0, tskin, skinsize, 4);
|
||||||
0x08, 0x00, 0x00,
|
Skin_CalcTopMask (cmap_data + 1, tskin, skinsize, 4);
|
||||||
0x18, 0xff, 0x00,
|
Skin_CalcBottomColors (cmap_data + 2, tskin, skinsize, 4);
|
||||||
0x28, 0xff, 0x00,
|
Skin_CalcBottomMask (cmap_data + 3, tskin, skinsize, 4);
|
||||||
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_ClearTopColors (tskin, tskin, skinsize);
|
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);
|
Skin_ClearBottomColors (tskin, tskin, skinsize);
|
||||||
|
|
||||||
Vulkan_ExpandPalette (base_data, tskin, vid.palette, 1, 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 = {
|
VkBufferImageCopy copy = {
|
||||||
packet->offset, 0, 0,
|
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},
|
{0, 0, 0}, {w, h, 1},
|
||||||
};
|
};
|
||||||
dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer,
|
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);
|
1, &ib.barrier);
|
||||||
} else {
|
} else {
|
||||||
QFV_GenerateMipMaps (device, packet->cmd, skin->image,
|
QFV_GenerateMipMaps (device, packet->cmd, skin->image,
|
||||||
mipLevels, w, h, 4);
|
mipLevels, w, h, SKIN_LAYERS);
|
||||||
}
|
}
|
||||||
QFV_PacketSubmit (packet);
|
QFV_PacketSubmit (packet);
|
||||||
QFV_DestroyStagingBuffer (stage);
|
QFV_DestroyStagingBuffer (stage);
|
||||||
|
|
|
@ -256,7 +256,7 @@ Skin_Init (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
VISIBLE int
|
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;
|
byte tc = 0;
|
||||||
|
|
||||||
|
@ -264,16 +264,35 @@ Skin_CalcTopColors (byte *out, const byte *in, size_t pixels)
|
||||||
byte pix = *in++;
|
byte pix = *in++;
|
||||||
if (pix >= TOP_RANGE && pix < TOP_RANGE + 16) {
|
if (pix >= TOP_RANGE && pix < TOP_RANGE + 16) {
|
||||||
tc = 1;
|
tc = 1;
|
||||||
*out++ = pix - TOP_RANGE;
|
*out = (pix - TOP_RANGE) * 16 + 8;
|
||||||
} else {
|
} else {
|
||||||
*out++ = 0;
|
*out = 0;
|
||||||
}
|
}
|
||||||
|
out += stride;
|
||||||
}
|
}
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
VISIBLE int
|
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;
|
byte bc = 0;
|
||||||
|
|
||||||
|
@ -281,10 +300,29 @@ Skin_CalcBottomColors (byte *out, const byte *in, size_t pixels)
|
||||||
byte pix = *in++;
|
byte pix = *in++;
|
||||||
if (pix >= BOTTOM_RANGE && pix < BOTTOM_RANGE + 16) {
|
if (pix >= BOTTOM_RANGE && pix < BOTTOM_RANGE + 16) {
|
||||||
bc = 1;
|
bc = 1;
|
||||||
*out++ = pix - BOTTOM_RANGE;
|
*out = (pix - BOTTOM_RANGE) * 16 + 8;
|
||||||
} else {
|
} 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;
|
return bc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,17 +24,12 @@ main (void)
|
||||||
{
|
{
|
||||||
vec4 c;
|
vec4 c;
|
||||||
vec4 e;
|
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 (Skin, vec3 (st, 0)) * base_color;
|
||||||
c += texture (Palette, vec2 (cols.x, rows.x)) * mask.x;
|
e = texture (Skin, vec3 (st, 1));
|
||||||
c += texture (Palette, vec2 (cols.y, rows.y)) * mask.y;
|
vec4 rows = unpackUnorm4x8(colors);
|
||||||
e = texture (Skin, vec3 (st, 3));
|
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_color = c;
|
||||||
frag_emission = e;
|
frag_emission = e;
|
||||||
|
|
Loading…
Reference in a new issue