From 6deeed1829467bee6b8925cb0a22e4b7be6e7e05 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Jun 2023 23:31:08 +0900 Subject: [PATCH] [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. --- include/QF/Vulkan/qf_draw.h | 2 - include/QF/Vulkan/qf_matrices.h | 2 - libs/video/renderer/vid_render_vulkan.c | 168 +--------- libs/video/renderer/vulkan/render.c | 12 +- libs/video/renderer/vulkan/rp_main_def.plist | 57 ++++ libs/video/renderer/vulkan/vulkan_draw.c | 336 +++++++++---------- libs/video/renderer/vulkan/vulkan_main.c | 1 - libs/video/renderer/vulkan/vulkan_matrices.c | 26 +- libs/video/renderer/vulkan/vulkan_output.c | 75 +---- 9 files changed, 236 insertions(+), 443 deletions(-) diff --git a/include/QF/Vulkan/qf_draw.h b/include/QF/Vulkan/qf_draw.h index e2b93c6ad..852a012be 100644 --- a/include/QF/Vulkan/qf_draw.h +++ b/include/QF/Vulkan/qf_draw.h @@ -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, 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, struct vulkan_ctx_s *ctx); diff --git a/include/QF/Vulkan/qf_matrices.h b/include/QF/Vulkan/qf_matrices.h index 1eaeed2aa..011a69972 100644 --- a/include/QF/Vulkan/qf_matrices.h +++ b/include/QF/Vulkan/qf_matrices.h @@ -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_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) __attribute__((pure)); diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index e403394fa..88f46c0a4 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -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); } -//#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 vulkan_set_2d (int scaled) @@ -353,153 +325,15 @@ vulkan_set_2d (int scaled) 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 vulkan_UpdateScreen (transform_t camera, double realtime, SCR_Func *scr_funcs) { -#ifdef TEST_RENDER + vulkan_set_2d (1);//FIXME while (*scr_funcs) { (*scr_funcs) (); scr_funcs++; } 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 diff --git a/libs/video/renderer/vulkan/render.c b/libs/video/renderer/vulkan/render.c index 9c7e352f1..82015188b 100644 --- a/libs/video/renderer/vulkan/render.c +++ b/libs/video/renderer/vulkan/render.c @@ -137,7 +137,7 @@ run_subpass (qfv_subpass_t *sp, VkCommandBuffer cmd, vulkan_ctx_t *ctx) static void 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_devfuncs_t *dfunc = device->funcs; @@ -177,7 +177,7 @@ static void run_compute_pipeline (qfv_pipeline_t *pipeline, VkCommandBuffer cmd, 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_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++) { __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) { run_renderpass (step->render->active, ctx); } @@ -266,8 +266,8 @@ QFV_RunRenderJob (vulkan_ctx_t *ctx) job->commands.size, job->commands.a, 1, &frame->renderDoneSemaphore, }; - printf ("%10.2f submit for frame %d: %zd %p\n", Sys_DoubleTime (), - ctx->curFrame, job->commands.size, frame->imageAvailableSemaphore); + //printf ("%10.2f submit for frame %d: %zd %p\n", Sys_DoubleTime (), + // ctx->curFrame, job->commands.size, frame->imageAvailableSemaphore); dfunc->vkResetFences (device->dev, 1, &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; job->command_pool = frame->command_pool; dfunc->vkResetCommandPool (device->dev, job->command_pool, 0); - DARRAY_CLEAR (&job->commands); + DARRAY_RESIZE (&job->commands, 0); } static void diff --git a/libs/video/renderer/vulkan/rp_main_def.plist b/libs/video/renderer/vulkan/rp_main_def.plist index abe043d97..e9ed4edf6 100644 --- a/libs/video/renderer/vulkan/rp_main_def.plist +++ b/libs/video/renderer/vulkan/rp_main_def.plist @@ -11,6 +11,7 @@ properties = { output = "[0.0, 0.7, 0.7, 1]"; waterwarp = "[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 = { 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 = { matrix_set = { @@ -1271,6 +1308,22 @@ renderpasses = { ); 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 = { tasks = ( { func = wait_on_fence; }, + { func = update_matrices; }, ); }; }; +/* particles = { dependencies = (wait_on_fence); compute = { @@ -1342,6 +1397,7 @@ steps = { }; }; }; +*/ preoutput = { dependencies = (wait_on_fence); process = { @@ -1349,6 +1405,7 @@ steps = { { func = acquire_output; params = ("\"output\""); }, { func = update_input; }, + { func = flush_draw; }, ); }; }; diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 6915e4f7e..7539e9518 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -72,14 +72,6 @@ #include "r_internal.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 { uint32_t vert_index; uint32_t slice_index; @@ -875,9 +867,161 @@ load_white_pic (vulkan_ctx_t *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 Vulkan_Draw_Init (vulkan_ctx_t *ctx) { + QFV_Render_AddTasks (ctx, draw_task_syms); + qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; @@ -973,15 +1117,6 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) DARRAY_INIT (&dframe->cmdSet, QFV_drawNumPasses); DARRAY_RESIZE (&dframe->cmdSet, QFV_drawNumPasses); 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); } @@ -1412,173 +1547,6 @@ Vulkan_Draw_FadeScreen (vulkan_ctx_t *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 Vulkan_Draw_BlendScreen (quat_t color, vulkan_ctx_t *ctx) { diff --git a/libs/video/renderer/vulkan/vulkan_main.c b/libs/video/renderer/vulkan/vulkan_main.c index 06880ef02..a4dbd0bfa 100644 --- a/libs/video/renderer/vulkan/vulkan_main.c +++ b/libs/video/renderer/vulkan/vulkan_main.c @@ -167,7 +167,6 @@ Vulkan_NewScene (scene_t *scene, vulkan_ctx_t *ctx) static void main_draw (qfv_renderframe_t *rFrame) { - Vulkan_Matrix_Draw (rFrame); Vulkan_RenderView (rFrame); Vulkan_Lighting_Draw (rFrame); Vulkan_Compose_Draw (rFrame); diff --git a/libs/video/renderer/vulkan/vulkan_matrices.c b/libs/video/renderer/vulkan/vulkan_matrices.c index 76d424711..3fb0daf1e 100644 --- a/libs/video/renderer/vulkan/vulkan_matrices.c +++ b/libs/video/renderer/vulkan/vulkan_matrices.c @@ -174,15 +174,15 @@ Vulkan_SetSkyMatrix (vulkan_ctx_t *ctx, mat4f_t sky) } } -void -Vulkan_Matrix_Draw (qfv_renderframe_t *rFrame) +static void +update_matrices (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { - vulkan_ctx_t *ctx = rFrame->vulkan_ctx; - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - - __auto_type mctx = ctx->matrix_context; - __auto_type mframe = &mctx->frames.a[ctx->curFrame]; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto device = ctx->device; + auto dfunc = device->funcs; + auto mctx = ctx->matrix_context; + auto mframe = &mctx->frames.a[ctx->curFrame]; setup_view (ctx); setup_sky (ctx); @@ -218,9 +218,19 @@ Vulkan_Matrix_Draw (qfv_renderframe_t *rFrame) 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 Vulkan_Matrix_Init (vulkan_ctx_t *ctx) { + QFV_Render_AddTasks (ctx, matrix_task_syms); qfvPushDebug (ctx, "matrix init"); qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; diff --git a/libs/video/renderer/vulkan/vulkan_output.c b/libs/video/renderer/vulkan/vulkan_output.c index cc5058d20..b84533b98 100644 --- a/libs/video/renderer/vulkan/vulkan_output.c +++ b/libs/video/renderer/vulkan/vulkan_output.c @@ -62,85 +62,15 @@ #include "vid_vulkan.h" #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 preoutput_draw (qfv_renderframe_t *rFrame) { - acquire_image (rFrame); - output_update_input (rFrame); } static void process_input (qfv_renderframe_t *rFrame) { + return; vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; @@ -216,7 +146,6 @@ static void draw_output (qfv_renderframe_t *rFrame) { process_input (rFrame); - Vulkan_FlushText (rFrame); } void @@ -256,7 +185,6 @@ acquire_output (const exprval_t **params, exprval_t *result, exprctx_t *ectx) auto octx = ctx->output_context; auto sc = ctx->swapchain; - printf ("acquire_output: %d\n", ctx->curFrame); uint32_t imageIndex = 0; while (!QFV_AcquireNextImage (sc, frame->imageAvailableSemaphore, 0, &imageIndex)) { @@ -309,6 +237,7 @@ acquire_output (const exprval_t **params, exprval_t *result, exprctx_t *ectx) octx->framebuffers[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++) { auto sp = &rp->subpasses[i]; for (uint32_t j = 0; j < sp->pipeline_count; j++) {