mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
[vulkan] Load cachepics as separate images
They are usually larger images (eg, the main menu graphic) and thus make a mess of the atlas (thus, making them separate means a smaller atlas can be used). All sorts of things are in a mess (descriptor management, subpic rendering not supported, wrong alpha value for the transparent pixel), but this gets the basic loader going.
This commit is contained in:
parent
2f564ca5a6
commit
0953446c3e
1 changed files with 125 additions and 25 deletions
|
@ -82,6 +82,7 @@ static QFV_Subpass subpass_map[] = {
|
||||||
|
|
||||||
typedef struct pic_data_s {
|
typedef struct pic_data_s {
|
||||||
uint32_t vert_index;
|
uint32_t vert_index;
|
||||||
|
uint32_t descid;
|
||||||
subpic_t *subpic;
|
subpic_t *subpic;
|
||||||
} picdata_t;
|
} picdata_t;
|
||||||
|
|
||||||
|
@ -376,7 +377,9 @@ static void
|
||||||
pic_free (drawctx_t *dctx, qpic_t *pic)
|
pic_free (drawctx_t *dctx, qpic_t *pic)
|
||||||
{
|
{
|
||||||
__auto_type pd = (picdata_t *) pic->data;
|
__auto_type pd = (picdata_t *) pic->data;
|
||||||
QFV_SubpicDelete (pd->subpic);
|
if (pd->subpic) {
|
||||||
|
QFV_SubpicDelete (pd->subpic);
|
||||||
|
}
|
||||||
cmemfree (dctx->pic_memsuper, pic);
|
cmemfree (dctx->pic_memsuper, pic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,13 +458,17 @@ create_quad (int x, int y, int w, int h, qpic_t *pic, uint32_t *vertex_index,
|
||||||
{
|
{
|
||||||
__auto_type pd = (picdata_t *) pic->data;
|
__auto_type pd = (picdata_t *) pic->data;
|
||||||
|
|
||||||
x += pd->subpic->rect->x;
|
float sl = 0, sr = 1, st = 0, sb = 1;
|
||||||
y += pd->subpic->rect->y;
|
|
||||||
float size = pd->subpic->size;
|
if (pd->subpic) {
|
||||||
float sl = (x + 0) * size;
|
x += pd->subpic->rect->x;
|
||||||
float sr = (x + w) * size;
|
y += pd->subpic->rect->y;
|
||||||
float st = (y + 0) * size;
|
float size = pd->subpic->size;
|
||||||
float sb = (y + h) * size;
|
sl = (x + 0) * size;
|
||||||
|
sr = (x + w) * size;
|
||||||
|
st = (y + 0) * size;
|
||||||
|
sb = (y + h) * size;
|
||||||
|
}
|
||||||
|
|
||||||
qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging);
|
qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging);
|
||||||
quadvert_t *verts = QFV_PacketExtend (packet, BYTES_PER_QUAD);
|
quadvert_t *verts = QFV_PacketExtend (packet, BYTES_PER_QUAD);
|
||||||
|
@ -512,6 +519,7 @@ pic_data (const char *name, int w, int h, const byte *data, vulkan_ctx_t *ctx)
|
||||||
__auto_type pd = (picdata_t *) pic->data;
|
__auto_type pd = (picdata_t *) pic->data;
|
||||||
pd->subpic = QFV_ScrapSubpic (dctx->scrap, w, h);
|
pd->subpic = QFV_ScrapSubpic (dctx->scrap, w, h);
|
||||||
pd->vert_index = make_static_quad (w, h, pic, ctx);
|
pd->vert_index = make_static_quad (w, h, pic, ctx);
|
||||||
|
pd->descid = 1;
|
||||||
|
|
||||||
picdata = QFV_SubpicBatch (pd->subpic, dctx->stage);
|
picdata = QFV_SubpicBatch (pd->subpic, dctx->stage);
|
||||||
size_t size = w * h;
|
size_t size = w * h;
|
||||||
|
@ -556,24 +564,117 @@ Vulkan_Draw_PicFromWad (const char *name, vulkan_ctx_t *ctx)
|
||||||
return pic_data (name, wadpic->width, wadpic->height, wadpic->data, ctx);
|
return pic_data (name, wadpic->width, wadpic->height, wadpic->data, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static qpic_t *
|
||||||
|
load_lmp (const char *path, vulkan_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
qpic_t *p;
|
||||||
|
if (strlen (path) < 4 || strcmp (path + strlen (path) - 4, ".lmp")
|
||||||
|
|| !(p = (qpic_t *) QFS_LoadFile (QFS_FOpenFile (path), 0))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
drawctx_t *dctx = ctx->draw_context;
|
||||||
|
int fontid = dctx->fonts.size;
|
||||||
|
DARRAY_OPEN_AT (&dctx->fonts, fontid, 1);
|
||||||
|
drawfont_t *font = &dctx->fonts.a[fontid];
|
||||||
|
|
||||||
|
font->resource = malloc (sizeof (drawfontres_t));
|
||||||
|
font->resource->resource = (qfv_resource_t) {
|
||||||
|
.name = va (ctx->va_ctx, "cachepic:%d", fontid),
|
||||||
|
.va_ctx = ctx->va_ctx,
|
||||||
|
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
.num_objects = 2,
|
||||||
|
.objects = &font->resource->glyph_image,
|
||||||
|
};
|
||||||
|
|
||||||
|
tex_t tex = {
|
||||||
|
.width = p->width,
|
||||||
|
.height = p->height,
|
||||||
|
.format = tex_rgba,
|
||||||
|
.loaded = 1,
|
||||||
|
.data = p->data,
|
||||||
|
};
|
||||||
|
QFV_ResourceInitTexImage (&font->resource->glyph_image, "image", 0, &tex);
|
||||||
|
__auto_type cache_image = &font->resource->glyph_image;
|
||||||
|
|
||||||
|
font->resource->glyph_iview = (qfv_resobj_t) {
|
||||||
|
.name = "image_view",
|
||||||
|
.type = qfv_res_image_view,
|
||||||
|
.image_view = {
|
||||||
|
.image = 0,
|
||||||
|
.type = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
.format = font->resource->glyph_image.image.format,
|
||||||
|
.aspect = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.components = {
|
||||||
|
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
__auto_type cache_iview = &font->resource->glyph_iview;
|
||||||
|
|
||||||
|
QFV_CreateResource (ctx->device, &font->resource->resource);
|
||||||
|
|
||||||
|
__auto_type packet = QFV_PacketAcquire (ctx->staging);
|
||||||
|
int count = tex.width * tex.height;
|
||||||
|
byte *texels = QFV_PacketExtend (packet, 4 * count);
|
||||||
|
Vulkan_ExpandPalette (texels, tex.data, vid.palette32, 2, count);
|
||||||
|
QFV_PacketCopyImage (packet, cache_image->image.image,
|
||||||
|
tex.width, tex.height,
|
||||||
|
&imageBarriers[qfv_LT_TransferDst_to_ShaderReadOnly]);
|
||||||
|
QFV_PacketSubmit (packet);
|
||||||
|
|
||||||
|
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (1, alloca);
|
||||||
|
layouts->a[0] = Vulkan_CreateDescriptorSetLayout (ctx, "quad_data_set");
|
||||||
|
__auto_type pool = Vulkan_CreateDescriptorPool (ctx, "quad_pool");
|
||||||
|
__auto_type cache_sets = QFV_AllocateDescriptorSet (device, pool, layouts);
|
||||||
|
font->set = cache_sets->a[0];
|
||||||
|
VkDescriptorImageInfo imageInfo = {
|
||||||
|
dctx->pic_sampler,
|
||||||
|
cache_iview->image_view.view,
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
};
|
||||||
|
VkWriteDescriptorSet write[] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||||
|
font->set, 0, 0, 1,
|
||||||
|
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
|
&imageInfo, 0, 0 },
|
||||||
|
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||||
|
font->set, 1, 0, 1,
|
||||||
|
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||||
|
0, 0, &dctx->svertex_objects[1].buffer_view.view },
|
||||||
|
};
|
||||||
|
dfunc->vkUpdateDescriptorSets (device->dev, 2, write, 0, 0);
|
||||||
|
free (cache_sets);
|
||||||
|
|
||||||
|
qpic_t *pic;
|
||||||
|
pic = cmemalloc (dctx->pic_memsuper,
|
||||||
|
field_offset (qpic_t, data[sizeof (picdata_t)]));
|
||||||
|
pic->width = p->width;
|
||||||
|
pic->height = p->height;
|
||||||
|
__auto_type pd = (picdata_t *) pic->data;
|
||||||
|
pd->subpic = 0;
|
||||||
|
pd->vert_index = make_static_quad (p->width, p->height, pic, ctx);
|
||||||
|
pd->descid = fontid;
|
||||||
|
|
||||||
|
free (p);
|
||||||
|
return pic;
|
||||||
|
}
|
||||||
|
|
||||||
qpic_t *
|
qpic_t *
|
||||||
Vulkan_Draw_CachePic (const char *path, qboolean alpha, vulkan_ctx_t *ctx)
|
Vulkan_Draw_CachePic (const char *path, qboolean alpha, vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
qpic_t *p;
|
|
||||||
qpic_t *pic;
|
|
||||||
cachepic_t *cpic;
|
cachepic_t *cpic;
|
||||||
drawctx_t *dctx = ctx->draw_context;
|
drawctx_t *dctx = ctx->draw_context;
|
||||||
|
|
||||||
if ((cpic = Hash_Find (dctx->pic_cache, path))) {
|
if ((cpic = Hash_Find (dctx->pic_cache, path))) {
|
||||||
return cpic->pic;
|
return cpic->pic;
|
||||||
}
|
}
|
||||||
if (strlen (path) < 4 || strcmp (path + strlen (path) - 4, ".lmp")
|
qpic_t *pic = load_lmp (path, ctx);;
|
||||||
|| !(p = (qpic_t *) QFS_LoadFile (QFS_FOpenFile (path), 0))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pic = pic_data (path, p->width, p->height, p->data, ctx);
|
|
||||||
free (p);
|
|
||||||
cpic = new_cachepic (dctx, path, pic);
|
cpic = new_cachepic (dctx, path, pic);
|
||||||
Hash_Add (dctx->pic_cache, cpic);
|
Hash_Add (dctx->pic_cache, cpic);
|
||||||
return pic;
|
return pic;
|
||||||
|
@ -595,12 +696,11 @@ Vulkan_Draw_Shutdown (vulkan_ctx_t *ctx)
|
||||||
|
|
||||||
QFV_DestroyResource (device, &dctx->draw_resource[0]);
|
QFV_DestroyResource (device, &dctx->draw_resource[0]);
|
||||||
QFV_DestroyResource (device, &dctx->draw_resource[1]);
|
QFV_DestroyResource (device, &dctx->draw_resource[1]);
|
||||||
// the first two "fonts" are reserved for the dynamic and core quad data
|
for (size_t i = 0; i < dctx->fonts.size; i++) {
|
||||||
// sets and thus does not have its own resources (they are created
|
if (dctx->fonts.a[i].resource) {
|
||||||
// separately)
|
QFV_DestroyResource (device, &dctx->fonts.a[i].resource->resource);
|
||||||
for (size_t i = 2; i < dctx->fonts.size; i++) {
|
free (dctx->fonts.a[i].resource);
|
||||||
QFV_DestroyResource (device, &dctx->fonts.a[i].resource->resource);
|
}
|
||||||
free (dctx->fonts.a[i].resource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dfunc->vkDestroyPipeline (device->dev, dctx->quad_pipeline, 0);
|
dfunc->vkDestroyPipeline (device->dev, dctx->quad_pipeline, 0);
|
||||||
|
@ -1077,7 +1177,7 @@ Vulkan_Draw_Pic (int x, int y, qpic_t *pic, vulkan_ctx_t *ctx)
|
||||||
|
|
||||||
static byte color[4] = { 255, 255, 255, 255};
|
static byte color[4] = { 255, 255, 255, 255};
|
||||||
__auto_type pd = (picdata_t *) pic->data;
|
__auto_type pd = (picdata_t *) pic->data;
|
||||||
draw_quad (x, y, 1, pd->vert_index, color, frame);
|
draw_quad (x, y, pd->descid, pd->vert_index, color, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1088,7 +1188,7 @@ Vulkan_Draw_Picf (float x, float y, qpic_t *pic, vulkan_ctx_t *ctx)
|
||||||
|
|
||||||
static byte color[4] = { 255, 255, 255, 255};
|
static byte color[4] = { 255, 255, 255, 255};
|
||||||
__auto_type pd = (picdata_t *) pic->data;
|
__auto_type pd = (picdata_t *) pic->data;
|
||||||
draw_quad (x, y, 1, pd->vert_index, color, frame);
|
draw_quad (x, y, pd->descid, pd->vert_index, color, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue