From e6ecf5e8559b1e99038fe39614522392313332ab Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 23 Feb 2021 15:43:02 +0900 Subject: [PATCH] [vulkan] Fix up commands for deferred rendering Nothing gets output yet (lighting and composite passes not implemented), but everything passes validation until exit (not destroying everything). --- libs/video/renderer/Makemodule.am | 5 + libs/video/renderer/vulkan/qfpipeline.plist | 29 +++--- libs/video/renderer/vulkan/shader.c | 3 + .../video/renderer/vulkan/shader/bsp_sky.frag | 96 +++++++++++++++++++ libs/video/renderer/vulkan/vulkan_alias.c | 2 +- libs/video/renderer/vulkan/vulkan_bsp.c | 11 ++- 6 files changed, 133 insertions(+), 13 deletions(-) create mode 100644 libs/video/renderer/vulkan/shader/bsp_sky.frag diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index a5c3fc1a0..93f6a51b4 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -283,6 +283,8 @@ bsp_gbufg_src = $(vkshaderpath)/bsp_gbuf.geom bsp_gbufg_c = $(vkshaderpath)/bsp_gbuf.geom.spvc bsp_gbuff_src = $(vkshaderpath)/bsp_gbuf.frag bsp_gbuff_c = $(vkshaderpath)/bsp_gbuf.frag.spvc +bsp_skyf_src = $(vkshaderpath)/bsp_sky.frag +bsp_skyf_c = $(vkshaderpath)/bsp_sky.frag.spvc aliasv_src = $(vkshaderpath)/alias.vert aliasv_c = $(vkshaderpath)/alias.vert.spvc aliasf_src = $(vkshaderpath)/alias.frag @@ -312,6 +314,8 @@ $(bsp_gbufg_c): $(bsp_gbufg_src) $(bsp_gbuff_c): $(bsp_gbuff_src) +$(bsp_skyf_c): $(bsp_skyf_src) + $(aliasv_c): $(aliasv_src) $(alias_depth_c): $(alias_depth_src) @@ -333,6 +337,7 @@ vkshader_c = \ $(bsp_gbufv_c) \ $(bsp_gbufg_c) \ $(bsp_gbuff_c) \ + $(bsp_skyf_c) \ $(aliasv_c) \ $(alias_depth_c) \ $(aliasf_c) \ diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index d71ce6037..03e200fc7 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -607,28 +607,21 @@ //renderPass = renderpass; }; bsp_skysheet = { - subpass = 1; + subpass = 2; stages = ( { stage = vertex; name = main; module = $builtin/bsp_gbuf.vert; }, - { - stage = geometry; - name = main; - module = $builtin/bsp_gbuf.geom; - }, { stage = fragment; name = main; - module = $builtin/bsp_gbuf.frag; + module = $builtin/bsp_sky.frag; specializationInfo = { mapEntries = ( { size = 4; offset = 0; constantID = 0; }, - { size = 4; offset = 0; constantID = 1; }, - { size = 4; offset = 0; constantID = 2; }, - { size = 4; offset = 4; constantID = 3; }, + { size = 4; offset = 4; constantID = 1; }, ); data = <00000000ffffffff>; }; @@ -640,7 +633,21 @@ rasterization = $properties.pipelines.bsp_gbuf.rasterization; multisample = $properties.pipelines.bsp_gbuf.multisample; depthStencil = $properties.pipelines.bsp_gbuf.depthStencil; - colorBlend = $properties.pipelines.bsp_gbuf.colorBlend; + colorBlend = { + logicOpEnable = false; + attachments = ( + { + blendEnable = false; + srcColorBlendFactor = src_alpha; + dstColorBlendFactor = one_minus_src_alpha; + colorBlendOp = add; + srcAlphaBlendFactor = src_alpha; + dstAlphaBlendFactor = one_minus_src_alpha; + alphaBlendOp = add; + colorWriteMask = r|g|b|a; + }, + ); + }; dynamic = { dynamicState = ( viewport, scissor ); }; diff --git a/libs/video/renderer/vulkan/shader.c b/libs/video/renderer/vulkan/shader.c index 64c0954cb..4063e6f33 100644 --- a/libs/video/renderer/vulkan/shader.c +++ b/libs/video/renderer/vulkan/shader.c @@ -71,6 +71,8 @@ static static #include "libs/video/renderer/vulkan/shader/bsp_gbuf.frag.spvc" static +#include "libs/video/renderer/vulkan/shader/bsp_sky.frag.spvc" +static #include "libs/video/renderer/vulkan/shader/alias.vert.spvc" static #include "libs/video/renderer/vulkan/shader/alias_depth.vert.spvc" @@ -98,6 +100,7 @@ static shaderdata_t builtin_shaders[] = { { "bsp_gbuf.vert", bsp_gbuf_vert, sizeof (bsp_gbuf_vert) }, { "bsp_gbuf.geom", bsp_gbuf_geom, sizeof (bsp_gbuf_geom) }, { "bsp_gbuf.frag", bsp_gbuf_frag, sizeof (bsp_gbuf_frag) }, + { "bsp_sky.frag", bsp_sky_frag, sizeof (bsp_sky_frag) }, { "alias.vert", alias_vert, sizeof (alias_vert) }, { "alias_depth.vert", alias_depth_vert, sizeof (alias_depth_vert) }, { "alias.frag", alias_frag, sizeof (alias_frag) }, diff --git a/libs/video/renderer/vulkan/shader/bsp_sky.frag b/libs/video/renderer/vulkan/shader/bsp_sky.frag new file mode 100644 index 000000000..28ce41421 --- /dev/null +++ b/libs/video/renderer/vulkan/shader/bsp_sky.frag @@ -0,0 +1,96 @@ +#version 450 + +layout (set = 0, binding = 4) uniform sampler2DArray SkySheet; +layout (set = 0, binding = 5) uniform samplerCube SkyCube; + +layout (push_constant) uniform PushConstants { + layout (offset = 64) + vec4 fog; + float time; +}; + +layout (location = 0) in vec4 tl_st; +layout (location = 1) in vec3 direction; + +layout (location = 0) out vec4 frag_color; + +layout (constant_id = 0) const bool doSkyCube = false; +layout (constant_id = 1) const bool doSkySheet = false; + +const float SCALE = 8.0; + +vec4 +fogBlend (vec4 color) +{ + float az = fog.a * gl_FragCoord.z / gl_FragCoord.w; + vec3 fog_color = fog.rgb; + float fog_factor = exp (-az * az); + + return vec4 (mix (fog_color.rgb, color.rgb, fog_factor), color.a); +} + +vec4 +sky_sheet (vec3 dir, float time) +{ + float len; + vec2 flow = vec2 (1.0, 1.0); + vec2 base; + vec3 st1, st2; + vec4 c1, c2, c; + + dir.z *= 3.0; + len = dot (dir, dir); + len = SCALE * inversesqrt (len); + base = dir.yx * vec2(1.0, -1.0) * len; + + st1 = vec3 (base + flow * time / 8.0, 0); + st2 = vec3 (base + flow * time / 16.0, 1); + + c1 = texture (SkySheet, st1); + c2 = texture (SkySheet, st2); + + c = vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a)); + + return c; +} + +vec4 +sky_cube (vec3 dir, float time) +{ + // NOTE: quake's world is right-handed with Z up and X forward, but + // Vulkan's cube maps are left-handed with Y up and Z forward. The + // rotation to X foward is done by the Sky matrix so all that's left + // 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 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) + // 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 (1, 0, 1, 1); + } +} + +void +main (void) +{ + vec4 c; + + if (doSkyCube || doSkySheet) { + c = sky_color (direction, time); + } else { + c = vec4 (0, 0, 0, 1); + } + frag_color = c;//fogBlend (c); +} diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index f7d9b2f0b..8468335c1 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -186,7 +186,7 @@ alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline, // actx->layout, 0, 2, sets, 0, 0); dfunc->vkCmdPushDescriptorSetKHR (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, actx->layout, - 0, 2, aframe->descriptors + 0); + 0, 1, aframe->descriptors + 0); VkViewport viewport = {0, 0, vid.width, vid.height, 0, 1}; VkRect2D scissor = { {0, 0}, {vid.width, vid.height} }; dfunc->vkCmdSetViewport (cmd, 0, 1, &viewport); diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index dfd58b1f5..8b33cebb3 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -798,7 +798,7 @@ push_fragconst (fragconst_t *fragconst, VkPipelineLayout layout, qfv_devfuncs_t *dfunc, VkCommandBuffer cmd) { dfunc->vkCmdPushConstants (cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, - 0, sizeof (fragconst_t), fragconst); + 64, sizeof (fragconst_t), fragconst);//FIXME 64 } static void @@ -1259,6 +1259,15 @@ Vulkan_DrawSky (vulkan_ctx_t *ctx) fragconst_t frag_constants = { time: vr_data.realtime }; push_fragconst (&frag_constants, bctx->layout, dfunc, bframe->cmdSet.a[QFV_bspTranslucent]); + bind_view (qfv_bsp_texture, ctx->default_black->view, bframe, + bframe->cmdSet.a[QFV_bspTranslucent],//FIXME + bctx->layout, dfunc); + bind_view (qfv_bsp_glowmap, ctx->default_black->view, bframe, + bframe->cmdSet.a[QFV_bspTranslucent],//FIXME + bctx->layout, dfunc); + bind_view (qfv_bsp_lightmap, ctx->default_black->view, bframe, + bframe->cmdSet.a[QFV_bspTranslucent],//FIXME + bctx->layout, dfunc); for (is = bctx->sky_chain; is; is = is->tex_chain) { surf = is->surface; if (tex != surf->texinfo->texture->render) {