mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[vulkan] Move oit blending into compose subpass
I had debated putting the blending in the compose subpass or a separate pass but went with the separate pass originally, but it turns out that removing the separate pass gains 1-3% (5-15/545 fps in a timedemo of demo1).
This commit is contained in:
parent
7a64bb1149
commit
966ef949c5
12 changed files with 23 additions and 161 deletions
|
@ -36,7 +36,7 @@
|
|||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
||||
#define COMPOSE_IMAGE_INFOS 2
|
||||
#define COMPOSE_IMAGE_INFOS 1
|
||||
|
||||
typedef struct composeframe_s {
|
||||
VkCommandBuffer cmd;
|
||||
|
|
|
@ -40,8 +40,6 @@ typedef struct translucentctx_s {
|
|||
|
||||
struct qfv_resource_s *resources;
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkPipelineLayout layout;
|
||||
VkDescriptorPool pool;
|
||||
VkDescriptorSetLayout setLayout;
|
||||
} translucentctx_t;
|
||||
|
|
|
@ -53,7 +53,6 @@ typedef enum {
|
|||
QFV_passTranslucentFrag, // geometry
|
||||
QFV_passGBuffer, // geometry
|
||||
QFV_passLighting, // single triangle
|
||||
QFV_passTranslucentFinal, // single triangle
|
||||
QFV_passCompose, // single triangle
|
||||
|
||||
QFV_NumPasses
|
||||
|
@ -66,7 +65,6 @@ enum {
|
|||
QFV_attachNormal,
|
||||
QFV_attachPosition,
|
||||
QFV_attachOpaque,
|
||||
QFV_attachTranslucent,
|
||||
QFV_attachSwapchain,
|
||||
};
|
||||
|
||||
|
|
|
@ -340,10 +340,9 @@ lightingf_src = $(vkshaderpath)/lighting.frag
|
|||
lightingf_c = $(vkshaderpath)/lighting.frag.spvc
|
||||
composef_src = $(vkshaderpath)/compose.frag
|
||||
composef_c = $(vkshaderpath)/compose.frag.spvc
|
||||
oit_blend = $(vkshaderpath)/oit_blend.finc
|
||||
oit_store = $(vkshaderpath)/oit_store.finc
|
||||
oit_h = $(vkshaderpath)/oit.h
|
||||
oit_blendf_src = $(vkshaderpath)/oit_blend.frag
|
||||
oit_blendf_c = $(vkshaderpath)/oit_blend.frag.spvc
|
||||
aliasv_src = $(vkshaderpath)/alias.vert
|
||||
aliasv_c = $(vkshaderpath)/alias.vert.spvc
|
||||
aliasf_src = $(vkshaderpath)/alias.frag
|
||||
|
@ -419,9 +418,7 @@ $(bsp_turbf_c): $(bsp_turbf_src) $(oit_store) $(oit_h)
|
|||
|
||||
$(lightingf_c): $(lightingf_src)
|
||||
|
||||
$(composef_c): $(composef_src)
|
||||
|
||||
$(oit_blendf_c): $(oit_blendf_src) $(oit_h)
|
||||
$(composef_c): $(composef_src) $(oit_blend) $(oit_h)
|
||||
|
||||
$(aliasv_c): $(aliasv_src)
|
||||
|
||||
|
@ -478,7 +475,6 @@ vkshader_c = \
|
|||
$(bsp_turbf_c) \
|
||||
$(lightingf_c) \
|
||||
$(composef_c) \
|
||||
$(oit_blendf_c) \
|
||||
$(aliasv_c) \
|
||||
$(alias_depth_c) \
|
||||
$(aliasf_c) \
|
||||
|
@ -530,6 +526,9 @@ EXTRA_DIST += \
|
|||
$(rp_shadow_src) \
|
||||
$(pl_quake_def_src) \
|
||||
$(pl_output_src) \
|
||||
$(oit_blend) \
|
||||
$(oit_store) \
|
||||
$(oit_h) \
|
||||
libs/video/renderer/vulkan/vkparse.plist \
|
||||
libs/video/renderer/vulkan/vkparse.h \
|
||||
libs/video/renderer/vulkan/shader/alias.frag \
|
||||
|
@ -545,7 +544,6 @@ EXTRA_DIST += \
|
|||
libs/video/renderer/vulkan/shader/bsp_sky.frag \
|
||||
libs/video/renderer/vulkan/shader/bsp_turb.frag \
|
||||
libs/video/renderer/vulkan/shader/compose.frag \
|
||||
libs/video/renderer/vulkan/shader/oit_blend.frag \
|
||||
libs/video/renderer/vulkan/shader/iqm.frag \
|
||||
libs/video/renderer/vulkan/shader/iqm.vert \
|
||||
libs/video/renderer/vulkan/shader/lighting.frag \
|
||||
|
|
|
@ -427,12 +427,6 @@
|
|||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 1;
|
||||
descriptorType = input_attachment;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
);
|
||||
};
|
||||
particle_set = {
|
||||
|
@ -526,11 +520,8 @@
|
|||
lighting_layout = {
|
||||
setLayouts = (lighting_attach, lighting_lights, lighting_shadow);
|
||||
};
|
||||
oit_layout = {
|
||||
setLayouts = (oit_set);
|
||||
};
|
||||
compose_layout = {
|
||||
setLayouts = (compose_attach);
|
||||
setLayouts = (compose_attach, oit_set);
|
||||
};
|
||||
partphysics_layout = {
|
||||
setLayouts = (particle_set);
|
||||
|
@ -1264,22 +1255,9 @@
|
|||
);
|
||||
layout = lighting_layout;
|
||||
};
|
||||
oit = {
|
||||
@inherit = $properties.pipelines.comp_base;
|
||||
subpass = 4;
|
||||
stages = (
|
||||
$properties.fstriangle.vertexStage,
|
||||
{
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/oit_blend.frag;
|
||||
},
|
||||
);
|
||||
layout = oit_layout;
|
||||
};
|
||||
compose = {
|
||||
@inherit = $properties.pipelines.comp_base;
|
||||
subpass = 5;
|
||||
subpass = 4;
|
||||
stages = (
|
||||
$properties.fstriangle.vertexStage,
|
||||
{
|
||||
|
|
|
@ -39,10 +39,6 @@
|
|||
@inherit = $properties.flat_color_image_template;
|
||||
format = r16g16b16a16_sfloat;
|
||||
};
|
||||
translucent = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
format = r8g8b8a8_unorm;
|
||||
};
|
||||
};
|
||||
flat_color_view_template = {
|
||||
viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
|
@ -92,11 +88,6 @@
|
|||
image = opaque;
|
||||
format = $properties.images.opaque.format;
|
||||
};
|
||||
translucent = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = translucent;
|
||||
format = $properties.images.translucent.format;
|
||||
};
|
||||
};
|
||||
output = {
|
||||
image = {
|
||||
|
@ -115,7 +106,7 @@
|
|||
framebuffer = {
|
||||
renderPass = deferred;
|
||||
attachments = (depth, color, emission, normal, position, opaque,
|
||||
translucent, $output.view);
|
||||
$output.view);
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
layers = 1;
|
||||
|
@ -127,7 +118,6 @@
|
|||
{ color = "[0, 0, 0, 1]"; }, // normal
|
||||
{ color = "[0, 0, 0, 1]"; }, // position
|
||||
{ color = "[0, 0, 0, 1]"; }, // opaque
|
||||
{ color = "[0, 0, 0, 0]"; }, // translucent
|
||||
{ color = "[0, 0, 0, 1]"; }, // output
|
||||
);
|
||||
attachment_template = {
|
||||
|
@ -146,7 +136,6 @@
|
|||
{ name = translucent; color = "[ 0.25, 0.25, 0.6, 1]" },
|
||||
{ name = g-buffef; color = "[ 0.3, 0.7, 0.3, 1]" },
|
||||
{ name = lighting; color = "[ 0.8, 0.8, 0.8, 1]" },
|
||||
{ name = translucent; color = "[ 0.25, 0.6, 0.25, 1]" },
|
||||
{ name = compose; color = "[ 0.7, 0.3, 0.3, 1]" },
|
||||
);
|
||||
};
|
||||
|
@ -180,11 +169,6 @@
|
|||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.opaque.format;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.translucent.format;
|
||||
loadOp = clear;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $output.format;
|
||||
|
@ -267,31 +251,17 @@
|
|||
);
|
||||
preserveAttachments = (6);
|
||||
},
|
||||
{ // 4 translucent-final
|
||||
pipelineBindPoint = graphics;
|
||||
colorAttachments = (
|
||||
{ // translucent
|
||||
attachment = 6;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
preserveAttachments = (1, 2, 3, 4, 5);
|
||||
},
|
||||
{ // 5 compose
|
||||
{ // 4 compose
|
||||
pipelineBindPoint = graphics;
|
||||
inputAttachments = (
|
||||
{ // opaque
|
||||
attachment = 5;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // translucent
|
||||
attachment = 6;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
);
|
||||
colorAttachments = (
|
||||
{ // output
|
||||
attachment = 7;
|
||||
attachment = 6;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
|
@ -308,14 +278,6 @@
|
|||
dstAccessMask = input_attachment_read|depth_stencil_attachment_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
/*{
|
||||
srcSubpass = ~0u; // external
|
||||
dstSubpass = 1; // translucent-frags
|
||||
srcStageMask = transfer;
|
||||
dstStageMask = fragment_shader|early_fragment_tests;
|
||||
srcAccessMask = transfer_write;
|
||||
dstAccessMask = shader_read|shader_write;
|
||||
},*/
|
||||
{
|
||||
srcSubpass = 0; // depth
|
||||
dstSubpass = 2; // g-buffer
|
||||
|
@ -336,7 +298,7 @@
|
|||
},
|
||||
{
|
||||
srcSubpass = 3; // lighting
|
||||
dstSubpass = 5; // compose
|
||||
dstSubpass = 4; // compose
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
|
@ -345,16 +307,7 @@
|
|||
},
|
||||
{
|
||||
srcSubpass = 1; // translucent-frags
|
||||
dstSubpass = 4; // translucent-final
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = input_attachment_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 4; // translucent-final
|
||||
dstSubpass = 5; // compose
|
||||
dstSubpass = 4; // translucent-final/compose
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
|
|
|
@ -95,8 +95,6 @@ static
|
|||
static
|
||||
#include "libs/video/renderer/vulkan/shader/compose.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/oit_blend.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/alias.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/alias_depth.vert.spvc"
|
||||
|
@ -158,7 +156,6 @@ static shaderdata_t builtin_shaders[] = {
|
|||
{ "bsp_turb.frag", bsp_turb_frag, sizeof (bsp_turb_frag) },
|
||||
{ "lighting.frag", lighting_frag, sizeof (lighting_frag) },
|
||||
{ "compose.frag", compose_frag, sizeof (compose_frag) },
|
||||
{ "oit_blend.frag", oit_blend_frag, sizeof (oit_blend_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) },
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#define OIT_SET 1
|
||||
#include "oit_blend.finc"
|
||||
|
||||
layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput opaque;
|
||||
layout (input_attachment_index = 1, set = 0, binding = 1) uniform subpassInput translucent;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
|
@ -9,12 +11,10 @@ void
|
|||
main (void)
|
||||
{
|
||||
vec3 o;
|
||||
vec4 t;
|
||||
vec3 c;
|
||||
|
||||
o = subpassLoad (opaque).rgb;
|
||||
t = subpassLoad (translucent);
|
||||
c = mix (o, t.rgb, t.a);
|
||||
c = BlendFrags (vec4 (o, 1)).xyz;
|
||||
c = pow (c, vec3(0.83));//FIXME make gamma correction configurable
|
||||
frag_color = vec4 (c, 1);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#define OIT_SET 0
|
||||
#include "oit.h"
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
void
|
||||
main (void)
|
||||
vec4
|
||||
BlendFrags (vec4 color)
|
||||
{
|
||||
#define MAX_FRAGMENTS 64
|
||||
FragData frags[MAX_FRAGMENTS];
|
||||
|
@ -31,10 +26,9 @@ main (void)
|
|||
frags[j] = toInsert;
|
||||
}
|
||||
|
||||
vec4 color = vec4 (0, 0, 0, 0);
|
||||
for (int i = 0; i < numFrags; i++) {
|
||||
color = mix (color, frags[i].color,
|
||||
clamp (frags[i].color.a, 0.0f, 1.0f));
|
||||
}
|
||||
frag_color = color;
|
||||
return color;
|
||||
}
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
#include "QF/Vulkan/qf_compose.h"
|
||||
#include "QF/Vulkan/qf_renderpass.h"
|
||||
#include "QF/Vulkan/qf_translucent.h"
|
||||
#include "QF/Vulkan/debug.h"
|
||||
#include "QF/Vulkan/descriptor.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
|
@ -90,16 +91,15 @@ Vulkan_Compose_Draw (qfv_renderframe_t *rFrame)
|
|||
|
||||
cframe->imageInfo[0].imageView
|
||||
= renderpass->attachment_views->a[QFV_attachOpaque];
|
||||
cframe->imageInfo[1].imageView
|
||||
= renderpass->attachment_views->a[QFV_attachTranslucent];
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, COMPOSE_IMAGE_INFOS,
|
||||
cframe->descriptors, 0, 0);
|
||||
|
||||
VkDescriptorSet sets[] = {
|
||||
cframe->descriptors[0].dstSet,
|
||||
Vulkan_Translucent_Descriptors (ctx, ctx->curFrame),
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
cctx->layout, 0, 1, sets, 0, 0);
|
||||
cctx->layout, 0, 2, sets, 0, 0);
|
||||
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
||||
|
|
|
@ -141,7 +141,6 @@ Vulkan_RenderView (qfv_renderframe_t *rFrame)
|
|||
Vulkan_Bsp_Flush (ctx);
|
||||
Vulkan_RenderEntities (r_ent_queue, rFrame);
|
||||
Vulkan_Scene_Flush (ctx);
|
||||
Vulkan_Translucent_Draw (rFrame);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -66,54 +66,6 @@ static const char * __attribute__((used)) translucent_pass_names[] = {
|
|||
"blend",
|
||||
};
|
||||
|
||||
void
|
||||
Vulkan_Translucent_Draw (qfv_renderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
qfv_renderpass_t *renderpass = rFrame->renderpass;
|
||||
|
||||
translucentctx_t *tctx = ctx->translucent_context;
|
||||
translucentframe_t *tframe = &tctx->frames.a[ctx->curFrame];
|
||||
VkCommandBuffer cmd = tframe->cmdSet.a[QFV_translucentBlend];
|
||||
|
||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucentFinal], cmd);
|
||||
|
||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
renderpass->renderpass, QFV_passTranslucentFinal,
|
||||
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, "translucent", { 0, 0.2, 0.6, 1});
|
||||
|
||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
tctx->pipeline);
|
||||
VkDescriptorSet set[] = {
|
||||
tframe->descriptors,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
tctx->layout, 0, 1, set, 0, 0);
|
||||
|
||||
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
||||
|
||||
dfunc->vkCmdDraw (cmd, 3, 1, 0, 0);
|
||||
|
||||
QFV_duCmdEndLabel (device, cmd);
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Translucent_Init (vulkan_ctx_t *ctx)
|
||||
{
|
||||
|
@ -132,9 +84,6 @@ Vulkan_Translucent_Init (vulkan_ctx_t *ctx)
|
|||
DARRAY_RESIZE (&tctx->frames, frames);
|
||||
tctx->frames.grow = 0;
|
||||
|
||||
tctx->pipeline = Vulkan_CreateGraphicsPipeline (ctx, "oit");
|
||||
tctx->layout = Vulkan_CreatePipelineLayout (ctx, "oit_layout");
|
||||
|
||||
__auto_type setLayout = QFV_AllocDescriptorSetLayoutSet (frames, alloca);
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
setLayout->a[i] = Vulkan_CreateDescriptorSetLayout (ctx, "oit_set");
|
||||
|
@ -168,7 +117,6 @@ void
|
|||
Vulkan_Translucent_Shutdown (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
translucentctx_t *tctx = ctx->translucent_context;
|
||||
|
||||
if (tctx->resources) {
|
||||
|
@ -177,7 +125,6 @@ Vulkan_Translucent_Shutdown (vulkan_ctx_t *ctx)
|
|||
tctx->resources = 0;
|
||||
}
|
||||
|
||||
dfunc->vkDestroyPipeline (device->dev, tctx->pipeline, 0);
|
||||
free (tctx->frames.a);
|
||||
free (tctx);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue