[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.
This commit is contained in:
Bill Currie 2023-01-05 16:00:05 +09:00
parent 3da90b612f
commit 82d0b7ecd5
6 changed files with 13 additions and 81 deletions

View file

@ -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) \

View file

@ -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 = (

View file

@ -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) },

View file

@ -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;
}

View file

@ -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);

View file

@ -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