From 82d0b7ecd5fac48cf1c0422adaf18264594ec21c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 5 Jan 2023 16:00:05 +0900 Subject: [PATCH] [vulkan] Use slice pipeline for glyphs It turns out the slice pipeline is compatible with the glyph pipeline in that its vertex attribute data is a superset (just the addition of the offset attributes). While the queues have yet to be merged, this will eventually get glyphs, sliced sprites, and general (static) quads into the one pipeline. Although this is slightly slower for glyph rendering (due to the need to pass an extra 8 bytes per glyph), this should be faster for quad rendering (when done) as it will be 24 bytes per quad instead of 32 bytes per vertex (ie, 128 bytes per quad), but this does serve as a proof of concept for doing quads, glyphs and sprites in the one pipeline. --- libs/video/renderer/Makemodule.am | 6 ---- libs/video/renderer/vulkan/pl_quake_def.plist | 22 -------------- libs/video/renderer/vulkan/shader.c | 3 -- libs/video/renderer/vulkan/shader/glyph.vert | 30 ------------------- libs/video/renderer/vulkan/shader/slice.vert | 8 ++--- libs/video/renderer/vulkan/vulkan_draw.c | 25 ++++++---------- 6 files changed, 13 insertions(+), 81 deletions(-) delete mode 100644 libs/video/renderer/vulkan/shader/glyph.vert diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index 316f9449e..d21ecf882 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -283,8 +283,6 @@ vkshaderpath = libs/video/renderer/vulkan/shader slice_src = $(vkshaderpath)/slice.vert slice_c = $(vkshaderpath)/slice.vert.spvc -glyphv_src = $(vkshaderpath)/glyph.vert -glyphv_c = $(vkshaderpath)/glyph.vert.spvc linev_src = $(vkshaderpath)/line.vert linev_c = $(vkshaderpath)/line.vert.spvc linef_src = $(vkshaderpath)/line.frag @@ -370,8 +368,6 @@ waterwarp_c = $(vkshaderpath)/waterwarp.frag.spvc $(slice_vert_c): $(slice_vert_src) $(matrices_h) -$(glyphv_c): $(glyphv_src) $(matrices_h) - $(linev_c): $(linev_src) $(matrices_h) $(linef_c): $(linef_src) @@ -445,7 +441,6 @@ $(waterwarp_c): $(waterwarp_src) $(matrices_h) vkshader_c = \ $(slice_c) \ - $(glyphv_c) \ $(linev_c) \ $(linef_c) \ $(partphysicsc_c) \ @@ -530,7 +525,6 @@ EXTRA_DIST += \ $(matrices_h) \ $(entity_h) \ $(slice_src) \ - $(glyphv_src) \ $(linev_src) \ $(linef_src) \ $(partphysicsc_src) \ diff --git a/libs/video/renderer/vulkan/pl_quake_def.plist b/libs/video/renderer/vulkan/pl_quake_def.plist index dcd8f55fe..76a37030c 100644 --- a/libs/video/renderer/vulkan/pl_quake_def.plist +++ b/libs/video/renderer/vulkan/pl_quake_def.plist @@ -1205,28 +1205,6 @@ }; layout = glyph_layout;//slices use the same descriptors as glyphs }; - glyph = { - @inherit = $properties.pipelines.trans_base; - renderPass = output; - subpass = 0; - stages = ( - { stage = vertex; name = main; module = $builtin/glyph.vert; }, - { stage = fragment; name = main; module = $builtin/twod.frag; }, - ); - vertexInput = $properties.vertexInput.glyph; - inputAssembly = { - // glyphs are drawn using instanced quads, so primitive restart - // is not needed as only four vertices are drawn per instance. - topology = triangle_strip; - primitiveRestartEnable = false; - }; - rasterization = $properties.rasterization.counter_cw_cull_back; - colorBlend = { - logicOpEnable = false; - attachments = ($properties.attachmentBlendOp.alpha_blend); - }; - layout = glyph_layout; - }; lines = { @inherit = $properties.pipelines.twod; stages = ( diff --git a/libs/video/renderer/vulkan/shader.c b/libs/video/renderer/vulkan/shader.c index 954e386ae..cde12f5b8 100644 --- a/libs/video/renderer/vulkan/shader.c +++ b/libs/video/renderer/vulkan/shader.c @@ -41,8 +41,6 @@ static #include "libs/video/renderer/vulkan/shader/slice.vert.spvc" static -#include "libs/video/renderer/vulkan/shader/glyph.vert.spvc" -static #include "libs/video/renderer/vulkan/shader/line.vert.spvc" static #include "libs/video/renderer/vulkan/shader/line.frag.spvc" @@ -127,7 +125,6 @@ typedef struct shaderdata_s { static shaderdata_t builtin_shaders[] = { { "slice.vert", slice_vert, sizeof (slice_vert) }, - { "glyph.vert", glyph_vert, sizeof (glyph_vert) }, { "line.vert", line_vert, sizeof (line_vert) }, { "line.frag", line_frag, sizeof (line_frag) }, { "particle.vert", particle_vert, sizeof (particle_vert) }, diff --git a/libs/video/renderer/vulkan/shader/glyph.vert b/libs/video/renderer/vulkan/shader/glyph.vert deleted file mode 100644 index 7c21dc2a5..000000000 --- a/libs/video/renderer/vulkan/shader/glyph.vert +++ /dev/null @@ -1,30 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : enable - -layout (set = 0, binding = 0) uniform -#include "matrices.h" -; -layout (set = 1, binding = 1) uniform textureBuffer glyph_data; - -// per instance data -layout (location = 0) in uint glyph_index; -layout (location = 1) in vec4 glyph_color; -layout (location = 2) in vec2 glyph_position; - -// rg -> offset x,y -// ba -> texture u,v - -layout (location = 0) out vec2 uv; -layout (location = 1) out vec4 color; - -void -main (void) -{ - vec4 glyph = texelFetch (glyph_data, int(glyph_index) * 4 + gl_VertexIndex); - // offset stored in glyph components 0 and 1 - vec2 position = glyph_position + glyph.xy; - gl_Position = Projection2d * vec4 (position.xy, 0.0, 1.0); - // texture uv stored in glyph components 2 and 3 - uv = glyph.pq; - color = glyph_color; -} diff --git a/libs/video/renderer/vulkan/shader/slice.vert b/libs/video/renderer/vulkan/shader/slice.vert index 676dd0ed5..ca67404cd 100644 --- a/libs/video/renderer/vulkan/shader/slice.vert +++ b/libs/video/renderer/vulkan/shader/slice.vert @@ -4,6 +4,9 @@ layout (set = 0, binding = 0) uniform #include "matrices.h" ; + +// rg -> offset x,y +// ba -> texture u,v layout (set = 1, binding = 1) uniform textureBuffer glyph_data; // per instance data @@ -12,9 +15,6 @@ layout (location = 1) in vec4 glyph_color; layout (location = 2) in vec2 glyph_position; layout (location = 3) in vec2 glyph_offset; // for 9-slice -// rg -> offset x,y -// ba -> texture u,v - layout (location = 0) out vec2 uv; layout (location = 1) out vec4 color; @@ -22,7 +22,7 @@ void main (void) { vec2 offset = vec2 ((gl_VertexIndex & 4) >> 2, (gl_VertexIndex & 8) >> 3); - vec4 glyph = texelFetch (glyph_data, int(glyph_index) * 4 + gl_VertexIndex); + vec4 glyph = texelFetch (glyph_data, int(glyph_index + gl_VertexIndex)); // offset stored in glyph components 0 and 1 vec2 position = glyph_position + glyph.xy + offset * glyph_offset; gl_Position = Projection2d * vec4 (position.xy, 0.0, 1.0); diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 67d5a1bee..009f78b76 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -101,12 +101,6 @@ typedef struct { float offset[2]; } sliceinst_t; -typedef struct { - uint32_t index; - byte color[4]; - float position[2]; -} glyphinst_t; - typedef struct { float offset[2]; float uv[2]; @@ -130,7 +124,7 @@ typedef struct slicequeue_s { } slicequeue_t; typedef struct glyphqueue_s { - glyphinst_t *glyphs; + sliceinst_t *glyphs; int count; int size; } glyphqueue_t; @@ -198,7 +192,6 @@ typedef struct drawctx_s { qfv_resobj_t *line_objects; VkPipeline quad_pipeline; VkPipeline slice_pipeline; - VkPipeline glyph_pipeline; VkPipeline line_pipeline; VkPipelineLayout layout; VkPipelineLayout glyph_layout;//slice pipeline uses same layout @@ -338,7 +331,7 @@ create_quad_buffers (vulkan_ctx_t *ctx) .name = "glyphs.inst", .type = qfv_res_buffer, .buffer = { - .size = MAX_GLYPHS * sizeof (glyphinst_t), + .size = MAX_GLYPHS * sizeof (sliceinst_t), .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, }, @@ -382,7 +375,7 @@ create_quad_buffers (vulkan_ctx_t *ctx) }; DARRAY_INIT (&frame->slice_batch, 16); frame->glyph_insts = (glyphqueue_t) { - .glyphs = (glyphinst_t *) ((byte *)data + frame->glyph_offset), + .glyphs = (sliceinst_t *) ((byte *)data + frame->glyph_offset), .size = MAX_QUADS, }; DARRAY_INIT (&frame->glyph_batch, 16); @@ -545,7 +538,6 @@ Vulkan_Draw_Shutdown (vulkan_ctx_t *ctx) dfunc->vkDestroyPipeline (device->dev, dctx->quad_pipeline, 0); dfunc->vkDestroyPipeline (device->dev, dctx->slice_pipeline, 0); - dfunc->vkDestroyPipeline (device->dev, dctx->glyph_pipeline, 0); dfunc->vkDestroyPipeline (device->dev, dctx->line_pipeline, 0); Hash_DelTable (dctx->pic_cache); delete_memsuper (dctx->pic_memsuper); @@ -620,7 +612,6 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) dctx->quad_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "twod"); dctx->slice_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "slice"); - dctx->glyph_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "glyph"); dctx->line_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "lines"); dctx->layout = Vulkan_CreatePipelineLayout (ctx, "twod_layout"); @@ -1319,7 +1310,7 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame) a(dframe->slice_insts.count * sizeof (sliceinst_t)) }, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, memory, dframe->glyph_offset, - a(dframe->glyph_insts.count * sizeof (glyphinst_t)) }, + a(dframe->glyph_insts.count * sizeof (sliceinst_t)) }, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, memory, dframe->line_offset, a(dframe->line_verts.count * VERTS_PER_LINE * sizeof (drawvert_t)) }, @@ -1343,7 +1334,7 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame) draw_slices (rFrame, dframe->cmdSet.a[QFV_draw2d]); } if (dframe->glyph_insts.count) { - bind_pipeline (rFrame, dctx->glyph_pipeline, + bind_pipeline (rFrame, dctx->slice_pipeline, dframe->cmdSet.a[QFV_draw2d]); draw_glyphs (rFrame, dframe->cmdSet.a[QFV_draw2d]); } @@ -1536,12 +1527,14 @@ Vulkan_Draw_Glyph (int x, int y, int fontid, int glyph, int c, } batch->count++; - glyphinst_t *inst = &queue->glyphs[queue->count++]; - inst->index = glyph; + sliceinst_t *inst = &queue->glyphs[queue->count++]; + inst->index = glyph * 4; // index is actual vertex index VectorCopy (vid.palette + c * 3, inst->color); inst->color[3] = 255; inst->position[0] = x; inst->position[1] = y; + inst->offset[0] = 0; + inst->offset[1] = 0; } void