[vulkan] Add support for 9-slice rendering

There's no API yet as I need to look into the handling of qpic_t before
I can get any of this into the other renderers (or even vulkan, for that
matter).

However, the current design for slice rendering is based on glyphs (ie,
using instances and vertex pulling), with 3 strips of 3 quads, 16 verts,
and 26 indices (2 reset). Hacky testing seems to work, but real tests
need the API.
This commit is contained in:
Bill Currie 2022-11-18 09:44:01 +09:00
parent b1d7bad2e3
commit bffe9413b7
5 changed files with 221 additions and 32 deletions

View file

@ -275,6 +275,8 @@ vkparse_plist = \
vkshaderpath = libs/video/renderer/vulkan/shader vkshaderpath = libs/video/renderer/vulkan/shader
slice_src = $(vkshaderpath)/slice.vert
slice_c = $(vkshaderpath)/slice.vert.spvc
glyph_src = $(vkshaderpath)/glyph.vert glyph_src = $(vkshaderpath)/glyph.vert
glyph_c = $(vkshaderpath)/glyph.vert.spvc glyph_c = $(vkshaderpath)/glyph.vert.spvc
glyph_color_src = $(vkshaderpath)/glyph_color.frag glyph_color_src = $(vkshaderpath)/glyph_color.frag
@ -351,6 +353,8 @@ fstriangle_c = $(vkshaderpath)/fstriangle.vert.spvc
pushcolor_src = $(vkshaderpath)/pushcolor.frag pushcolor_src = $(vkshaderpath)/pushcolor.frag
pushcolor_c = $(vkshaderpath)/pushcolor.frag.spvc pushcolor_c = $(vkshaderpath)/pushcolor.frag.spvc
$(slice_vert_c): $(slice_vert_src)
$(glyph_vert_c): $(glyph_vert_src) $(glyph_vert_c): $(glyph_vert_src)
$(glyph_color_c): $(glyph_color_src) $(glyph_color_c): $(glyph_color_src)
$(glyph_coverage_c): $(glyph_coverage_src) $(glyph_coverage_c): $(glyph_coverage_src)
@ -419,6 +423,7 @@ $(fstriangle_c): $(fstriangle_src)
$(pushcolor_c): $(pushcolor_src) $(pushcolor_c): $(pushcolor_src)
vkshader_c = \ vkshader_c = \
$(slice_c) \
$(glyph_c) \ $(glyph_c) \
$(glyph_color_c) \ $(glyph_color_c) \
$(glyph_coverage_c) \ $(glyph_coverage_c) \

View file

@ -582,6 +582,21 @@
{ location = 2; binding = 1; format = r32_uint; offset = 0; }, { location = 2; binding = 1; format = r32_uint; offset = 0; },
); );
}; };
slice = {
bindings = (
{ binding = 0; stride = "4 + 4 + 4 * 4"; inputRate = instance; },
);
attributes = (
// 9-slice index
{ location = 0; binding = 0; format = r32_uint; offset = 0; },
// 9-slice color
{ location = 1; binding = 0; format = r8g8b8a8_unorm; offset = 4; },
// 9-slice position (2d)
{ location = 2; binding = 0; format = r32g32_sfloat; offset = 8; },
// 9-slice size delta (2d)
{ location = 3; binding = 0; format = r32g32_sfloat; offset = 16; },
);
};
glyph = { glyph = {
bindings = ( bindings = (
{ binding = 0; stride = "4 + 4 + 2 * 4"; inputRate = instance; }, { binding = 0; stride = "4 + 4 + 2 * 4"; inputRate = instance; },
@ -1115,6 +1130,25 @@
}; };
layout = twod_layout; layout = twod_layout;
}; };
slice = {
@inherit = $properties.pipelines.trans_base;//FIXME should be sparate
stages = (
{ stage = vertex; name = main; module = $builtin/slice.vert; },
{ stage = fragment; name = main; module = $builtin/glyph_color.frag; },
);
vertexInput = $properties.vertexInput.slice;
inputAssembly = {
// slices are drawn using instanced slice triples
topology = triangle_strip;
primitiveRestartEnable = true;
};
rasterization = $properties.rasterization.counter_cw_cull_back;
colorBlend = {
logicOpEnable = false;
attachments = ($properties.attachmentBlendOp.alpha_blend);
};
layout = glyph_layout;//slices use the same descriptors as glyphs
};
glyph = { glyph = {
@inherit = $properties.pipelines.trans_base;//FIXME should be sparate @inherit = $properties.pipelines.trans_base;//FIXME should be sparate
vertexInput = $properties.vertexInput.glyph; vertexInput = $properties.vertexInput.glyph;

View file

@ -38,6 +38,8 @@
#include "QF/Vulkan/device.h" #include "QF/Vulkan/device.h"
#include "QF/Vulkan/shader.h" #include "QF/Vulkan/shader.h"
static
#include "libs/video/renderer/vulkan/shader/slice.vert.spvc"
static static
#include "libs/video/renderer/vulkan/shader/glyph.vert.spvc" #include "libs/video/renderer/vulkan/shader/glyph.vert.spvc"
static static
@ -120,6 +122,7 @@ typedef struct shaderdata_s {
} shaderdata_t; } shaderdata_t;
static shaderdata_t builtin_shaders[] = { static shaderdata_t builtin_shaders[] = {
{ "slice.vert", slice_vert, sizeof (slice_vert) },
{ "glyph.vert", glyph_vert, sizeof (glyph_vert) }, { "glyph.vert", glyph_vert, sizeof (glyph_vert) },
{ "glyph_color.frag", glyph_color_frag, sizeof (glyph_color_frag) }, { "glyph_color.frag", glyph_color_frag, sizeof (glyph_color_frag) },
{ "glyph_coverage.frag", glyph_coverage_frag, sizeof (glyph_coverage_frag) }, { "glyph_coverage.frag", glyph_coverage_frag, sizeof (glyph_coverage_frag) },

View file

@ -0,0 +1,34 @@
#version 450
layout (set = 0, binding = 0) uniform Matrices {
mat4 Projection3d;
mat4 View;
mat4 Sky;
mat4 Projection2d;
};
layout (set = 1, binding = 0) 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;
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;
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);
// 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);
// texture uv stored in glyph components 2 and 3
uv = glyph.pq;
color = glyph_color;
}

View file

@ -87,6 +87,13 @@ typedef struct {
float color[4]; float color[4];
} drawvert_t; } drawvert_t;
typedef struct {
uint32_t index;
byte color[4];
float position[2];
float offset[2];
} sliceinst_t;
typedef struct { typedef struct {
uint32_t index; uint32_t index;
byte color[4]; byte color[4];
@ -109,6 +116,12 @@ typedef struct vertqueue_s {
int size; int size;
} vertqueue_t; } vertqueue_t;
typedef struct slicequeue_s {
sliceinst_t *slices;
int count;
int size;
} slicequeue_t;
typedef struct glyphqueue_s { typedef struct glyphqueue_s {
glyphinst_t *glyphs; glyphinst_t *glyphs;
int count; int count;
@ -117,14 +130,18 @@ typedef struct glyphqueue_s {
typedef struct drawframe_s { typedef struct drawframe_s {
size_t quad_offset; size_t quad_offset;
size_t slice_offset;
size_t glyph_offset; size_t glyph_offset;
size_t line_offset; size_t line_offset;
VkBuffer quad_buffer; VkBuffer quad_buffer;
descbatchset_t quad_batch; descbatchset_t quad_batch;
VkBuffer slice_buffer;
descbatchset_t slice_batch;
VkBuffer glyph_buffer; VkBuffer glyph_buffer;
descbatchset_t glyph_batch; descbatchset_t glyph_batch;
VkBuffer line_buffer; VkBuffer line_buffer;
vertqueue_t quad_verts; vertqueue_t quad_verts;
slicequeue_t slice_insts;
glyphqueue_t glyph_insts; glyphqueue_t glyph_insts;
vertqueue_t line_verts; vertqueue_t line_verts;
VkCommandBuffer cmd; VkCommandBuffer cmd;
@ -166,14 +183,17 @@ typedef struct drawctx_s {
memsuper_t *string_memsuper; memsuper_t *string_memsuper;
hashtab_t *pic_cache; hashtab_t *pic_cache;
qfv_resource_t *draw_resource; qfv_resource_t *draw_resource;
qfv_resobj_t *ind_objects;
qfv_resobj_t *quad_objects; qfv_resobj_t *quad_objects;
qfv_resobj_t *slice_objects;
qfv_resobj_t *glyph_objects; qfv_resobj_t *glyph_objects;
qfv_resobj_t *line_objects; qfv_resobj_t *line_objects;
VkPipeline quad_pipeline; VkPipeline quad_pipeline;
VkPipeline slice_pipeline;
VkPipeline glyph_coverage_pipeline; VkPipeline glyph_coverage_pipeline;
VkPipeline line_pipeline; VkPipeline line_pipeline;
VkPipelineLayout layout; VkPipelineLayout layout;
VkPipelineLayout glyph_layout; VkPipelineLayout glyph_layout;//slice pipeline uses same layout
VkDescriptorSet quad_set; VkDescriptorSet quad_set;
drawframeset_t frames; drawframeset_t frames;
drawfontset_t fonts; drawfontset_t fonts;
@ -195,6 +215,39 @@ typedef struct drawctx_s {
#define VERTS_PER_FRAME (LINES_OFFSET + MAX_LINES*VERTS_PER_LINE) #define VERTS_PER_FRAME (LINES_OFFSET + MAX_LINES*VERTS_PER_LINE)
static void
generate_quad_indices (qfv_stagebuf_t *staging, qfv_resobj_t *ind_buffer)
{
qfv_packet_t *packet = QFV_PacketAcquire (staging);
uint32_t *ind = QFV_PacketExtend (packet, ind_buffer->buffer.size);
for (int i = 0; i < MAX_QUADS; i++) {
for (int j = 0; j < VERTS_PER_QUAD; j++) {
*ind++ = i * VERTS_PER_QUAD + j;
}
// mark end of primitive
*ind++ = -1;
}
QFV_PacketCopyBuffer (packet, ind_buffer->buffer.buffer,
&bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]);
QFV_PacketSubmit (packet);
}
static void
generate_slice_indices (qfv_stagebuf_t *staging, qfv_resobj_t *ind_buffer)
{
qfv_packet_t *packet = QFV_PacketAcquire (staging);
uint32_t *ind = QFV_PacketExtend (packet, ind_buffer->buffer.size);
for (int i = 0; i < 8; i++) {
ind[i] = i;
ind[i + 9] = i + 1 + (i & 1) * 6;
ind[i + 18] = i + 8;
}
ind[8] = ind[17] = ~0;
QFV_PacketCopyBuffer (packet, ind_buffer->buffer.buffer,
&bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]);
QFV_PacketSubmit (packet);
}
static void static void
create_quad_buffers (vulkan_ctx_t *ctx) create_quad_buffers (vulkan_ctx_t *ctx)
{ {
@ -204,32 +257,38 @@ create_quad_buffers (vulkan_ctx_t *ctx)
size_t frames = ctx->frames.size; size_t frames = ctx->frames.size;
dctx->draw_resource = malloc (2 * sizeof (qfv_resource_t) dctx->draw_resource = malloc (2 * sizeof (qfv_resource_t)
// quads: index + frames vertex buffers // index buffers
+ (1 + frames) * sizeof (qfv_resobj_t) + 2 * sizeof (qfv_resobj_t)
// quads: frames vertex buffers
+ (frames) * sizeof (qfv_resobj_t)
// slicess: frames instance vertex buffers
+ (frames) * sizeof (qfv_resobj_t)
// glyphs: frames instance vertex buffers // glyphs: frames instance vertex buffers
+ (frames) * sizeof (qfv_resobj_t) + (frames) * sizeof (qfv_resobj_t)
// lines: frames vertex buffers // lines: frames vertex buffers
+ (frames) * sizeof (qfv_resobj_t)); + (frames) * sizeof (qfv_resobj_t));
dctx->quad_objects = (qfv_resobj_t *) &dctx->draw_resource[2]; dctx->ind_objects = (qfv_resobj_t *) &dctx->draw_resource[2];
dctx->glyph_objects = &dctx->quad_objects[1 + frames]; dctx->quad_objects = &dctx->ind_objects[2];
dctx->slice_objects = &dctx->quad_objects[frames];
dctx->glyph_objects = &dctx->slice_objects[frames];
dctx->line_objects = &dctx->glyph_objects[frames]; dctx->line_objects = &dctx->glyph_objects[frames];
dctx->draw_resource[0] = (qfv_resource_t) { dctx->draw_resource[0] = (qfv_resource_t) {
.name = "draw", .name = "draw",
.va_ctx = ctx->va_ctx, .va_ctx = ctx->va_ctx,
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, .memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
.num_objects = 1, // has only the quad index buffer .num_objects = 2, // quad and 9-slice indices
.objects = dctx->quad_objects, .objects = dctx->ind_objects,
}; };
dctx->draw_resource[1] = (qfv_resource_t) { dctx->draw_resource[1] = (qfv_resource_t) {
.name = "draw", .name = "draw",
.va_ctx = ctx->va_ctx, .va_ctx = ctx->va_ctx,
.memory_properties = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
.num_objects = (frames) + (frames) + (frames), .num_objects = (frames) + (frames) + (frames) + (frames),
.objects = dctx->quad_objects + 1, .objects = dctx->quad_objects,
}; };
dctx->quad_objects[0] = (qfv_resobj_t) { dctx->ind_objects[0] = (qfv_resobj_t) {
.name = "quads.index", .name = "quads.index",
.type = qfv_res_buffer, .type = qfv_res_buffer,
.buffer = { .buffer = {
@ -238,10 +297,18 @@ create_quad_buffers (vulkan_ctx_t *ctx)
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT, | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
}, },
}; };
__auto_type ind_buffer = &dctx->quad_objects[0]; dctx->ind_objects[1] = (qfv_resobj_t) {
.name = "9-slice.index",
.type = qfv_res_buffer,
.buffer = {
.size = 26 * sizeof (uint32_t),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
},
};
for (size_t i = 0; i < frames; i++) { for (size_t i = 0; i < frames; i++) {
dctx->quad_objects[i + 1] = (qfv_resobj_t) { dctx->quad_objects[i] = (qfv_resobj_t) {
.name = "quads.geom", .name = "quads.geom",
.type = qfv_res_buffer, .type = qfv_res_buffer,
.buffer = { .buffer = {
@ -250,6 +317,15 @@ create_quad_buffers (vulkan_ctx_t *ctx)
| VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
}, },
}; };
dctx->slice_objects[i] = (qfv_resobj_t) {
.name = "slices.inst",
.type = qfv_res_buffer,
.buffer = {
.size = MAX_GLYPHS * sizeof (sliceinst_t),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
| VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
},
};
dctx->glyph_objects[i] = (qfv_resobj_t) { dctx->glyph_objects[i] = (qfv_resobj_t) {
.name = "glyphs.inst", .name = "glyphs.inst",
.type = qfv_res_buffer, .type = qfv_res_buffer,
@ -278,8 +354,10 @@ create_quad_buffers (vulkan_ctx_t *ctx)
for (size_t f = 0; f < frames; f++) { for (size_t f = 0; f < frames; f++) {
drawframe_t *frame = &dctx->frames.a[f]; drawframe_t *frame = &dctx->frames.a[f];
frame->quad_buffer = dctx->quad_objects[1 + f].buffer.buffer; frame->quad_buffer = dctx->quad_objects[f].buffer.buffer;
frame->quad_offset = dctx->quad_objects[1 + f].buffer.offset; frame->quad_offset = dctx->quad_objects[f].buffer.offset;
frame->slice_buffer = dctx->slice_objects[f].buffer.buffer;
frame->slice_offset = dctx->slice_objects[f].buffer.offset;
frame->glyph_buffer = dctx->glyph_objects[f].buffer.buffer; frame->glyph_buffer = dctx->glyph_objects[f].buffer.buffer;
frame->glyph_offset = dctx->glyph_objects[f].buffer.offset; frame->glyph_offset = dctx->glyph_objects[f].buffer.offset;
frame->line_buffer = dctx->line_objects[f].buffer.buffer; frame->line_buffer = dctx->line_objects[f].buffer.buffer;
@ -290,6 +368,11 @@ create_quad_buffers (vulkan_ctx_t *ctx)
.size = MAX_QUADS, .size = MAX_QUADS,
}; };
DARRAY_INIT (&frame->quad_batch, 16); DARRAY_INIT (&frame->quad_batch, 16);
frame->slice_insts = (slicequeue_t) {
.slices = (sliceinst_t *) ((byte *)data + frame->slice_offset),
.size = MAX_QUADS,
};
DARRAY_INIT (&frame->slice_batch, 16);
frame->glyph_insts = (glyphqueue_t) { frame->glyph_insts = (glyphqueue_t) {
.glyphs = (glyphinst_t *) ((byte *)data + frame->glyph_offset), .glyphs = (glyphinst_t *) ((byte *)data + frame->glyph_offset),
.size = MAX_QUADS, .size = MAX_QUADS,
@ -302,18 +385,8 @@ create_quad_buffers (vulkan_ctx_t *ctx)
} }
// The indices will never change so pre-generate and stash them // The indices will never change so pre-generate and stash them
qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging); generate_quad_indices (ctx->staging, &dctx->ind_objects[0]);
uint32_t *ind = QFV_PacketExtend (packet, ind_buffer->buffer.size); generate_slice_indices (ctx->staging, &dctx->ind_objects[1]);
for (int i = 0; i < MAX_QUADS; i++) {
for (int j = 0; j < VERTS_PER_QUAD; j++) {
*ind++ = i * VERTS_PER_QUAD + j;
}
// mark end of primitive
*ind++ = -1;
}
QFV_PacketCopyBuffer (packet, ind_buffer->buffer.buffer,
&bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]);
QFV_PacketSubmit (packet);
} }
static void static void
@ -463,6 +536,7 @@ Vulkan_Draw_Shutdown (vulkan_ctx_t *ctx)
} }
dfunc->vkDestroyPipeline (device->dev, dctx->quad_pipeline, 0); dfunc->vkDestroyPipeline (device->dev, dctx->quad_pipeline, 0);
dfunc->vkDestroyPipeline (device->dev, dctx->slice_pipeline, 0);
dfunc->vkDestroyPipeline (device->dev, dctx->glyph_coverage_pipeline, 0); dfunc->vkDestroyPipeline (device->dev, dctx->glyph_coverage_pipeline, 0);
dfunc->vkDestroyPipeline (device->dev, dctx->line_pipeline, 0); dfunc->vkDestroyPipeline (device->dev, dctx->line_pipeline, 0);
Hash_DelTable (dctx->pic_cache); Hash_DelTable (dctx->pic_cache);
@ -536,6 +610,7 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx)
flush_draw_scrap (ctx); flush_draw_scrap (ctx);
dctx->quad_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "twod"); dctx->quad_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "twod");
dctx->slice_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "slice");
dctx->glyph_coverage_pipeline dctx->glyph_coverage_pipeline
= Vulkan_CreateGraphicsPipeline (ctx, "glyph_coverage"); = Vulkan_CreateGraphicsPipeline (ctx, "glyph_coverage");
dctx->line_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "lines"); dctx->line_pipeline = Vulkan_CreateGraphicsPipeline (ctx, "lines");
@ -1045,8 +1120,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->quad_verts.count && !dframe->glyph_insts.count if (!dframe->quad_verts.count && !dframe->slice_insts.count
&& !dframe->line_verts.count) { && !dframe->glyph_insts.count && !dframe->line_verts.count) {
return; return;
} }
@ -1055,17 +1130,24 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent], cmd); DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent], cmd);
VkDeviceMemory memory = dctx->draw_resource[1].memory; VkDeviceMemory memory = dctx->draw_resource[1].memory;
size_t atom = device->physDev->properties->limits.nonCoherentAtomSize;
size_t atom_mask = atom - 1;
#define a(x) (((x) + atom_mask) & ~atom_mask)
VkMappedMemoryRange ranges[] = { VkMappedMemoryRange ranges[] = {
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
memory, dframe->quad_offset, memory, dframe->quad_offset,
dframe->quad_verts.count * VERTS_PER_QUAD * sizeof (drawvert_t) }, a(dframe->quad_verts.count * VERTS_PER_QUAD * sizeof (drawvert_t)) },
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
memory, dframe->slice_offset,
a(dframe->slice_insts.count * sizeof (sliceinst_t)) },
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
memory, dframe->glyph_offset, memory, dframe->glyph_offset,
dframe->glyph_insts.count * VERTS_PER_QUAD * sizeof (drawvert_t) }, a(dframe->glyph_insts.count * sizeof (glyphinst_t)) },
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
memory, dframe->line_offset, memory, dframe->line_offset,
dframe->line_verts.count * VERTS_PER_LINE * sizeof (drawvert_t) }, a(dframe->line_verts.count * VERTS_PER_LINE * sizeof (drawvert_t)) },
}; };
#undef a
dfunc->vkFlushMappedMemoryRanges (device->dev, 3, ranges); dfunc->vkFlushMappedMemoryRanges (device->dev, 3, ranges);
dfunc->vkResetCommandBuffer (cmd, 0); dfunc->vkResetCommandBuffer (cmd, 0);
@ -1086,7 +1168,7 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
if (dframe->quad_verts.count) { if (dframe->quad_verts.count) {
VkBuffer quad_buffer = dframe->quad_buffer; VkBuffer quad_buffer = dframe->quad_buffer;
VkBuffer ind_buffer = dctx->quad_objects[0].buffer.buffer; VkBuffer ind_buffer = dctx->ind_objects[0].buffer.buffer;
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &quad_buffer, offsets); dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &quad_buffer, offsets);
dfunc->vkCmdBindIndexBuffer (cmd, ind_buffer, 0, VK_INDEX_TYPE_UINT32); dfunc->vkCmdBindIndexBuffer (cmd, ind_buffer, 0, VK_INDEX_TYPE_UINT32);
@ -1106,6 +1188,36 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
1, 0, 0, 0); 1, 0, 0, 0);
} }
if (dframe->slice_insts.count) {
VkBuffer slice_buffer = dframe->slice_buffer;
VkBuffer ind_buffer = dctx->ind_objects[1].buffer.buffer;
VkDeviceSize offsets[] = {0};
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &slice_buffer, offsets);
dfunc->vkCmdBindIndexBuffer (cmd, ind_buffer, 0, VK_INDEX_TYPE_UINT32);
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
dctx->slice_pipeline);
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
uint32_t inst_start = 0;
for (size_t i = 0; i < dframe->slice_batch.size; i++) {
int fontid = dframe->slice_batch.a[i].descid;
uint32_t inst_count = dframe->slice_batch.a[i].count;
VkDescriptorSet set[2] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
dctx->fonts.a[fontid].set,
};
VkPipelineLayout layout = dctx->glyph_layout;
dfunc->vkCmdBindDescriptorSets (cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 0, 2, set, 0, 0);
dfunc->vkCmdDrawIndexed (cmd, 26, inst_count, 0, 0, inst_start);
inst_start += inst_count;
}
DARRAY_RESIZE (&dframe->slice_batch, 0);
}
if (dframe->glyph_insts.count) { if (dframe->glyph_insts.count) {
VkBuffer glyph_buffer = dframe->glyph_buffer; VkBuffer glyph_buffer = dframe->glyph_buffer;
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
@ -1155,6 +1267,7 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame)
dfunc->vkEndCommandBuffer (cmd); dfunc->vkEndCommandBuffer (cmd);
dframe->quad_verts.count = 0; dframe->quad_verts.count = 0;
dframe->slice_insts.count = 0;
dframe->glyph_insts.count = 0; dframe->glyph_insts.count = 0;
dframe->line_verts.count = 0; dframe->line_verts.count = 0;
} }