mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-23 09:20:40 +00:00
254 lines
6.5 KiB
C
254 lines
6.5 KiB
C
|
/*
|
||
|
vulkan_planes.c
|
||
|
|
||
|
Vulkan debug planes pipeline
|
||
|
|
||
|
Copyright (C) 2023 Bill Currie <bill@taniwha.org>
|
||
|
|
||
|
Author: Bill Currie <bill@taniwha.org>
|
||
|
Date: 2023/7/20
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
as published by the Free Software Foundation; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
|
||
|
See the GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to:
|
||
|
|
||
|
Free Software Foundation, Inc.
|
||
|
59 Temple Place - Suite 330
|
||
|
Boston, MA 02111-1307, USA
|
||
|
|
||
|
*/
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
# include "config.h"
|
||
|
#endif
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "QF/simd/types.h"
|
||
|
#include "QF/va.h"
|
||
|
|
||
|
#include "QF/Vulkan/qf_matrices.h"
|
||
|
#include "QF/Vulkan/qf_planes.h"
|
||
|
#include "QF/Vulkan/barrier.h"
|
||
|
#include "QF/Vulkan/debug.h"
|
||
|
#include "QF/Vulkan/descriptor.h"
|
||
|
#include "QF/Vulkan/device.h"
|
||
|
#include "QF/Vulkan/dsmanager.h"
|
||
|
#include "QF/Vulkan/instance.h"
|
||
|
#include "QF/Vulkan/resource.h"
|
||
|
#include "QF/Vulkan/render.h"
|
||
|
#include "QF/Vulkan/staging.h"
|
||
|
|
||
|
#include "r_internal.h"
|
||
|
#include "vid_vulkan.h"
|
||
|
|
||
|
typedef struct {
|
||
|
vec4f_t p[3];
|
||
|
vec4f_t scolor;
|
||
|
vec4f_t tcolor;
|
||
|
} qfv_plane_t;
|
||
|
|
||
|
typedef struct {
|
||
|
int num_planes;
|
||
|
qfv_plane_t planes[64];
|
||
|
} qfv_planebuf_t;
|
||
|
|
||
|
static qfv_plane_t
|
||
|
make_plane (vec4f_t s, vec4f_t t, vec4f_t scolor, vec4f_t tcolor)
|
||
|
{
|
||
|
vec4f_t n = crossf (s, t);
|
||
|
vec4f_t d = -r_refdef.camera[3];
|
||
|
vec4f_t S = dotf (t, t) * s - dotf (s, t) * t;
|
||
|
vec4f_t T = dotf (s, s) * t - dotf (s, t) * s;
|
||
|
vec4f_t dn = dotf (d, n);
|
||
|
vec4f_t Sd = dotf (S, d);
|
||
|
vec4f_t Td = dotf (T, d);
|
||
|
vec4f_t SS = dn * S - Sd * n;
|
||
|
vec4f_t TT = dn * T - Td * n;
|
||
|
vec4f_t nn = dotf (n, n) * n;
|
||
|
|
||
|
return (qfv_plane_t) {
|
||
|
.p = {
|
||
|
{SS[0], TT[0], nn[0], dn[0]},
|
||
|
{SS[1], TT[1], nn[1], 0},
|
||
|
{SS[2], TT[2], nn[2], 0},
|
||
|
},
|
||
|
.scolor = scolor,
|
||
|
.tcolor = tcolor,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
debug_planes_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||
|
{
|
||
|
auto taskctx = (qfv_taskctx_t *) ectx;
|
||
|
auto ctx = taskctx->ctx;
|
||
|
auto device = ctx->device;
|
||
|
auto dfunc = device->funcs;
|
||
|
|
||
|
auto pctx = ctx->planes_context;
|
||
|
auto pframe = &pctx->frames.a[ctx->curFrame];
|
||
|
auto layout = taskctx->pipeline->layout;
|
||
|
auto cmd = taskctx->cmd;
|
||
|
|
||
|
auto packet = QFV_PacketAcquire (ctx->staging);
|
||
|
qfv_planebuf_t *planes = QFV_PacketExtend (packet, sizeof (qfv_planebuf_t));
|
||
|
vec4f_t x = {256, 0, 0, 0};
|
||
|
vec4f_t y = {0, 256, 0, 0};
|
||
|
vec4f_t z = {0, 0, 256, 0};
|
||
|
vec4f_t r = {1, 0, 0, 1 };
|
||
|
vec4f_t g = {0, 1, 0, 1 };
|
||
|
vec4f_t b = {0, 0, 1, 1 };
|
||
|
*planes = (qfv_planebuf_t) {
|
||
|
.num_planes = 3,
|
||
|
.planes[0] = make_plane (x, y, r, g),
|
||
|
.planes[1] = make_plane (y, z, g, b),
|
||
|
.planes[2] = make_plane (z, x, b, r),
|
||
|
};
|
||
|
auto buffer = &pctx->resources->objects[ctx->curFrame].buffer;
|
||
|
auto bb = &bufferBarriers[qfv_BB_TransferWrite_to_UniformRead];
|
||
|
QFV_PacketCopyBuffer (packet, buffer->buffer, 0, bb);
|
||
|
QFV_PacketSubmit (packet);
|
||
|
|
||
|
VkDescriptorSet sets[] = {
|
||
|
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||
|
pframe->descriptor,
|
||
|
};
|
||
|
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||
|
layout, 0, 2, sets, 0, 0);
|
||
|
dfunc->vkCmdDraw (cmd, 3, 1, 0, 0);
|
||
|
}
|
||
|
|
||
|
static exprtype_t *debug_planes_draw_params[] = {
|
||
|
&cexpr_int,
|
||
|
};
|
||
|
static exprfunc_t debug_planes_draw_func[] = {
|
||
|
{ .func = debug_planes_draw, .num_params = 1, .param_types = debug_planes_draw_params },
|
||
|
{}
|
||
|
};
|
||
|
static exprsym_t debug_planes_task_syms[] = {
|
||
|
{ "debug_planes_draw", &cexpr_function, debug_planes_draw_func },
|
||
|
{}
|
||
|
};
|
||
|
|
||
|
void
|
||
|
Vulkan_Planes_Init (vulkan_ctx_t *ctx)
|
||
|
{
|
||
|
qfvPushDebug (ctx, "debug planes init");
|
||
|
QFV_Render_AddTasks (ctx, debug_planes_task_syms);
|
||
|
|
||
|
planesctx_t *pctx = calloc (1, sizeof (planesctx_t));
|
||
|
ctx->planes_context = pctx;
|
||
|
|
||
|
qfvPopDebug (ctx);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Vulkan_Planes_Setup (vulkan_ctx_t *ctx)
|
||
|
{
|
||
|
auto device = ctx->device;
|
||
|
auto dfunc = device->funcs;
|
||
|
auto pctx = ctx->planes_context;
|
||
|
|
||
|
auto rctx = ctx->render_context;
|
||
|
size_t frames = rctx->frames.size;
|
||
|
DARRAY_INIT (&pctx->frames, frames);
|
||
|
DARRAY_RESIZE (&pctx->frames, frames);
|
||
|
pctx->frames.grow = 0;
|
||
|
|
||
|
pctx->resources = malloc (sizeof (qfv_resource_t)
|
||
|
+ sizeof (qfv_resobj_t[frames]));
|
||
|
*pctx->resources = (qfv_resource_t) {
|
||
|
.name = "planes",
|
||
|
.va_ctx = ctx->va_ctx,
|
||
|
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||
|
.num_objects = frames,
|
||
|
.objects = (qfv_resobj_t *) &pctx->resources[1],
|
||
|
};
|
||
|
for (size_t i = 0; i < frames; i++) {
|
||
|
auto obj = &pctx->resources->objects[i];
|
||
|
*obj = (qfv_resobj_t) {
|
||
|
.name = va (ctx->va_ctx, "planes:%zd", i),
|
||
|
.type = qfv_res_buffer,
|
||
|
.buffer = {
|
||
|
.size = sizeof (qfv_planebuf_t),
|
||
|
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||
|
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
QFV_CreateResource (device, pctx->resources);
|
||
|
|
||
|
auto packet = QFV_PacketAcquire (ctx->staging);
|
||
|
qfv_planebuf_t *planes = QFV_PacketExtend (packet, sizeof (qfv_planebuf_t));
|
||
|
*planes = (qfv_planebuf_t) {
|
||
|
.num_planes = 3,
|
||
|
.planes[0] = {{
|
||
|
{1, 0, 0, 0},
|
||
|
{0, 1, 0, 0},
|
||
|
{0, 0, 1, 0},
|
||
|
}},
|
||
|
.planes[1] = {{
|
||
|
{0, 1, 0, 0},
|
||
|
{0, 0, 1, 0},
|
||
|
{1, 0, 0, 0},
|
||
|
}},
|
||
|
.planes[2] = {{
|
||
|
{0, 0, 1, 0},
|
||
|
{1, 0, 0, 0},
|
||
|
{0, 1, 0, 0},
|
||
|
}},
|
||
|
};
|
||
|
for (size_t i = 0; i < frames; i++) {
|
||
|
auto buffer = &pctx->resources->objects[i].buffer;
|
||
|
auto bb = &bufferBarriers[qfv_BB_TransferWrite_to_UniformRead];
|
||
|
QFV_PacketCopyBuffer (packet, buffer->buffer, 0, bb);
|
||
|
}
|
||
|
QFV_PacketSubmit (packet);
|
||
|
|
||
|
auto dsmanager = QFV_Render_DSManager (ctx, "planes_set");
|
||
|
for (size_t i = 0; i < frames; i++) {
|
||
|
auto pframe = &pctx->frames.a[i];
|
||
|
auto buffer = &pctx->resources->objects[i].buffer;
|
||
|
auto set = QFV_DSManager_AllocSet (dsmanager);
|
||
|
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DESCRIPTOR_SET, set,
|
||
|
va (ctx->va_ctx, "debug:planes_set:%zd", i));
|
||
|
|
||
|
pframe->descriptor = set;
|
||
|
VkDescriptorBufferInfo bufferInfo[] = {
|
||
|
{ buffer->buffer, 0, VK_WHOLE_SIZE },
|
||
|
};
|
||
|
VkWriteDescriptorSet write[] = {
|
||
|
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||
|
.dstSet = set,
|
||
|
.dstBinding = 0,
|
||
|
.descriptorCount = 1,
|
||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||
|
.pBufferInfo = bufferInfo,
|
||
|
},
|
||
|
};
|
||
|
dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Vulkan_Planes_Shutdown (vulkan_ctx_t *ctx)
|
||
|
{
|
||
|
auto device = ctx->device;
|
||
|
auto pctx = ctx->planes_context;
|
||
|
|
||
|
QFV_DestroyResource (device, pctx->resources);
|
||
|
|
||
|
free (pctx->frames.a);
|
||
|
free (pctx);
|
||
|
}
|