[vulkan] Use vertex queue objects for Draw

This makes working with quads, implied alpha quads, and lines much
cleaner (and gets rid of the bulk of the "eww" fixme), and will probably
make it easier to support multiple scraps and fonts, and potentially
more flexible ordering between pipelines.
This commit is contained in:
Bill Currie 2022-09-09 17:06:33 +09:00
parent a6611fc827
commit 936f6d91e4
1 changed files with 56 additions and 51 deletions

View File

@ -83,16 +83,19 @@ typedef struct cachepic_s {
qpic_t *pic; qpic_t *pic;
} cachepic_t; } cachepic_t;
typedef struct vertqueue_s {
drawvert_t *verts;
int count;
int size;
} vertqueue_t;
typedef struct drawframe_s { typedef struct drawframe_s {
size_t vert_offset; size_t vert_offset;
size_t iavert_offset; size_t iavert_offset;
size_t line_offset; size_t line_offset;
drawvert_t *quad_verts; vertqueue_t quad_verts;
drawvert_t *iaquad_verts; vertqueue_t iaquad_verts;
drawvert_t *line_verts; vertqueue_t line_verts;
uint32_t num_quads;
uint32_t num_iaquads;
uint32_t num_lines;
VkCommandBuffer cmd; VkCommandBuffer cmd;
VkDescriptorSet descriptors; VkDescriptorSet descriptors;
VkDescriptorSet iadescriptors; VkDescriptorSet iadescriptors;
@ -190,11 +193,18 @@ create_quad_buffers (vulkan_ctx_t *ctx)
frame->vert_offset = ind * sizeof (drawvert_t); frame->vert_offset = ind * sizeof (drawvert_t);
frame->iavert_offset = iaind; frame->iavert_offset = iaind;
frame->line_offset = lind; frame->line_offset = lind;
frame->quad_verts = vert_data + ind; frame->quad_verts = (vertqueue_t) {
frame->iaquad_verts = frame->quad_verts + IAQUADS_OFFSET; .verts = vert_data + ind,
frame->line_verts = frame->quad_verts + LINES_OFFSET; .size = MAX_QUADS,
frame->num_quads = 0; };
frame->num_lines = 0; frame->iaquad_verts = (vertqueue_t) {
.verts = frame->quad_verts.verts + IAQUADS_OFFSET,
.size = MAX_QUADS,
};
frame->line_verts = (vertqueue_t) {
.verts = frame->quad_verts.verts + LINES_OFFSET,
.size = MAX_LINES,
};
} }
// The indices will never change so pre-generate and stash them // The indices will never change so pre-generate and stash them
@ -502,14 +512,14 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx)
static inline void static inline void
draw_pic (float x, float y, int w, int h, qpic_t *pic, draw_pic (float x, float y, int w, int h, qpic_t *pic,
int srcx, int srcy, int srcw, int srch, int srcx, int srcy, int srcw, int srch,
float *color, drawframe_t *frame) float *color, vertqueue_t *queue)
{ {
if (frame->num_quads >= MAX_QUADS) { if (queue->count >= queue->size) {
return; return;
} }
drawvert_t *verts = frame->quad_verts + frame->num_quads * VERTS_PER_QUAD; drawvert_t *verts = queue->verts + queue->count * VERTS_PER_QUAD;
frame->num_quads++; queue->count++;
subpic_t *subpic = *(subpic_t **) pic->data; subpic_t *subpic = *(subpic_t **) pic->data;
srcx += subpic->rect->x; srcx += subpic->rect->x;
@ -557,7 +567,8 @@ queue_character (int x, int y, byte chr, vulkan_ctx_t *ctx)
cx = chr % 16; cx = chr % 16;
cy = chr / 16; cy = chr / 16;
draw_pic (x, y, 8, 8, dctx->conchars, cx * 8, cy * 8, 8, 8, color, frame); draw_pic (x, y, 8, 8, dctx->conchars, cx * 8, cy * 8, 8, 8, color,
&frame->quad_verts);
} }
void void
@ -656,7 +667,7 @@ draw_crosshair_pic (int ch, int x, int y, vulkan_ctx_t *ctx)
draw_pic (x - CROSSHAIR_WIDTH + 1, y - CROSSHAIR_HEIGHT + 1, draw_pic (x - CROSSHAIR_WIDTH + 1, y - CROSSHAIR_HEIGHT + 1,
CROSSHAIR_WIDTH * 2, CROSSHAIR_HEIGHT * 2, dctx->crosshair, CROSSHAIR_WIDTH * 2, CROSSHAIR_HEIGHT * 2, dctx->crosshair,
p[0], p[1], p[2], p[3], crosshair_color, frame); p[0], p[1], p[2], p[3], crosshair_color, &frame->quad_verts);
} }
static void (*crosshair_func[]) (int ch, int x, int y, vulkan_ctx_t *ctx) = { static void (*crosshair_func[]) (int ch, int x, int y, vulkan_ctx_t *ctx) = {
@ -701,7 +712,7 @@ Vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha,
int cx, cy, n; int cx, cy, n;
#define draw(px, py, pp) \ #define draw(px, py, pp) \
draw_pic (px, py, pp->width, pp->height, pp, \ draw_pic (px, py, pp->width, pp->height, pp, \
0, 0, pp->width, pp->height, color, frame); 0, 0, pp->width, pp->height, color, &frame->quad_verts);
color[3] = alpha; color[3] = alpha;
// draw left side // draw left side
@ -758,7 +769,7 @@ Vulkan_Draw_Pic (int x, int y, qpic_t *pic, vulkan_ctx_t *ctx)
static quat_t color = { 1, 1, 1, 1}; static quat_t color = { 1, 1, 1, 1};
draw_pic (x, y, pic->width, pic->height, pic, draw_pic (x, y, pic->width, pic->height, pic,
0, 0, pic->width, pic->height, color, frame); 0, 0, pic->width, pic->height, color, &frame->quad_verts);
} }
void void
@ -769,7 +780,7 @@ Vulkan_Draw_Picf (float x, float y, qpic_t *pic, vulkan_ctx_t *ctx)
static quat_t color = { 1, 1, 1, 1}; static quat_t color = { 1, 1, 1, 1};
draw_pic (x, y, pic->width, pic->height, pic, draw_pic (x, y, pic->width, pic->height, pic,
0, 0, pic->width, pic->height, color, frame); 0, 0, pic->width, pic->height, color, &frame->quad_verts);
} }
void void
@ -782,7 +793,7 @@ Vulkan_Draw_SubPic (int x, int y, qpic_t *pic,
static quat_t color = { 1, 1, 1, 1}; static quat_t color = { 1, 1, 1, 1};
draw_pic (x, y, width, height, pic, srcx, srcy, width, height, draw_pic (x, y, width, height, pic, srcx, srcy, width, height,
color, frame); color, &frame->quad_verts);
} }
void void
@ -799,7 +810,7 @@ Vulkan_Draw_ConsoleBackground (int lines, byte alpha, vulkan_ctx_t *ctx)
int ofs = max (0, cpic->height - lines); int ofs = max (0, cpic->height - lines);
lines = min (lines, cpic->height); lines = min (lines, cpic->height);
draw_pic (0, 0, vid.conview->xlen, lines, cpic, draw_pic (0, 0, vid.conview->xlen, lines, cpic,
0, ofs, cpic->width, lines, color, frame); 0, ofs, cpic->width, lines, color, &frame->quad_verts);
} }
void void
@ -817,7 +828,8 @@ Vulkan_Draw_Fill (int x, int y, int w, int h, int c, vulkan_ctx_t *ctx)
VectorScale (vid.palette + c * 3, 1.0f/255.0f, color); VectorScale (vid.palette + c * 3, 1.0f/255.0f, color);
color[3] = 1; color[3] = 1;
draw_pic (x, y, w, h, dctx->white_pic, 0, 0, 1, 1, color, frame); draw_pic (x, y, w, h, dctx->white_pic, 0, 0, 1, 1, color,
&frame->quad_verts);
} }
void void
@ -825,14 +837,15 @@ Vulkan_Draw_Line (int x0, int y0, int x1, int y1, int c, vulkan_ctx_t *ctx)
{ {
drawctx_t *dctx = ctx->draw_context; drawctx_t *dctx = ctx->draw_context;
drawframe_t *frame = &dctx->frames.a[ctx->curFrame]; drawframe_t *frame = &dctx->frames.a[ctx->curFrame];
vertqueue_t *queue = &frame->line_verts;
if (frame->num_quads >= MAX_QUADS) { if (queue->count >= queue->size) {
return; return;
} }
quat_t color = { VectorExpand (vid.palette + c * 3), 255 }; quat_t color = { VectorExpand (vid.palette + c * 3), 255 };
QuatScale (color, 1/255.0, color); QuatScale (color, 1/255.0, color);
drawvert_t *verts = frame->line_verts + frame->num_lines * VERTS_PER_LINE; drawvert_t *verts = queue->verts + queue->count * VERTS_PER_LINE;
verts[0] = (drawvert_t) { verts[0] = (drawvert_t) {
.xy = { x0, y0 }, .xy = { x0, y0 },
@ -843,7 +856,7 @@ Vulkan_Draw_Line (int x0, int y0, int x1, int y1, int c, vulkan_ctx_t *ctx)
.color = { QuatExpand (color) }, .color = { QuatExpand (color) },
}; };
frame->num_lines++; queue->count++;
} }
static inline void static inline void
@ -853,7 +866,7 @@ draw_blendscreen (quat_t color, vulkan_ctx_t *ctx)
drawframe_t *frame = &dctx->frames.a[ctx->curFrame]; drawframe_t *frame = &dctx->frames.a[ctx->curFrame];
draw_pic (0, 0, vid.conview->xlen, vid.conview->ylen, dctx->white_pic, draw_pic (0, 0, vid.conview->xlen, vid.conview->ylen, dctx->white_pic,
0, 0, 1, 1, color, frame); 0, 0, 1, 1, color, &frame->quad_verts);
} }
void void
@ -895,7 +908,8 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
drawctx_t *dctx = ctx->draw_context; drawctx_t *dctx = ctx->draw_context;
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame]; drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
if (!dframe->num_quads && !dframe->num_iaquads && !dframe->num_lines) { if (!dframe->quad_verts.count && !dframe->iaquad_verts.count
&& !dframe->line_verts.count) {
return; return;
} }
@ -906,13 +920,13 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
VkMappedMemoryRange ranges[] = { VkMappedMemoryRange ranges[] = {
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
dctx->vert_memory, dframe->vert_offset, dctx->vert_memory, dframe->vert_offset,
dframe->num_quads * VERTS_PER_QUAD * sizeof (drawvert_t) }, dframe->quad_verts.count * VERTS_PER_QUAD * sizeof (drawvert_t) },
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
dctx->vert_memory, dframe->iavert_offset, dctx->vert_memory, dframe->iavert_offset,
dframe->num_iaquads * VERTS_PER_QUAD * sizeof (drawvert_t) }, dframe->iaquad_verts.count * VERTS_PER_QUAD * sizeof (drawvert_t) },
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
dctx->vert_memory, dframe->line_offset, dctx->vert_memory, dframe->line_offset,
dframe->num_lines * VERTS_PER_LINE * sizeof (drawvert_t) }, dframe->line_verts.count * VERTS_PER_LINE * sizeof (drawvert_t) },
}; };
dfunc->vkFlushMappedMemoryRanges (device->dev, 2, ranges); dfunc->vkFlushMappedMemoryRanges (device->dev, 2, ranges);
@ -936,7 +950,7 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &dctx->vert_buffer, offsets); dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &dctx->vert_buffer, offsets);
dfunc->vkCmdBindIndexBuffer (cmd, dctx->ind_buffer, 0, dfunc->vkCmdBindIndexBuffer (cmd, dctx->ind_buffer, 0,
VK_INDEX_TYPE_UINT32); VK_INDEX_TYPE_UINT32);
if (dframe->num_quads) { if (dframe->quad_verts.count) {
VkDescriptorSet set[2] = { VkDescriptorSet set[2] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
dframe->descriptors, dframe->descriptors,
@ -949,10 +963,10 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
dctx->quad_pipeline); dctx->quad_pipeline);
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport); dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor); dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
dfunc->vkCmdDrawIndexed (cmd, dframe->num_quads * INDS_PER_QUAD, dfunc->vkCmdDrawIndexed (cmd, dframe->quad_verts.count * INDS_PER_QUAD,
1, 0, QUADS_OFFSET, 0); 1, 0, QUADS_OFFSET, 0);
} }
if (dframe->num_iaquads) { if (dframe->iaquad_verts.count) {
VkDescriptorImageInfo iaimageInfo = { VkDescriptorImageInfo iaimageInfo = {
dctx->sampler, dctx->sampler,
Vulkan_TexImageView (dctx->font_tex), Vulkan_TexImageView (dctx->font_tex),
@ -978,11 +992,11 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
dctx->iaquad_pipeline); dctx->iaquad_pipeline);
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport); dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor); dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
dfunc->vkCmdDrawIndexed (cmd, dframe->num_iaquads * INDS_PER_QUAD, dfunc->vkCmdDrawIndexed (cmd, dframe->iaquad_verts.count*INDS_PER_QUAD,
1, 0, IAQUADS_OFFSET, 0); 1, 0, IAQUADS_OFFSET, 0);
} }
if (dframe->num_lines) { if (dframe->line_verts.count) {
VkDescriptorSet set[2] = { VkDescriptorSet set[2] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
dframe->descriptors, dframe->descriptors,
@ -993,16 +1007,16 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
dctx->line_pipeline); dctx->line_pipeline);
dfunc->vkCmdDraw (cmd, dframe->num_lines * VERTS_PER_LINE, dfunc->vkCmdDraw (cmd, dframe->line_verts.count * VERTS_PER_LINE,
1, LINES_OFFSET, 0); 1, LINES_OFFSET, 0);
} }
QFV_duCmdEndLabel (device, cmd); QFV_duCmdEndLabel (device, cmd);
dfunc->vkEndCommandBuffer (cmd); dfunc->vkEndCommandBuffer (cmd);
dframe->num_quads = 0; dframe->quad_verts.count = 0;
dframe->num_iaquads = 0; dframe->iaquad_verts.count = 0;
dframe->num_lines = 0; dframe->line_verts.count = 0;
} }
void void
@ -1058,7 +1072,7 @@ vulkan_render_glyph (rglyph_t *glyph, int x, int y, void *_rgctx)
int gw = glyph->rect->width; int gw = glyph->rect->width;
int gh = glyph->rect->height; int gh = glyph->rect->height;
draw_pic (x, y, gw, gh, &rgctx->pic, 0, 0, gw, gh, rgctx->color, draw_pic (x, y, gw, gh, &rgctx->pic, 0, 0, gw, gh, rgctx->color,
rgctx->dframe); &rgctx->dframe->iaquad_verts);
} }
void void
@ -1068,13 +1082,9 @@ Vulkan_Draw_FontString (int x, int y, const char *str, vulkan_ctx_t *ctx)
if (!dctx->font) { if (!dctx->font) {
return; return;
} }
//FIXME ewwwwwww
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame]; drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
uint32_t num_quads = dframe->num_quads;
drawvert_t *quad_verts = dframe->quad_verts;
dframe->num_quads = dframe->num_iaquads;
dframe->quad_verts = dframe->iaquad_verts;
//FIXME ewwwwwww
subpic_t glyph_subpic = { subpic_t glyph_subpic = {
.width = dctx->font->scrap.width, .width = dctx->font->scrap.width,
.height = dctx->font->scrap.height, .height = dctx->font->scrap.height,
@ -1099,9 +1109,4 @@ Vulkan_Draw_FontString (int x, int y, const char *str, vulkan_ctx_t *ctx)
rshaper_t *shaper = RText_NewShaper (dctx->font); rshaper_t *shaper = RText_NewShaper (dctx->font);
RText_RenderText (shaper, &text, x, y, vulkan_render_glyph, &rgctx); RText_RenderText (shaper, &text, x, y, vulkan_render_glyph, &rgctx);
RText_DeleteShaper (shaper); RText_DeleteShaper (shaper);
dframe->num_iaquads = dframe->num_quads;
dframe->iaquad_verts = dframe->quad_verts;
dframe->num_quads = num_quads;
dframe->quad_verts = quad_verts;
} }