mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-19 15:30:50 +00:00
[vulkan] Implement mouse-picking for light entities
Currently, only light entities get drawn to the entid buffer, and the ids are simply displayed in a window for now (not very useful yet).
This commit is contained in:
parent
95b660d7fd
commit
1745d3bccc
17 changed files with 697 additions and 46 deletions
46
include/QF/Vulkan/mouse_pick.h
Normal file
46
include/QF/Vulkan/mouse_pick.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef __QF_Vulkan_mouse_pick_h
|
||||
#define __QF_Vulkan_mouse_pick_h
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
#define mousepick_size 5
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
typedef void (*mousepickfunc_t) (const uint32_t *entid, void *data);
|
||||
|
||||
typedef struct qfv_mousepick_frame_s {
|
||||
VkBuffer entid_buffer;
|
||||
uint32_t *entid_data;
|
||||
|
||||
bool initiated;
|
||||
mousepickfunc_t callback;
|
||||
void *callback_data;
|
||||
uint32_t x, y;
|
||||
VkOffset3D offset;
|
||||
VkExtent3D extent;
|
||||
VkImage entid_image;
|
||||
} qfv_mousepick_frame_t;
|
||||
|
||||
typedef struct qfv_mousepick_frame_set_s
|
||||
DARRAY_TYPE (qfv_mousepick_frame_t) qfv_mousepick_frame_set_t;
|
||||
|
||||
typedef struct qfv_mousepickctx_s {
|
||||
qfv_mousepick_frame_set_t frames;
|
||||
struct qfv_resobj_s *entid_res;
|
||||
struct qfv_resource_s *resources;
|
||||
} qfv_mousepickctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
||||
void QFV_MousePick_Init (struct vulkan_ctx_s *ctx);
|
||||
void QFV_MousePick_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
void QFV_MousePick_Read (struct vulkan_ctx_s *ctx, uint32_t x, uint32_t y,
|
||||
mousepickfunc_t callback, void *data);
|
||||
|
||||
#endif//__QF_Vulkan_mouse_pick_h
|
|
@ -85,6 +85,7 @@ typedef struct lightingframe_s {
|
|||
VkBuffer render_buffer;
|
||||
VkBuffer style_buffer;
|
||||
VkBuffer id_buffer;
|
||||
VkBuffer entid_buffer;
|
||||
light_queue_t light_queue[4];
|
||||
|
||||
qfv_imageviewset_t views;
|
||||
|
|
|
@ -433,8 +433,7 @@ typedef struct qfv_renderctx_s {
|
|||
qfv_job_t *job;
|
||||
qfv_renderframeset_t frames;
|
||||
int64_t size_time;
|
||||
struct imui_window_s *job_timings_window;
|
||||
struct imui_window_s *job_control_window;
|
||||
struct qfv_renderdebug_s *debug;
|
||||
} qfv_renderctx_t;
|
||||
|
||||
typedef struct qfv_taskctx_s {
|
||||
|
@ -472,6 +471,7 @@ VkSampler QFV_Render_Sampler (struct vulkan_ctx_s *ctx, const char *name);
|
|||
|
||||
qfv_step_t *QFV_GetStep (const exprval_t *param, qfv_job_t *job);
|
||||
qfv_step_t *QFV_FindStep (const char *step, qfv_job_t *job) __attribute__((pure));
|
||||
struct qfv_resobj_s *QFV_FindResource (const char *name, qfv_renderpass_t *rp) __attribute__((pure));
|
||||
|
||||
struct imui_ctx_s;
|
||||
void QFV_Render_UI (struct vulkan_ctx_s *ctx, struct imui_ctx_s *imui_ctx);
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct vulkan_ctx_s {
|
|||
struct scriptctx_s *script_context;
|
||||
struct qfv_renderctx_s *render_context;
|
||||
struct qfv_capturectx_s *capture_context;
|
||||
struct qfv_mousepickctx_s *mousepick_context;
|
||||
struct texturectx_s *texture_context;
|
||||
struct matrixctx_s *matrix_context;
|
||||
struct translucentctx_s *translucent_context;
|
||||
|
|
|
@ -222,6 +222,7 @@ libs_video_renderer_librender_vulkan_la_SOURCES = \
|
|||
libs/video/renderer/vulkan/dsmanager.c \
|
||||
libs/video/renderer/vulkan/image.c \
|
||||
libs/video/renderer/vulkan/instance.c \
|
||||
libs/video/renderer/vulkan/mouse_pick.c \
|
||||
libs/video/renderer/vulkan/memory.c \
|
||||
libs/video/renderer/vulkan/pipeline.c \
|
||||
libs/video/renderer/vulkan/projection.c \
|
||||
|
@ -330,7 +331,11 @@ bsp_turbf_src = $(vkshaderpath)/bsp_turb.frag
|
|||
bsp_turbf_c = $(vkshaderpath)/bsp_turb.frag.spvc
|
||||
debug_src = $(vkshaderpath)/debug.frag
|
||||
debug_c = $(vkshaderpath)/debug.frag.spvc
|
||||
entid_src = $(vkshaderpath)/entid.frag
|
||||
entid_c = $(vkshaderpath)/entid.frag.spvc
|
||||
light_attach_h = $(vkshaderpath)/light_attach.h
|
||||
light_entid_src = $(vkshaderpath)/light_entid.vert
|
||||
light_entid_c = $(vkshaderpath)/light_entid.vert.spvc
|
||||
light_flat_src = $(vkshaderpath)/light_flat.vert
|
||||
light_flat_c = $(vkshaderpath)/light_flat.vert.spvc
|
||||
light_splatv_src = $(vkshaderpath)/light_splat.vert
|
||||
|
@ -437,6 +442,10 @@ $(bsp_turbf_c): $(bsp_turbf_src) $(oit_store) $(oit_h)
|
|||
|
||||
$(debug_c): $(debug_src) $(lighting_h)
|
||||
|
||||
$(entid_c): $(entid_src)
|
||||
|
||||
$(light_entid_c): $(light_entid_src) $(lighting_h)
|
||||
|
||||
$(light_flat_c): $(light_flat_src) $(lighting_h)
|
||||
|
||||
$(light_splatv_c): $(light_splatv_src) $(lighting_h)
|
||||
|
@ -514,6 +523,8 @@ vkshader_c = \
|
|||
$(bsp_skyf_c) \
|
||||
$(bsp_turbf_c) \
|
||||
$(debug_c) \
|
||||
$(entid_c) \
|
||||
$(light_entid_c) \
|
||||
$(light_flat_c) \
|
||||
$(light_splatv_c) \
|
||||
$(light_splatf_c) \
|
||||
|
@ -608,7 +619,9 @@ EXTRA_DIST += \
|
|||
$(bsp_skyf_src) \
|
||||
$(bsp_turbf_src) \
|
||||
$(debug_src) \
|
||||
$(entid_src) \
|
||||
$(light_attach_h) \
|
||||
$(light_entid_src) \
|
||||
$(light_flat_src) \
|
||||
$(light_splatv_src) \
|
||||
$(light_splatf_src) \
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/image.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
#include "QF/Vulkan/mouse_pick.h"
|
||||
#include "QF/Vulkan/projection.h"
|
||||
#include "QF/Vulkan/render.h"
|
||||
#include "QF/Vulkan/staging.h"
|
||||
|
@ -99,6 +100,7 @@ vulkan_R_Init (void)
|
|||
Vulkan_CreateSwapchain (vulkan_ctx);
|
||||
|
||||
QFV_Capture_Init (vulkan_ctx);
|
||||
QFV_MousePick_Init (vulkan_ctx);
|
||||
Vulkan_Output_Init (vulkan_ctx);
|
||||
|
||||
Vulkan_Matrix_Init (vulkan_ctx);
|
||||
|
@ -372,12 +374,12 @@ vulkan_capture_screen (capfunc_t callback, void *data)
|
|||
static void
|
||||
vulkan_debug_ui (struct imui_ctx_s *imui_ctx)
|
||||
{
|
||||
QFV_Render_UI (vulkan_ctx, imui_ctx);
|
||||
#define IMUI_context imui_ctx
|
||||
UI_ExtendPanel ("Renderer##menu") {
|
||||
QFV_Render_Menu (vulkan_ctx, imui_ctx);
|
||||
}
|
||||
#undef IMUI_context
|
||||
QFV_Render_UI (vulkan_ctx, imui_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -560,6 +562,7 @@ vulkan_vid_render_shutdown (void)
|
|||
Vulkan_Scene_Shutdown (vulkan_ctx);
|
||||
Vulkan_Matrix_Shutdown (vulkan_ctx);
|
||||
|
||||
QFV_MousePick_Shutdown (vulkan_ctx);
|
||||
QFV_Capture_Shutdown (vulkan_ctx);
|
||||
Vulkan_Output_Shutdown (vulkan_ctx);
|
||||
|
||||
|
|
263
libs/video/renderer/vulkan/mouse_pick.c
Normal file
263
libs/video/renderer/vulkan/mouse_pick.c
Normal file
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
mouse_pick.c
|
||||
|
||||
Vulkan frame mouse picking support
|
||||
|
||||
Copyright (C) 2023 Bill Currie <bill@taniwha.org>
|
||||
|
||||
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 "QF/cexpr.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/Vulkan/command.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/image.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
#include "QF/Vulkan/mouse_pick.h"
|
||||
#include "QF/Vulkan/render.h"
|
||||
#include "QF/Vulkan/resource.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
static void
|
||||
mousepick_initiate (const exprval_t **params, exprval_t *result,
|
||||
exprctx_t *ectx)
|
||||
{
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
|
||||
auto mpctx = ctx->mousepick_context;
|
||||
auto frame = &mpctx->frames.a[ctx->curFrame];
|
||||
|
||||
if (!frame->callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
|
||||
auto cmd = QFV_GetCmdBuffer (ctx, false);
|
||||
dfunc->vkBeginCommandBuffer (cmd, &(VkCommandBufferBeginInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
});
|
||||
|
||||
dfunc->vkCmdCopyImageToBuffer (cmd, frame->entid_image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
frame->entid_buffer, 1,
|
||||
&(VkBufferImageCopy) {
|
||||
.bufferOffset = 0,
|
||||
.bufferRowLength = 0,
|
||||
.bufferImageHeight = 0,
|
||||
.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 },
|
||||
.imageOffset = frame->offset,
|
||||
.imageExtent = frame->extent,
|
||||
});
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
QFV_AppendCmdBuffer (ctx, cmd);
|
||||
|
||||
frame->initiated = true;
|
||||
}
|
||||
|
||||
static void
|
||||
mousepick_finalize (const exprval_t **params, exprval_t *result,
|
||||
exprctx_t *ectx)
|
||||
{
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
|
||||
auto mpctx = ctx->mousepick_context;
|
||||
auto frame = &mpctx->frames.a[ctx->curFrame];
|
||||
|
||||
if (!frame->callback || !frame->initiated) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
|
||||
dfunc->vkInvalidateMappedMemoryRanges (device->dev, 1,
|
||||
&(VkMappedMemoryRange) {
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.memory = mpctx->resources->memory,
|
||||
.offset = 0,
|
||||
.size = VK_WHOLE_SIZE,
|
||||
});
|
||||
|
||||
uint32_t entids[mousepick_size * mousepick_size];
|
||||
memset (entids, 0xff, sizeof (entids));
|
||||
if (frame->extent.width > mousepick_size
|
||||
|| frame->extent.height > mousepick_size) {
|
||||
Sys_Error ("mousepick_finalize: invalid extent: %d %d\n",
|
||||
frame->extent.width, frame->extent.height);
|
||||
}
|
||||
for (uint32_t j = 0; j < frame->extent.height; j++) {
|
||||
uint32_t y = j + 2 - (frame->y - frame->offset.y);
|
||||
uint32_t srcInd = j * frame->extent.width;
|
||||
uint32_t dstInd = y * mousepick_size;
|
||||
for (uint32_t i = 0; i < frame->extent.width; i++) {
|
||||
uint32_t x = i + 2 - (frame->x - frame->offset.x);
|
||||
entids[dstInd + x] = frame->entid_data[srcInd + i];
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
for (uint32_t j = 0; j < mousepick_size; j++) {
|
||||
for (uint32_t i = 0; i < mousepick_size; i++) {
|
||||
printf ("%03x ", entids[j * mousepick_size + i] & 0xfff);
|
||||
}
|
||||
puts ("");
|
||||
}
|
||||
puts ("");
|
||||
#endif
|
||||
frame->callback (entids, frame->callback_data);
|
||||
frame->callback = 0;
|
||||
frame->callback_data = 0;
|
||||
frame->initiated = false;
|
||||
}
|
||||
|
||||
static exprfunc_t mousepick_initiate_func[] = {
|
||||
{ .func = mousepick_initiate },
|
||||
{}
|
||||
};
|
||||
static exprfunc_t mousepick_finalize_func[] = {
|
||||
{ .func = mousepick_finalize },
|
||||
{}
|
||||
};
|
||||
static exprsym_t mousepick_task_syms[] = {
|
||||
{ "mousepick_initiate", &cexpr_function, mousepick_initiate_func },
|
||||
{ "mousepick_finalize", &cexpr_function, mousepick_finalize_func },
|
||||
{}
|
||||
};
|
||||
|
||||
void
|
||||
QFV_MousePick_Init (vulkan_ctx_t *ctx)
|
||||
{
|
||||
QFV_Render_AddTasks (ctx, mousepick_task_syms);
|
||||
|
||||
qfvPushDebug (ctx, "mouse pick init");
|
||||
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
|
||||
ctx->mousepick_context = calloc (1, sizeof (qfv_mousepickctx_t));
|
||||
auto mpctx = ctx->mousepick_context;
|
||||
|
||||
auto rctx = ctx->render_context;
|
||||
size_t frames = rctx->frames.size;
|
||||
DARRAY_INIT (&mpctx->frames, frames);
|
||||
DARRAY_RESIZE (&mpctx->frames, frames);
|
||||
mpctx->frames.grow = 0;
|
||||
|
||||
mpctx->resources = calloc (1, sizeof (qfv_resource_t)
|
||||
+ sizeof (qfv_resobj_t[frames]));
|
||||
auto buffers = (qfv_resobj_t *) &mpctx->resources[1];
|
||||
mpctx->resources[0] = (qfv_resource_t) {
|
||||
.name = "mousepick",
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
|
||||
.num_objects = frames,
|
||||
.objects = buffers,
|
||||
};
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
buffers[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "entids:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
.size = 16 * 16 * sizeof (uint32_t),
|
||||
},
|
||||
};
|
||||
}
|
||||
QFV_CreateResource (device, mpctx->resources);
|
||||
|
||||
byte *entid_data;
|
||||
dfunc->vkMapMemory (device->dev, mpctx->resources->memory, 0,
|
||||
mpctx->resources->size, 0, (void **) &entid_data);
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
auto frame = &mpctx->frames.a[i];
|
||||
*frame = (qfv_mousepick_frame_t) {
|
||||
.entid_buffer = buffers[i].buffer.buffer,
|
||||
.entid_data = (uint32_t *) (entid_data + buffers[i].buffer.offset),
|
||||
};
|
||||
}
|
||||
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
void
|
||||
QFV_MousePick_Shutdown (vulkan_ctx_t *ctx)
|
||||
{
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto mpctx = ctx->mousepick_context;
|
||||
|
||||
dfunc->vkUnmapMemory (device->dev, mpctx->resources->memory);
|
||||
QFV_DestroyResource (device, mpctx->resources);
|
||||
free (mpctx->resources);
|
||||
free (mpctx->frames.a);
|
||||
free (mpctx);
|
||||
}
|
||||
|
||||
void
|
||||
QFV_MousePick_Read (vulkan_ctx_t *ctx, uint32_t x, uint32_t y,
|
||||
mousepickfunc_t callback, void *data)
|
||||
{
|
||||
auto mpctx = ctx->mousepick_context;
|
||||
auto frame = &mpctx->frames.a[ctx->curFrame];
|
||||
|
||||
if (!mpctx->entid_res) {
|
||||
auto job = ctx->render_context->job;
|
||||
auto step = QFV_FindStep ("main", job);
|
||||
auto rp = &step->render->renderpasses[0];
|
||||
mpctx->entid_res = QFV_FindResource ("entid", rp);
|
||||
}
|
||||
frame->entid_image = mpctx->entid_res->image.image;
|
||||
VkExtent3D extent = mpctx->entid_res->image.extent;
|
||||
|
||||
if (x >= extent.width || y >= extent.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
frame->callback = callback;
|
||||
frame->callback_data = data;
|
||||
|
||||
frame->x = x;
|
||||
frame->y = y;
|
||||
frame->offset = (VkOffset3D) {
|
||||
.x = x >= (mousepick_size / 2) ? x - (mousepick_size / 2) : 0,
|
||||
.y = y >= (mousepick_size / 2) ? y - (mousepick_size / 2) : 0,
|
||||
};
|
||||
frame->extent = (VkExtent3D) {
|
||||
.width = extent.width > x + (mousepick_size / 2)
|
||||
? (mousepick_size / 2) + 1 : extent.width - x,
|
||||
.height = extent.height > y + (mousepick_size / 2)
|
||||
? (mousepick_size / 2) + 1 : extent.height - y,
|
||||
.depth = 1,
|
||||
};
|
||||
frame->extent.width += x - frame->offset.x;
|
||||
frame->extent.height += y - frame->offset.y;
|
||||
}
|
|
@ -629,6 +629,21 @@ QFV_Render_AddAttachments (vulkan_ctx_t *ctx, uint32_t num_attachments,
|
|||
}
|
||||
}
|
||||
|
||||
qfv_resobj_t *
|
||||
QFV_FindResource (const char *name, qfv_renderpass_t *rp)
|
||||
{
|
||||
if (!rp->resources) {
|
||||
return 0;
|
||||
}
|
||||
for (uint32_t i = 0; i < rp->resources->num_objects; i++) {
|
||||
auto obj = &rp->resources->objects[i];
|
||||
if (!strcmp (obj->name, name)) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
qfv_step_t *
|
||||
QFV_FindStep (const char *name, qfv_job_t *job)
|
||||
{
|
||||
|
|
|
@ -28,14 +28,25 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/fbsearch.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/ui/imui.h"
|
||||
|
||||
#include "QF/Vulkan/mouse_pick.h"
|
||||
#include "QF/Vulkan/render.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
#define IMUI_context imui_ctx
|
||||
|
||||
#define picked_entity_count (mousepick_size * mousepick_size)
|
||||
|
||||
typedef struct qfv_renderdebug_s {
|
||||
imui_window_t job_timings_window;
|
||||
imui_window_t job_control_window;
|
||||
imui_window_t entity_window;
|
||||
uint32_t picked_enties[picked_entity_count];
|
||||
} qfv_renderdebug_t;
|
||||
|
||||
static void
|
||||
hs (imui_ctx_t *imui_ctx, int size)
|
||||
{
|
||||
|
@ -61,16 +72,8 @@ static void
|
|||
job_timings_window (vulkan_ctx_t *ctx, imui_ctx_t *imui_ctx)
|
||||
{
|
||||
auto rctx = ctx->render_context;
|
||||
if (!rctx->job_timings_window) {
|
||||
rctx->job_timings_window = malloc (sizeof (imui_window_t));
|
||||
*rctx->job_timings_window = (imui_window_t) {
|
||||
.name = nva ("Job Timings##%p.window", rctx),
|
||||
.xpos = 100,
|
||||
.ypos = 50,
|
||||
};
|
||||
}
|
||||
UI_Window (rctx->job_timings_window) {
|
||||
if (rctx->job_timings_window->is_collapsed) {
|
||||
UI_Window (&rctx->debug->job_timings_window) {
|
||||
if (rctx->debug->job_timings_window.is_collapsed) {
|
||||
continue;
|
||||
}
|
||||
auto job = rctx->job;
|
||||
|
@ -126,16 +129,8 @@ static void
|
|||
job_control_window (vulkan_ctx_t *ctx, imui_ctx_t *imui_ctx)
|
||||
{
|
||||
auto rctx = ctx->render_context;
|
||||
if (!rctx->job_control_window) {
|
||||
rctx->job_control_window = malloc (sizeof (imui_window_t));
|
||||
*rctx->job_control_window = (imui_window_t) {
|
||||
.name = nva ("Job Control##%p.window", rctx),
|
||||
.xpos = 100,
|
||||
.ypos = 50,
|
||||
};
|
||||
}
|
||||
UI_Window (rctx->job_control_window) {
|
||||
if (rctx->job_control_window->is_collapsed) {
|
||||
UI_Window (&rctx->debug->job_control_window) {
|
||||
if (rctx->debug->job_control_window.is_collapsed) {
|
||||
continue;
|
||||
}
|
||||
auto job = rctx->job;
|
||||
|
@ -180,11 +175,114 @@ job_control_window (vulkan_ctx_t *ctx, imui_ctx_t *imui_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mousepick_callback (const uint32_t *entid, void *data)
|
||||
{
|
||||
auto debug = ((qfv_renderctx_t *) data)->debug;
|
||||
memcpy (debug->picked_enties, entid, sizeof (debug->picked_enties));
|
||||
}
|
||||
|
||||
static int
|
||||
entid_counts_cmp (const void *_a, const void *_b)
|
||||
{
|
||||
const uint32_t *a = _a;
|
||||
const uint32_t *b = _b;
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
static void
|
||||
entity_window (vulkan_ctx_t *ctx, imui_ctx_t *imui_ctx)
|
||||
{
|
||||
auto rctx = ctx->render_context;
|
||||
auto debug = rctx->debug;
|
||||
UI_Window (&debug->entity_window) {
|
||||
if (debug->entity_window.is_collapsed) {
|
||||
continue;
|
||||
}
|
||||
typedef struct {
|
||||
uint32_t entid;
|
||||
uint32_t count;
|
||||
} entid_counts_t;
|
||||
entid_counts_t entid_counts[picked_entity_count];
|
||||
uint32_t num_entids = 0;
|
||||
for (uint32_t i = 0; i < picked_entity_count; i++) {
|
||||
if (debug->picked_enties[i] == nullent) {
|
||||
continue;
|
||||
}
|
||||
if (!num_entids) {
|
||||
entid_counts[num_entids++] = (entid_counts_t) {
|
||||
.entid = debug->picked_enties[i],
|
||||
.count = 1,
|
||||
};
|
||||
continue;
|
||||
}
|
||||
entid_counts_t *ec = 0;
|
||||
ec = fbsearch (&debug->picked_enties[i],
|
||||
entid_counts, num_entids, sizeof (entid_counts_t),
|
||||
entid_counts_cmp);
|
||||
uint32_t ind = 0;
|
||||
if (ec) {
|
||||
if (ec->entid == debug->picked_enties[i]) {
|
||||
ec->count++;
|
||||
continue;
|
||||
}
|
||||
ind = ec - entid_counts + 1;
|
||||
}
|
||||
memmove (entid_counts + ind + 1, entid_counts + ind,
|
||||
sizeof (entid_counts_t[num_entids - ind]));
|
||||
entid_counts[ind] = (entid_counts_t) {
|
||||
.entid = debug->picked_enties[i],
|
||||
.count = 1,
|
||||
};
|
||||
num_entids++;
|
||||
}
|
||||
|
||||
auto io = IMUI_GetIO (imui_ctx);
|
||||
if (io.hot == nullent && io.active == nullent) {
|
||||
QFV_MousePick_Read (ctx, io.mouse.x, io.mouse.y,
|
||||
mousepick_callback, rctx);
|
||||
for (uint32_t i = num_entids; i-- > 0; ) {
|
||||
UI_Horizontal {
|
||||
UI_Label ("Entity");
|
||||
hs (imui_ctx, 1);
|
||||
UI_FlexibleSpace ();
|
||||
UI_Labelf ("%08x %2d##%p.entity", entid_counts[i].entid,
|
||||
entid_counts[i].count, rctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
QFV_Render_UI (vulkan_ctx_t *ctx, imui_ctx_t *imui_ctx)
|
||||
{
|
||||
auto rctx = ctx->render_context;
|
||||
if (!rctx->debug) {
|
||||
rctx->debug = malloc (sizeof (qfv_renderdebug_t));
|
||||
*rctx->debug = (qfv_renderdebug_t) {
|
||||
.job_timings_window = {
|
||||
.name = nva ("Job Timings##%p.window", rctx),
|
||||
.xpos = 100,
|
||||
.ypos = 50,
|
||||
},
|
||||
.job_control_window = {
|
||||
.name = nva ("Job Control##%p.window", rctx),
|
||||
.xpos = 100,
|
||||
.ypos = 50,
|
||||
},
|
||||
.entity_window = {
|
||||
.name = nva ("Entities##%p.window", rctx),
|
||||
.xpos = 100,
|
||||
.ypos = 50,
|
||||
},
|
||||
};
|
||||
memset (rctx->debug->picked_enties, 0xff,
|
||||
sizeof (rctx->debug->picked_enties));
|
||||
}
|
||||
job_timings_window (ctx, imui_ctx);
|
||||
job_control_window (ctx, imui_ctx);
|
||||
entity_window (ctx, imui_ctx);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -192,10 +290,13 @@ QFV_Render_Menu (vulkan_ctx_t *ctx, imui_ctx_t *imui_ctx)
|
|||
{
|
||||
auto rctx = ctx->render_context;
|
||||
if (UI_MenuItem (va (ctx->va_ctx, "Job Timings##%p", rctx))) {
|
||||
rctx->job_timings_window->is_open = true;
|
||||
rctx->debug->job_timings_window.is_open = true;
|
||||
}
|
||||
if (UI_MenuItem (va (ctx->va_ctx, "Job Control##%p", rctx))) {
|
||||
rctx->job_control_window->is_open = true;
|
||||
rctx->debug->job_control_window.is_open = true;
|
||||
}
|
||||
if (UI_MenuItem (va (ctx->va_ctx, "Entities##%p", rctx))) {
|
||||
rctx->debug->entity_window.is_open = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,12 +304,10 @@ void
|
|||
QFV_Render_UI_Shutdown (vulkan_ctx_t *ctx)
|
||||
{
|
||||
auto rctx = ctx->render_context;
|
||||
if (rctx->job_timings_window) {
|
||||
free ((char *) rctx->job_timings_window->name);
|
||||
free (rctx->job_timings_window);
|
||||
}
|
||||
if (rctx->job_control_window) {
|
||||
free ((char *) rctx->job_control_window->name);
|
||||
free (rctx->job_control_window);
|
||||
if (rctx->debug) {
|
||||
free ((char *) rctx->debug->job_timings_window.name);
|
||||
free ((char *) rctx->debug->job_control_window.name);
|
||||
free ((char *) rctx->debug->entity_window.name);
|
||||
free (rctx->debug);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -610,6 +610,15 @@ properties = {
|
|||
descriptorSets = (matrix_set, planes_set);
|
||||
};
|
||||
};
|
||||
general = {
|
||||
shader = {
|
||||
fragment_entid = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/entid.frag;
|
||||
};
|
||||
};
|
||||
};
|
||||
lighting = {
|
||||
shader = {
|
||||
vertex_splat = {
|
||||
|
@ -617,6 +626,11 @@ properties = {
|
|||
name = main;
|
||||
module = $builtin/light_splat.vert;
|
||||
};
|
||||
vertex_entid = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/light_entid.vert;
|
||||
};
|
||||
vertex_flat = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
|
@ -983,6 +997,12 @@ descriptorSetLayouts = {
|
|||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 4;
|
||||
descriptorType = storage_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = vertex;
|
||||
},
|
||||
);
|
||||
};
|
||||
lighting_shadow = {
|
||||
|
@ -1103,6 +1123,11 @@ images = {
|
|||
usage = color_attachment|input_attachment|sampled;
|
||||
format = $render_output.format;
|
||||
};
|
||||
entid = {
|
||||
@inherit = $image_base;
|
||||
usage = color_attachment|transfer_src;
|
||||
format = r32_uint;
|
||||
};
|
||||
|
||||
cube_depth = {
|
||||
@inherit = $cube_image_base;
|
||||
|
@ -1135,6 +1160,11 @@ images = {
|
|||
usage = color_attachment|input_attachment|sampled;
|
||||
format = $render_output.format;
|
||||
};
|
||||
cube_entid = {
|
||||
@inherit = $cube_image_base;
|
||||
usage = color_attachment|transfer_src;
|
||||
format = r32_uint;
|
||||
};
|
||||
};
|
||||
imageviews = {
|
||||
depth = {
|
||||
|
@ -1175,6 +1205,10 @@ imageviews = {
|
|||
image = output;
|
||||
format = $render_output.format;
|
||||
};
|
||||
entid = {
|
||||
@inherit = $view_base;
|
||||
image = entid;
|
||||
};
|
||||
cube_depth = {
|
||||
@inherit = $cube_view_base;
|
||||
image = cube_depth;
|
||||
|
@ -1214,6 +1248,10 @@ imageviews = {
|
|||
image = cube_output;
|
||||
format = $render_output.format;
|
||||
};
|
||||
cube_entid = {
|
||||
@inherit = $cube_view_base;
|
||||
image = cube_entid;
|
||||
};
|
||||
};
|
||||
output = {
|
||||
view = $output;
|
||||
|
@ -1264,6 +1302,17 @@ renderpasses = {
|
|||
loadOp = clear;
|
||||
view = light;
|
||||
};
|
||||
entid = {
|
||||
@inherit = $attachment_base;
|
||||
format = $images.entid.format;
|
||||
loadOp = clear;
|
||||
storeOp = store;
|
||||
finalLayout = transfer_src_optimal;
|
||||
clearValue = {
|
||||
color = { int32 = ( -1, -1, -1, -1); };
|
||||
};
|
||||
view = entid;
|
||||
};
|
||||
output = {
|
||||
@inherit = $attachment_base;
|
||||
format = $render_output.format;
|
||||
|
@ -1748,13 +1797,51 @@ renderpasses = {
|
|||
};
|
||||
};
|
||||
};
|
||||
entid = {
|
||||
color = "[ 1, 0, 0, 1]";
|
||||
dependencies = {
|
||||
depth = $depth_dependency;
|
||||
};
|
||||
attachments = {
|
||||
color = {
|
||||
entid = {
|
||||
layout = color_attachment_optimal;
|
||||
blend = $blend_disable;
|
||||
};
|
||||
};
|
||||
preserve = (depth, normal, position, output);
|
||||
};
|
||||
pipelines = {
|
||||
entid_lights = {
|
||||
@inherit = $compose_base;
|
||||
disabled = false;
|
||||
|
||||
color = $color.lights;
|
||||
tasks = (
|
||||
{ func = lighting_bind_descriptors;
|
||||
params = (debug, none); },
|
||||
{ func = lighting_draw_splats; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$lighting.shader.vertex_entid,
|
||||
$general.shader.fragment_entid,
|
||||
);
|
||||
vertexInput = $lighting.vertexInput_splat;
|
||||
inputAssembly = $lighting.inputAssembly;
|
||||
layout = $lighting.splat_layout;
|
||||
rasterization = $debug_poly_lines;
|
||||
depthStencil = $depth_disable;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
output = output;
|
||||
};
|
||||
deferred_cube = {
|
||||
@inherit = $renderpasses.deferred;
|
||||
@next = (VkRenderPassMultiviewCreateInfo, {
|
||||
viewMasks = (0x3fu, 0x3fu, 0x3fu, 0x3fu, 0x3fu);
|
||||
viewMasks = (0x3fu, 0x3fu, 0x3fu, 0x3fu, 0x3fu, 0x3fu);
|
||||
});
|
||||
framebuffer = {
|
||||
width = "min($render_output.extent.width,$render_output.extent.height)";
|
||||
|
@ -1796,6 +1883,17 @@ renderpasses = {
|
|||
format = $images.cube_light.format;
|
||||
view = cube_light;
|
||||
};
|
||||
entid = {
|
||||
@inherit = $attachment_base;
|
||||
format = $images.cube_entid.format;
|
||||
loadOp = clear;
|
||||
storeOp = store;
|
||||
finalLayout = transfer_src_optimal;
|
||||
clearValue = {
|
||||
color = { int32 = ( -1, -1, -1, -1); };
|
||||
};
|
||||
view = cube_entid;
|
||||
};
|
||||
output = {
|
||||
@inherit = $attachment_base;
|
||||
format = $render_output.format;
|
||||
|
@ -2020,6 +2118,7 @@ steps = {
|
|||
tasks = (
|
||||
{ func = wait_on_fence; },
|
||||
{ func = capture_finalize; },
|
||||
{ func = mousepick_finalize; },
|
||||
{ func = update_matrices; },
|
||||
{ func = draw_scr_funcs; },
|
||||
);
|
||||
|
@ -2140,4 +2239,12 @@ steps = {
|
|||
);
|
||||
};
|
||||
};
|
||||
mouse_pick = {
|
||||
dependencies = (main);
|
||||
process = {
|
||||
tasks = (
|
||||
{ func = mousepick_initiate; },
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -91,6 +91,10 @@ static
|
|||
static
|
||||
#include "libs/video/renderer/vulkan/shader/debug.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/entid.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/light_entid.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/light_flat.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/light_splat.vert.spvc"
|
||||
|
@ -174,6 +178,8 @@ static shaderdata_t builtin_shaders[] = {
|
|||
{ "bsp_sky.frag", bsp_sky_frag, sizeof (bsp_sky_frag) },
|
||||
{ "bsp_turb.frag", bsp_turb_frag, sizeof (bsp_turb_frag) },
|
||||
{ "debug.frag", debug_frag, sizeof (debug_frag) },
|
||||
{ "entid.frag", entid_frag, sizeof (entid_frag) },
|
||||
{ "light_entid.vert", light_entid_vert, sizeof (light_entid_vert) },
|
||||
{ "light_flat.vert", light_flat_vert, sizeof (light_flat_vert) },
|
||||
{ "light_splat.vert", light_splat_vert, sizeof (light_splat_vert) },
|
||||
{ "light_splat.frag", light_splat_frag, sizeof (light_splat_frag) },
|
||||
|
|
|
@ -13,11 +13,11 @@ layout (set = 1, binding = 0) buffer Entities {
|
|||
};
|
||||
|
||||
layout (location = 0) in vec4 vertex;
|
||||
layout (location = 2) in uint entid;
|
||||
layout (location = 2) in uint entind;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec3 vert = vertex * entities[entid].transform;
|
||||
vec3 vert = vertex * entities[entind].transform;
|
||||
gl_Position = Projection3d * (View[gl_ViewIndex] * vec4 (vert, 1));
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ layout (set = 1, binding = 0) buffer Entities {
|
|||
|
||||
layout (location = 0) in vec4 vertex;
|
||||
layout (location = 1) in vec4 tl_uv;
|
||||
layout (location = 2) in uint entid;
|
||||
layout (location = 2) in uint entind;
|
||||
|
||||
layout (location = 0) out vec4 tl_st;
|
||||
layout (location = 1) out vec3 direction;
|
||||
|
@ -23,9 +23,9 @@ void
|
|||
main (void)
|
||||
{
|
||||
// geometry shader will take care of Projection and View
|
||||
vec3 vert = vertex * entities[entid].transform;
|
||||
vec3 vert = vertex * entities[entind].transform;
|
||||
gl_Position = vec4 (vert, 1);
|
||||
direction = (Sky * vertex).xyz;
|
||||
tl_st = tl_uv;
|
||||
color = entities[entid].color;
|
||||
color = entities[entind].color;
|
||||
}
|
||||
|
|
10
libs/video/renderer/vulkan/shader/entid.frag
Normal file
10
libs/video/renderer/vulkan/shader/entid.frag
Normal file
|
@ -0,0 +1,10 @@
|
|||
#version 450
|
||||
|
||||
layout (location = 0) in flat uint entid;
|
||||
layout (location = 0) out uint frag_entid;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
frag_entid = entid;
|
||||
}
|
46
libs/video/renderer/vulkan/shader/light_entid.vert
Normal file
46
libs/video/renderer/vulkan/shader/light_entid.vert
Normal file
|
@ -0,0 +1,46 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_multiview : enable
|
||||
|
||||
layout (set = 0, binding = 0) uniform
|
||||
#include "matrices.h"
|
||||
;
|
||||
|
||||
#include "lighting.h"
|
||||
|
||||
layout (location = 0) in uint light_index;
|
||||
layout (location = 1) in vec3 splat_vert;
|
||||
layout (location = 0) out uint light_index_out;
|
||||
|
||||
vec4 // assumes a and b are unit vectors
|
||||
from_to_rotation (vec3 a, vec3 b)
|
||||
{
|
||||
float d = dot (a + b, a + b);
|
||||
float qc = sqrt (d);
|
||||
vec3 qv = d > 1e-6 ? cross (a, b) / qc : vec3 (1, 0, 0);
|
||||
return vec4 (qv, qc * 0.5);
|
||||
}
|
||||
|
||||
vec3
|
||||
quat_mul (vec4 q, vec3 v)
|
||||
{
|
||||
vec3 uv = cross (q.xyz, v);
|
||||
vec3 uuv = cross (q.xyz, uv);
|
||||
return v + ((uv * q.w) + uuv) * 2;
|
||||
}
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
LightData l = lights[light_index];
|
||||
float sz = l.attenuation.w > 0 ? 1 / l.attenuation.w : sqrt(abs(l.color.w));
|
||||
float c = l.direction.w;
|
||||
float sxy = sz * (c < 0 ? sqrt (c*c * (1 - c*c)) / (0.5 - c) : 1);
|
||||
vec3 scale = vec3 (sxy, sxy, sz);
|
||||
|
||||
vec4 q = from_to_rotation (vec3 (0, 0, -1), l.direction.xyz);
|
||||
vec4 pos = vec4 (quat_mul (q, splat_vert * scale), 0);
|
||||
|
||||
gl_Position = Projection3d * (View[gl_ViewIndex] * (pos + l.position));
|
||||
light_index_out = light_entids[gl_InstanceIndex];
|
||||
}
|
|
@ -27,3 +27,6 @@ layout (set = 1, binding = 2) buffer Renderer {
|
|||
layout (set = 1, binding = 3) buffer Style {
|
||||
vec4 style[];
|
||||
};
|
||||
layout (set = 1, binding = 4) buffer LightEntIds {
|
||||
uint light_entids[];
|
||||
};
|
||||
|
|
|
@ -372,7 +372,8 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
QFV_PacketCopyBuffer (packet, lframe->style_buffer, 0, bb);
|
||||
QFV_PacketSubmit (packet);
|
||||
|
||||
uint32_t ids[4][MaxLights];
|
||||
uint32_t light_ids[4][MaxLights];
|
||||
uint32_t entids[4][MaxLights];
|
||||
|
||||
uint32_t light_count = 0;
|
||||
auto queue = lframe->light_queue;
|
||||
|
@ -398,7 +399,9 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
light_count++;
|
||||
uint32_t id = lctx->light_control.a[get_lightid (ent)].light_id;
|
||||
int mode = lctx->light_control.a[get_lightid (ent)].mode;
|
||||
ids[mode][queue[mode].count++] = id;
|
||||
light_ids[mode][queue[mode].count] = id;
|
||||
entids[mode][queue[mode].count] = ent.id;
|
||||
queue[mode].count++;
|
||||
}
|
||||
|
||||
if (ndlight) {
|
||||
|
@ -408,7 +411,9 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
for (int i = 0; i < ndlight; i++) {
|
||||
uint32_t id = lctx->dynamic_base + i;
|
||||
set_lightid (dynamic_light_entities[i], lctx->scene->reg, id);
|
||||
ids[ST_CUBE][queue[ST_CUBE].count++] = id;
|
||||
light_ids[ST_CUBE][queue[ST_CUBE].count] = id;
|
||||
entids[ST_CUBE][queue[ST_CUBE].count] = dynamic_light_entities[i];
|
||||
queue[ST_CUBE].count++;
|
||||
|
||||
VectorCopy (dynamic_lights[i]->color, lights[i].color);
|
||||
// dynamic lights seem a tad faint, so 16x map lights
|
||||
|
@ -464,12 +469,23 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
uint32_t *lids = QFV_PacketExtend (packet,
|
||||
sizeof (uint32_t[light_count]));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
memcpy (lids + queue[i].start, ids[i],
|
||||
memcpy (lids + queue[i].start, light_ids[i],
|
||||
sizeof (uint32_t[queue[i].count]));
|
||||
}
|
||||
QFV_PacketCopyBuffer (packet, lframe->id_buffer, 0,
|
||||
&bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]);
|
||||
QFV_PacketSubmit (packet);
|
||||
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
uint32_t *eids = QFV_PacketExtend (packet,
|
||||
sizeof (uint32_t[light_count]));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
memcpy (eids + queue[i].start, entids[i],
|
||||
sizeof (uint32_t[queue[i].count]));
|
||||
}
|
||||
QFV_PacketCopyBuffer (packet, lframe->entid_buffer, 0,
|
||||
&bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]);
|
||||
QFV_PacketSubmit (packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,6 +910,8 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
+ sizeof (qfv_resobj_t)
|
||||
// default shadow map and views
|
||||
+ 3 * sizeof (qfv_resobj_t)
|
||||
// light entids
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light ids
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light data
|
||||
|
@ -908,7 +926,7 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
.name = "lights",
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
.num_objects = 2 + 3 + 5 * frames,
|
||||
.num_objects = 2 + 3 + 6 * frames,
|
||||
.objects = (qfv_resobj_t *) &lctx->light_resources[1],
|
||||
};
|
||||
auto splat_verts = lctx->light_resources->objects;
|
||||
|
@ -916,7 +934,8 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
auto default_map = &splat_inds[1];
|
||||
auto default_view_cube = &default_map[1];
|
||||
auto default_view_2d = &default_view_cube[1];
|
||||
auto light_ids = &default_view_2d[1];
|
||||
auto light_entids = &default_view_2d[1];
|
||||
auto light_ids = &light_entids[frames];
|
||||
auto light_data = &light_ids[frames];
|
||||
auto light_render = &light_data[frames];
|
||||
auto light_styles = &light_render[frames];
|
||||
|
@ -983,11 +1002,21 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
},
|
||||
};
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
light_entids[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "entids:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.size = MaxLights * sizeof (uint32_t),
|
||||
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
light_ids[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "ids:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.size = 2 * MaxLights * sizeof (uint32_t),
|
||||
.size = MaxLights * sizeof (uint32_t),
|
||||
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
|
@ -1063,6 +1092,7 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
.render_buffer = light_render[i].buffer.buffer,
|
||||
.style_buffer = light_styles[i].buffer.buffer,
|
||||
.id_buffer = light_ids[i].buffer.buffer,
|
||||
.entid_buffer = light_entids[i].buffer.buffer,
|
||||
};
|
||||
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DESCRIPTOR_SET,
|
||||
|
@ -1089,6 +1119,8 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
.offset = 0, .range = VK_WHOLE_SIZE, },
|
||||
{ .buffer = lframe->style_buffer,
|
||||
.offset = 0, .range = VK_WHOLE_SIZE, },
|
||||
{ .buffer = lframe->entid_buffer,
|
||||
.offset = 0, .range = VK_WHOLE_SIZE, },
|
||||
};
|
||||
VkWriteDescriptorSet bufferWrite[] = {
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
|
@ -1122,8 +1154,14 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[4], },
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = lframe->lights_set,
|
||||
.dstBinding = 4,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[5], },
|
||||
};
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 5, bufferWrite, 0, 0);
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 6, bufferWrite, 0, 0);
|
||||
}
|
||||
|
||||
make_default_map (64, lctx->default_map, ctx);
|
||||
|
|
Loading…
Reference in a new issue