mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 23:52:22 +00:00
[vulkan] Implement order implement transparency
It's a bit flaky for particles, especially at higher frame rates, but that's due to supporting only 64 overlapping pixels. A reasonable solution is probably switching to a priority heap for the "sort" and upping the limit.
This commit is contained in:
parent
ecd5e1de9f
commit
00cade072c
27 changed files with 694 additions and 50 deletions
|
@ -21,7 +21,9 @@ typedef struct qfv_bufferbarrier_s {
|
||||||
// image layout transitions
|
// image layout transitions
|
||||||
enum {
|
enum {
|
||||||
qfv_LT_Undefined_to_TransferDst,
|
qfv_LT_Undefined_to_TransferDst,
|
||||||
|
qfv_LT_Undefined_to_General,
|
||||||
qfv_LT_TransferDst_to_TransferSrc,
|
qfv_LT_TransferDst_to_TransferSrc,
|
||||||
|
qfv_LT_TransferDst_to_General,
|
||||||
qfv_LT_TransferDst_to_ShaderReadOnly,
|
qfv_LT_TransferDst_to_ShaderReadOnly,
|
||||||
qfv_LT_TransferSrc_to_ShaderReadOnly,
|
qfv_LT_TransferSrc_to_ShaderReadOnly,
|
||||||
qfv_LT_ShaderReadOnly_to_TransferDst,
|
qfv_LT_ShaderReadOnly_to_TransferDst,
|
||||||
|
@ -35,6 +37,7 @@ enum {
|
||||||
qfv_BB_TransferWrite_to_VertexAttrRead,
|
qfv_BB_TransferWrite_to_VertexAttrRead,
|
||||||
qfv_BB_TransferWrite_to_IndexRead,
|
qfv_BB_TransferWrite_to_IndexRead,
|
||||||
qfv_BB_TransferWrite_to_UniformRead,
|
qfv_BB_TransferWrite_to_UniformRead,
|
||||||
|
qfv_BB_TransferWrite_to_ShaderRW,
|
||||||
qfv_BB_ShaderRW_to_ShaderRO,
|
qfv_BB_ShaderRW_to_ShaderRO,
|
||||||
qfv_BB_ShaderRW_to_ShaderRO_VA,
|
qfv_BB_ShaderRW_to_ShaderRO_VA,
|
||||||
qfv_BB_ShaderRO_to_ShaderWrite,
|
qfv_BB_ShaderRO_to_ShaderWrite,
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
#ifndef __QF_Vulkan_renderpass_h
|
#ifndef __QF_Vulkan_renderpass_h
|
||||||
#define __QF_Vulkan_renderpass_h
|
#define __QF_Vulkan_renderpass_h
|
||||||
|
|
||||||
|
#ifndef VK_NO_PROTOTYPES
|
||||||
|
#define VK_NO_PROTOTYPES
|
||||||
|
#endif
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
#include "QF/darray.h"
|
#include "QF/darray.h"
|
||||||
#include "QF/simd/types.h"
|
#include "QF/simd/types.h"
|
||||||
|
|
||||||
|
|
61
include/QF/Vulkan/qf_translucent.h
Normal file
61
include/QF/Vulkan/qf_translucent.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef __QF_Vulkan_qf_translucent_h
|
||||||
|
#define __QF_Vulkan_qf_translucent_h
|
||||||
|
|
||||||
|
#include "QF/darray.h"
|
||||||
|
|
||||||
|
#include "QF/simd/types.h"
|
||||||
|
|
||||||
|
#include "QF/Vulkan/command.h"
|
||||||
|
|
||||||
|
typedef struct qfv_transfrag_s {
|
||||||
|
vec4f_t color;
|
||||||
|
float depth;
|
||||||
|
int32_t next;
|
||||||
|
} qfv_transfrag_t;
|
||||||
|
|
||||||
|
typedef struct qfv_transtate_s {
|
||||||
|
int32_t numFragments;
|
||||||
|
int32_t maxFragments;
|
||||||
|
} qfv_transtate_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QFV_translucentClear,
|
||||||
|
QFV_translucentBlend,
|
||||||
|
|
||||||
|
QFV_translucentNumPasses
|
||||||
|
} QFV_TranslucentSubpass;
|
||||||
|
|
||||||
|
typedef struct translucentframe_s {
|
||||||
|
VkDescriptorSet descriptors;
|
||||||
|
VkImage heads;
|
||||||
|
VkBuffer state;
|
||||||
|
qfv_cmdbufferset_t cmdSet;
|
||||||
|
} translucentframe_t;
|
||||||
|
|
||||||
|
typedef struct translucentframeset_s
|
||||||
|
DARRAY_TYPE (translucentframe_t) translucentframeset_t;
|
||||||
|
|
||||||
|
typedef struct translucentctx_s {
|
||||||
|
translucentframeset_t frames;
|
||||||
|
|
||||||
|
struct qfv_resource_s *resources;
|
||||||
|
|
||||||
|
VkPipeline pipeline;
|
||||||
|
VkPipelineLayout layout;
|
||||||
|
VkDescriptorPool pool;
|
||||||
|
VkDescriptorSetLayout setLayout;
|
||||||
|
} translucentctx_t;
|
||||||
|
|
||||||
|
struct vulkan_ctx_s;
|
||||||
|
struct qfv_renderframe_s;
|
||||||
|
|
||||||
|
void Vulkan_Translucent_Init (struct vulkan_ctx_s *ctx);
|
||||||
|
void Vulkan_Translucent_Shutdown (struct vulkan_ctx_s *ctx);
|
||||||
|
void Vulkan_Translucent_Draw (struct qfv_renderframe_s *rFrame);
|
||||||
|
VkDescriptorSet Vulkan_Translucent_Descriptors (struct vulkan_ctx_s *ctx,
|
||||||
|
int frame)__attribute__((pure));
|
||||||
|
void Vulkan_Translucent_CreateBuffers (struct vulkan_ctx_s *ctx,
|
||||||
|
VkExtent2D extent);
|
||||||
|
void Vulkan_Translucent_CreateRenderPasses (struct vulkan_ctx_s *ctx);
|
||||||
|
|
||||||
|
#endif//__QF_Vulkan_qf_translucent_h
|
|
@ -42,17 +42,19 @@ enum {
|
||||||
QFV_rp_particles,
|
QFV_rp_particles,
|
||||||
QFV_rp_shadowmap,
|
QFV_rp_shadowmap,
|
||||||
QFV_rp_preoutput,
|
QFV_rp_preoutput,
|
||||||
|
QFV_rp_translucent,
|
||||||
QFV_rp_main,
|
QFV_rp_main,
|
||||||
QFV_rp_output,
|
QFV_rp_output,
|
||||||
};
|
};
|
||||||
|
|
||||||
//FIXME location
|
//FIXME location
|
||||||
typedef enum {
|
typedef enum {
|
||||||
QFV_passDepth, // geometry
|
QFV_passDepth, // geometry
|
||||||
QFV_passTranslucent, // geometry
|
QFV_passTranslucentFrag, // geometry
|
||||||
QFV_passGBuffer, // geometry
|
QFV_passGBuffer, // geometry
|
||||||
QFV_passLighting, // single triangle
|
QFV_passLighting, // single triangle
|
||||||
QFV_passCompose, // single triangle
|
QFV_passTranslucentFinal, // single triangle
|
||||||
|
QFV_passCompose, // single triangle
|
||||||
|
|
||||||
QFV_NumPasses
|
QFV_NumPasses
|
||||||
} QFV_Subpass;
|
} QFV_Subpass;
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct vulkan_ctx_s {
|
||||||
struct scriptctx_s *script_context;
|
struct scriptctx_s *script_context;
|
||||||
struct texturectx_s *texture_context;
|
struct texturectx_s *texture_context;
|
||||||
struct matrixctx_s *matrix_context;
|
struct matrixctx_s *matrix_context;
|
||||||
|
struct translucentctx_s *translucent_context;
|
||||||
struct aliasctx_s *alias_context;
|
struct aliasctx_s *alias_context;
|
||||||
struct bspctx_s *bsp_context;
|
struct bspctx_s *bsp_context;
|
||||||
struct iqmctx_s *iqm_context;
|
struct iqmctx_s *iqm_context;
|
||||||
|
|
|
@ -254,6 +254,7 @@ libs_video_renderer_librender_vulkan_la_SOURCES = \
|
||||||
libs/video/renderer/vulkan/vulkan_scene.c \
|
libs/video/renderer/vulkan/vulkan_scene.c \
|
||||||
libs/video/renderer/vulkan/vulkan_sprite.c \
|
libs/video/renderer/vulkan/vulkan_sprite.c \
|
||||||
libs/video/renderer/vulkan/vulkan_texture.c \
|
libs/video/renderer/vulkan/vulkan_texture.c \
|
||||||
|
libs/video/renderer/vulkan/vulkan_translucent.c \
|
||||||
libs/video/renderer/vulkan/vulkan_vid_common.c
|
libs/video/renderer/vulkan/vulkan_vid_common.c
|
||||||
|
|
||||||
libs/video/renderer/vulkan/vkparse.lo: \
|
libs/video/renderer/vulkan/vkparse.lo: \
|
||||||
|
@ -339,6 +340,10 @@ lightingf_src = $(vkshaderpath)/lighting.frag
|
||||||
lightingf_c = $(vkshaderpath)/lighting.frag.spvc
|
lightingf_c = $(vkshaderpath)/lighting.frag.spvc
|
||||||
composef_src = $(vkshaderpath)/compose.frag
|
composef_src = $(vkshaderpath)/compose.frag
|
||||||
composef_c = $(vkshaderpath)/compose.frag.spvc
|
composef_c = $(vkshaderpath)/compose.frag.spvc
|
||||||
|
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_src = $(vkshaderpath)/alias.vert
|
||||||
aliasv_c = $(vkshaderpath)/alias.vert.spvc
|
aliasv_c = $(vkshaderpath)/alias.vert.spvc
|
||||||
aliasf_src = $(vkshaderpath)/alias.frag
|
aliasf_src = $(vkshaderpath)/alias.frag
|
||||||
|
@ -378,7 +383,7 @@ $(partphysicsc_c): $(partphysicsc_src)
|
||||||
$(partupdatec_c): $(partupdatec_src)
|
$(partupdatec_c): $(partupdatec_src)
|
||||||
$(particlev_c): $(particlev_src)
|
$(particlev_c): $(particlev_src)
|
||||||
$(particleg_c): $(particleg_src)
|
$(particleg_c): $(particleg_src)
|
||||||
$(particlef_c): $(particlef_src)
|
$(particlef_c): $(particlef_src) $(oit_store) $(oit_h)
|
||||||
|
|
||||||
$(sprite_gbufv_c): $(sprite_gbufv_src)
|
$(sprite_gbufv_c): $(sprite_gbufv_src)
|
||||||
|
|
||||||
|
@ -408,14 +413,16 @@ $(bsp_gbuff_c): $(bsp_gbuff_src)
|
||||||
|
|
||||||
$(bsp_shadow_c): $(bsp_shadow_src)
|
$(bsp_shadow_c): $(bsp_shadow_src)
|
||||||
|
|
||||||
$(bsp_skyf_c): $(bsp_skyf_src)
|
$(bsp_skyf_c): $(bsp_skyf_src) $(oit_store) $(oit_h)
|
||||||
|
|
||||||
$(bsp_turbf_c): $(bsp_turbf_src)
|
$(bsp_turbf_c): $(bsp_turbf_src) $(oit_store) $(oit_h)
|
||||||
|
|
||||||
$(lightingf_c): $(lightingf_src)
|
$(lightingf_c): $(lightingf_src)
|
||||||
|
|
||||||
$(composef_c): $(composef_src)
|
$(composef_c): $(composef_src)
|
||||||
|
|
||||||
|
$(oit_blendf_c): $(oit_blendf_src) $(oit_h)
|
||||||
|
|
||||||
$(aliasv_c): $(aliasv_src)
|
$(aliasv_c): $(aliasv_src)
|
||||||
|
|
||||||
$(alias_depth_c): $(alias_depth_src)
|
$(alias_depth_c): $(alias_depth_src)
|
||||||
|
@ -471,6 +478,7 @@ vkshader_c = \
|
||||||
$(bsp_turbf_c) \
|
$(bsp_turbf_c) \
|
||||||
$(lightingf_c) \
|
$(lightingf_c) \
|
||||||
$(composef_c) \
|
$(composef_c) \
|
||||||
|
$(oit_blendf_c) \
|
||||||
$(aliasv_c) \
|
$(aliasv_c) \
|
||||||
$(alias_depth_c) \
|
$(alias_depth_c) \
|
||||||
$(aliasf_c) \
|
$(aliasf_c) \
|
||||||
|
@ -537,6 +545,7 @@ EXTRA_DIST += \
|
||||||
libs/video/renderer/vulkan/shader/bsp_sky.frag \
|
libs/video/renderer/vulkan/shader/bsp_sky.frag \
|
||||||
libs/video/renderer/vulkan/shader/bsp_turb.frag \
|
libs/video/renderer/vulkan/shader/bsp_turb.frag \
|
||||||
libs/video/renderer/vulkan/shader/compose.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.frag \
|
||||||
libs/video/renderer/vulkan/shader/iqm.vert \
|
libs/video/renderer/vulkan/shader/iqm.vert \
|
||||||
libs/video/renderer/vulkan/shader/lighting.frag \
|
libs/video/renderer/vulkan/shader/lighting.frag \
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include "QF/Vulkan/qf_scene.h"
|
#include "QF/Vulkan/qf_scene.h"
|
||||||
#include "QF/Vulkan/qf_sprite.h"
|
#include "QF/Vulkan/qf_sprite.h"
|
||||||
#include "QF/Vulkan/qf_texture.h"
|
#include "QF/Vulkan/qf_texture.h"
|
||||||
|
#include "QF/Vulkan/qf_translucent.h"
|
||||||
#include "QF/Vulkan/qf_vid.h"
|
#include "QF/Vulkan/qf_vid.h"
|
||||||
#include "QF/Vulkan/capture.h"
|
#include "QF/Vulkan/capture.h"
|
||||||
#include "QF/Vulkan/command.h"
|
#include "QF/Vulkan/command.h"
|
||||||
|
@ -109,6 +110,7 @@ vulkan_R_Init (void)
|
||||||
Vulkan_Sprite_Init (vulkan_ctx);
|
Vulkan_Sprite_Init (vulkan_ctx);
|
||||||
Vulkan_Draw_Init (vulkan_ctx);
|
Vulkan_Draw_Init (vulkan_ctx);
|
||||||
Vulkan_Lighting_Init (vulkan_ctx);
|
Vulkan_Lighting_Init (vulkan_ctx);
|
||||||
|
Vulkan_Translucent_Init (vulkan_ctx);
|
||||||
Vulkan_Compose_Init (vulkan_ctx);
|
Vulkan_Compose_Init (vulkan_ctx);
|
||||||
|
|
||||||
Skin_Init ();
|
Skin_Init ();
|
||||||
|
@ -740,6 +742,7 @@ vulkan_vid_render_shutdown (void)
|
||||||
Mod_ClearAll ();
|
Mod_ClearAll ();
|
||||||
|
|
||||||
Vulkan_Compose_Shutdown (vulkan_ctx);
|
Vulkan_Compose_Shutdown (vulkan_ctx);
|
||||||
|
Vulkan_Translucent_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Lighting_Shutdown (vulkan_ctx);
|
Vulkan_Lighting_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Draw_Shutdown (vulkan_ctx);
|
Vulkan_Draw_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Sprite_Shutdown (vulkan_ctx);
|
Vulkan_Sprite_Shutdown (vulkan_ctx);
|
||||||
|
|
|
@ -44,6 +44,19 @@ const qfv_imagebarrier_t imageBarriers[] = {
|
||||||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[qfv_LT_Undefined_to_General] = {
|
||||||
|
.srcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||||
|
.dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
.barrier = {
|
||||||
|
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0,
|
||||||
|
0,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, 0,
|
||||||
|
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||||
|
},
|
||||||
|
},
|
||||||
[qfv_LT_TransferDst_to_TransferSrc] = {
|
[qfv_LT_TransferDst_to_TransferSrc] = {
|
||||||
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
.dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
.dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
@ -57,6 +70,19 @@ const qfv_imagebarrier_t imageBarriers[] = {
|
||||||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[qfv_LT_TransferDst_to_General] = {
|
||||||
|
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
.dstStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
|
.barrier = {
|
||||||
|
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
VK_ACCESS_SHADER_READ_BIT,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, 0,
|
||||||
|
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||||
|
},
|
||||||
|
},
|
||||||
[qfv_LT_TransferDst_to_ShaderReadOnly] = {
|
[qfv_LT_TransferDst_to_ShaderReadOnly] = {
|
||||||
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
.dstStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
.dstStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
|
@ -164,6 +190,16 @@ const qfv_bufferbarrier_t bufferBarriers[] = {
|
||||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[qfv_BB_TransferWrite_to_ShaderRW] = {
|
||||||
|
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
.dstStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
|
.barrier = {
|
||||||
|
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
},
|
||||||
|
},
|
||||||
[qfv_BB_ShaderRW_to_ShaderRO] = {
|
[qfv_BB_ShaderRW_to_ShaderRO] = {
|
||||||
.srcStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
.srcStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
.dstStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
.dstStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
|
|
@ -156,6 +156,7 @@ QFV_CreateDevice (vulkan_ctx_t *ctx, const char **extensions)
|
||||||
VkPhysicalDeviceFeatures features = {
|
VkPhysicalDeviceFeatures features = {
|
||||||
.geometryShader = 1,
|
.geometryShader = 1,
|
||||||
.multiViewport = 1,
|
.multiViewport = 1,
|
||||||
|
.fragmentStoresAndAtomics = 1,
|
||||||
};
|
};
|
||||||
VkDeviceCreateInfo dCreateInfo = {
|
VkDeviceCreateInfo dCreateInfo = {
|
||||||
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, &multiview_features, 0,
|
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, &multiview_features, 0,
|
||||||
|
|
|
@ -233,6 +233,20 @@
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
oit_pool = {
|
||||||
|
flags = 0;
|
||||||
|
maxSets = $frames.size;
|
||||||
|
bindings = (
|
||||||
|
{
|
||||||
|
type = storage_buffer;
|
||||||
|
descriptorCount = "2z * $frames.size";
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = storage_image;
|
||||||
|
descriptorCount = "1z * $frames.size";
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
compose_attach_pool = {
|
compose_attach_pool = {
|
||||||
flags = 0;
|
flags = 0;
|
||||||
maxSets = $frames.size;
|
maxSets = $frames.size;
|
||||||
|
@ -293,6 +307,28 @@
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
oit_set = {
|
||||||
|
bindings = (
|
||||||
|
{
|
||||||
|
binding = 0;
|
||||||
|
descriptorType = storage_buffer;
|
||||||
|
descriptorCount = 1;
|
||||||
|
stageFlags = fragment;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
binding = 1;
|
||||||
|
descriptorType = storage_buffer;
|
||||||
|
descriptorCount = 1;
|
||||||
|
stageFlags = fragment;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
binding = 2;
|
||||||
|
descriptorType = storage_image;
|
||||||
|
descriptorCount = 1;
|
||||||
|
stageFlags = fragment;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
entity_set = {
|
entity_set = {
|
||||||
bindings = (
|
bindings = (
|
||||||
{
|
{
|
||||||
|
@ -433,7 +469,7 @@
|
||||||
setLayouts = (matrix_set);
|
setLayouts = (matrix_set);
|
||||||
};
|
};
|
||||||
quakebsp_layout = {
|
quakebsp_layout = {
|
||||||
setLayouts = (matrix_set, entity_set, texture_set, texture_set);
|
setLayouts = (matrix_set, entity_set, oit_set, texture_set, texture_set);
|
||||||
pushConstantRanges = (
|
pushConstantRanges = (
|
||||||
{
|
{
|
||||||
stageFlags = fragment;
|
stageFlags = fragment;
|
||||||
|
@ -490,6 +526,9 @@
|
||||||
lighting_layout = {
|
lighting_layout = {
|
||||||
setLayouts = (lighting_attach, lighting_lights, lighting_shadow);
|
setLayouts = (lighting_attach, lighting_lights, lighting_shadow);
|
||||||
};
|
};
|
||||||
|
oit_layout = {
|
||||||
|
setLayouts = (oit_set);
|
||||||
|
};
|
||||||
compose_layout = {
|
compose_layout = {
|
||||||
setLayouts = (compose_attach);
|
setLayouts = (compose_attach);
|
||||||
};
|
};
|
||||||
|
@ -507,7 +546,7 @@
|
||||||
setLayouts = (particle_set, particle_set, particle_set);
|
setLayouts = (particle_set, particle_set, particle_set);
|
||||||
};
|
};
|
||||||
partdraw_layout = {
|
partdraw_layout = {
|
||||||
setLayouts = (matrix_set, texture_set);
|
setLayouts = (matrix_set, texture_set, oit_set);
|
||||||
pushConstantRanges = (
|
pushConstantRanges = (
|
||||||
{
|
{
|
||||||
stageFlags = vertex;
|
stageFlags = vertex;
|
||||||
|
@ -1225,9 +1264,22 @@
|
||||||
);
|
);
|
||||||
layout = lighting_layout;
|
layout = lighting_layout;
|
||||||
};
|
};
|
||||||
compose = {
|
oit = {
|
||||||
@inherit = $properties.pipelines.comp_base;
|
@inherit = $properties.pipelines.comp_base;
|
||||||
subpass = 4;
|
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;
|
||||||
stages = (
|
stages = (
|
||||||
$properties.fstriangle.vertexStage,
|
$properties.fstriangle.vertexStage,
|
||||||
{
|
{
|
||||||
|
|
|
@ -146,6 +146,7 @@
|
||||||
{ name = translucent; color = "[ 0.25, 0.25, 0.6, 1]" },
|
{ name = translucent; color = "[ 0.25, 0.25, 0.6, 1]" },
|
||||||
{ name = g-buffef; color = "[ 0.3, 0.7, 0.3, 1]" },
|
{ name = g-buffef; color = "[ 0.3, 0.7, 0.3, 1]" },
|
||||||
{ name = lighting; color = "[ 0.8, 0.8, 0.8, 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]" },
|
{ name = compose; color = "[ 0.7, 0.3, 0.3, 1]" },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -200,14 +201,8 @@
|
||||||
layout = depth_stencil_attachment_optimal;
|
layout = depth_stencil_attachment_optimal;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ // 1 translucent
|
{ // 1 translucent-frags
|
||||||
pipelineBindPoint = graphics;
|
pipelineBindPoint = graphics;
|
||||||
colorAttachments = (
|
|
||||||
{ // translucent
|
|
||||||
attachment = 6;
|
|
||||||
layout = color_attachment_optimal;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
depthStencilAttachment = {
|
depthStencilAttachment = {
|
||||||
attachment = 0;
|
attachment = 0;
|
||||||
layout = depth_stencil_read_only_optimal;
|
layout = depth_stencil_read_only_optimal;
|
||||||
|
@ -272,7 +267,17 @@
|
||||||
);
|
);
|
||||||
preserveAttachments = (6);
|
preserveAttachments = (6);
|
||||||
},
|
},
|
||||||
{ // 4 compose
|
{ // 4 translucent-final
|
||||||
|
pipelineBindPoint = graphics;
|
||||||
|
colorAttachments = (
|
||||||
|
{ // translucent
|
||||||
|
attachment = 6;
|
||||||
|
layout = color_attachment_optimal;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
preserveAttachments = (1, 2, 3, 4, 5);
|
||||||
|
},
|
||||||
|
{ // 5 compose
|
||||||
pipelineBindPoint = graphics;
|
pipelineBindPoint = graphics;
|
||||||
inputAttachments = (
|
inputAttachments = (
|
||||||
{ // opaque
|
{ // opaque
|
||||||
|
@ -305,11 +310,11 @@
|
||||||
},
|
},
|
||||||
/*{
|
/*{
|
||||||
srcSubpass = ~0u; // external
|
srcSubpass = ~0u; // external
|
||||||
dstSubpass = 1; // translucent
|
dstSubpass = 1; // translucent-frags
|
||||||
srcStageMask = compute_shader;
|
srcStageMask = transfer;
|
||||||
dstStageMask = vertex_input|draw_indirect;
|
dstStageMask = fragment_shader|early_fragment_tests;
|
||||||
srcAccessMask = shader_write;
|
srcAccessMask = transfer_write;
|
||||||
dstAccessMask = vertex_attribute_read|indirect_command_read;
|
dstAccessMask = shader_read|shader_write;
|
||||||
},*/
|
},*/
|
||||||
{
|
{
|
||||||
srcSubpass = 0; // depth
|
srcSubpass = 0; // depth
|
||||||
|
@ -331,7 +336,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
srcSubpass = 3; // lighting
|
srcSubpass = 3; // lighting
|
||||||
dstSubpass = 4; // compose
|
dstSubpass = 5; // compose
|
||||||
srcStageMask = color_attachment_output;
|
srcStageMask = color_attachment_output;
|
||||||
dstStageMask = fragment_shader;
|
dstStageMask = fragment_shader;
|
||||||
srcAccessMask = color_attachment_write;
|
srcAccessMask = color_attachment_write;
|
||||||
|
@ -339,8 +344,17 @@
|
||||||
dependencyFlags = by_region;
|
dependencyFlags = by_region;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
srcSubpass = 1; // translucent
|
srcSubpass = 1; // translucent-frags
|
||||||
dstSubpass = 4; // compose
|
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
|
||||||
srcStageMask = color_attachment_output;
|
srcStageMask = color_attachment_output;
|
||||||
dstStageMask = fragment_shader;
|
dstStageMask = fragment_shader;
|
||||||
srcAccessMask = color_attachment_write;
|
srcAccessMask = color_attachment_write;
|
||||||
|
|
|
@ -95,6 +95,8 @@ static
|
||||||
static
|
static
|
||||||
#include "libs/video/renderer/vulkan/shader/compose.frag.spvc"
|
#include "libs/video/renderer/vulkan/shader/compose.frag.spvc"
|
||||||
static
|
static
|
||||||
|
#include "libs/video/renderer/vulkan/shader/oit_blend.frag.spvc"
|
||||||
|
static
|
||||||
#include "libs/video/renderer/vulkan/shader/alias.vert.spvc"
|
#include "libs/video/renderer/vulkan/shader/alias.vert.spvc"
|
||||||
static
|
static
|
||||||
#include "libs/video/renderer/vulkan/shader/alias_depth.vert.spvc"
|
#include "libs/video/renderer/vulkan/shader/alias_depth.vert.spvc"
|
||||||
|
@ -156,6 +158,7 @@ static shaderdata_t builtin_shaders[] = {
|
||||||
{ "bsp_turb.frag", bsp_turb_frag, sizeof (bsp_turb_frag) },
|
{ "bsp_turb.frag", bsp_turb_frag, sizeof (bsp_turb_frag) },
|
||||||
{ "lighting.frag", lighting_frag, sizeof (lighting_frag) },
|
{ "lighting.frag", lighting_frag, sizeof (lighting_frag) },
|
||||||
{ "compose.frag", compose_frag, sizeof (compose_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.vert", alias_vert, sizeof (alias_vert) },
|
||||||
{ "alias_depth.vert", alias_depth_vert, sizeof (alias_depth_vert) },
|
{ "alias_depth.vert", alias_depth_vert, sizeof (alias_depth_vert) },
|
||||||
{ "alias.frag", alias_frag, sizeof (alias_frag) },
|
{ "alias.frag", alias_frag, sizeof (alias_frag) },
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout (set = 2, binding = 0) uniform sampler2DArray Texture;
|
layout (set = 3, binding = 0) uniform sampler2DArray Texture;
|
||||||
|
|
||||||
layout (push_constant) uniform PushConstants {
|
layout (push_constant) uniform PushConstants {
|
||||||
vec4 fog;
|
vec4 fog;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#include "oit_store.finc"
|
||||||
|
|
||||||
layout (constant_id = 0) const bool doSkyBox = false;
|
layout (constant_id = 0) const bool doSkyBox = false;
|
||||||
layout (constant_id = 1) const bool doSkySheet = false;
|
layout (constant_id = 1) const bool doSkySheet = false;
|
||||||
|
|
||||||
layout (set = 2, binding = 0) uniform sampler2DArray SkySheet;
|
layout (set = 3, binding = 0) uniform sampler2DArray SkySheet;
|
||||||
layout (set = 3, binding = 0) uniform samplerCube SkyBox;
|
layout (set = 4, binding = 0) uniform samplerCube SkyBox;
|
||||||
|
|
||||||
layout (push_constant) uniform PushConstants {
|
layout (push_constant) uniform PushConstants {
|
||||||
vec4 fog;
|
vec4 fog;
|
||||||
|
@ -17,7 +19,8 @@ layout (location = 0) in vec4 tl_st;
|
||||||
layout (location = 1) in vec3 direction;
|
layout (location = 1) in vec3 direction;
|
||||||
layout (location = 2) in vec4 color;
|
layout (location = 2) in vec4 color;
|
||||||
|
|
||||||
layout (location = 0) out vec4 frag_color;
|
layout(early_fragment_tests) in;
|
||||||
|
//layout (location = 0) out vec4 frag_color;
|
||||||
|
|
||||||
const float SCALE = 189.0 / 64.0;
|
const float SCALE = 189.0 / 64.0;
|
||||||
|
|
||||||
|
@ -95,5 +98,6 @@ main (void)
|
||||||
} else {
|
} else {
|
||||||
c = vec4 (0, 0, 0, 1);
|
c = vec4 (0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
frag_color = c;//fogBlend (c);
|
//frag_color = c;//fogBlend (c);
|
||||||
|
StoreFrag (c, gl_FragCoord.z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#include "oit_store.finc"
|
||||||
|
|
||||||
layout (set = 2, binding = 0) uniform sampler2DArray Texture;
|
layout (set = 3, binding = 0) uniform sampler2DArray Texture;
|
||||||
|
|
||||||
layout (push_constant) uniform PushConstants {
|
layout (push_constant) uniform PushConstants {
|
||||||
vec4 fog;
|
vec4 fog;
|
||||||
|
@ -13,7 +15,8 @@ layout (location = 0) in vec4 tl_st;
|
||||||
layout (location = 1) in vec3 direction;
|
layout (location = 1) in vec3 direction;
|
||||||
layout (location = 2) in vec4 color;
|
layout (location = 2) in vec4 color;
|
||||||
|
|
||||||
layout (location = 0) out vec4 frag_color;
|
layout(early_fragment_tests) in;
|
||||||
|
//layout (location = 0) out vec4 frag_color;
|
||||||
|
|
||||||
const float PI = 3.14159265;
|
const float PI = 3.14159265;
|
||||||
const float SPEED = 20.0;
|
const float SPEED = 20.0;
|
||||||
|
@ -49,5 +52,6 @@ main (void)
|
||||||
float a = c.a * e.a * alpha;
|
float a = c.a * e.a * alpha;
|
||||||
c += e;
|
c += e;
|
||||||
c.a = a;
|
c.a = a;
|
||||||
frag_color = c * color;//fogBlend (c);
|
//frag_color = c * color;//fogBlend (c);
|
||||||
|
StoreFrag (c * color, gl_FragCoord.z);
|
||||||
}
|
}
|
||||||
|
|
20
libs/video/renderer/vulkan/shader/oit.h
Normal file
20
libs/video/renderer/vulkan/shader/oit.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef OIT_SET
|
||||||
|
#define OIT_SET 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct FragData {
|
||||||
|
vec4 color;
|
||||||
|
float depth;
|
||||||
|
int next;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (set = OIT_SET, binding = 0) coherent buffer FragCount {
|
||||||
|
int numFragments;
|
||||||
|
int maxFragments;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (set = OIT_SET, binding = 1) buffer Fragments {
|
||||||
|
FragData fragments[];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (set = OIT_SET, binding = 2, r32i) coherent uniform iimage2D heads;
|
40
libs/video/renderer/vulkan/shader/oit_blend.frag
Normal file
40
libs/video/renderer/vulkan/shader/oit_blend.frag
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
#define MAX_FRAGMENTS 64
|
||||||
|
FragData frags[MAX_FRAGMENTS];
|
||||||
|
int numFrags = 0;
|
||||||
|
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||||
|
int index = imageLoad (heads, coord).r;
|
||||||
|
|
||||||
|
//FIXME use a heap and prioritize closer fragments
|
||||||
|
while (index != -1 && numFrags < MAX_FRAGMENTS) {
|
||||||
|
frags[numFrags] = fragments[index];
|
||||||
|
numFrags++;
|
||||||
|
index = fragments[index].next;
|
||||||
|
}
|
||||||
|
//insertion sort
|
||||||
|
for (int i = 1; i < numFrags; i++) {
|
||||||
|
FragData toInsert = frags[i];
|
||||||
|
int j = i;
|
||||||
|
while (j > 0 && toInsert.depth > frags[j - 1].depth) {
|
||||||
|
frags[j] = frags[j - 1];
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
14
libs/video/renderer/vulkan/shader/oit_store.finc
Normal file
14
libs/video/renderer/vulkan/shader/oit_store.finc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "oit.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
StoreFrag (vec4 color, float depth)
|
||||||
|
{
|
||||||
|
int index = atomicAdd (numFragments, 1);
|
||||||
|
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||||
|
if (index < maxFragments) {
|
||||||
|
int prevIndex = imageAtomicExchange (heads, coord, index);
|
||||||
|
fragments[index].color = color;
|
||||||
|
fragments[index].depth = depth;
|
||||||
|
fragments[index].next = prevIndex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
#include "oit_store.finc"
|
||||||
|
|
||||||
layout (location = 0) in vec4 uv_tr;
|
layout (location = 0) in vec4 uv_tr;
|
||||||
layout (location = 1) in vec4 color;
|
layout (location = 1) in vec4 color;
|
||||||
|
|
||||||
layout (location = 0) out vec4 frag_color;
|
layout(early_fragment_tests) in;
|
||||||
|
|
||||||
void
|
void
|
||||||
main (void)
|
main (void)
|
||||||
|
@ -16,5 +18,5 @@ main (void)
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
c *= (a);
|
c *= (a);
|
||||||
frag_color = c;
|
StoreFrag (c, gl_FragCoord.z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ static const char * __attribute__((used)) alias_pass_names[] = {
|
||||||
static QFV_Subpass subpass_map[] = {
|
static QFV_Subpass subpass_map[] = {
|
||||||
QFV_passDepth, // QFV_aliasDepth
|
QFV_passDepth, // QFV_aliasDepth
|
||||||
QFV_passGBuffer, // QFV_aliasGBuffer
|
QFV_passGBuffer, // QFV_aliasGBuffer
|
||||||
QFV_passTranslucent, // QFV_aliasTranslucent
|
QFV_passTranslucentFrag,// QFV_aliasTranslucent
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "QF/Vulkan/qf_renderpass.h"
|
#include "QF/Vulkan/qf_renderpass.h"
|
||||||
#include "QF/Vulkan/qf_scene.h"
|
#include "QF/Vulkan/qf_scene.h"
|
||||||
#include "QF/Vulkan/qf_texture.h"
|
#include "QF/Vulkan/qf_texture.h"
|
||||||
|
#include "QF/Vulkan/qf_translucent.h"
|
||||||
#include "QF/Vulkan/buffer.h"
|
#include "QF/Vulkan/buffer.h"
|
||||||
#include "QF/Vulkan/barrier.h"
|
#include "QF/Vulkan/barrier.h"
|
||||||
#include "QF/Vulkan/command.h"
|
#include "QF/Vulkan/command.h"
|
||||||
|
@ -76,6 +77,9 @@
|
||||||
#include "r_internal.h"
|
#include "r_internal.h"
|
||||||
#include "vid_vulkan.h"
|
#include "vid_vulkan.h"
|
||||||
|
|
||||||
|
#define TEX_SET 3
|
||||||
|
#define SKYBOX_SET 4
|
||||||
|
|
||||||
typedef struct bsp_push_constants_s {
|
typedef struct bsp_push_constants_s {
|
||||||
quat_t fog;
|
quat_t fog;
|
||||||
float time;
|
float time;
|
||||||
|
@ -93,8 +97,8 @@ static const char * __attribute__((used)) bsp_pass_names[] = {
|
||||||
static QFV_Subpass subpass_map[] = {
|
static QFV_Subpass subpass_map[] = {
|
||||||
[QFV_bspDepth] = QFV_passDepth,
|
[QFV_bspDepth] = QFV_passDepth,
|
||||||
[QFV_bspGBuffer] = QFV_passGBuffer,
|
[QFV_bspGBuffer] = QFV_passGBuffer,
|
||||||
[QFV_bspSky] = QFV_passTranslucent,
|
[QFV_bspSky] = QFV_passTranslucentFrag,
|
||||||
[QFV_bspTurb] = QFV_passTranslucent,
|
[QFV_bspTurb] = QFV_passTranslucentFrag,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -828,9 +832,10 @@ bsp_begin_subpass (QFV_BspSubpass subpass, VkPipeline pipeline,
|
||||||
VkDescriptorSet sets[] = {
|
VkDescriptorSet sets[] = {
|
||||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||||
Vulkan_Scene_Descriptors (ctx),
|
Vulkan_Scene_Descriptors (ctx),
|
||||||
|
Vulkan_Translucent_Descriptors (ctx, ctx->curFrame),
|
||||||
};
|
};
|
||||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
layout, 0, 2, sets, 0, 0);
|
layout, 0, 3, sets, 0, 0);
|
||||||
|
|
||||||
//XXX glsl_Fog_GetColor (fog);
|
//XXX glsl_Fog_GetColor (fog);
|
||||||
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
|
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
|
||||||
|
@ -884,7 +889,7 @@ turb_begin (qfv_renderframe_t *rFrame)
|
||||||
|
|
||||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
|
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucentFrag],
|
||||||
bframe->cmdSet.a[QFV_bspTurb]);
|
bframe->cmdSet.a[QFV_bspTurb]);
|
||||||
|
|
||||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||||
|
@ -909,7 +914,7 @@ sky_begin (qfv_renderframe_t *rFrame)
|
||||||
|
|
||||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
|
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucentFrag],
|
||||||
bframe->cmdSet.a[QFV_bspSky]);
|
bframe->cmdSet.a[QFV_bspSky]);
|
||||||
|
|
||||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||||
|
@ -1020,7 +1025,7 @@ draw_queue (bsp_pass_t *pass, int queue, VkPipelineLayout layout,
|
||||||
__auto_type d = pass->draw_queues[queue].a[i];
|
__auto_type d = pass->draw_queues[queue].a[i];
|
||||||
if (pass->textures) {
|
if (pass->textures) {
|
||||||
vulktex_t *tex = pass->textures->a[d.tex_id];
|
vulktex_t *tex = pass->textures->a[d.tex_id];
|
||||||
bind_texture (tex, 2, layout, dfunc, cmd);
|
bind_texture (tex, TEX_SET, layout, dfunc, cmd);
|
||||||
}
|
}
|
||||||
dfunc->vkCmdDrawIndexed (cmd, d.index_count, d.instance_count,
|
dfunc->vkCmdDrawIndexed (cmd, d.index_count, d.instance_count,
|
||||||
d.first_index, 0, d.first_instance);
|
d.first_index, 0, d.first_instance);
|
||||||
|
@ -1189,7 +1194,7 @@ Vulkan_DrawSky (qfv_renderframe_t *rFrame)
|
||||||
|
|
||||||
sky_begin (rFrame);
|
sky_begin (rFrame);
|
||||||
vulktex_t skybox = { .descriptor = bctx->skybox_descriptor };
|
vulktex_t skybox = { .descriptor = bctx->skybox_descriptor };
|
||||||
bind_texture (&skybox, 3, bctx->layout, dfunc,
|
bind_texture (&skybox, SKYBOX_SET, bctx->layout, dfunc,
|
||||||
bframe->cmdSet.a[QFV_bspSky]);
|
bframe->cmdSet.a[QFV_bspSky]);
|
||||||
bsp_push_constants_t frag_constants = { .time = vr_data.realtime };
|
bsp_push_constants_t frag_constants = { .time = vr_data.realtime };
|
||||||
push_fragconst (&frag_constants, bctx->layout, device,
|
push_fragconst (&frag_constants, bctx->layout, device,
|
||||||
|
|
|
@ -70,7 +70,7 @@ static const char * __attribute__((used)) iqm_pass_names[] = {
|
||||||
static QFV_Subpass subpass_map[] = {
|
static QFV_Subpass subpass_map[] = {
|
||||||
QFV_passDepth, // QFV_iqmDepth
|
QFV_passDepth, // QFV_iqmDepth
|
||||||
QFV_passGBuffer, // QFV_iqmGBuffer
|
QFV_passGBuffer, // QFV_iqmGBuffer
|
||||||
QFV_passTranslucent, // QFV_iqmTranslucent
|
QFV_passTranslucentFrag,// QFV_iqmTranslucent
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "QF/Vulkan/qf_renderpass.h"
|
#include "QF/Vulkan/qf_renderpass.h"
|
||||||
#include "QF/Vulkan/qf_scene.h"
|
#include "QF/Vulkan/qf_scene.h"
|
||||||
#include "QF/Vulkan/qf_sprite.h"
|
#include "QF/Vulkan/qf_sprite.h"
|
||||||
|
#include "QF/Vulkan/qf_translucent.h"
|
||||||
#include "QF/Vulkan/qf_vid.h"
|
#include "QF/Vulkan/qf_vid.h"
|
||||||
#include "QF/Vulkan/swapchain.h"
|
#include "QF/Vulkan/swapchain.h"
|
||||||
|
|
||||||
|
@ -140,6 +141,7 @@ Vulkan_RenderView (qfv_renderframe_t *rFrame)
|
||||||
Vulkan_Bsp_Flush (ctx);
|
Vulkan_Bsp_Flush (ctx);
|
||||||
Vulkan_RenderEntities (r_ent_queue, rFrame);
|
Vulkan_RenderEntities (r_ent_queue, rFrame);
|
||||||
Vulkan_Scene_Flush (ctx);
|
Vulkan_Scene_Flush (ctx);
|
||||||
|
Vulkan_Translucent_Draw (rFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -187,4 +189,5 @@ Vulkan_Main_CreateRenderPasses (vulkan_ctx_t *ctx)
|
||||||
DARRAY_APPEND (&ctx->renderPasses, rp);
|
DARRAY_APPEND (&ctx->renderPasses, rp);
|
||||||
|
|
||||||
Vulkan_Output_SetInput (ctx, rp->output.view);
|
Vulkan_Output_SetInput (ctx, rp->output.view);
|
||||||
|
Vulkan_Translucent_CreateBuffers (ctx, rp->output.extent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "QF/Vulkan/qf_palette.h"
|
#include "QF/Vulkan/qf_palette.h"
|
||||||
#include "QF/Vulkan/qf_particles.h"
|
#include "QF/Vulkan/qf_particles.h"
|
||||||
#include "QF/Vulkan/qf_renderpass.h"
|
#include "QF/Vulkan/qf_renderpass.h"
|
||||||
|
#include "QF/Vulkan/qf_translucent.h"
|
||||||
|
|
||||||
#include "r_internal.h"
|
#include "r_internal.h"
|
||||||
#include "vid_vulkan.h"
|
#include "vid_vulkan.h"
|
||||||
|
@ -83,7 +84,7 @@ particle_begin_subpass (VkPipeline pipeline, qfv_renderframe_t *rFrame)
|
||||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||||
VkCommandBufferInheritanceInfo inherit = {
|
VkCommandBufferInheritanceInfo inherit = {
|
||||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||||
rFrame->renderpass->renderpass, QFV_passTranslucent,
|
rFrame->renderpass->renderpass, QFV_passTranslucentFrag,
|
||||||
rFrame->framebuffer,
|
rFrame->framebuffer,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
};
|
};
|
||||||
|
@ -100,9 +101,10 @@ particle_begin_subpass (VkPipeline pipeline, qfv_renderframe_t *rFrame)
|
||||||
VkDescriptorSet sets[] = {
|
VkDescriptorSet sets[] = {
|
||||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||||
Vulkan_Palette_Descriptor (ctx),
|
Vulkan_Palette_Descriptor (ctx),
|
||||||
|
Vulkan_Translucent_Descriptors (ctx, ctx->curFrame),
|
||||||
};
|
};
|
||||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
pctx->draw_layout, 0, 2, sets, 0, 0);
|
pctx->draw_layout, 0, 3, sets, 0, 0);
|
||||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
||||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
||||||
}
|
}
|
||||||
|
@ -128,7 +130,7 @@ Vulkan_DrawParticles (qfv_renderframe_t *rFrame)
|
||||||
particleframe_t *pframe = &pctx->frames.a[curFrame];
|
particleframe_t *pframe = &pctx->frames.a[curFrame];
|
||||||
VkCommandBuffer cmd = pframe->cmdSet.a[0];
|
VkCommandBuffer cmd = pframe->cmdSet.a[0];
|
||||||
|
|
||||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
|
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucentFrag],
|
||||||
pframe->cmdSet.a[0]);
|
pframe->cmdSet.a[0]);
|
||||||
|
|
||||||
particle_begin_subpass (pctx->draw, rFrame);
|
particle_begin_subpass (pctx->draw, rFrame);
|
||||||
|
|
|
@ -76,7 +76,7 @@ static const char * __attribute__((used)) sprite_pass_names[] = {
|
||||||
static QFV_Subpass subpass_map[] = {
|
static QFV_Subpass subpass_map[] = {
|
||||||
QFV_passDepth, // QFV_spriteDepth
|
QFV_passDepth, // QFV_spriteDepth
|
||||||
QFV_passGBuffer, // QFV_spriteGBuffer
|
QFV_passGBuffer, // QFV_spriteGBuffer
|
||||||
QFV_passTranslucent, // QFV_spriteTranslucent
|
QFV_passTranslucentFrag,// QFV_spriteTranslucent
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
358
libs/video/renderer/vulkan/vulkan_translucent.c
Normal file
358
libs/video/renderer/vulkan/vulkan_translucent.c
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
/*
|
||||||
|
vulkan_translucent.c
|
||||||
|
|
||||||
|
Vulkan translucent pass pipeline
|
||||||
|
|
||||||
|
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2022/11/30
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "qfalloca.h"
|
||||||
|
|
||||||
|
#include "QF/cvar.h"
|
||||||
|
#include "QF/sys.h"
|
||||||
|
#include "QF/va.h"
|
||||||
|
|
||||||
|
#include "QF/Vulkan/qf_renderpass.h"
|
||||||
|
#include "QF/Vulkan/qf_translucent.h"
|
||||||
|
#include "QF/Vulkan/barrier.h"
|
||||||
|
#include "QF/Vulkan/debug.h"
|
||||||
|
#include "QF/Vulkan/descriptor.h"
|
||||||
|
#include "QF/Vulkan/device.h"
|
||||||
|
#include "QF/Vulkan/image.h"
|
||||||
|
#include "QF/Vulkan/instance.h"
|
||||||
|
#include "QF/Vulkan/resource.h"
|
||||||
|
#include "QF/Vulkan/staging.h"
|
||||||
|
|
||||||
|
#include "r_internal.h"
|
||||||
|
#include "vid_vulkan.h"
|
||||||
|
|
||||||
|
#define MAX_FRAGMENTS (1<<24)
|
||||||
|
|
||||||
|
static const char * __attribute__((used)) translucent_pass_names[] = {
|
||||||
|
"clear",
|
||||||
|
"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)
|
||||||
|
{
|
||||||
|
if (ctx->translucent_context) {//FIXME
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
|
||||||
|
qfvPushDebug (ctx, "translucent init");
|
||||||
|
|
||||||
|
translucentctx_t *tctx = calloc (1, sizeof (translucentctx_t));
|
||||||
|
ctx->translucent_context = tctx;
|
||||||
|
|
||||||
|
size_t frames = ctx->frames.size;
|
||||||
|
DARRAY_INIT (&tctx->frames, frames);
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
__auto_type pool = Vulkan_CreateDescriptorPool (ctx, "oit_pool");
|
||||||
|
|
||||||
|
__auto_type sets = QFV_AllocateDescriptorSet (device, pool, setLayout);
|
||||||
|
for (size_t i = 0; i < frames; i++) {
|
||||||
|
__auto_type tframe = &tctx->frames.a[i];
|
||||||
|
|
||||||
|
DARRAY_INIT (&tframe->cmdSet, QFV_translucentNumPasses);
|
||||||
|
DARRAY_RESIZE (&tframe->cmdSet, QFV_translucentNumPasses);
|
||||||
|
tframe->cmdSet.grow = 0;
|
||||||
|
|
||||||
|
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, &tframe->cmdSet);
|
||||||
|
|
||||||
|
tframe->descriptors = sets->a[i];
|
||||||
|
|
||||||
|
for (int j = 0; j < QFV_translucentNumPasses; j++) {
|
||||||
|
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||||
|
tframe->cmdSet.a[j],
|
||||||
|
va (ctx->va_ctx, "cmd:translucent:%zd:%s", i,
|
||||||
|
translucent_pass_names[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (sets);
|
||||||
|
qfvPopDebug (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
QFV_DestroyResource (device, tctx->resources);
|
||||||
|
free (tctx->resources);
|
||||||
|
tctx->resources = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfunc->vkDestroyPipeline (device->dev, tctx->pipeline, 0);
|
||||||
|
free (tctx->frames.a);
|
||||||
|
free (tctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDescriptorSet
|
||||||
|
Vulkan_Translucent_Descriptors (vulkan_ctx_t *ctx, int frame)
|
||||||
|
{
|
||||||
|
__auto_type tctx = ctx->translucent_context;
|
||||||
|
return tctx->frames.a[frame].descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vulkan_Translucent_CreateBuffers (vulkan_ctx_t *ctx, VkExtent2D extent)
|
||||||
|
{
|
||||||
|
if (!ctx->translucent_context) {//FIXME
|
||||||
|
Vulkan_Translucent_Init (ctx);
|
||||||
|
}
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
__auto_type tctx = ctx->translucent_context;
|
||||||
|
size_t frames = ctx->frames.size;
|
||||||
|
|
||||||
|
if (tctx->resources) {
|
||||||
|
QFV_DestroyResource (device, tctx->resources);
|
||||||
|
free (tctx->resources);
|
||||||
|
tctx->resources = 0;
|
||||||
|
}
|
||||||
|
tctx->resources = malloc (sizeof (qfv_resource_t)
|
||||||
|
// heads image
|
||||||
|
+ frames * sizeof (qfv_resobj_t)
|
||||||
|
// heads image view
|
||||||
|
+ frames * sizeof (qfv_resobj_t)
|
||||||
|
// fragment buffer
|
||||||
|
+ frames * sizeof (qfv_resobj_t)
|
||||||
|
// fragment count
|
||||||
|
+ frames * sizeof (qfv_resobj_t));
|
||||||
|
__auto_type heads_objs = (qfv_resobj_t *) &tctx->resources[1];
|
||||||
|
__auto_type head_views_objs = &heads_objs[frames];
|
||||||
|
__auto_type buffer_objs = &head_views_objs[frames];
|
||||||
|
__auto_type count_objs = &buffer_objs[frames];
|
||||||
|
tctx->resources[0] = (qfv_resource_t) {
|
||||||
|
.name = "oit",
|
||||||
|
.va_ctx = ctx->va_ctx,
|
||||||
|
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
.num_objects = 4 * frames,
|
||||||
|
.objects = heads_objs,
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < frames; i++) {
|
||||||
|
heads_objs[i] = (qfv_resobj_t) {
|
||||||
|
.name = va (ctx->va_ctx, "heads:%zd", i),
|
||||||
|
.type = qfv_res_image,
|
||||||
|
.image = {
|
||||||
|
.type = VK_IMAGE_TYPE_2D,
|
||||||
|
.format = VK_FORMAT_R32_SINT,
|
||||||
|
.extent = { extent.width, extent.height, 1 },
|
||||||
|
.num_mipmaps = 1,
|
||||||
|
.num_layers = 1,
|
||||||
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
.usage = VK_IMAGE_USAGE_STORAGE_BIT
|
||||||
|
| VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
head_views_objs[i] = (qfv_resobj_t) {
|
||||||
|
.name = "head view",
|
||||||
|
.type = qfv_res_image_view,
|
||||||
|
.image_view = {
|
||||||
|
.image = i,
|
||||||
|
.type = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
.format = VK_FORMAT_R32_SINT,
|
||||||
|
.aspect = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
buffer_objs[i] = (qfv_resobj_t) {
|
||||||
|
.name = va (ctx->va_ctx, "frags:%zd", i),
|
||||||
|
.type = qfv_res_buffer,
|
||||||
|
.buffer = {
|
||||||
|
.size = sizeof (qfv_transfrag_t) * MAX_FRAGMENTS,
|
||||||
|
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
count_objs[i] = (qfv_resobj_t) {
|
||||||
|
.name = va (ctx->va_ctx, "count:%zd", i),
|
||||||
|
.type = qfv_res_buffer,
|
||||||
|
.buffer = {
|
||||||
|
.size = 2 * sizeof (qfv_transtate_t),
|
||||||
|
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||||
|
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
QFV_CreateResource (device, tctx->resources);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < frames; i++) {
|
||||||
|
__auto_type tframe = &tctx->frames.a[i];
|
||||||
|
tframe->heads = heads_objs[i].image.image;
|
||||||
|
tframe->state = count_objs[i].buffer.buffer;
|
||||||
|
|
||||||
|
VkDescriptorImageInfo imageInfo[] = {
|
||||||
|
{ 0, head_views_objs[i].image_view.view, VK_IMAGE_LAYOUT_GENERAL },
|
||||||
|
};
|
||||||
|
VkDescriptorBufferInfo bufferInfo[] = {
|
||||||
|
{ count_objs[i].buffer.buffer, 0, VK_WHOLE_SIZE },
|
||||||
|
{ buffer_objs[i].buffer.buffer, 0, VK_WHOLE_SIZE },
|
||||||
|
};
|
||||||
|
VkWriteDescriptorSet write[] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||||
|
tframe->descriptors, 2, 0, 1,
|
||||||
|
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
|
.pImageInfo = imageInfo },
|
||||||
|
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||||
|
tframe->descriptors, 0, 0, 2,
|
||||||
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.pBufferInfo = bufferInfo },
|
||||||
|
};
|
||||||
|
dfunc->vkUpdateDescriptorSets (device->dev, 2, write, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
translucent_clear (qfv_renderframe_t *rFrame)
|
||||||
|
{
|
||||||
|
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
translucentctx_t *tctx = ctx->translucent_context;
|
||||||
|
__auto_type tframe = &tctx->frames.a[ctx->curFrame];
|
||||||
|
VkCommandBuffer cmd = tframe->cmdSet.a[QFV_translucentClear];
|
||||||
|
|
||||||
|
DARRAY_APPEND (&rFrame->subpassCmdSets[0], cmd);
|
||||||
|
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||||
|
VkCommandBufferInheritanceInfo inherit = {
|
||||||
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
};
|
||||||
|
VkCommandBufferBeginInfo beginInfo = {
|
||||||
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
|
||||||
|
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &inherit,
|
||||||
|
};
|
||||||
|
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||||
|
|
||||||
|
qfv_imagebarrier_t ib = imageBarriers[qfv_LT_Undefined_to_TransferDst];
|
||||||
|
ib.barrier.image = tframe->heads;
|
||||||
|
dfunc->vkCmdPipelineBarrier (cmd, ib.srcStages, ib.dstStages,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
1, &ib.barrier);
|
||||||
|
VkClearColorValue clear_color[] = {
|
||||||
|
{ .int32 = {-1, -1, -1, -1} },
|
||||||
|
};
|
||||||
|
VkImageSubresourceRange ranges[] = {
|
||||||
|
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 },
|
||||||
|
};
|
||||||
|
dfunc->vkCmdClearColorImage (cmd, tframe->heads,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
clear_color, 1, ranges);
|
||||||
|
ib = imageBarriers[qfv_LT_TransferDst_to_General];
|
||||||
|
ib.barrier.image = tframe->heads;
|
||||||
|
dfunc->vkCmdPipelineBarrier (cmd, ib.srcStages, ib.dstStages,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
1, &ib.barrier);
|
||||||
|
|
||||||
|
dfunc->vkEndCommandBuffer (cmd);
|
||||||
|
|
||||||
|
qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging);
|
||||||
|
qfv_transtate_t *state = QFV_PacketExtend (packet, 2 * sizeof (*state));
|
||||||
|
*state = (qfv_transtate_t) { 0, MAX_FRAGMENTS };
|
||||||
|
__auto_type bb = &bufferBarriers[qfv_BB_TransferWrite_to_ShaderRW];
|
||||||
|
QFV_PacketCopyBuffer (packet, tframe->state, bb);
|
||||||
|
QFV_PacketSubmit (packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vulkan_Translucent_CreateRenderPasses (vulkan_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
__auto_type rp = QFV_RenderPass_New (ctx, "translucent", translucent_clear);
|
||||||
|
rp->order = QFV_rp_translucent;
|
||||||
|
DARRAY_APPEND (&ctx->renderPasses, rp);
|
||||||
|
}
|
|
@ -56,6 +56,7 @@
|
||||||
#include "QF/Vulkan/qf_output.h"
|
#include "QF/Vulkan/qf_output.h"
|
||||||
#include "QF/Vulkan/qf_particles.h"
|
#include "QF/Vulkan/qf_particles.h"
|
||||||
#include "QF/Vulkan/qf_renderpass.h"
|
#include "QF/Vulkan/qf_renderpass.h"
|
||||||
|
#include "QF/Vulkan/qf_translucent.h"
|
||||||
#include "QF/Vulkan/qf_vid.h"
|
#include "QF/Vulkan/qf_vid.h"
|
||||||
|
|
||||||
#include "r_internal.h"
|
#include "r_internal.h"
|
||||||
|
@ -169,6 +170,7 @@ Vulkan_CreateRenderPasses (vulkan_ctx_t *ctx)
|
||||||
Vulkan_Main_CreateRenderPasses (ctx);
|
Vulkan_Main_CreateRenderPasses (ctx);
|
||||||
Vulkan_Particles_CreateRenderPasses (ctx);
|
Vulkan_Particles_CreateRenderPasses (ctx);
|
||||||
Vulkan_Lighting_CreateRenderPasses (ctx);
|
Vulkan_Lighting_CreateRenderPasses (ctx);
|
||||||
|
Vulkan_Translucent_CreateRenderPasses (ctx);
|
||||||
|
|
||||||
heapsort (ctx->renderPasses.a, ctx->renderPasses.size,
|
heapsort (ctx->renderPasses.a, ctx->renderPasses.size,
|
||||||
sizeof (qfv_renderpass_t *), renderpass_cmp);
|
sizeof (qfv_renderpass_t *), renderpass_cmp);
|
||||||
|
|
Loading…
Reference in a new issue