mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-19 15:30:50 +00:00
[vulkan] Get the output step working for draw
It leaks command buffers (due to a misunderstanding of vkResetCommandPool), but it seems 2d draw (sliced quads) is working nicely.
This commit is contained in:
parent
3de39f5408
commit
6deeed1829
9 changed files with 236 additions and 443 deletions
|
@ -87,8 +87,6 @@ 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_FlushText (struct qfv_renderframe_s *rFrame);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,6 @@ void Vulkan_SetSkyMatrix (struct vulkan_ctx_s *ctx, mat4f_t sky);
|
||||||
|
|
||||||
void Vulkan_Matrix_Init (struct vulkan_ctx_s *ctx);
|
void Vulkan_Matrix_Init (struct vulkan_ctx_s *ctx);
|
||||||
void Vulkan_Matrix_Shutdown (struct vulkan_ctx_s *ctx);
|
void Vulkan_Matrix_Shutdown (struct vulkan_ctx_s *ctx);
|
||||||
// "Draw" :)
|
|
||||||
void Vulkan_Matrix_Draw (struct qfv_renderframe_s *rFrame);
|
|
||||||
VkDescriptorSet Vulkan_Matrix_Descriptors (struct vulkan_ctx_s *ctx, int frame)
|
VkDescriptorSet Vulkan_Matrix_Descriptors (struct vulkan_ctx_s *ctx, int frame)
|
||||||
__attribute__((pure));
|
__attribute__((pure));
|
||||||
|
|
||||||
|
|
|
@ -307,34 +307,6 @@ 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);
|
||||||
}
|
}
|
||||||
//#define TEST_RENDER
|
|
||||||
#ifndef TEST_RENDER
|
|
||||||
static void
|
|
||||||
vulkan_begin_frame (void)
|
|
||||||
{
|
|
||||||
qfv_device_t *device = vulkan_ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
VkDevice dev = device->dev;
|
|
||||||
|
|
||||||
__auto_type frame = &vulkan_ctx->frames.a[vulkan_ctx->curFrame];
|
|
||||||
|
|
||||||
dfunc->vkWaitForFences (dev, 1, &frame->fence, VK_TRUE, 2000000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vulkan_render_view (void)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < vulkan_ctx->renderPasses.size; i++) {
|
|
||||||
__auto_type rp = vulkan_ctx->renderPasses.a[i];
|
|
||||||
__auto_type rpFrame = &rp->frames.a[vulkan_ctx->curFrame];
|
|
||||||
// swapImageIndex may be updated by a render pass
|
|
||||||
uint32_t imageIndex = vulkan_ctx->swapImageIndex;
|
|
||||||
if (rp->framebuffers) {
|
|
||||||
rpFrame->framebuffer = rp->framebuffers->a[imageIndex];
|
|
||||||
}
|
|
||||||
rp->draw (rpFrame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vulkan_set_2d (int scaled)
|
vulkan_set_2d (int scaled)
|
||||||
|
@ -353,153 +325,15 @@ vulkan_set_2d (int scaled)
|
||||||
mctx->dirty = mctx->frames.size;
|
mctx->dirty = mctx->frames.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
vulkan_end_frame (void)
|
|
||||||
{
|
|
||||||
qfv_device_t *device = vulkan_ctx->device;
|
|
||||||
VkDevice dev = device->dev;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
qfv_queue_t *queue = &device->queue;
|
|
||||||
uint32_t curFrame = vulkan_ctx->curFrame;
|
|
||||||
__auto_type frame = &vulkan_ctx->frames.a[curFrame];
|
|
||||||
uint32_t imageIndex = vulkan_ctx->swapImageIndex;
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo
|
|
||||||
= { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
|
||||||
|
|
||||||
__auto_type cmdBufs = (qfv_cmdbufferset_t) DARRAY_STATIC_INIT (4);
|
|
||||||
DARRAY_APPEND (&cmdBufs, frame->cmdBuffer);
|
|
||||||
|
|
||||||
dfunc->vkBeginCommandBuffer (frame->cmdBuffer, &beginInfo);
|
|
||||||
for (size_t i = 0; i < vulkan_ctx->renderPasses.size; i++) {
|
|
||||||
__auto_type rp = vulkan_ctx->renderPasses.a[i];
|
|
||||||
__auto_type rpFrame = &rp->frames.a[curFrame];
|
|
||||||
|
|
||||||
if (rp->primary_commands) {
|
|
||||||
for (int j = 0; j < rpFrame->subpassCount; j++) {
|
|
||||||
__auto_type cmdSet = &rpFrame->subpassCmdSets[j];
|
|
||||||
size_t base = cmdBufs.size;
|
|
||||||
DARRAY_RESIZE (&cmdBufs, base + cmdSet->size);
|
|
||||||
memcpy (&cmdBufs.a[base], cmdSet->a,
|
|
||||||
cmdSet->size * sizeof (VkCommandBuffer));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFV_CmdBeginLabel (device, frame->cmdBuffer, rp->name, rp->color);
|
|
||||||
if (rpFrame->renderpass && rp->renderpass) {
|
|
||||||
VkRenderPassBeginInfo renderPassInfo = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
|
||||||
.renderPass = rp->renderpass,
|
|
||||||
.framebuffer = rp->framebuffers->a[imageIndex],
|
|
||||||
.renderArea = rp->renderArea,
|
|
||||||
.clearValueCount = rp->clearValues->size,
|
|
||||||
.pClearValues = rp->clearValues->a,
|
|
||||||
};
|
|
||||||
|
|
||||||
dfunc->vkCmdBeginRenderPass (frame->cmdBuffer, &renderPassInfo,
|
|
||||||
rpFrame->subpassContents);
|
|
||||||
|
|
||||||
for (int j = 0; j < rpFrame->subpassCount; j++) {
|
|
||||||
__auto_type cmdSet = &rpFrame->subpassCmdSets[j];
|
|
||||||
if (cmdSet->size) {
|
|
||||||
QFV_CmdBeginLabel (device, frame->cmdBuffer,
|
|
||||||
rpFrame->subpassInfo[j].name,
|
|
||||||
rpFrame->subpassInfo[j].color);
|
|
||||||
dfunc->vkCmdExecuteCommands (frame->cmdBuffer,
|
|
||||||
cmdSet->size, cmdSet->a);
|
|
||||||
QFV_CmdEndLabel (device, frame->cmdBuffer);
|
|
||||||
}
|
|
||||||
// reset for next time around
|
|
||||||
cmdSet->size = 0;
|
|
||||||
|
|
||||||
//Regardless of whether any commands were submitted for this
|
|
||||||
//subpass, must step through each and every subpass, otherwise
|
|
||||||
//the attachments won't be transitioned correctly.
|
|
||||||
if (j < rpFrame->subpassCount - 1) {
|
|
||||||
dfunc->vkCmdNextSubpass (frame->cmdBuffer,
|
|
||||||
rpFrame->subpassContents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dfunc->vkCmdEndRenderPass (frame->cmdBuffer);
|
|
||||||
} else {
|
|
||||||
for (int j = 0; j < rpFrame->subpassCount; j++) {
|
|
||||||
__auto_type cmdSet = &rpFrame->subpassCmdSets[j];
|
|
||||||
if (cmdSet->size) {
|
|
||||||
dfunc->vkCmdExecuteCommands (frame->cmdBuffer,
|
|
||||||
cmdSet->size, cmdSet->a);
|
|
||||||
}
|
|
||||||
// reset for next time around
|
|
||||||
cmdSet->size = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QFV_CmdEndLabel (device, frame->cmdBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vulkan_ctx->capture_callback) {
|
|
||||||
VkImage srcImage = vulkan_ctx->swapchain->images->a[imageIndex];
|
|
||||||
VkCommandBuffer cmd = QFV_CaptureImage (vulkan_ctx->capture, srcImage,
|
|
||||||
curFrame);
|
|
||||||
dfunc->vkCmdExecuteCommands (frame->cmdBuffer, 1, &cmd);
|
|
||||||
}
|
|
||||||
dfunc->vkEndCommandBuffer (frame->cmdBuffer);
|
|
||||||
|
|
||||||
VkPipelineStageFlags waitStage
|
|
||||||
= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
||||||
VkSubmitInfo submitInfo = {
|
|
||||||
VK_STRUCTURE_TYPE_SUBMIT_INFO, 0,
|
|
||||||
1, &frame->imageAvailableSemaphore, &waitStage,
|
|
||||||
cmdBufs.size, cmdBufs.a,
|
|
||||||
1, &frame->renderDoneSemaphore,
|
|
||||||
};
|
|
||||||
dfunc->vkResetFences (dev, 1, &frame->fence);
|
|
||||||
dfunc->vkQueueSubmit (queue->queue, 1, &submitInfo, frame->fence);
|
|
||||||
|
|
||||||
DARRAY_CLEAR (&cmdBufs);
|
|
||||||
|
|
||||||
if (vulkan_ctx->capture_callback) {
|
|
||||||
//FIXME look into "threading" this rather than waiting here
|
|
||||||
dfunc->vkWaitForFences (device->dev, 1, &frame->fence, VK_TRUE,
|
|
||||||
1000000000ull);
|
|
||||||
vulkan_ctx->capture_callback (QFV_CaptureData (vulkan_ctx->capture,
|
|
||||||
curFrame),
|
|
||||||
vulkan_ctx->capture->extent.width,
|
|
||||||
vulkan_ctx->capture->extent.height);
|
|
||||||
vulkan_ctx->capture_callback = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkPresentInfoKHR presentInfo = {
|
|
||||||
VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 0,
|
|
||||||
1, &frame->renderDoneSemaphore,
|
|
||||||
1, &vulkan_ctx->swapchain->swapchain, &imageIndex,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
dfunc->vkQueuePresentKHR (queue->queue, &presentInfo);
|
|
||||||
|
|
||||||
vulkan_ctx->curFrame++;
|
|
||||||
vulkan_ctx->curFrame %= vulkan_ctx->frames.size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static void
|
static void
|
||||||
vulkan_UpdateScreen (transform_t camera, double realtime, SCR_Func *scr_funcs)
|
vulkan_UpdateScreen (transform_t camera, double realtime, SCR_Func *scr_funcs)
|
||||||
{
|
{
|
||||||
#ifdef TEST_RENDER
|
vulkan_set_2d (1);//FIXME
|
||||||
while (*scr_funcs) {
|
while (*scr_funcs) {
|
||||||
(*scr_funcs) ();
|
(*scr_funcs) ();
|
||||||
scr_funcs++;
|
scr_funcs++;
|
||||||
}
|
}
|
||||||
QFV_RunRenderJob (vulkan_ctx);
|
QFV_RunRenderJob (vulkan_ctx);
|
||||||
#else
|
|
||||||
EntQueue_Clear (r_ent_queue);
|
|
||||||
vulkan_begin_frame ();
|
|
||||||
vulkan_set_2d (1);
|
|
||||||
while (*scr_funcs) {
|
|
||||||
(*scr_funcs) ();
|
|
||||||
scr_funcs++;
|
|
||||||
}
|
|
||||||
vulkan_render_view ();
|
|
||||||
vulkan_end_frame ();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -137,7 +137,7 @@ run_subpass (qfv_subpass_t *sp, VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
||||||
static void
|
static void
|
||||||
run_renderpass (qfv_renderpass_t *rp, vulkan_ctx_t *ctx)
|
run_renderpass (qfv_renderpass_t *rp, vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
printf ("%10.2f run_renderpass: %s\n", Sys_DoubleTime (), rp->label.name);
|
//printf ("%10.2f run_renderpass: %s\n", Sys_DoubleTime (), rp->label.name);
|
||||||
|
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
@ -177,7 +177,7 @@ static void
|
||||||
run_compute_pipeline (qfv_pipeline_t *pipeline, VkCommandBuffer cmd,
|
run_compute_pipeline (qfv_pipeline_t *pipeline, VkCommandBuffer cmd,
|
||||||
vulkan_ctx_t *ctx)
|
vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
printf ("run_compute_pipeline: %s\n", pipeline->label.name);
|
//printf ("run_compute_pipeline: %s\n", pipeline->label.name);
|
||||||
|
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
@ -242,7 +242,7 @@ QFV_RunRenderJob (vulkan_ctx_t *ctx)
|
||||||
|
|
||||||
for (uint32_t i = 0; i < job->num_steps; i++) {
|
for (uint32_t i = 0; i < job->num_steps; i++) {
|
||||||
__auto_type step = &job->steps[i];
|
__auto_type step = &job->steps[i];
|
||||||
printf ("%10.2f run_step: %s\n", Sys_DoubleTime (), step->label.name);
|
//printf ("%10.2f run_step: %s\n", Sys_DoubleTime (), step->label.name);
|
||||||
if (step->render) {
|
if (step->render) {
|
||||||
run_renderpass (step->render->active, ctx);
|
run_renderpass (step->render->active, ctx);
|
||||||
}
|
}
|
||||||
|
@ -266,8 +266,8 @@ QFV_RunRenderJob (vulkan_ctx_t *ctx)
|
||||||
job->commands.size, job->commands.a,
|
job->commands.size, job->commands.a,
|
||||||
1, &frame->renderDoneSemaphore,
|
1, &frame->renderDoneSemaphore,
|
||||||
};
|
};
|
||||||
printf ("%10.2f submit for frame %d: %zd %p\n", Sys_DoubleTime (),
|
//printf ("%10.2f submit for frame %d: %zd %p\n", Sys_DoubleTime (),
|
||||||
ctx->curFrame, job->commands.size, frame->imageAvailableSemaphore);
|
// ctx->curFrame, job->commands.size, frame->imageAvailableSemaphore);
|
||||||
dfunc->vkResetFences (device->dev, 1, &frame->fence);
|
dfunc->vkResetFences (device->dev, 1, &frame->fence);
|
||||||
dfunc->vkQueueSubmit (queue->queue, 1, &submitInfo, frame->fence);
|
dfunc->vkQueueSubmit (queue->queue, 1, &submitInfo, frame->fence);
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ wait_on_fence (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
auto job = ctx->render_context->job;
|
auto job = ctx->render_context->job;
|
||||||
job->command_pool = frame->command_pool;
|
job->command_pool = frame->command_pool;
|
||||||
dfunc->vkResetCommandPool (device->dev, job->command_pool, 0);
|
dfunc->vkResetCommandPool (device->dev, job->command_pool, 0);
|
||||||
DARRAY_CLEAR (&job->commands);
|
DARRAY_RESIZE (&job->commands, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -11,6 +11,7 @@ properties = {
|
||||||
output = "[0.0, 0.7, 0.7, 1]";
|
output = "[0.0, 0.7, 0.7, 1]";
|
||||||
waterwarp = "[0.0, 0.7, 0.7, 1]";
|
waterwarp = "[0.0, 0.7, 0.7, 1]";
|
||||||
fisheye = "[0.0, 0.7, 0.7, 1]";
|
fisheye = "[0.0, 0.7, 0.7, 1]";
|
||||||
|
slice = "[0.8, 0.7, 0.2, 1]";
|
||||||
};
|
};
|
||||||
color_dependency = {
|
color_dependency = {
|
||||||
src = {
|
src = {
|
||||||
|
@ -549,6 +550,42 @@ properties = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
slice = {
|
||||||
|
shader = {
|
||||||
|
vertex = {
|
||||||
|
stage = vertex;
|
||||||
|
name = main;
|
||||||
|
module = $builtin/slice.vert;
|
||||||
|
};
|
||||||
|
fragment = {
|
||||||
|
stage = fragment;
|
||||||
|
name = main;
|
||||||
|
module = $builtin/twod.frag;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
vertexInput = {
|
||||||
|
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; },
|
||||||
|
);
|
||||||
|
};
|
||||||
|
inputAssembly = {
|
||||||
|
topology = triangle_strip;
|
||||||
|
primitiveRestartEnable = true;
|
||||||
|
};
|
||||||
|
layout = {
|
||||||
|
descriptorSets = (matrix_set, quad_data_set);
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
descriptorSetLayouts = {
|
descriptorSetLayouts = {
|
||||||
matrix_set = {
|
matrix_set = {
|
||||||
|
@ -1271,6 +1308,22 @@ renderpasses = {
|
||||||
);
|
);
|
||||||
layout = $output.layout;
|
layout = $output.layout;
|
||||||
};
|
};
|
||||||
|
slice = {
|
||||||
|
@inherit = $compose_base;
|
||||||
|
|
||||||
|
color = $color.slice;
|
||||||
|
tasks = (
|
||||||
|
{ func = slice_draw; },
|
||||||
|
);
|
||||||
|
|
||||||
|
stages = (
|
||||||
|
$slice.shader.vertex,
|
||||||
|
$slice.shader.fragment,
|
||||||
|
);
|
||||||
|
vertexInput = $slice.vertexInput;
|
||||||
|
inputAssembly = $slice.inputAssembly;
|
||||||
|
layout = $slice.layout;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1281,9 +1334,11 @@ steps = {
|
||||||
process = {
|
process = {
|
||||||
tasks = (
|
tasks = (
|
||||||
{ func = wait_on_fence; },
|
{ func = wait_on_fence; },
|
||||||
|
{ func = update_matrices; },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
particles = {
|
particles = {
|
||||||
dependencies = (wait_on_fence);
|
dependencies = (wait_on_fence);
|
||||||
compute = {
|
compute = {
|
||||||
|
@ -1342,6 +1397,7 @@ steps = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
preoutput = {
|
preoutput = {
|
||||||
dependencies = (wait_on_fence);
|
dependencies = (wait_on_fence);
|
||||||
process = {
|
process = {
|
||||||
|
@ -1349,6 +1405,7 @@ steps = {
|
||||||
{ func = acquire_output;
|
{ func = acquire_output;
|
||||||
params = ("\"output\""); },
|
params = ("\"output\""); },
|
||||||
{ func = update_input; },
|
{ func = update_input; },
|
||||||
|
{ func = flush_draw; },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,14 +72,6 @@
|
||||||
#include "r_internal.h"
|
#include "r_internal.h"
|
||||||
#include "vid_vulkan.h"
|
#include "vid_vulkan.h"
|
||||||
|
|
||||||
static const char * __attribute__((used)) draw_pass_names[] = {
|
|
||||||
"2d",
|
|
||||||
};
|
|
||||||
|
|
||||||
static QFV_Subpass subpass_map[] = {
|
|
||||||
[QFV_draw2d] = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct pic_data_s {
|
typedef struct pic_data_s {
|
||||||
uint32_t vert_index;
|
uint32_t vert_index;
|
||||||
uint32_t slice_index;
|
uint32_t slice_index;
|
||||||
|
@ -875,9 +867,161 @@ load_white_pic (vulkan_ctx_t *ctx)
|
||||||
dctx->white_pic, ctx);
|
dctx->white_pic, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_quads (vulkan_ctx_t *ctx, VkCommandBuffer cmd)
|
||||||
|
{
|
||||||
|
auto device = ctx->device;
|
||||||
|
auto dfunc = device->funcs;
|
||||||
|
auto dctx = ctx->draw_context;
|
||||||
|
auto dframe = &dctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
|
VkBuffer instance_buffer = dframe->instance_buffer;
|
||||||
|
VkDeviceSize offsets[] = {0};
|
||||||
|
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &instance_buffer, offsets);
|
||||||
|
|
||||||
|
VkBuffer ind_buffer = dctx->index_object[0].buffer.buffer;
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
VkPipelineLayout layout = dctx->quad_layout;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
DARRAY_RESIZE (&dframe->quad_batch, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_lines (vulkan_ctx_t *ctx, VkCommandBuffer cmd)
|
||||||
|
{
|
||||||
|
auto device = ctx->device;
|
||||||
|
auto dfunc = device->funcs;
|
||||||
|
auto dctx = ctx->draw_context;
|
||||||
|
auto dframe = &dctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
|
VkBuffer line_buffer = dframe->line_buffer;
|
||||||
|
VkDeviceSize offsets[] = {0};
|
||||||
|
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &line_buffer, offsets);
|
||||||
|
VkDescriptorSet set[1] = {
|
||||||
|
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||||
|
};
|
||||||
|
VkPipelineLayout layout = dctx->lines_layout;
|
||||||
|
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
layout, 0, 1, set, 0, 0);
|
||||||
|
dfunc->vkCmdDraw (cmd, dframe->line_verts.count * VERTS_PER_LINE,
|
||||||
|
1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flush_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
|
{
|
||||||
|
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||||
|
auto ctx = taskctx->ctx;
|
||||||
|
flush_draw_scrap (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
slice_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 dctx = ctx->draw_context;
|
||||||
|
auto dframe = &dctx->frames.a[ctx->curFrame];
|
||||||
|
if (!dframe->quad_insts.count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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[] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
|
||||||
|
memory, dframe->instance_offset,
|
||||||
|
a(dframe->quad_insts.count * BYTES_PER_QUAD) },
|
||||||
|
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
|
||||||
|
memory, dframe->dvert_offset,
|
||||||
|
a(dframe->dvertex_index * sizeof (quadvert_t)) },
|
||||||
|
};
|
||||||
|
#undef a
|
||||||
|
dfunc->vkFlushMappedMemoryRanges (device->dev, 2, ranges);
|
||||||
|
|
||||||
|
draw_quads (ctx, taskctx->cmd);
|
||||||
|
|
||||||
|
dframe->quad_insts.count = 0;
|
||||||
|
dframe->dvertex_index = 0;
|
||||||
|
dframe->dyn_descs.in_use = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
line_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 dctx = ctx->draw_context;
|
||||||
|
auto dframe = &dctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
|
if (!dframe->line_verts.count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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[] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
|
||||||
|
memory, dframe->line_offset,
|
||||||
|
a(dframe->line_verts.count * BYTES_PER_LINE) },
|
||||||
|
};
|
||||||
|
#undef a
|
||||||
|
dfunc->vkFlushMappedMemoryRanges (device->dev, 1, ranges);
|
||||||
|
|
||||||
|
draw_lines (ctx, taskctx->cmd);
|
||||||
|
|
||||||
|
dframe->line_verts.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static exprfunc_t flush_draw_func[] = {
|
||||||
|
{ .func = flush_draw },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
static exprfunc_t slice_draw_func[] = {
|
||||||
|
{ .func = slice_draw },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
static exprfunc_t line_draw_func[] = {
|
||||||
|
{ .func = line_draw },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
static exprsym_t draw_task_syms[] = {
|
||||||
|
{ "flush_draw", &cexpr_function, flush_draw_func },
|
||||||
|
{ "slice_draw", &cexpr_function, slice_draw_func },
|
||||||
|
{ "line_draw", &cexpr_function, line_draw_func },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
Vulkan_Draw_Init (vulkan_ctx_t *ctx)
|
Vulkan_Draw_Init (vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
QFV_Render_AddTasks (ctx, draw_task_syms);
|
||||||
|
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
|
||||||
|
@ -973,15 +1117,6 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx)
|
||||||
DARRAY_INIT (&dframe->cmdSet, QFV_drawNumPasses);
|
DARRAY_INIT (&dframe->cmdSet, QFV_drawNumPasses);
|
||||||
DARRAY_RESIZE (&dframe->cmdSet, QFV_drawNumPasses);
|
DARRAY_RESIZE (&dframe->cmdSet, QFV_drawNumPasses);
|
||||||
dframe->cmdSet.grow = 0;
|
dframe->cmdSet.grow = 0;
|
||||||
|
|
||||||
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, &dframe->cmdSet);
|
|
||||||
|
|
||||||
for (int j = 0; j < QFV_drawNumPasses; j++) {
|
|
||||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
|
||||||
dframe->cmdSet.a[j],
|
|
||||||
va (ctx->va_ctx, "cmd:draw:%zd:%s", i,
|
|
||||||
draw_pass_names[j]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
qfvPopDebug (ctx);
|
qfvPopDebug (ctx);
|
||||||
}
|
}
|
||||||
|
@ -1412,173 +1547,6 @@ Vulkan_Draw_FadeScreen (vulkan_ctx_t *ctx)
|
||||||
draw_blendscreen (color, ctx);
|
draw_blendscreen (color, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
draw_begin_subpass (QFV_DrawSubpass subpass, qfv_renderframe_t *rFrame)
|
|
||||||
{
|
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
drawctx_t *dctx = ctx->draw_context;
|
|
||||||
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
|
|
||||||
VkCommandBuffer cmd = dframe->cmdSet.a[subpass];
|
|
||||||
|
|
||||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
|
||||||
VkCommandBufferInheritanceInfo inherit = {
|
|
||||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
|
||||||
rFrame->renderpass->renderpass, subpass_map[subpass],
|
|
||||||
rFrame->framebuffer,
|
|
||||||
0, 0, 0,
|
|
||||||
};
|
|
||||||
VkCommandBufferBeginInfo beginInfo = {
|
|
||||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
|
|
||||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
|
||||||
| VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &inherit,
|
|
||||||
};
|
|
||||||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
|
||||||
|
|
||||||
QFV_duCmdBeginLabel (device, cmd, va (ctx->va_ctx, "draw:%s",
|
|
||||||
draw_pass_names[subpass]),
|
|
||||||
{0.5, 0.8, 0.1, 1});
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
draw_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
|
||||||
{
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
|
|
||||||
QFV_duCmdEndLabel (device, cmd);
|
|
||||||
dfunc->vkEndCommandBuffer (cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bind_pipeline (qfv_renderframe_t *rFrame, VkPipeline pipeline,
|
|
||||||
VkCommandBuffer cmd)
|
|
||||||
{
|
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
|
||||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
|
||||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
draw_quads (qfv_renderframe_t *rFrame, VkCommandBuffer cmd)
|
|
||||||
{
|
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
drawctx_t *dctx = ctx->draw_context;
|
|
||||||
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
|
|
||||||
|
|
||||||
VkBuffer instance_buffer = dframe->instance_buffer;
|
|
||||||
VkDeviceSize offsets[] = {0};
|
|
||||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &instance_buffer, offsets);
|
|
||||||
|
|
||||||
VkBuffer ind_buffer = dctx->index_object[0].buffer.buffer;
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
VkPipelineLayout layout = dctx->quad_layout;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
DARRAY_RESIZE (&dframe->quad_batch, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
draw_lines (qfv_renderframe_t *rFrame, VkCommandBuffer cmd)
|
|
||||||
{
|
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
drawctx_t *dctx = ctx->draw_context;
|
|
||||||
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
|
|
||||||
|
|
||||||
VkBuffer line_buffer = dframe->line_buffer;
|
|
||||||
VkDeviceSize offsets[] = {0};
|
|
||||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &line_buffer, offsets);
|
|
||||||
VkDescriptorSet set[1] = {
|
|
||||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
|
||||||
};
|
|
||||||
VkPipelineLayout layout = dctx->lines_layout;
|
|
||||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
||||||
layout, 0, 1, set, 0, 0);
|
|
||||||
dfunc->vkCmdDraw (cmd, dframe->line_verts.count * VERTS_PER_LINE,
|
|
||||||
1, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vulkan_FlushText (qfv_renderframe_t *rFrame)
|
|
||||||
{
|
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
|
||||||
flush_draw_scrap (ctx);
|
|
||||||
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
drawctx_t *dctx = ctx->draw_context;
|
|
||||||
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
|
|
||||||
|
|
||||||
if (!dframe->quad_insts.count && !dframe->line_verts.count) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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[] = {
|
|
||||||
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
|
|
||||||
memory, dframe->instance_offset,
|
|
||||||
a(dframe->quad_insts.count * BYTES_PER_QUAD) },
|
|
||||||
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
|
|
||||||
memory, dframe->dvert_offset,
|
|
||||||
a(dframe->dvertex_index * sizeof (quadvert_t)) },
|
|
||||||
{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
|
|
||||||
memory, dframe->line_offset,
|
|
||||||
a(dframe->line_verts.count * BYTES_PER_LINE) },
|
|
||||||
};
|
|
||||||
#undef a
|
|
||||||
dfunc->vkFlushMappedMemoryRanges (device->dev, 2, ranges);
|
|
||||||
|
|
||||||
DARRAY_APPEND (&rFrame->subpassCmdSets[subpass_map[QFV_draw2d]],
|
|
||||||
dframe->cmdSet.a[QFV_draw2d]);
|
|
||||||
|
|
||||||
draw_begin_subpass (QFV_draw2d, rFrame);
|
|
||||||
|
|
||||||
if (dframe->quad_insts.count) {
|
|
||||||
bind_pipeline (rFrame, dctx->quad_pipeline,
|
|
||||||
dframe->cmdSet.a[QFV_draw2d]);
|
|
||||||
draw_quads (rFrame, dframe->cmdSet.a[QFV_draw2d]);
|
|
||||||
}
|
|
||||||
if (dframe->line_verts.count) {
|
|
||||||
bind_pipeline (rFrame, dctx->line_pipeline,
|
|
||||||
dframe->cmdSet.a[QFV_draw2d]);
|
|
||||||
draw_lines (rFrame, dframe->cmdSet.a[QFV_draw2d]);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_end_subpass (dframe->cmdSet.a[QFV_draw2d], ctx);
|
|
||||||
|
|
||||||
dframe->quad_insts.count = 0;
|
|
||||||
dframe->line_verts.count = 0;
|
|
||||||
dframe->dvertex_index = 0;
|
|
||||||
dframe->dyn_descs.in_use = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Vulkan_Draw_BlendScreen (quat_t color, vulkan_ctx_t *ctx)
|
Vulkan_Draw_BlendScreen (quat_t color, vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,7 +167,6 @@ Vulkan_NewScene (scene_t *scene, vulkan_ctx_t *ctx)
|
||||||
static void
|
static void
|
||||||
main_draw (qfv_renderframe_t *rFrame)
|
main_draw (qfv_renderframe_t *rFrame)
|
||||||
{
|
{
|
||||||
Vulkan_Matrix_Draw (rFrame);
|
|
||||||
Vulkan_RenderView (rFrame);
|
Vulkan_RenderView (rFrame);
|
||||||
Vulkan_Lighting_Draw (rFrame);
|
Vulkan_Lighting_Draw (rFrame);
|
||||||
Vulkan_Compose_Draw (rFrame);
|
Vulkan_Compose_Draw (rFrame);
|
||||||
|
|
|
@ -174,15 +174,15 @@ Vulkan_SetSkyMatrix (vulkan_ctx_t *ctx, mat4f_t sky)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
Vulkan_Matrix_Draw (qfv_renderframe_t *rFrame)
|
update_matrices (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
{
|
{
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||||
qfv_device_t *device = ctx->device;
|
auto ctx = taskctx->ctx;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
auto device = ctx->device;
|
||||||
|
auto dfunc = device->funcs;
|
||||||
__auto_type mctx = ctx->matrix_context;
|
auto mctx = ctx->matrix_context;
|
||||||
__auto_type mframe = &mctx->frames.a[ctx->curFrame];
|
auto mframe = &mctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
setup_view (ctx);
|
setup_view (ctx);
|
||||||
setup_sky (ctx);
|
setup_sky (ctx);
|
||||||
|
@ -218,9 +218,19 @@ Vulkan_Matrix_Draw (qfv_renderframe_t *rFrame)
|
||||||
QFV_PacketSubmit (packet);
|
QFV_PacketSubmit (packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static exprfunc_t update_matrices_func[] = {
|
||||||
|
{ .func = update_matrices },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
static exprsym_t matrix_task_syms[] = {
|
||||||
|
{ "update_matrices", &cexpr_function, update_matrices_func },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
Vulkan_Matrix_Init (vulkan_ctx_t *ctx)
|
Vulkan_Matrix_Init (vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
QFV_Render_AddTasks (ctx, matrix_task_syms);
|
||||||
qfvPushDebug (ctx, "matrix init");
|
qfvPushDebug (ctx, "matrix init");
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
|
|
@ -62,85 +62,15 @@
|
||||||
#include "vid_vulkan.h"
|
#include "vid_vulkan.h"
|
||||||
#include "vkparse.h"//FIXME
|
#include "vkparse.h"//FIXME
|
||||||
|
|
||||||
static void
|
|
||||||
acquire_image (qfv_renderframe_t *rFrame)
|
|
||||||
{
|
|
||||||
auto ctx = rFrame->vulkan_ctx;
|
|
||||||
auto device = ctx->device;
|
|
||||||
auto dfunc = device->funcs;
|
|
||||||
auto frame = &ctx->frames.a[ctx->curFrame];
|
|
||||||
|
|
||||||
uint32_t imageIndex = 0;
|
|
||||||
while (!QFV_AcquireNextImage (ctx->swapchain,
|
|
||||||
frame->imageAvailableSemaphore,
|
|
||||||
0, &imageIndex)) {
|
|
||||||
QFV_DeviceWaitIdle (device);
|
|
||||||
if (ctx->capture) {
|
|
||||||
QFV_DestroyCapture (ctx->capture);
|
|
||||||
}
|
|
||||||
Vulkan_CreateSwapchain (ctx);
|
|
||||||
Vulkan_CreateCapture (ctx);
|
|
||||||
|
|
||||||
__auto_type out = ctx->output_renderpass;
|
|
||||||
out->output = (qfv_output_t) {
|
|
||||||
.extent = ctx->swapchain->extent,
|
|
||||||
.format = ctx->swapchain->format,
|
|
||||||
.frames = ctx->swapchain->numImages,
|
|
||||||
.view_list = ctx->swapchain->imageViews->a,
|
|
||||||
};
|
|
||||||
out->viewport.width = out->output.extent.width;
|
|
||||||
out->viewport.height = out->output.extent.height;
|
|
||||||
out->scissor.extent = out->output.extent;
|
|
||||||
QFV_RenderPass_CreateFramebuffer (out);
|
|
||||||
|
|
||||||
dfunc->vkDestroySemaphore (device->dev, frame->imageAvailableSemaphore,
|
|
||||||
0);
|
|
||||||
frame->imageAvailableSemaphore = QFV_CreateSemaphore (device);
|
|
||||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_SEMAPHORE,
|
|
||||||
frame->imageAvailableSemaphore,
|
|
||||||
va (ctx->va_ctx, "sc image:%d", ctx->curFrame));
|
|
||||||
}
|
|
||||||
ctx->swapImageIndex = imageIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
output_update_input (qfv_renderframe_t *rFrame)
|
|
||||||
{
|
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
outputctx_t *octx = ctx->output_context;
|
|
||||||
uint32_t curFrame = ctx->curFrame;
|
|
||||||
outputframe_t *oframe = &octx->frames.a[curFrame];
|
|
||||||
|
|
||||||
if (oframe->input == octx->input) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
oframe->input = octx->input;
|
|
||||||
|
|
||||||
VkDescriptorImageInfo imageInfo = {
|
|
||||||
octx->sampler, oframe->input,
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
||||||
};
|
|
||||||
VkWriteDescriptorSet write[] = {
|
|
||||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
|
||||||
oframe->set, 0, 0, 1,
|
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
||||||
&imageInfo, 0, 0 }
|
|
||||||
};
|
|
||||||
dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
preoutput_draw (qfv_renderframe_t *rFrame)
|
preoutput_draw (qfv_renderframe_t *rFrame)
|
||||||
{
|
{
|
||||||
acquire_image (rFrame);
|
|
||||||
output_update_input (rFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_input (qfv_renderframe_t *rFrame)
|
process_input (qfv_renderframe_t *rFrame)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
@ -216,7 +146,6 @@ static void
|
||||||
draw_output (qfv_renderframe_t *rFrame)
|
draw_output (qfv_renderframe_t *rFrame)
|
||||||
{
|
{
|
||||||
process_input (rFrame);
|
process_input (rFrame);
|
||||||
Vulkan_FlushText (rFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -256,7 +185,6 @@ acquire_output (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
auto octx = ctx->output_context;
|
auto octx = ctx->output_context;
|
||||||
auto sc = ctx->swapchain;
|
auto sc = ctx->swapchain;
|
||||||
|
|
||||||
printf ("acquire_output: %d\n", ctx->curFrame);
|
|
||||||
uint32_t imageIndex = 0;
|
uint32_t imageIndex = 0;
|
||||||
while (!QFV_AcquireNextImage (sc, frame->imageAvailableSemaphore,
|
while (!QFV_AcquireNextImage (sc, frame->imageAvailableSemaphore,
|
||||||
0, &imageIndex)) {
|
0, &imageIndex)) {
|
||||||
|
@ -309,6 +237,7 @@ acquire_output (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
octx->framebuffers[i],
|
octx->framebuffers[i],
|
||||||
va (ctx->va_ctx, "sc fb:%d", i));
|
va (ctx->va_ctx, "sc fb:%d", i));
|
||||||
}
|
}
|
||||||
|
rp->beginInfo.renderArea.extent = sc->extent;
|
||||||
for (uint32_t i = 0; i < rp->subpass_count; i++) {
|
for (uint32_t i = 0; i < rp->subpass_count; i++) {
|
||||||
auto sp = &rp->subpasses[i];
|
auto sp = &rp->subpasses[i];
|
||||||
for (uint32_t j = 0; j < sp->pipeline_count; j++) {
|
for (uint32_t j = 0; j < sp->pipeline_count; j++) {
|
||||||
|
|
Loading…
Reference in a new issue