mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 20:51:35 +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 srcx, int srcy, int width, int height);
|
||||||
int gl_Draw_AddFont (struct font_s *font);
|
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_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_Set2D (void);
|
||||||
void GL_Set2DScaled (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 srcx, int srcy, int width, int height);
|
||||||
int glsl_Draw_AddFont (struct font_s *font);
|
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_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_Set2D (void);
|
||||||
void GLSL_Set2DScaled (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);
|
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,
|
void Vulkan_Draw_Glyph (int x, int y, int fontid, int glyphid, int c,
|
||||||
struct vulkan_ctx_s *ctx);
|
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,
|
void Vulkan_LineGraph (int x, int y, int *h_vals, int count, int height,
|
||||||
struct vulkan_ctx_s *ctx);
|
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;
|
struct font_s;
|
||||||
int Draw_AddFont (struct font_s *font);
|
int Draw_AddFont (struct font_s *font);
|
||||||
void Draw_Glyph (int x, int y, int fontid, int glyphid, int c);
|
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);
|
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);
|
int (*Draw_AddFont) (struct font_s *font);
|
||||||
void (*Draw_Glyph) (int x, int y, int fontid, int glyphid, int c);
|
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 *(*ParticleSystem) (void);
|
||||||
struct psystem_s *(*TrailSystem) (void);
|
struct psystem_s *(*TrailSystem) (void);
|
||||||
|
|
|
@ -1131,3 +1131,13 @@ gl_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
||||||
qfglEnd ();
|
qfglEnd ();
|
||||||
qfglColor4ubv (color_white);
|
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[4].color);
|
||||||
QuatCopy (color, verts[5].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;
|
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_SubPic = gl_Draw_SubPic,
|
||||||
.Draw_AddFont = gl_Draw_AddFont,
|
.Draw_AddFont = gl_Draw_AddFont,
|
||||||
.Draw_Glyph = gl_Draw_Glyph,
|
.Draw_Glyph = gl_Draw_Glyph,
|
||||||
|
.Draw_SetClip = gl_Draw_SetClip,
|
||||||
|
.Draw_ResetClip = gl_Draw_ResetClip,
|
||||||
|
|
||||||
.ParticleSystem = gl_ParticleSystem,
|
.ParticleSystem = gl_ParticleSystem,
|
||||||
.R_Init = gl_R_Init,
|
.R_Init = gl_R_Init,
|
||||||
|
|
|
@ -475,6 +475,8 @@ vid_render_funcs_t glsl_vid_render_funcs = {
|
||||||
.Draw_SubPic = glsl_Draw_SubPic,
|
.Draw_SubPic = glsl_Draw_SubPic,
|
||||||
.Draw_AddFont = glsl_Draw_AddFont,
|
.Draw_AddFont = glsl_Draw_AddFont,
|
||||||
.Draw_Glyph = glsl_Draw_Glyph,
|
.Draw_Glyph = glsl_Draw_Glyph,
|
||||||
|
.Draw_SetClip = glsl_Draw_SetClip,
|
||||||
|
.Draw_ResetClip = glsl_Draw_ResetClip,
|
||||||
|
|
||||||
.ParticleSystem = glsl_ParticleSystem,
|
.ParticleSystem = glsl_ParticleSystem,
|
||||||
.TrailSystem = glsl_TrailSystem,
|
.TrailSystem = glsl_TrailSystem,
|
||||||
|
|
|
@ -485,6 +485,8 @@ vid_render_funcs_t sw_vid_render_funcs = {
|
||||||
.Draw_SubPic = Draw_SubPic,
|
.Draw_SubPic = Draw_SubPic,
|
||||||
.Draw_AddFont = Draw_AddFont,
|
.Draw_AddFont = Draw_AddFont,
|
||||||
.Draw_Glyph = Draw_Glyph,
|
.Draw_Glyph = Draw_Glyph,
|
||||||
|
.Draw_SetClip = Draw_SetClip,
|
||||||
|
.Draw_ResetClip = Draw_ResetClip,
|
||||||
|
|
||||||
.ParticleSystem = sw_ParticleSystem,
|
.ParticleSystem = sw_ParticleSystem,
|
||||||
.R_Init = sw_R_Init,
|
.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);
|
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
|
static void
|
||||||
vulkan_set_2d (int scaled)
|
vulkan_set_2d (int scaled)
|
||||||
{
|
{
|
||||||
|
@ -612,6 +624,8 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
|
||||||
.Draw_SubPic = vulkan_Draw_SubPic,
|
.Draw_SubPic = vulkan_Draw_SubPic,
|
||||||
.Draw_AddFont = vulkan_Draw_AddFont,
|
.Draw_AddFont = vulkan_Draw_AddFont,
|
||||||
.Draw_Glyph = vulkan_Draw_Glyph,
|
.Draw_Glyph = vulkan_Draw_Glyph,
|
||||||
|
.Draw_SetClip = vulkan_Draw_SetClip,
|
||||||
|
.Draw_ResetClip = vulkan_Draw_ResetClip,
|
||||||
|
|
||||||
.ParticleSystem = vulkan_ParticleSystem,
|
.ParticleSystem = vulkan_ParticleSystem,
|
||||||
.R_Init = vulkan_R_Init,
|
.R_Init = vulkan_R_Init,
|
||||||
|
|
|
@ -87,6 +87,15 @@ typedef struct descbatch_s {
|
||||||
typedef struct descbatchset_s
|
typedef struct descbatchset_s
|
||||||
DARRAY_TYPE (descbatch_t) descbatchset_t;
|
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 {
|
typedef struct {
|
||||||
float xy[2];
|
float xy[2];
|
||||||
byte color[4];
|
byte color[4];
|
||||||
|
@ -167,6 +176,7 @@ typedef struct drawframe_s {
|
||||||
uint32_t dvertex_index;
|
uint32_t dvertex_index;
|
||||||
uint32_t dvertex_max;
|
uint32_t dvertex_max;
|
||||||
descbatchset_t quad_batch;
|
descbatchset_t quad_batch;
|
||||||
|
drawclipset_t clip_range;
|
||||||
quadqueue_t quad_insts;
|
quadqueue_t quad_insts;
|
||||||
linequeue_t line_verts;
|
linequeue_t line_verts;
|
||||||
descpool_t dyn_descs;
|
descpool_t dyn_descs;
|
||||||
|
@ -428,6 +438,7 @@ create_buffers (vulkan_ctx_t *ctx)
|
||||||
};
|
};
|
||||||
|
|
||||||
DARRAY_INIT (&frame->quad_batch, 16);
|
DARRAY_INIT (&frame->quad_batch, 16);
|
||||||
|
DARRAY_INIT (&frame->clip_range, 16);
|
||||||
frame->quad_insts = (quadqueue_t) {
|
frame->quad_insts = (quadqueue_t) {
|
||||||
.quads = (quadinst_t *) ((byte *)data + frame->instance_offset),
|
.quads = (quadinst_t *) ((byte *)data + frame->instance_offset),
|
||||||
.max_count = MAX_INSTANCES,
|
.max_count = MAX_INSTANCES,
|
||||||
|
@ -908,22 +919,32 @@ draw_quads (qfv_taskctx_t *taskctx)
|
||||||
dfunc->vkCmdBindIndexBuffer (cmd, ind_buffer, 0, VK_INDEX_TYPE_UINT32);
|
dfunc->vkCmdBindIndexBuffer (cmd, ind_buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||||
|
|
||||||
uint32_t inst_start = 0;
|
uint32_t inst_start = 0;
|
||||||
for (size_t i = 0; i < dframe->quad_batch.size; i++) {
|
for (size_t i = 0; i < dframe->clip_range.size; i++) {
|
||||||
int fontid = dframe->quad_batch.a[i].descid;
|
auto cr = &dframe->clip_range.a[i];
|
||||||
uint32_t inst_count = dframe->quad_batch.a[i].count;
|
dfunc->vkCmdSetScissor (cmd, 0, 1, &cr->clip);
|
||||||
uint32_t ind_count = inst_count >> 24;
|
for (uint32_t j = 0; j < cr->count; j++) {
|
||||||
inst_count &= 0xffffff;
|
int fontid = dframe->quad_batch.a[cr->start + j].descid;
|
||||||
VkDescriptorSet set[2] = {
|
uint32_t inst_count = dframe->quad_batch.a[cr->start + j].count;
|
||||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
uint32_t ind_count = inst_count >> 24;
|
||||||
fontid < 0 ? dframe->dyn_descs.sets[~fontid]
|
inst_count &= 0xffffff;
|
||||||
: dctx->fonts.a[fontid].set,
|
VkDescriptorSet set[2] = {
|
||||||
};
|
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
fontid < 0 ? dframe->dyn_descs.sets[~fontid]
|
||||||
layout, 0, 2, set, 0, 0);
|
: 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);
|
dfunc->vkCmdDrawIndexed (cmd, ind_count, inst_count, 0, 0,
|
||||||
inst_start += inst_count;
|
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);
|
DARRAY_RESIZE (&dframe->quad_batch, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -973,6 +994,9 @@ slice_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
return;
|
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");
|
qftVkScopedZone (taskctx->frame->qftVkCtx, taskctx->cmd, "slice_draw");
|
||||||
VkDeviceMemory memory = dctx->draw_resource[1].memory;
|
VkDeviceMemory memory = dctx->draw_resource[1].memory;
|
||||||
size_t atom = device->physDev->p.properties.limits.nonCoherentAtomSize;
|
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 taskctx = (qfv_taskctx_t *) ectx;
|
||||||
auto ctx = taskctx->ctx;
|
auto ctx = taskctx->ctx;
|
||||||
auto dctx = ctx->draw_context;
|
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;
|
auto scr_funcs = dctx->scr_funcs;
|
||||||
if (!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;
|
dctx->scr_funcs = 0;
|
||||||
|
|
||||||
flush_vertqueue (&dctx->slice_vert_queue, ctx);
|
flush_vertqueue (&dctx->slice_vert_queue, ctx);
|
||||||
auto frame = &dctx->frames.a[ctx->curFrame];
|
flush_vertqueue (&dframe->dyn_vert_queue, ctx);
|
||||||
flush_vertqueue (&frame->dyn_vert_queue, ctx);
|
dframe->dyn_vert_queue.base = 0;
|
||||||
frame->dyn_vert_queue.base = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static exprfunc_t flush_draw_func[] = {
|
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);
|
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
|
void
|
||||||
Vulkan_LineGraph (int x, int y, int *h_vals, int count, int height,
|
Vulkan_LineGraph (int x, int y, int *h_vals, int count, int height,
|
||||||
vulkan_ctx_t *ctx)
|
vulkan_ctx_t *ctx)
|
||||||
|
|
Loading…
Reference in a new issue