mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 12:31:10 +00:00
[vulkan] Implement most of the changes for cube rendering
There are some missing parts from this commit as these are the fairly clean changes. Missing is building a separate set of pipelines for the new render pass (might be able to get away from that), OIT heads texture is flat rather than an array, view matrices aren't set up, and the fisheye renderer isn't hooked up to the output pass (code exists but is messy). However, with the missing parts included, testing shows things mostly working: the cube map is rendered correctly even though it's not displayed correctly (incorrect view). This has definitely proven to be a good test for Vulkan's multiview feature (very nice).
This commit is contained in:
parent
0cf341d1cb
commit
4cb120e878
13 changed files with 419 additions and 0 deletions
|
@ -47,8 +47,10 @@ typedef struct outputctx_s {
|
|||
outputframeset_t frames;
|
||||
VkPipeline output;
|
||||
VkPipeline waterwarp;
|
||||
VkPipeline fisheye;
|
||||
VkPipelineLayout output_layout;
|
||||
VkPipelineLayout warp_layout;
|
||||
VkPipelineLayout fish_layout;
|
||||
VkSampler sampler;
|
||||
VkImageView input;
|
||||
} outputctx_t;
|
||||
|
|
|
@ -195,6 +195,8 @@ pl_quake_def_src = libs/video/renderer/vulkan/pl_quake_def.plist
|
|||
pl_quake_def_gen = libs/video/renderer/vulkan/pl_quake_def.plc
|
||||
pl_output_src = libs/video/renderer/vulkan/pl_output.plist
|
||||
pl_output_gen = libs/video/renderer/vulkan/pl_output.plc
|
||||
rp_defcube_src = libs/video/renderer/vulkan/rp_defcube.plist
|
||||
rp_defcube_gen = libs/video/renderer/vulkan/rp_defcube.plc
|
||||
rp_deferred_src = libs/video/renderer/vulkan/rp_deferred.plist
|
||||
rp_deferred_gen = libs/video/renderer/vulkan/rp_deferred.plc
|
||||
rp_forward_src = libs/video/renderer/vulkan/rp_forward.plist
|
||||
|
@ -260,6 +262,7 @@ libs/video/renderer/vulkan/vkparse.lo: \
|
|||
$(vkparse_src) \
|
||||
$(pl_quake_def_gen) \
|
||||
$(pl_output_gen) \
|
||||
${rp_defcube_gen} \
|
||||
${rp_deferred_gen} \
|
||||
$(rp_forward_gen) \
|
||||
$(rp_output_gen) \
|
||||
|
@ -363,6 +366,8 @@ fstrianglest_src = $(vkshaderpath)/fstrianglest.vert
|
|||
fstrianglest_c = $(vkshaderpath)/fstrianglest.vert.spvc
|
||||
pushcolor_src = $(vkshaderpath)/pushcolor.frag
|
||||
pushcolor_c = $(vkshaderpath)/pushcolor.frag.spvc
|
||||
fisheye_src = $(vkshaderpath)/fisheye.frag
|
||||
fisheye_c = $(vkshaderpath)/fisheye.frag.spvc
|
||||
waterwarp_src = $(vkshaderpath)/waterwarp.frag
|
||||
waterwarp_c = $(vkshaderpath)/waterwarp.frag.spvc
|
||||
|
||||
|
@ -437,6 +442,8 @@ $(fstrianglest_c): $(fstrianglest_src)
|
|||
|
||||
$(pushcolor_c): $(pushcolor_src)
|
||||
|
||||
$(fisheye_c): $(fisheye_src) $(matrices_h)
|
||||
|
||||
$(waterwarp_c): $(waterwarp_src) $(matrices_h)
|
||||
|
||||
vkshader_c = \
|
||||
|
@ -479,6 +486,7 @@ vkshader_c = \
|
|||
$(fstrianglest_c) \
|
||||
$(pushcolor_c) \
|
||||
$(shadow_c) \
|
||||
$(fisheye_c) \
|
||||
$(waterwarp_c)
|
||||
|
||||
V_VKGEN = $(V_VKGEN_@AM_V@)
|
||||
|
@ -513,6 +521,7 @@ BUILT_SOURCES += $(shader_gen)
|
|||
EXTRA_DIST += \
|
||||
libs/video/renderer/vulkan/vkparse.plist \
|
||||
libs/video/renderer/vulkan/vkparse.h \
|
||||
$(rp_defcube_src) \
|
||||
$(rp_deferred_src) \
|
||||
$(rp_forward_src) \
|
||||
$(rp_output_src) \
|
||||
|
@ -562,4 +571,5 @@ EXTRA_DIST += \
|
|||
$(fstriangle_src) \
|
||||
$(fstrianglest_src) \
|
||||
$(pushcolor_src) \
|
||||
$(fisheye_src) \
|
||||
$(waterwarp_src)
|
||||
|
|
|
@ -152,6 +152,7 @@ QFV_CreateDevice (vulkan_ctx_t *ctx, const char **extensions)
|
|||
VkPhysicalDeviceMultiviewFeatures multiview_features = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
|
||||
.multiview = 1,
|
||||
.multiviewGeometryShader = 1,
|
||||
};
|
||||
VkPhysicalDeviceFeatures features = {
|
||||
.geometryShader = 1,
|
||||
|
|
|
@ -66,6 +66,16 @@
|
|||
}
|
||||
);
|
||||
};
|
||||
fisheye_layout = {
|
||||
@inherit = $properties.pipelineLayouts.output_layout;
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 0;
|
||||
size = "2 * 4";
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
depthStencil = {
|
||||
|
@ -233,5 +243,18 @@
|
|||
);
|
||||
layout = waterwarp_layout;
|
||||
};
|
||||
fisheye = {
|
||||
@inherit = $properties.pipelines.output_base;
|
||||
subpass = 0;
|
||||
stages = (
|
||||
$properties.fstriangle.vertexStageST,
|
||||
{
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/fisheye.frag;
|
||||
},
|
||||
);
|
||||
layout = fisheye_layout;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
335
libs/video/renderer/vulkan/rp_defcube.plist
Normal file
335
libs/video/renderer/vulkan/rp_defcube.plist
Normal file
|
@ -0,0 +1,335 @@
|
|||
{
|
||||
flat_color_image_template = {
|
||||
imageType = `2d;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
arrayLayers = 6;
|
||||
tiling = optimal;
|
||||
usage = color_attachment|input_attachment|transient_attachment;
|
||||
initialLayout = undefined;
|
||||
};
|
||||
images = {
|
||||
depth = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
format = x8_d24_unorm_pack32;
|
||||
usage = depth_stencil_attachment|input_attachment|transient_attachment;
|
||||
};
|
||||
color = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
format = r8g8b8a8_unorm;
|
||||
};
|
||||
emission = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
format = r16g16b16a16_sfloat;
|
||||
};
|
||||
normal = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
format = r16g16b16a16_sfloat;
|
||||
};
|
||||
position = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
format = r32g32b32a32_sfloat;
|
||||
};
|
||||
opaque = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
format = r16g16b16a16_sfloat;
|
||||
};
|
||||
};
|
||||
flat_color_view_template = {
|
||||
viewType = `2d_array;
|
||||
components = {
|
||||
r = identity;
|
||||
g = identity;
|
||||
b = identity;
|
||||
a = identity;
|
||||
};
|
||||
subresourceRange = {
|
||||
aspectMask = color;
|
||||
levelCount = 1;
|
||||
layerCount = 6;
|
||||
};
|
||||
};
|
||||
imageViews = {
|
||||
depth = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = depth;
|
||||
format = $properties.images.depth.format;
|
||||
subresourceRange = {
|
||||
aspectMask = depth;
|
||||
};
|
||||
};
|
||||
color = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = color;
|
||||
format = $properties.images.color.format;
|
||||
};
|
||||
emission = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = emission;
|
||||
format = $properties.images.emission.format;
|
||||
};
|
||||
normal = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = normal;
|
||||
format = $properties.images.normal.format;
|
||||
};
|
||||
position = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = position;
|
||||
format = $properties.images.position.format;
|
||||
};
|
||||
opaque = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = opaque;
|
||||
format = $properties.images.opaque.format;
|
||||
};
|
||||
aview = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
image = $output.image;
|
||||
format = $output.format;
|
||||
};
|
||||
};
|
||||
output = {
|
||||
image = {
|
||||
@inherit = $properties.flat_color_image_template;
|
||||
flags = cube_compatible;
|
||||
usage = color_attachment|input_attachment|sampled;
|
||||
format = $output.format;
|
||||
};
|
||||
view = {
|
||||
@inherit = $properties.flat_color_view_template;
|
||||
viewType = cube;
|
||||
image = $output.image;
|
||||
format = $output.format;
|
||||
};
|
||||
format = r16g16b16a16_sfloat;
|
||||
finalLayout = shader_read_only_optimal;
|
||||
};
|
||||
framebuffer = {
|
||||
renderPass = defcube;
|
||||
attachments = (depth, color, emission, normal, position, opaque,
|
||||
$properties.imageViews.aview);
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
layers = 1;
|
||||
};
|
||||
clearValues = (
|
||||
{ depthStencil = { depth = 1; stencil = 0; }; },
|
||||
{ color = "[0, 0, 0, 1]"; }, // color
|
||||
{ color = "[0, 0, 0, 1]"; }, // emission
|
||||
{ color = "[0, 0, 0, 1]"; }, // normal
|
||||
{ color = "[0, 0, 0, 1]"; }, // position
|
||||
{ color = "[0, 0, 0, 1]"; }, // opaque
|
||||
{ color = "[0, 0, 0, 1]"; }, // output
|
||||
);
|
||||
attachment_template = {
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = store;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
initialLayout = undefined;
|
||||
finalLayout = color_attachment_optimal;
|
||||
};
|
||||
info = {
|
||||
color = "[0, 1, 0, 1]";
|
||||
subpass_info = (
|
||||
{ name = depth; color = "[ 0.5, 0.5, 0.5, 1]" },
|
||||
{ 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 = compose; color = "[ 0.7, 0.3, 0.3, 1]" },
|
||||
);
|
||||
};
|
||||
renderpass = {
|
||||
attachments = (
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.depth.format;
|
||||
loadOp = clear;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.color.format;
|
||||
loadOp = clear;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.emission.format;
|
||||
loadOp = clear;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.normal.format;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.position.format;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $properties.images.opaque.format;
|
||||
},
|
||||
{
|
||||
@inherit = $properties.attachment_template;
|
||||
format = $output.format;
|
||||
loadOp = clear;
|
||||
storeOp = store;
|
||||
finalLayout = $output.finalLayout;
|
||||
},
|
||||
);
|
||||
subpasses = (
|
||||
{ // 0 depth
|
||||
pipelineBindPoint = graphics;
|
||||
depthStencilAttachment = {
|
||||
attachment = 0;
|
||||
layout = depth_stencil_attachment_optimal;
|
||||
};
|
||||
},
|
||||
{ // 1 translucent-frags
|
||||
pipelineBindPoint = graphics;
|
||||
depthStencilAttachment = {
|
||||
attachment = 0;
|
||||
layout = depth_stencil_read_only_optimal;
|
||||
};
|
||||
preserveAttachments = (1, 2, 3, 4, 5);
|
||||
},
|
||||
{ // 2 g-buffer generation
|
||||
pipelineBindPoint = graphics;
|
||||
colorAttachments = (
|
||||
{ // color
|
||||
attachment = 1;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
{ // emission
|
||||
attachment = 2;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
{ // normal
|
||||
attachment = 3;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
{ // position
|
||||
attachment = 4;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
depthStencilAttachment = {
|
||||
attachment = 0;
|
||||
layout = depth_stencil_read_only_optimal;
|
||||
};
|
||||
preserveAttachments = (6);
|
||||
},
|
||||
{ // 3 lighting
|
||||
pipelineBindPoint = graphics;
|
||||
inputAttachments = (
|
||||
{ // depth
|
||||
attachment = 0;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // color
|
||||
attachment = 1;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // emission
|
||||
attachment = 2;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // normal
|
||||
attachment = 3;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // position
|
||||
attachment = 4;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
);
|
||||
colorAttachments = (
|
||||
{ // opaque
|
||||
attachment = 5;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
preserveAttachments = (6);
|
||||
},
|
||||
{ // 4 compose
|
||||
pipelineBindPoint = graphics;
|
||||
inputAttachments = (
|
||||
{ // opaque
|
||||
attachment = 5;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
);
|
||||
colorAttachments = (
|
||||
{ // output
|
||||
attachment = 6;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
preserveAttachments = (0, 1, 2, 3, 4);
|
||||
},
|
||||
);
|
||||
dependencies = (
|
||||
{
|
||||
srcSubpass = 0; // depth
|
||||
dstSubpass = 1; // translucent
|
||||
srcStageMask = late_fragment_tests;
|
||||
dstStageMask = fragment_shader|early_fragment_tests;
|
||||
srcAccessMask = depth_stencil_attachment_write;
|
||||
dstAccessMask = input_attachment_read|depth_stencil_attachment_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 0; // depth
|
||||
dstSubpass = 2; // g-buffer
|
||||
srcStageMask = late_fragment_tests;
|
||||
dstStageMask = early_fragment_tests;
|
||||
srcAccessMask = depth_stencil_attachment_write;
|
||||
dstAccessMask = depth_stencil_attachment_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 2; // g-buffer
|
||||
dstSubpass = 3; // lighting
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = input_attachment_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 3; // lighting
|
||||
dstSubpass = 4; // compose
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = input_attachment_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 1; // translucent-frags
|
||||
dstSubpass = 4; // translucent-final/compose
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = input_attachment_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
);
|
||||
@next = (VkRenderPassMultiviewCreateInfo, {
|
||||
viewMasks = (
|
||||
0x0000003fu,
|
||||
0x0000003fu,
|
||||
0x0000003fu,
|
||||
0x0000003fu,
|
||||
0x0000003fu,
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
|
@ -115,6 +115,8 @@ static
|
|||
static
|
||||
#include "libs/video/renderer/vulkan/shader/pushcolor.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/fisheye.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/waterwarp.frag.spvc"
|
||||
|
||||
typedef struct shaderdata_s {
|
||||
|
@ -162,6 +164,7 @@ static shaderdata_t builtin_shaders[] = {
|
|||
{ "fstriangle.vert", fstriangle_vert, sizeof (fstriangle_vert) },
|
||||
{ "fstrianglest.vert", fstrianglest_vert, sizeof (fstrianglest_vert) },
|
||||
{ "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) },
|
||||
{ "fisheye.frag", fisheye_frag, sizeof (fisheye_frag) },
|
||||
{ "waterwarp.frag", waterwarp_frag, sizeof (waterwarp_frag) },
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_multiview : enable
|
||||
|
||||
#include "oit_store.finc"
|
||||
|
||||
layout (constant_id = 0) const bool doSkyBox = false;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_multiview : enable
|
||||
|
||||
#include "oit_store.finc"
|
||||
|
||||
layout (set = 3, binding = 0) uniform sampler2DArray Texture;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_multiview : enable
|
||||
|
||||
#define OIT_SET 1
|
||||
#include "oit_blend.finc"
|
||||
|
||||
|
|
30
libs/video/renderer/vulkan/shader/fisheye.frag
Normal file
30
libs/video/renderer/vulkan/shader/fisheye.frag
Normal file
|
@ -0,0 +1,30 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
layout (set = 0, binding = 0) uniform
|
||||
#include "matrices.h"
|
||||
;
|
||||
|
||||
layout (set = 1, binding = 0) uniform samplerCube Input;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
float fov;
|
||||
float aspect;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 uv;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
// slight offset on y is to avoid the singularity straight ahead
|
||||
vec2 xy = (2.0 * uv - vec2 (1, 1.00002)) * (vec2(1, -aspect));
|
||||
float r = sqrt (dot (xy, xy));
|
||||
vec2 cs = vec2 (cos (r * fov), sin (r * fov));
|
||||
vec3 dir = vec3 (cs.y * xy / r, cs.x);
|
||||
|
||||
vec4 c = texture (Input, dir);
|
||||
frag_color = c;// * 0.001 + vec4(dir, 1);
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_multiview : enable
|
||||
|
||||
#include "oit_store.finc"
|
||||
|
||||
layout (location = 0) in vec4 uv_tr;
|
||||
|
|
|
@ -1724,6 +1724,10 @@ static exprsym_t builtin_plist_syms[] = {
|
|||
.value = (void *)
|
||||
#include "libs/video/renderer/vulkan/pl_output.plc"
|
||||
},
|
||||
{ .name = "defcube",
|
||||
.value = (void *)
|
||||
#include "libs/video/renderer/vulkan/rp_defcube.plc"
|
||||
},
|
||||
{ .name = "deferred",
|
||||
.value = (void *)
|
||||
#include "libs/video/renderer/vulkan/rp_deferred.plc"
|
||||
|
|
|
@ -245,8 +245,10 @@ Vulkan_Output_Init (vulkan_ctx_t *ctx)
|
|||
|
||||
octx->output = Vulkan_CreateGraphicsPipeline (ctx, "output");
|
||||
octx->waterwarp = Vulkan_CreateGraphicsPipeline (ctx, "waterwarp");
|
||||
octx->fisheye = Vulkan_CreateGraphicsPipeline (ctx, "fisheye");
|
||||
octx->output_layout = Vulkan_CreatePipelineLayout (ctx, "output_layout");
|
||||
octx->warp_layout = Vulkan_CreatePipelineLayout (ctx, "waterwarp_layout");
|
||||
octx->fish_layout = Vulkan_CreatePipelineLayout (ctx, "fisheye_layout");
|
||||
octx->sampler = Vulkan_CreateSampler (ctx, "linear");
|
||||
|
||||
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (frames, alloca);
|
||||
|
@ -285,6 +287,7 @@ Vulkan_Output_Shutdown (vulkan_ctx_t *ctx)
|
|||
|
||||
dfunc->vkDestroyPipeline (device->dev, octx->output, 0);
|
||||
dfunc->vkDestroyPipeline (device->dev, octx->waterwarp, 0);
|
||||
dfunc->vkDestroyPipeline (device->dev, octx->fisheye, 0);
|
||||
free (octx->frames.a);
|
||||
free (octx);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue