From 9e03096da6d116461a06bce1c35df4498094ebab Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 21 Jan 2021 02:13:40 +0900 Subject: [PATCH] [vulkan] Build brush model display lists Not working particularly well yet, but no errors out of validation. --- include/QF/Vulkan/funclist.h | 1 + include/QF/Vulkan/qf_bsp.h | 11 +- libs/video/renderer/r_init.c | 1 - libs/video/renderer/vid_render_vulkan.c | 1 + libs/video/renderer/vulkan/qfpipeline.plist | 25 ++- libs/video/renderer/vulkan/quakebsp.frag | 17 ++- libs/video/renderer/vulkan/vulkan_bsp.c | 161 ++++++++++++++------ 7 files changed, 151 insertions(+), 66 deletions(-) diff --git a/include/QF/Vulkan/funclist.h b/include/QF/Vulkan/funclist.h index 209ee0561..b0fe394d9 100644 --- a/include/QF/Vulkan/funclist.h +++ b/include/QF/Vulkan/funclist.h @@ -169,6 +169,7 @@ DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdEndRenderPass) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdBindPipeline) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdClearColorImage) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdExecuteCommands) +DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdPushConstants) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdSetViewport) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdSetScissor) diff --git a/include/QF/Vulkan/qf_bsp.h b/include/QF/Vulkan/qf_bsp.h index 6d4440bd6..95f128e5b 100644 --- a/include/QF/Vulkan/qf_bsp.h +++ b/include/QF/Vulkan/qf_bsp.h @@ -44,7 +44,8 @@ typedef struct bspvert_s { typedef struct elements_s { struct elements_s *_next; struct elements_s *next; - byte *base; + uint32_t first_index; + uint32_t index_count; } elements_t; typedef struct elechain_s { @@ -57,9 +58,9 @@ typedef struct elechain_s { } elechain_t; typedef struct bspframe_s { - uint32_t *index_data; - uint32_t index_count; - uint32_t index_offset; + uint32_t *index_data; // pointer into mega-buffer for this frame (c) + uint32_t index_offset; // offset of index_data within mega-buffer (c) + uint32_t index_count; // number if indices queued (d) VkCommandBuffer bsp_cmd; VkCommandBuffer turb_cmd; VkCommandBuffer sky_cmd; @@ -96,6 +97,7 @@ typedef struct bspctx_s { instsurf_t **instsurfs_tail; instsurf_t *free_instsurfs; + struct qfv_tex_s *skysheet_tex; struct qfv_tex_s *skybox_tex; quat_t sky_rotation[2]; quat_t sky_velocity; @@ -110,6 +112,7 @@ typedef struct bspctx_s { struct bsppoly_s *polys; + VkSampler sampler; VkDeviceMemory texture_memory; VkPipeline main; VkPipelineLayout layout; diff --git a/libs/video/renderer/r_init.c b/libs/video/renderer/r_init.c index 94385e1c2..733004a21 100644 --- a/libs/video/renderer/r_init.c +++ b/libs/video/renderer/r_init.c @@ -68,7 +68,6 @@ static U void (*const r_scrapdelete)(rscrap_t *) = R_ScrapDelete; static void R_shutdown (void *data) { - Mod_ClearAll (); if (vidrendmodule->functions->general->p_Shutdown) { vidrendmodule->functions->general->p_Shutdown (); } diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 9e6dc90fd..85d090b37 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -606,6 +606,7 @@ vulkan_vid_render_shutdown (void) df->vkDestroyCommandPool (dev, vulkan_ctx->cmdpool, 0); Vulkan_Draw_Shutdown (vulkan_ctx); Vulkan_Bsp_Shutdown (vulkan_ctx); + Mod_ClearAll (); Vulkan_Shutdown_Common (vulkan_ctx); } diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 822e187a5..aa60ec958 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -30,6 +30,23 @@ borderColor = float_transparent_black; unnormalizedCoordinates = false; }; + quakebsp = { + magFilter = linear; + minFilter = linear; + mipmapMode = linear; + addressModeU = repeat; + addressModeV = repeat; + addressModeW = repeat; + mipLodBias = 0; + anisotropyEnable = false; + maxAnisotropy = 0; + compareEnable = false; + compareOp = always; + minLod = 0; + maxLod = 1; + borderColor = float_transparent_black; + unnormalizedCoordinates = false; + }; }; descriptorPools = { twod = { @@ -110,12 +127,12 @@ descriptorCount = 1; stageFlags = fragment; }, - { + /*{ binding = 5; descriptorType = combined_image_sampler; descriptorCount = 1; stageFlags = fragment; - }, + },*/ ); }; something = { @@ -150,7 +167,7 @@ }, { stageFlags = fragment; - offset = 0; + offset = 64; size = 32; }, ); @@ -176,7 +193,7 @@ bindings = ( { binding = 0; - stride = "3 * 4 * 4"; + stride = "2 * 4 * 4"; inputRate = vertex; }, ); diff --git a/libs/video/renderer/vulkan/quakebsp.frag b/libs/video/renderer/vulkan/quakebsp.frag index 219ce9212..24745fba0 100644 --- a/libs/video/renderer/vulkan/quakebsp.frag +++ b/libs/video/renderer/vulkan/quakebsp.frag @@ -4,9 +4,10 @@ layout (set = 0, binding = 1) uniform sampler2D Texture; layout (set = 0, binding = 2) uniform sampler2D Glowmap; layout (set = 0, binding = 3) uniform sampler2D Lightmap; layout (set = 0, binding = 4) uniform sampler2DArray SkySheet; -layout (set = 0, binding = 5) uniform samplerCube SkyCube; +//layout (set = 0, binding = 5) uniform samplerCube SkyCube; layout (push_constant) uniform PushConstants { + layout (offset = 64) float time; vec4 fog; }; @@ -70,7 +71,7 @@ sky_sheet (vec3 dir, float time) return c; } - +/* vec4 sky_cube (vec3 dir, float time) { @@ -80,20 +81,22 @@ sky_cube (vec3 dir, float time) // to do here is swizzle the Y and Z coordinates return texture (SkyCube, dir.xzy); } - +*/ vec4 sky_color (vec3 dir, float time) { if (!doSkySheet) { - return sky_cube (dir, time); + return vec4 (1, 0, 1, 1); + //return sky_cube (dir, time); } if (!doSkyCube) { return sky_sheet (dir, time); } else { - // can see through the sheet (may look funny when looking down) + /*// can see through the sheet (may look funny when looking down) // maybe have 4 sheet layers instead of 2? vec4 c1 = sky_sheet (dir, time); vec4 c2 = sky_cube (dir, time); - return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a)); + return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));*/ + return vec4 (1, 0, 1, 1); } } @@ -117,5 +120,5 @@ main (void) } c += texture (Glowmap, t_st); - frag_color = fogBlend (c); + frag_color = vec4(t_st, 1, 1);//fogBlend (c); } diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index aba44c043..d60f95bb5 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -496,10 +496,6 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx) el = el->next; vertex_index_base = 0; }*/ - // we don't use it now, but pre-initializing the list won't hurt - //XXX if (!el->list) - //XXX el->list = dstring_new (); - //XXX dstring_clear (el->list); surf->polys = (glpoly_t *) poly; poly = build_surf_displist (models, surf, vertex_index_base, @@ -757,16 +753,14 @@ R_VisitWorldNodes (model_t *model, vulkan_ctx_t *ctx) visit_leaf ((mleaf_t *) node); } -/*static void -draw_elechain (elechain_t *ec, int matloc, int vertloc, int tlstloc, - int colloc, bspctx_t *bctx) +static void +draw_elechain (elechain_t *ec, VkPipelineLayout layout, qfv_devfuncs_t *dfunc, + VkCommandBuffer cmd) { - mat4_t mat; elements_t *el; - int count; - float *color; - if (colloc >= 0) { + /*if (colloc >= 0) { + float *color; color = ec->color; if (!color) color = bctx->default_color; @@ -774,29 +768,31 @@ draw_elechain (elechain_t *ec, int matloc, int vertloc, int tlstloc, QuatCopy (color, bctx->last_color); qfeglVertexAttrib4fv (quake_bsp.color.location, color); } - } + }*/ if (ec->transform) { - Mat4Mult (bsp_vp, ec->transform, mat); - qfeglUniformMatrix4fv (matloc, 1, false, mat); - } else { - qfeglUniformMatrix4fv (matloc, 1, false, bsp_vp); + dfunc->vkCmdPushConstants (cmd, layout, VK_SHADER_STAGE_VERTEX_BIT, + 0, 16 * sizeof (float), ec->transform); } for (el = ec->elements; el; el = el->next) { - if (!el->list->size) + //FIXME check if these are contiguous and if so merge into one + //command + if (!el->index_count) continue; - count = el->list->size / sizeof (GLushort); - qfeglVertexAttribPointer (vertloc, 4, GL_FLOAT, - 0, sizeof (bspvert_t), - el->base + field_offset (bspvert_t, vertex)); - if (tlstloc >= 0) - qfeglVertexAttribPointer (tlstloc, 4, GL_FLOAT, - 0, sizeof (bspvert_t), - el->base + field_offset (bspvert_t,tlst)); - qfeglDrawElements (GL_TRIANGLES, count, - GL_UNSIGNED_SHORT, el->list->str); - dstring_clear (el->list); + dfunc->vkCmdDrawIndexed (cmd, el->index_count, 1, el->first_index, + 0, 0); + el->first_index = 0; + el->index_count = 0; } -}*/ +} + +static VkImageView +get_view (qfv_tex_t *tex) +{ + if (tex) { + return tex->view; + } + return 0; +} static void bsp_begin (vulkan_ctx_t *ctx) @@ -814,6 +810,54 @@ bsp_begin (vulkan_ctx_t *ctx) VkCommandBuffer cmd = bframe->bsp_cmd; DARRAY_APPEND (cframe->subCommand, cmd); + VkDescriptorBufferInfo bufferInfo = { + ctx->matrices.buffer_3d, 0, VK_WHOLE_SIZE + }; + VkDescriptorImageInfo imageInfo[] = { + { bctx->sampler, + QFV_ScrapImageView (bctx->light_scrap), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, + { bctx->sampler, + QFV_ScrapImageView (bctx->light_scrap), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, + { bctx->sampler, + QFV_ScrapImageView (bctx->light_scrap), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, + { bctx->sampler, + get_view (bctx->skysheet_tex), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, + { bctx->sampler, + get_view (bctx->skybox_tex), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, + }; + VkWriteDescriptorSet write[] = { + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + bframe->descriptors, 0, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 0, &bufferInfo, 0 }, + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + bframe->descriptors, 1, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + &imageInfo[0], 0, 0 }, + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + bframe->descriptors, 2, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + &imageInfo[1], 0, 0 }, + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + bframe->descriptors, 3, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + &imageInfo[2], 0, 0 }, + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + bframe->descriptors, 4, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + &imageInfo[3], 0, 0 }, + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + bframe->descriptors, 5, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + &imageInfo[4], 0, 0 }, + }; + dfunc->vkUpdateDescriptorSets (device->dev, 5, write, 0, 0); + dfunc->vkResetCommandBuffer (cmd, 0); VkCommandBufferInheritanceInfo inherit = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0, @@ -1011,49 +1055,56 @@ sky_end (bspctx_t *bctx) static inline void add_surf_elements (vulktex_t *tex, instsurf_t *is, - elechain_t **ec, elements_t **el, bspctx_t *bctx) + elechain_t **ec, elements_t **el, + bspctx_t *bctx, bspframe_t *bframe) { msurface_t *surf = is->surface; - //XXX bsppoly_t *poly = (bsppoly_t *) surf->polys; + bsppoly_t *poly = (bsppoly_t *) surf->polys; if (!tex->elechain) { (*ec) = add_elechain (tex, surf->ec_index, bctx); (*ec)->transform = is->transform; (*ec)->color = is->color; (*el) = (*ec)->elements; - //XXX if (!(*el)->list) - //XXX (*el)->list = dstring_new (); - //XXX dstring_clear ((*el)->list); + (*el)-> first_index = bframe->index_count; } if (is->transform != (*ec)->transform || is->color != (*ec)->color) { (*ec) = add_elechain (tex, surf->ec_index, bctx); (*ec)->transform = is->transform; (*ec)->color = is->color; (*el) = (*ec)->elements; - //XXX if (!(*el)->list) - //XXX (*el)->list = dstring_new (); - //XXX dstring_clear ((*el)->list); + (*el)-> first_index = bframe->index_count; } - //XXX dstring_append ((*el)->list, (char *) poly->indices, - //XXX poly->count * sizeof (poly->indices[0])); + memcpy (bframe->index_data + bframe->index_count, + poly->indices, poly->count * sizeof (poly->indices[0])); + (*el)->index_count += poly->count; } static void -build_tex_elechain (vulktex_t *tex, bspctx_t *bctx) +build_tex_elechain (vulktex_t *tex, bspctx_t *bctx, bspframe_t *bframe) { instsurf_t *is; elechain_t *ec = 0; elements_t *el = 0; for (is = tex->tex_chain; is; is = is->tex_chain) { - add_surf_elements (tex, is, &ec, &el, bctx); + add_surf_elements (tex, is, &ec, &el, bctx, bframe); } } void Vulkan_DrawWorld (vulkan_ctx_t *ctx) { + static float identity[] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + }; + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; bspctx_t *bctx = ctx->bsp_context; + bspframe_t *bframe = &bctx->frames.a[ctx->curFrame]; entity_t worldent; clear_texture_chains (bctx); // do this first for water and skys @@ -1061,6 +1112,9 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx) memset (&worldent, 0, sizeof (worldent)); worldent.model = r_worldentity.model; + vulktex_t *tex = r_worldentity.model->skytexture->render; + bctx->skysheet_tex = tex->tex; + currententity = &worldent; R_VisitWorldNodes (worldent.model, ctx); @@ -1077,24 +1131,29 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx) Vulkan_FlushLightmaps (ctx); bsp_begin (ctx); + + dfunc->vkCmdPushConstants (bframe->bsp_cmd, bctx->layout, + VK_SHADER_STAGE_VERTEX_BIT, + 0, 16 * sizeof (float), identity); + float frag_pc[8] = { }; + dfunc->vkCmdPushConstants (bframe->bsp_cmd, bctx->layout, + VK_SHADER_STAGE_FRAGMENT_BIT, + 64, 8 * sizeof (float), &frag_pc); //XXX qfeglActiveTexture (GL_TEXTURE0 + 0); for (size_t i = 0; i < bctx->texture_chains.size; i++) { vulktex_t *tex; - //XXX elechain_t *ec = 0; + elechain_t *ec = 0; tex = bctx->texture_chains.a[i]; - build_tex_elechain (tex, bctx); + build_tex_elechain (tex, bctx, bframe); //XXX if (tex->elechain) //XXX qfeglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum); - /*XXX for (ec = tex->elechain; ec; ec = ec->next) { - draw_elechain (ec, quake_bsp.mvp_matrix.location, - quake_bsp.vertex.location, - quake_bsp.tlst.location, - quake_bsp.color.location); - }*/ + for (ec = tex->elechain; ec; ec = ec->next) { + draw_elechain (ec, bctx->layout, dfunc, bframe->bsp_cmd); + } tex->elechain = 0; tex->elechain_tail = &tex->elechain; } @@ -1152,6 +1211,7 @@ void Vulkan_DrawSky (vulkan_ctx_t *ctx) { bspctx_t *bctx = ctx->bsp_context; + bspframe_t *bframe = &bctx->frames.a[ctx->curFrame]; instsurf_t *is; msurface_t *surf; vulktex_t *tex = 0; @@ -1180,7 +1240,7 @@ Vulkan_DrawSky (vulkan_ctx_t *ctx) } tex = surf->texinfo->texture->render; } - add_surf_elements (tex, is, &ec, &el, bctx); + add_surf_elements (tex, is, &ec, &el, bctx, bframe); } if (tex) { if (!bctx->skybox_tex) { @@ -1230,6 +1290,7 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx) bctx->main = Vulkan_CreatePipeline (ctx, "quakebsp.main"); bctx->layout = QFV_GetPipelineLayout (ctx, "quakebsp"); + bctx->sampler = QFV_GetSampler (ctx, "quakebsp"); __auto_type layouts = QFV_AllocDescriptorSetLayoutSet (frames, alloca); for (size_t i = 0; i < layouts->size; i++) {