diff --git a/include/QF/Vulkan/qf_matrices.h b/include/QF/Vulkan/qf_matrices.h new file mode 100644 index 000000000..6abbdde61 --- /dev/null +++ b/include/QF/Vulkan/qf_matrices.h @@ -0,0 +1,87 @@ +/* + qf_matrices.h + + Vulkan matrix "pass" + + Copyright (C) 2021 Bill Currie + + Author: Bill Currie + Date: 2021/12/8 + + 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 + +*/ +#ifndef __QF_Vulkan_qf_matrices_h +#define __QF_Vulkan_qf_matrices_h + +#include "QF/darray.h" +#include "QF/Vulkan/qf_vid.h" +#include "QF/Vulkan/command.h" +#include "QF/Vulkan/image.h" +#include "QF/simd/types.h" + +typedef struct qfv_matrix_buffer_s { + // projection and view matrices (model is push constant) + mat4f_t Projection3d; + mat4f_t View; + mat4f_t Sky; + mat4f_t Projection2d; +} qfv_matrix_buffer_t; + +#define LIGHTING_BUFFER_INFOS 1 +#define LIGHTING_ATTACH_INFOS 5 +#define LIGHTING_SHADOW_INFOS MaxLights +#define LIGHTING_DESCRIPTORS (LIGHTING_BUFFER_INFOS + LIGHTING_ATTACH_INFOS + 1) + +typedef struct matrixframe_s { + //VkCommandBuffer cmd; + VkBuffer buffer; + VkDescriptorSet descriptors; +} matrixframe_t; + +typedef struct matrixframeset_s + DARRAY_TYPE (matrixframe_t) matrixframeset_t; + +typedef struct matrixctx_s { + matrixframeset_t frames; + VkPipeline pipeline; + VkPipelineLayout layout; + VkDeviceMemory memory; + qfv_matrix_buffer_t matrices; + int dirty; + struct qfv_stagebuf_s *stage; + VkDescriptorPool pool; + VkDescriptorSetLayout setLayout; +} matrixctx_t; + +struct vulkan_ctx_s; +struct qfv_renderframe_s; + +void Vulkan_CalcProjectionMatrices (struct vulkan_ctx_s *ctx); +void Vulkan_CalcViewMatrix (struct vulkan_ctx_s *ctx); +void Vulkan_SetViewMatrix (struct vulkan_ctx_s *ctx, mat4f_t view); +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_Descrptors (struct vulkan_ctx_s *ctx, int frame); + +#endif//__QF_Vulkan_qf_matrices_h diff --git a/include/QF/Vulkan/qf_vid.h b/include/QF/Vulkan/qf_vid.h index db37faa59..1a94898a3 100644 --- a/include/QF/Vulkan/qf_vid.h +++ b/include/QF/Vulkan/qf_vid.h @@ -63,10 +63,6 @@ void Vulkan_CreateFrames (struct vulkan_ctx_s *ctx); void Vulkan_CreateCapture (struct vulkan_ctx_s *ctx); void Vulkan_CreateRenderPass (struct vulkan_ctx_s *ctx); void Vulkan_DestroyRenderPasses (struct vulkan_ctx_s *ctx); -void Vulkan_CreateMatrices (struct vulkan_ctx_s *ctx); -void Vulkan_DestroyMatrices (struct vulkan_ctx_s *ctx); -void Vulkan_CalcProjectionMatrices (struct vulkan_ctx_s *ctx); -void Vulkan_CalcViewMatrix (struct vulkan_ctx_s *ctx); void Vulkan_CreateSwapchain (struct vulkan_ctx_s *ctx); void Vulkan_CreateDevice (struct vulkan_ctx_s *ctx); void Vulkan_Init_Common (struct vulkan_ctx_s *ctx); diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index 584502b9c..27fadb159 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -17,16 +17,6 @@ typedef struct vulkan_frame_s { VkCommandBuffer cmdBuffer; } vulkan_frame_t; -typedef struct vulkan_matrices_s { - VkBuffer buffer_2d; - VkBuffer buffer_3d; - VkDeviceMemory memory; - vec4f_t *projection_2d; - vec4f_t *projection_3d; - vec4f_t *view_3d; - vec4f_t *sky_3d; -} vulkan_matrices_t; - typedef struct vulkan_frameset_s DARRAY_TYPE (vulkan_frame_t) vulkan_frameset_t; @@ -66,6 +56,7 @@ typedef struct vulkan_ctx_s { struct hashtab_s *imageViews; struct hashtab_s *renderpasses; + struct matrixctx_s *matrix_context; struct aliasctx_s *alias_context; struct bspctx_s *bsp_context; struct drawctx_s *draw_context; @@ -92,8 +83,6 @@ typedef struct vulkan_ctx_s { VkViewport viewport; VkRect2D scissor; - // projection and view matrices (model is push constant) - vulkan_matrices_t matrices; #define EXPORTED_VULKAN_FUNCTION(fname) PFN_##fname fname; #define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) PFN_##fname fname; diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 718d22464..0114610b8 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -47,6 +47,7 @@ #include "QF/Vulkan/qf_lighting.h" #include "QF/Vulkan/qf_lightmap.h" #include "QF/Vulkan/qf_main.h" +#include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_particles.h" #include "QF/Vulkan/qf_texture.h" #include "QF/Vulkan/qf_vid.h" @@ -93,13 +94,13 @@ static void vulkan_R_Init (void) { Vulkan_CreateStagingBuffers (vulkan_ctx); - Vulkan_CreateMatrices (vulkan_ctx); Vulkan_CreateSwapchain (vulkan_ctx); Vulkan_CreateFrames (vulkan_ctx); Vulkan_CreateCapture (vulkan_ctx); Vulkan_CreateRenderPass (vulkan_ctx); Vulkan_Texture_Init (vulkan_ctx); + Vulkan_Matrix_Init (vulkan_ctx); Vulkan_Alias_Init (vulkan_ctx); Vulkan_Bsp_Init (vulkan_ctx); Vulkan_Draw_Init (vulkan_ctx); @@ -629,6 +630,7 @@ vulkan_vid_render_shutdown (void) Vulkan_Draw_Shutdown (vulkan_ctx); Vulkan_Bsp_Shutdown (vulkan_ctx); Vulkan_Alias_Shutdown (vulkan_ctx); + Vulkan_Matrix_Shutdown (vulkan_ctx); Mod_ClearAll (); Vulkan_Texture_Shutdown (vulkan_ctx); diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 9ef5661a8..b2c83ceb5 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -77,7 +77,7 @@ }; }; descriptorPools = { - twod_pool = { + matrix_pool = { flags = 0; maxSets = $frames.size; bindings = ( @@ -85,6 +85,12 @@ type = uniform_buffer; descriptorCount = $frames.size; }, + ); + }; + twod_pool = { + flags = 0; + maxSets = $frames.size; + bindings = ( { type = combined_image_sampler; descriptorCount = $frames.size; @@ -143,7 +149,7 @@ }; }; setLayouts = { - twod_set = { + matrix_set = { bindings = ( { binding = 0; @@ -151,8 +157,12 @@ descriptorCount = 1; stageFlags = vertex; }, + ); + }; + twod_set = { + bindings = ( { - binding = 1; + binding = 0; descriptorType = combined_image_sampler; descriptorCount = 1; stageFlags = fragment; @@ -342,7 +352,7 @@ }; pipelineLayouts = { twod_layout = { - setLayouts = (twod_set); + setLayouts = (matrix_set, twod_set); }; quakebsp_layout = { setLayouts = (quakebsp_set); diff --git a/libs/video/renderer/vulkan/shader/twod.frag b/libs/video/renderer/vulkan/shader/twod.frag index a6a40212d..b705b270a 100644 --- a/libs/video/renderer/vulkan/shader/twod.frag +++ b/libs/video/renderer/vulkan/shader/twod.frag @@ -1,6 +1,6 @@ #version 450 -layout (set = 0, binding = 1) uniform sampler2D Texture; +layout (set = 1, binding = 0) uniform sampler2D Texture; layout (location = 0) in vec2 st; layout (location = 1) in vec4 color; diff --git a/libs/video/renderer/vulkan/shader/twod.vert b/libs/video/renderer/vulkan/shader/twod.vert index c5dc5063a..8f0a25f57 100644 --- a/libs/video/renderer/vulkan/shader/twod.vert +++ b/libs/video/renderer/vulkan/shader/twod.vert @@ -1,7 +1,10 @@ #version 450 layout (set = 0, binding = 0) uniform Matrices { - mat4 Projection; + mat4 Projection3d; + mat4 View; + mat4 Sky; + mat4 Projection2d; }; /** Vertex position. @@ -20,7 +23,7 @@ layout (location = 1) out vec4 color; void main (void) { - gl_Position = Projection * vec4 (vertex.xy, 0.0, 1.0); + gl_Position = Projection2d * vec4 (vertex.xy, 0.0, 1.0); st = uv; color = vcolor; } diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index b842d85d4..9a99e307a 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -244,7 +244,7 @@ Vulkan_AliasBegin (qfv_renderframe_t *rFrame) aframe->cmdSet.a[QFV_aliasGBuffer]); //FIXME need per frame matrices - aframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; + //XXX aframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; alias_begin_subpass (QFV_aliasDepth, actx->depth, rFrame); alias_begin_subpass (QFV_aliasGBuffer, actx->gbuf, rFrame); diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 735a03fe0..266b7c3a5 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -905,7 +905,7 @@ bsp_begin (qfv_renderframe_t *rFrame) bframe->cmdSet.a[QFV_bspGBuffer]); //FIXME need per frame matrices - bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; + //XXX bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; bframe->imageInfo[0].imageView = 0; // set by tex chain loop bframe->imageInfo[1].imageView = 0; // set by tex chain loop bframe->imageInfo[2].imageView = QFV_ScrapImageView (bctx->light_scrap); @@ -944,7 +944,7 @@ turb_begin (qfv_renderframe_t *rFrame) bframe->cmdSet.a[QFV_bspTurb]); //FIXME need per frame matrices - bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; + //XXX bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; bframe->imageInfo[0].imageView = ctx->default_magenta->view; bframe->imageInfo[1].imageView = ctx->default_magenta->view; bframe->imageInfo[2].imageView = QFV_ScrapImageView (bctx->light_scrap); @@ -962,7 +962,7 @@ turb_end (vulkan_ctx_t *ctx) bsp_end_subpass (bframe->cmdSet.a[QFV_bspTurb], ctx); } - +/*XXX static void spin (mat4f_t mat, bspctx_t *bctx) { @@ -985,7 +985,7 @@ spin (mat4f_t mat, bspctx_t *bctx) mat4fquat (m, q); mmulf (mat, m, mat); } - +*/ static void sky_begin (qfv_renderframe_t *rFrame) { @@ -995,7 +995,7 @@ sky_begin (qfv_renderframe_t *rFrame) bctx->default_color[3] = 1; QuatCopy (bctx->default_color, bctx->last_color); - spin (ctx->matrices.sky_3d, bctx); + //XXX spin (ctx->matrices.sky_3d, bctx); bspframe_t *bframe = &bctx->frames.a[ctx->curFrame]; @@ -1003,7 +1003,7 @@ sky_begin (qfv_renderframe_t *rFrame) bframe->cmdSet.a[QFV_bspSky]); //FIXME need per frame matrices - bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; + //XXX bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; bframe->imageInfo[0].imageView = ctx->default_magenta->view; bframe->imageInfo[1].imageView = ctx->default_magenta->view; bframe->imageInfo[2].imageView = QFV_ScrapImageView (bctx->light_scrap); diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 6a2d792ae..ed068032d 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -51,6 +51,7 @@ #include "compat.h" #include "QF/Vulkan/qf_draw.h" +#include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_vid.h" #include "QF/Vulkan/barrier.h" #include "QF/Vulkan/buffer.h" @@ -405,9 +406,6 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) } __auto_type pool = Vulkan_CreateDescriptorPool (ctx, "twod_pool"); - VkDescriptorBufferInfo bufferInfo = { - ctx->matrices.buffer_2d, 0, VK_WHOLE_SIZE - }; VkDescriptorImageInfo imageInfo = { dctx->sampler, QFV_ScrapImageView (dctx->scrap), @@ -424,14 +422,10 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) VkWriteDescriptorSet write[] = { { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, dframe->descriptors, 0, 0, 1, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, &bufferInfo, 0 }, - { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, - dframe->descriptors, 1, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageInfo, 0, 0 }, }; - dfunc->vkUpdateDescriptorSets (device->dev, 2, write, 0, 0); + dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0); dframe->cmd = cmdBuffers->a[i]; QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER, dframe->cmd, @@ -799,10 +793,13 @@ Vulkan_FlushText (qfv_renderframe_t *rFrame) dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &dctx->vert_buffer, offsets); dfunc->vkCmdBindIndexBuffer (cmd, dctx->ind_buffer, 0, VK_INDEX_TYPE_UINT32); - VkDescriptorSet set = dframe->descriptors; + VkDescriptorSet set[2] = { + Vulkan_Matrix_Descrptors (ctx, ctx->curFrame), + dframe->descriptors, + }; VkPipelineLayout layout = dctx->layout; dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, 0, 1, &set, 0, 0); + layout, 0, 2, set, 0, 0); dfunc->vkCmdDrawIndexed (cmd, dframe->num_quads * INDS_PER_QUAD, 1, 0, 0, 0); diff --git a/libs/video/renderer/vulkan/vulkan_main.c b/libs/video/renderer/vulkan/vulkan_main.c index 5cfa90094..b4ba322dc 100644 --- a/libs/video/renderer/vulkan/vulkan_main.c +++ b/libs/video/renderer/vulkan/vulkan_main.c @@ -77,32 +77,6 @@ setup_frame (vulkan_ctx_t *ctx) r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.renderer.model); } -static void -setup_view (vulkan_ctx_t *ctx) -{ - mat4f_t view; - static mat4f_t z_up = { - { 0, 0, -1, 0}, - {-1, 0, 0, 0}, - { 0, 1, 0, 0}, - { 0, 0, 0, 1}, - }; - vec4f_t offset = { 0, 0, 0, 1 }; - - /*x = r_refdef.vrect.x; - y = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)); - w = r_refdef.vrect.width; - h = r_refdef.vrect.height; - qfeglViewport (x, y, w, h);*/ - - mat4fquat (view, qconjf (r_refdef.viewrotation)); - mmulf (view, z_up, view); - offset = -r_refdef.viewposition; - offset[3] = 1; - view[3] = mvmulf (view, offset); - memcpy (ctx->matrices.view_3d, view, sizeof (view)); -} - static void Vulkan_RenderEntities (qfv_renderframe_t *rFrame) { @@ -166,7 +140,6 @@ Vulkan_RenderView (qfv_renderframe_t *rFrame) if (speeds) t[0] = Sys_DoubleTime (); setup_frame (ctx); - setup_view (ctx); if (speeds) t[1] = Sys_DoubleTime (); R_MarkLeaves (); diff --git a/libs/video/renderer/vulkan/vulkan_matrices.c b/libs/video/renderer/vulkan/vulkan_matrices.c index d43ecc7f2..9a892fdb0 100644 --- a/libs/video/renderer/vulkan/vulkan_matrices.c +++ b/libs/video/renderer/vulkan/vulkan_matrices.c @@ -28,16 +28,31 @@ # include "config.h" #endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + #ifdef HAVE_MATH_H # include #endif +#include "QF/cvar.h" #include "QF/sys.h" +#include "QF/va.h" #include "QF/vid.h" -#include "QF/Vulkan/qf_vid.h" +#include "QF/Vulkan/qf_matrices.h" +#include "QF/Vulkan/barrier.h" #include "QF/Vulkan/buffer.h" +#include "QF/Vulkan/debug.h" +#include "QF/Vulkan/descriptor.h" #include "QF/Vulkan/device.h" +#include "QF/Vulkan/instance.h" #include "QF/Vulkan/projection.h" +#include "QF/Vulkan/renderpass.h" +#include "QF/Vulkan/staging.h" #include "QF/ui/view.h" #include "r_internal.h" @@ -45,98 +60,222 @@ #include "util.h" -#define MAT_SIZE (16 * sizeof (float)) - -void -Vulkan_DestroyMatrices (vulkan_ctx_t *ctx) +static void +setup_view (vulkan_ctx_t *ctx) { - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; + mat4f_t view; + static mat4f_t z_up = { + { 0, 0, -1, 0}, + {-1, 0, 0, 0}, + { 0, 1, 0, 0}, + { 0, 0, 0, 1}, + }; + vec4f_t offset = { 0, 0, 0, 1 }; - __auto_type mat = &ctx->matrices; + /*x = r_refdef.vrect.x; + y = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)); + w = r_refdef.vrect.width; + h = r_refdef.vrect.height; + qfeglViewport (x, y, w, h);*/ - dfunc->vkUnmapMemory (device->dev, mat->memory); - dfunc->vkFreeMemory (device->dev, mat->memory, 0); - dfunc->vkDestroyBuffer (device->dev, mat->buffer_2d, 0); - dfunc->vkDestroyBuffer (device->dev, mat->buffer_3d, 0); + mat4fquat (view, qconjf (r_refdef.viewrotation)); + mmulf (view, z_up, view); + offset = -r_refdef.viewposition; + offset[3] = 1; + view[3] = mvmulf (view, offset); + Vulkan_SetViewMatrix (ctx, view); } void -Vulkan_CreateMatrices (vulkan_ctx_t *ctx) +Vulkan_SetViewMatrix (vulkan_ctx_t *ctx, mat4f_t view) { + __auto_type mctx = ctx->matrix_context; + + if (memcmp (mctx->matrices.View, view, sizeof (mat4f_t))) { + memcpy (mctx->matrices.View, view, sizeof (mat4f_t)); + mctx->dirty = mctx->frames.size; + } +} + +void +Vulkan_Matrix_Draw (qfv_renderframe_t *rFrame) +{ + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; - __auto_type mat = &ctx->matrices; - mat->buffer_2d = QFV_CreateBuffer (device, 1 * MAT_SIZE, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); - mat->buffer_3d = QFV_CreateBuffer (device, 3 * MAT_SIZE, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + __auto_type mctx = ctx->matrix_context; + __auto_type mframe = &mctx->frames.a[ctx->curFrame]; - size_t size = 0; - size_t offset; - VkMemoryRequirements req; + setup_view (ctx); - dfunc->vkGetBufferMemoryRequirements (device->dev, mat->buffer_2d, &req); - size += req.size; - offset = size; + if (mctx->dirty <= 0) { + mctx->dirty = 0; + return; + } - dfunc->vkGetBufferMemoryRequirements (device->dev, mat->buffer_3d, &req); - offset = (offset + req.alignment - 1) & ~(req.alignment - 1); - size += req.size; + mctx->dirty--; - mat->memory = QFV_AllocBufferMemory (device, mat->buffer_2d, - VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - size, 0); - QFV_BindBufferMemory (device, mat->buffer_2d, mat->memory, 0); - QFV_BindBufferMemory (device, mat->buffer_3d, mat->memory, offset); - void *data; - dfunc->vkMapMemory (device->dev, mat->memory, 0, size, 0, &data); - mat->projection_2d = data; - mat->projection_3d = (vec4f_t *) ((byte *) mat->projection_2d + offset); - mat->view_3d = mat->projection_3d + 4; - mat->sky_3d = mat->view_3d + 4; + qfv_packet_t *packet = QFV_PacketAcquire (mctx->stage); + qfv_matrix_buffer_t *m = QFV_PacketExtend (packet, sizeof (*m)); + *m = mctx->matrices; + + qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite]; bb.barrier.buffer = mframe->buffer; + bb.barrier.size = packet->length; + + dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages, + 0, 0, 0, 1, &bb.barrier, 0, 0); + + VkBufferCopy copy_region = { packet->offset, 0, packet->length }; + dfunc->vkCmdCopyBuffer (packet->cmd, mctx->stage->buffer, + mframe->buffer, 1, ©_region); + + bb = bufferBarriers[qfv_LT_TransferDst_to_ShaderReadOnly]; + bb.barrier.buffer = mframe->buffer; + bb.barrier.size = packet->length; + + dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages, + 0, 0, 0, 1, &bb.barrier, 0, 0); + + QFV_PacketSubmit (packet); } void Vulkan_CalcProjectionMatrices (vulkan_ctx_t *ctx) { - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - - __auto_type mat = &ctx->matrices; + __auto_type mctx = ctx->matrix_context; + __auto_type mat = &mctx->matrices; int width = vid.conview->xlen; int height = vid.conview->ylen; - QFV_Orthographic (mat->projection_2d, 0, width, 0, height, 0, 99999); + QFV_Orthographic (mat->Projection2d, 0, width, 0, height, 0, 99999); float aspect = (float) r_refdef.vrect.width / r_refdef.vrect.height; - QFV_Perspective (mat->projection_3d, r_refdef.fov_y, aspect); + QFV_Perspective (mat->Projection3d, r_refdef.fov_y, aspect); #if 0 Sys_MaskPrintf (SYS_vulkan, "ortho:\n"); Sys_MaskPrintf (SYS_vulkan, " [[%g, %g, %g, %g],\n", - QuatExpand (mat->projection_2d + 0)); + QuatExpand (mat->Projection2d + 0)); Sys_MaskPrintf (SYS_vulkan, " [%g, %g, %g, %g],\n", - QuatExpand (mat->projection_2d + 4)); + QuatExpand (mat->Projection2d + 4)); Sys_MaskPrintf (SYS_vulkan, " [%g, %g, %g, %g],\n", - QuatExpand (mat->projection_2d + 8)); + QuatExpand (mat->Projection2d + 8)); Sys_MaskPrintf (SYS_vulkan, " [%g, %g, %g, %g]]\n", - QuatExpand (mat->projection_2d + 12)); + QuatExpand (mat->Projection2d + 12)); Sys_MaskPrintf (SYS_vulkan, "presp:\n"); Sys_MaskPrintf (SYS_vulkan, " [[%g, %g, %g, %g],\n", - QuatExpand (mat->projection_3d + 0)); + QuatExpand (mat->Projection3d + 0)); Sys_MaskPrintf (SYS_vulkan, " [%g, %g, %g, %g],\n", - QuatExpand (mat->projection_3d + 4)); + QuatExpand (mat->Projection3d + 4)); Sys_MaskPrintf (SYS_vulkan, " [%g, %g, %g, %g],\n", - QuatExpand (mat->projection_3d + 8)); + QuatExpand (mat->Projection3d + 8)); Sys_MaskPrintf (SYS_vulkan, " [%g, %g, %g, %g]]\n", - QuatExpand (mat->projection_3d + 12)); + QuatExpand (mat->Projection3d + 12)); #endif - VkMappedMemoryRange ranges[] = { - { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, mat->memory, 0, MAT_SIZE }, - { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, mat->memory, - (mat->projection_3d - mat->projection_2d) * sizeof (mat->projection_2d[0]), - MAT_SIZE}, - }; - dfunc->vkFlushMappedMemoryRanges (device->dev, 2, ranges); + mctx->dirty = mctx->frames.size; +} + +void +Vulkan_Matrix_Init (vulkan_ctx_t *ctx) +{ + qfvPushDebug (ctx, "matrix init"); + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + matrixctx_t *mctx = calloc (1, sizeof (matrixctx_t)); + ctx->matrix_context = mctx; + + size_t frames = ctx->frames.size; + DARRAY_INIT (&mctx->frames, frames); + DARRAY_RESIZE (&mctx->frames, frames); + mctx->frames.grow = 0; + + //__auto_type cmdBuffers = QFV_AllocCommandBufferSet (frames, alloca); + //QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, cmdBuffers); + + mctx->pool = Vulkan_CreateDescriptorPool (ctx, "matrix_pool"); + mctx->setLayout = Vulkan_CreateDescriptorSetLayout (ctx, "matrix_set"); + __auto_type layouts = QFV_AllocDescriptorSetLayoutSet (frames, alloca); + for (size_t i = 0; i < layouts->size; i++) { + layouts->a[i] = mctx->setLayout; + } + + for (size_t i = 0; i < frames; i++) { + __auto_type mframe = &mctx->frames.a[i]; + //mframe->cmd = cmdBuffers->a[i]; + mframe->buffer = QFV_CreateBuffer (device, sizeof (qfv_matrix_buffer_t), + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT + | VK_BUFFER_USAGE_TRANSFER_DST_BIT); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_BUFFER, + mframe->buffer, va (ctx->va_ctx, + "buffer:matrices:%zd", i)); + } + + VkMemoryRequirements req; + //offset = (offset + req.alignment - 1) & ~(req.alignment - 1); + dfunc->vkGetBufferMemoryRequirements (device->dev, + mctx->frames.a[0].buffer, &req); + mctx->memory = QFV_AllocBufferMemory (device, mctx->frames.a[0].buffer, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + frames * req.size, 0); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY, + mctx->memory, "memory:matrices"); + + __auto_type sets = QFV_AllocateDescriptorSet (device, mctx->pool, layouts); + for (size_t i = 0; i < frames; i++) { + __auto_type mframe = &mctx->frames.a[i]; + QFV_BindBufferMemory (device, mframe->buffer, mctx->memory, + i * req.size); + + mframe->descriptors = sets->a[i]; + VkDescriptorBufferInfo bufferInfo = { + mframe->buffer, 0, VK_WHOLE_SIZE + }; + VkWriteDescriptorSet write[] = { + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + mframe->descriptors, 0, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 0, &bufferInfo, 0 }, + }; + dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0); + } + free (sets); + + mat4fidentity (mctx->matrices.Projection3d); + mat4fidentity (mctx->matrices.View); + mat4fidentity (mctx->matrices.Sky); + mat4fidentity (mctx->matrices.Projection2d); + mctx->dirty = mctx->frames.size; + + mctx->stage = QFV_CreateStagingBuffer (device, "matrix", + frames * sizeof (qfv_matrix_buffer_t), + ctx->cmdpool); + + qfvPopDebug (ctx); +} + +void +Vulkan_Matrix_Shutdown (vulkan_ctx_t *ctx) +{ + qfvPushDebug (ctx, "matrix shutdown"); + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + __auto_type mctx = ctx->matrix_context; + + QFV_DestroyStagingBuffer (mctx->stage); + + for (size_t i = 0; i < mctx->frames.size; i++) { + __auto_type mframe = &mctx->frames.a[i]; + dfunc->vkDestroyBuffer (device->dev, mframe->buffer, 0); + } + dfunc->vkFreeMemory (device->dev, mctx->memory, 0); + qfvPopDebug (ctx); +} + +VkDescriptorSet +Vulkan_Matrix_Descrptors (vulkan_ctx_t *ctx, int frame) +{ + __auto_type mctx = ctx->matrix_context; + return mctx->frames.a[frame].descriptors; } diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index 8bea24b51..de553fde0 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -50,6 +50,7 @@ #include "QF/sys.h" #include "QF/va.h" #include "QF/vid.h" +#include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_vid.h" #include "QF/Vulkan/barrier.h" #include "QF/Vulkan/buffer.h" @@ -228,7 +229,6 @@ Vulkan_Shutdown_Common (vulkan_ctx_t *ctx) QFV_DestroySwapchain (ctx->swapchain); } QFV_DestroyStagingBuffer (ctx->staging); - Vulkan_DestroyMatrices (ctx); ctx->instance->funcs->vkDestroySurfaceKHR (ctx->instance->instance, ctx->surface, 0); clear_table (&ctx->pipelineLayouts); @@ -336,6 +336,7 @@ get_image_size (VkImage image, qfv_device_t *device) static void renderpass_draw (qfv_renderframe_t *rFrame) { + Vulkan_Matrix_Draw (rFrame); Vulkan_RenderView (rFrame); Vulkan_FlushText (rFrame); Vulkan_Lighting_Draw (rFrame);