From 58b42ed1b7e2cdca0e1acf828516e1bc9345266d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 19 Jan 2024 17:06:03 +0900 Subject: [PATCH] [vulkan] Implement forward translucent pipelines This gets skies, liquids and particles working. I think it's only alias and iqm lighting to go before forward is caught up to deferred. --- libs/video/renderer/Makemodule.am | 6 + libs/video/renderer/vulkan/rp_main_fwd.plist | 162 +++++++++++++++++- libs/video/renderer/vulkan/shader.c | 3 + .../renderer/vulkan/shader/compose_fwd.frag | 24 +++ libs/video/renderer/vulkan/vulkan_compose.c | 4 +- 5 files changed, 191 insertions(+), 8 deletions(-) create mode 100644 libs/video/renderer/vulkan/shader/compose_fwd.frag diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index 069e49797..c1f5a8ba1 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -364,6 +364,8 @@ lighting_planef_c = $(vkshaderpath)/lighting_plane.frag.spvc lighting_h = $(vkshaderpath)/lighting.h composef_src = $(vkshaderpath)/compose.frag composef_c = $(vkshaderpath)/compose.frag.spvc +compose_fwdf_src = $(vkshaderpath)/compose_fwd.frag +compose_fwdf_c = $(vkshaderpath)/compose_fwd.frag.spvc infplane = $(vkshaderpath)/infplane.finc oit_blend = $(vkshaderpath)/oit_blend.finc oit_store = $(vkshaderpath)/oit_store.finc @@ -474,6 +476,8 @@ $(lighting_planef_c): $(lighting_planef_src) $(lighting_h) $(lighting_main) $(composef_c): $(composef_src) $(oit_blend) $(oit_h) +$(compose_fwdf_c): $(compose_fwdf_src) $(oit_blend) $(oit_h) + $(aliasv_c): $(aliasv_src) $(matrices_h) $(alias_depth_c): $(alias_depth_src) $(matrices_h) @@ -545,6 +549,7 @@ vkshader_c = \ $(lighting_nonef_c) \ $(lighting_planef_c) \ $(composef_c) \ + $(compose_fwdf_c) \ $(aliasv_c) \ $(alias_depth_c) \ $(aliasf_c) \ @@ -644,6 +649,7 @@ EXTRA_DIST += \ $(lighting_planef_src) \ $(lighting_h) \ $(composef_src) \ + $(compose_fwdf_src) \ $(aliasv_src) \ $(aliasf_src) \ $(alias_depth_src) \ diff --git a/libs/video/renderer/vulkan/rp_main_fwd.plist b/libs/video/renderer/vulkan/rp_main_fwd.plist index fc9830619..15ccad42a 100644 --- a/libs/video/renderer/vulkan/rp_main_fwd.plist +++ b/libs/video/renderer/vulkan/rp_main_fwd.plist @@ -52,6 +52,7 @@ properties = { }; cube_image_base = { @inherit = $image_base; + flags = cube_compatible; extent = { width = "min($render_output.extent.width,$render_output.extent.height)"; height = "min($render_output.extent.width,$render_output.extent.height)"; @@ -579,7 +580,7 @@ properties = { fragment = { stage = fragment; name = main; - module = $builtin/compose.frag; + module = $builtin/compose_fwd.frag; }; }; layout = { @@ -983,6 +984,10 @@ images = { usage = depth_stencil_attachment|input_attachment|transient_attachment; }; color = { + @inherit = $image_base; + format = r8g8b8a8_unorm; + }; + output = { @inherit = $image_base; usage = color_attachment|input_attachment|sampled; format = $render_output.format; @@ -993,6 +998,10 @@ images = { usage = depth_stencil_attachment|input_attachment|transient_attachment; }; cube_color = { + @inherit = $cube_image_base; + format = $render_output.format; + }; + cube_output = { @inherit = $cube_image_base; flags = cube_compatible; usage = color_attachment|input_attachment|sampled; @@ -1012,6 +1021,11 @@ imageviews = { image = color; format = $images.color.format; }; + output = { + @inherit = $view_base; + image = output; + format = $render_output.format; + }; cube_depth = { @inherit = $cube_view_base; image = cube_depth; @@ -1021,9 +1035,13 @@ imageviews = { }; cube_color = { @inherit = $cube_view_base; - viewType = cube; image = cube_color; }; + cube_output = { + @inherit = $cube_view_base; + viewType = cube; + image = cube_output; + } }; output = { view = $output; @@ -1054,10 +1072,18 @@ renderpasses = { finalLayout = $render_output.finalLayout; view = color; }; + output = { + @inherit = $attachment_base; + format = $render_output.format; + loadOp = clear; + storeOp = store; + finalLayout = $render_output.finalLayout; + view = output; + }; }; }; subpasses = { - color = { + solid = { color = "[ 0.3, 0.7, 0.3, 1]"; attachments = { color = { @@ -1082,8 +1108,6 @@ renderpasses = { tasks = ( { func = bsp_draw_queue; params = (main, solid, 1); }, - { func = bsp_draw_queue; - params = (main, sky, 1); }, ); stages = ( @@ -1141,13 +1165,127 @@ renderpasses = { }; }; }; + translucent = { + color = "[ 0.25, 0.25, 0.6, 1]"; + dependencies = { + solid = $depth_dependency; + }; + attachments = { + depth = { + depth = depth_stencil_read_only_optimal; + }; + preserve = (color); + }; + base_pipeline = { + @inherit = $pipeline_base; + rasterization = $cw_cull_back; + }; + pipelines = { + bsp:skybox = { + color = $color.bsp; + tasks = ( + // FIXME sky should not use OIT + { func = bsp_draw_queue; + params = (main, sky, 1); }, + ); + + stages = ( + $brush.shader.quake_vertex, + $brush.shader.skybox_fragment, + ); + vertexInput = $brush.vertexInput; + inputAssembly = $brush.inputAssembly; + layout = $brush.layout; + }; + bsp:skysheet = { + color = $color.bsp; + tasks = ( + // FIXME sky should not use OIT + { func = bsp_draw_queue; + params = (main, sky, 1); }, + ); + + stages = ( + $brush.shader.quake_vertex, + $brush.shader.skysheet_fragment, + ); + vertexInput = $brush.vertexInput; + inputAssembly = $brush.inputAssembly; + layout = $brush.layout; + }; + bsp:trans = { + color = $color.bsp; + tasks = ( + { func = bsp_draw_queue; + params = (main, translucent, 1); }, + { func = bsp_draw_queue; + params = (main, turbulent, 1); }, + ); + stages = ( + $brush.shader.quake_vertex, + $brush.shader.turb_fragment, + ); + vertexInput = $brush.vertexInput; + inputAssembly = $brush.inputAssembly; + layout = $brush.layout; + }; + particles:trans = { + color = $color.particles; + tasks = ( + { func = particles_draw; }, + ); + stages = ( + $particle.shader.vertex, + $particle.shader.geometry, + $particle.shader.fragment, + ); + vertexInput = $particle.vertexInput; + inputAssembly = $particle.inputAssembly; + layout = $particle.layout.draw; + }; + }; + }; + compose = { + color = "[ 0.7, 0.3, 0.3, 1]"; + dependencies = { + solid = $color_dependency; + translucent = $color_dependency;//FIXME is this right? no op + }; + attachments = { + input = { + color = shader_read_only_optimal; + }; + color = { + output = { + layout = color_attachment_optimal; + blend = $additive_blend; + }; + }; + preserve = (depth); + }; + pipelines = { + compose = { + @inherit = $compose_base; + + color = $color.compose; + tasks = ( + { func = compose_draw; }, + ); + stages = ( + $fstriangle.shader.vertex, + $compose.shader.fragment, + ); + layout = $compose.layout; + }; + }; + }; }; - output = color; + output = output; }; forward_cube = { @inherit = $renderpasses.forward; @next = (VkRenderPassMultiviewCreateInfo, { - viewMasks = (0x3fu); + viewMasks = (0x3fu, 0x3fu, 0x3fu); }); framebuffer = { width = "min($render_output.extent.width,$render_output.extent.height)"; @@ -1170,6 +1308,14 @@ renderpasses = { finalLayout = $render_output.finalLayout; view = cube_color; }; + output = { + @inherit = $attachment_base; + format = $images.cube_color.format; + loadOp = clear; + storeOp = store; + finalLayout = $render_output.finalLayout; + view = cube_output; + }; }; }; output = cube_color; @@ -1335,6 +1481,8 @@ steps = { params = ("\"main\""); }, { func = update_framebuffer; params = ("\"main\""); }, + { func = clear_translucent; + params = ("\"main\""); }, { func = particle_wait_physics; }, ); }; diff --git a/libs/video/renderer/vulkan/shader.c b/libs/video/renderer/vulkan/shader.c index d4674db48..0ff1ed694 100644 --- a/libs/video/renderer/vulkan/shader.c +++ b/libs/video/renderer/vulkan/shader.c @@ -115,6 +115,8 @@ static static #include "libs/video/renderer/vulkan/shader/compose.frag.spvc" static +#include "libs/video/renderer/vulkan/shader/compose_fwd.frag.spvc" +static #include "libs/video/renderer/vulkan/shader/alias.vert.spvc" static #include "libs/video/renderer/vulkan/shader/alias_depth.vert.spvc" @@ -194,6 +196,7 @@ static shaderdata_t builtin_shaders[] = { { "lighting_plane.frag", lighting_plane_frag, sizeof (lighting_plane_frag) }, { "compose.frag", compose_frag, sizeof (compose_frag) }, + { "compose_fwd.frag", compose_fwd_frag, sizeof (compose_fwd_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/compose_fwd.frag b/libs/video/renderer/vulkan/shader/compose_fwd.frag new file mode 100644 index 000000000..8dad314f2 --- /dev/null +++ b/libs/video/renderer/vulkan/shader/compose_fwd.frag @@ -0,0 +1,24 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_multiview : enable + +#define OIT_SET 1 +#include "oit_blend.finc" + +layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput color; + +layout (location = 0) out vec4 frag_color; + +void +main (void) +{ + vec3 c; + vec3 l; + vec3 e; + vec3 o; + + c = subpassLoad (color).rgb; + o = max(BlendFrags (vec4 (c, 1)).xyz, vec3(0)); + o = pow (o, vec3(0.83));//FIXME make gamma correction configurable + frag_color = vec4 (o, 1); +} diff --git a/libs/video/renderer/vulkan/vulkan_compose.c b/libs/video/renderer/vulkan/vulkan_compose.c index 346c734da..003c79349 100644 --- a/libs/video/renderer/vulkan/vulkan_compose.c +++ b/libs/video/renderer/vulkan/vulkan_compose.c @@ -85,8 +85,10 @@ compose_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) cframe->imageInfo[0].imageView = fb->views[QFV_attachColor]; cframe->imageInfo[1].imageView = fb->views[QFV_attachLight]; cframe->imageInfo[2].imageView = fb->views[QFV_attachEmission]; - dfunc->vkUpdateDescriptorSets (device->dev, COMPOSE_IMAGE_INFOS, + dfunc->vkUpdateDescriptorSets (device->dev, 1, cframe->descriptors, 0, 0); + //dfunc->vkUpdateDescriptorSets (device->dev, COMPOSE_IMAGE_INFOS, + // cframe->descriptors, 0, 0); VkDescriptorSet sets[] = { cframe->descriptors[0].dstSet,