mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 12:42:32 +00:00
[vulkan] Support clipping rectangles via scissor
Seems to work well. The other renderers have stubs because I don't feel like implementing clipping for them. The gl and glsl wouldn't be too difficult (need to handle the draw queues), but sw needs a fair bit of work and I'm not sure it's worth the effort.
This commit is contained in:
parent
f3eebae9bc
commit
650ea052ea
13 changed files with 139 additions and 17 deletions
|
@ -61,6 +61,8 @@ void gl_Draw_SubPic(int x, int y, struct qpic_s *pic,
|
|||
int srcx, int srcy, int width, int height);
|
||||
int gl_Draw_AddFont (struct font_s *font);
|
||||
void gl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c);
|
||||
void gl_Draw_SetClip (int x, int y, int w, int h);
|
||||
void gl_Draw_ResetClip (void);
|
||||
|
||||
void GL_Set2D (void);
|
||||
void GL_Set2DScaled (void);
|
||||
|
|
|
@ -62,6 +62,8 @@ void glsl_Draw_SubPic(int x, int y, struct qpic_s *pic,
|
|||
int srcx, int srcy, int width, int height);
|
||||
int glsl_Draw_AddFont (struct font_s *font);
|
||||
void glsl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c);
|
||||
void glsl_Draw_SetClip (int x, int y, int w, int h);
|
||||
void glsl_Draw_ResetClip (void);
|
||||
|
||||
void GLSL_Set2D (void);
|
||||
void GLSL_Set2DScaled (void);
|
||||
|
|
|
@ -82,6 +82,8 @@ void Vulkan_Draw_SubPic(int x, int y, struct qpic_s *pic,
|
|||
int Vulkan_Draw_AddFont (struct font_s *font, struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Draw_Glyph (int x, int y, int fontid, int glyphid, int c,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Draw_SetClip (int x, int y, int w, int h, struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Draw_ResetClip (struct vulkan_ctx_s *ctx);
|
||||
|
||||
void Vulkan_LineGraph (int x, int y, int *h_vals, int count, int height,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
|
|
|
@ -279,6 +279,8 @@ void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int h
|
|||
struct font_s;
|
||||
int Draw_AddFont (struct font_s *font);
|
||||
void Draw_Glyph (int x, int y, int fontid, int glyphid, int c);
|
||||
void Draw_SetClip (int x, int y, int w, int h);
|
||||
void Draw_ResetClip (void);
|
||||
|
||||
///@}
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ typedef struct vid_render_funcs_s {
|
|||
void (*Draw_SubPic) (int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height);
|
||||
int (*Draw_AddFont) (struct font_s *font);
|
||||
void (*Draw_Glyph) (int x, int y, int fontid, int glyphid, int c);
|
||||
void (*Draw_SetClip) (int x, int y, int w, int h);
|
||||
void (*Draw_ResetClip) (void);
|
||||
|
||||
struct psystem_s *(*ParticleSystem) (void);
|
||||
struct psystem_s *(*TrailSystem) (void);
|
||||
|
|
|
@ -1131,3 +1131,13 @@ gl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
|||
qfglEnd ();
|
||||
qfglColor4ubv (color_white);
|
||||
}
|
||||
|
||||
void
|
||||
gl_Draw_SetClip (int x, int y, int w, int h)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gl_Draw_ResetClip (void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1111,3 +1111,13 @@ glsl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
|||
QuatCopy (color, verts[4].color);
|
||||
QuatCopy (color, verts[5].color);
|
||||
}
|
||||
|
||||
void
|
||||
glsl_Draw_SetClip (int x, int y, int w, int h)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
glsl_Draw_ResetClip (void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1096,3 +1096,13 @@ Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
|||
dst += d_rowbytes;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Draw_SetClip (int x, int y, int w, int h)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Draw_ResetClip (void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -529,6 +529,8 @@ vid_render_funcs_t gl_vid_render_funcs = {
|
|||
.Draw_SubPic = gl_Draw_SubPic,
|
||||
.Draw_AddFont = gl_Draw_AddFont,
|
||||
.Draw_Glyph = gl_Draw_Glyph,
|
||||
.Draw_SetClip = gl_Draw_SetClip,
|
||||
.Draw_ResetClip = gl_Draw_ResetClip,
|
||||
|
||||
.ParticleSystem = gl_ParticleSystem,
|
||||
.R_Init = gl_R_Init,
|
||||
|
|
|
@ -475,6 +475,8 @@ vid_render_funcs_t glsl_vid_render_funcs = {
|
|||
.Draw_SubPic = glsl_Draw_SubPic,
|
||||
.Draw_AddFont = glsl_Draw_AddFont,
|
||||
.Draw_Glyph = glsl_Draw_Glyph,
|
||||
.Draw_SetClip = glsl_Draw_SetClip,
|
||||
.Draw_ResetClip = glsl_Draw_ResetClip,
|
||||
|
||||
.ParticleSystem = glsl_ParticleSystem,
|
||||
.TrailSystem = glsl_TrailSystem,
|
||||
|
|
|
@ -485,6 +485,8 @@ vid_render_funcs_t sw_vid_render_funcs = {
|
|||
.Draw_SubPic = Draw_SubPic,
|
||||
.Draw_AddFont = Draw_AddFont,
|
||||
.Draw_Glyph = Draw_Glyph,
|
||||
.Draw_SetClip = Draw_SetClip,
|
||||
.Draw_ResetClip = Draw_ResetClip,
|
||||
|
||||
.ParticleSystem = sw_ParticleSystem,
|
||||
.R_Init = sw_R_Init,
|
||||
|
|
|
@ -327,6 +327,18 @@ vulkan_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
|||
Vulkan_Draw_Glyph (x, y, fontid, glyphid, c, vulkan_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
vulkan_Draw_SetClip (int x, int y, int w, int h)
|
||||
{
|
||||
Vulkan_Draw_SetClip (x, y, w, h, vulkan_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
vulkan_Draw_ResetClip (void)
|
||||
{
|
||||
Vulkan_Draw_ResetClip (vulkan_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
vulkan_set_2d (int scaled)
|
||||
{
|
||||
|
@ -612,6 +624,8 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
|
|||
.Draw_SubPic = vulkan_Draw_SubPic,
|
||||
.Draw_AddFont = vulkan_Draw_AddFont,
|
||||
.Draw_Glyph = vulkan_Draw_Glyph,
|
||||
.Draw_SetClip = vulkan_Draw_SetClip,
|
||||
.Draw_ResetClip = vulkan_Draw_ResetClip,
|
||||
|
||||
.ParticleSystem = vulkan_ParticleSystem,
|
||||
.R_Init = vulkan_R_Init,
|
||||
|
|
|
@ -87,6 +87,15 @@ typedef struct descbatch_s {
|
|||
typedef struct descbatchset_s
|
||||
DARRAY_TYPE (descbatch_t) descbatchset_t;
|
||||
|
||||
typedef struct drawclip_s {
|
||||
uint32_t start;
|
||||
uint32_t count; // number of batches in quad_batch
|
||||
VkRect2D clip;
|
||||
} drawclip_t;
|
||||
|
||||
typedef struct drawclipset_s
|
||||
DARRAY_TYPE (drawclip_t) drawclipset_t;
|
||||
|
||||
typedef struct {
|
||||
float xy[2];
|
||||
byte color[4];
|
||||
|
@ -167,6 +176,7 @@ typedef struct drawframe_s {
|
|||
uint32_t dvertex_index;
|
||||
uint32_t dvertex_max;
|
||||
descbatchset_t quad_batch;
|
||||
drawclipset_t clip_range;
|
||||
quadqueue_t quad_insts;
|
||||
linequeue_t line_verts;
|
||||
descpool_t dyn_descs;
|
||||
|
@ -428,6 +438,7 @@ create_buffers (vulkan_ctx_t *ctx)
|
|||
};
|
||||
|
||||
DARRAY_INIT (&frame->quad_batch, 16);
|
||||
DARRAY_INIT (&frame->clip_range, 16);
|
||||
frame->quad_insts = (quadqueue_t) {
|
||||
.quads = (quadinst_t *) ((byte *)data + frame->instance_offset),
|
||||
.max_count = MAX_INSTANCES,
|
||||
|
@ -908,22 +919,32 @@ draw_quads (qfv_taskctx_t *taskctx)
|
|||
dfunc->vkCmdBindIndexBuffer (cmd, ind_buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
|
||||
uint32_t inst_start = 0;
|
||||
for (size_t i = 0; i < dframe->quad_batch.size; i++) {
|
||||
int fontid = dframe->quad_batch.a[i].descid;
|
||||
uint32_t inst_count = dframe->quad_batch.a[i].count;
|
||||
uint32_t ind_count = inst_count >> 24;
|
||||
inst_count &= 0xffffff;
|
||||
VkDescriptorSet set[2] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
fontid < 0 ? dframe->dyn_descs.sets[~fontid]
|
||||
: dctx->fonts.a[fontid].set,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout, 0, 2, set, 0, 0);
|
||||
for (size_t i = 0; i < dframe->clip_range.size; i++) {
|
||||
auto cr = &dframe->clip_range.a[i];
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &cr->clip);
|
||||
for (uint32_t j = 0; j < cr->count; j++) {
|
||||
int fontid = dframe->quad_batch.a[cr->start + j].descid;
|
||||
uint32_t inst_count = dframe->quad_batch.a[cr->start + j].count;
|
||||
uint32_t ind_count = inst_count >> 24;
|
||||
inst_count &= 0xffffff;
|
||||
VkDescriptorSet set[2] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
fontid < 0 ? dframe->dyn_descs.sets[~fontid]
|
||||
: dctx->fonts.a[fontid].set,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout, 0, 2, set, 0, 0);
|
||||
|
||||
dfunc->vkCmdDrawIndexed (cmd, ind_count, inst_count, 0, 0, inst_start);
|
||||
inst_start += inst_count;
|
||||
dfunc->vkCmdDrawIndexed (cmd, ind_count, inst_count, 0, 0,
|
||||
inst_start);
|
||||
inst_start += inst_count;
|
||||
}
|
||||
}
|
||||
VkRect2D scissor = {
|
||||
.extent = { .width = vid.width, .height = vid.height },
|
||||
};
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &scissor);
|
||||
DARRAY_RESIZE (&dframe->quad_batch, 0);
|
||||
}
|
||||
|
||||
|
@ -973,6 +994,9 @@ slice_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
return;
|
||||
}
|
||||
|
||||
auto cr = &dframe->clip_range.a[dframe->clip_range.size - 1];
|
||||
cr->count = dframe->quad_batch.size - cr->start;
|
||||
|
||||
qftVkScopedZone (taskctx->frame->qftVkCtx, taskctx->cmd, "slice_draw");
|
||||
VkDeviceMemory memory = dctx->draw_resource[1].memory;
|
||||
size_t atom = device->physDev->p.properties.limits.nonCoherentAtomSize;
|
||||
|
@ -1035,6 +1059,13 @@ draw_scr_funcs (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
auto dctx = ctx->draw_context;
|
||||
auto dframe = &dctx->frames.a[ctx->curFrame];
|
||||
|
||||
DARRAY_RESIZE (&dframe->clip_range, 0);
|
||||
DARRAY_APPEND (&dframe->clip_range, ((drawclip_t) {
|
||||
.clip.offset = { .x = 0, .y = 0 },
|
||||
.clip.extent = { .width = vid.width, .height = vid.height },
|
||||
}));
|
||||
|
||||
auto scr_funcs = dctx->scr_funcs;
|
||||
if (!scr_funcs) {
|
||||
|
@ -1047,9 +1078,8 @@ draw_scr_funcs (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
dctx->scr_funcs = 0;
|
||||
|
||||
flush_vertqueue (&dctx->slice_vert_queue, ctx);
|
||||
auto frame = &dctx->frames.a[ctx->curFrame];
|
||||
flush_vertqueue (&frame->dyn_vert_queue, ctx);
|
||||
frame->dyn_vert_queue.base = 0;
|
||||
flush_vertqueue (&dframe->dyn_vert_queue, ctx);
|
||||
dframe->dyn_vert_queue.base = 0;
|
||||
}
|
||||
|
||||
static exprfunc_t flush_draw_func[] = {
|
||||
|
@ -1759,6 +1789,38 @@ Vulkan_Draw_Glyph (int x, int y, int fontid, int glyph, int c,
|
|||
draw_quad (x, y, fontid, glyph * 4, color, frame);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Draw_SetClip (int x, int y, int w, int h, vulkan_ctx_t *ctx)
|
||||
{
|
||||
auto dctx = ctx->draw_context;
|
||||
auto dframe = &dctx->frames.a[ctx->curFrame];
|
||||
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
auto cr = &dframe->clip_range.a[dframe->clip_range.size - 1];
|
||||
if (x != cr->clip.offset.x || y != cr->clip.offset.y
|
||||
|| (uint32_t) w != cr->clip.extent.width
|
||||
|| (uint32_t) h != cr->clip.extent.height) {
|
||||
cr->count = dframe->quad_batch.size - cr->start;
|
||||
DARRAY_APPEND (&dframe->clip_range, ((drawclip_t) {
|
||||
.start = dframe->quad_batch.size,
|
||||
.clip.offset = { .x = x, .y = y },
|
||||
.clip.extent = { .width = w, .height = h },
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Draw_ResetClip (vulkan_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_LineGraph (int x, int y, int *h_vals, int count, int height,
|
||||
vulkan_ctx_t *ctx)
|
||||
|
|
Loading…
Reference in a new issue