mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[vulkan] Start work on particles for Vulkan
This gets the pipelines loaded (and unloaded on shutdown). Probably the easy part :P. Still need to sort out the command buffers, synchronization, and particle generation (and probably a bunch else that's not coming to mind).
This commit is contained in:
parent
9dcaa98205
commit
6aaf5c3722
12 changed files with 544 additions and 25 deletions
|
@ -1,8 +1,62 @@
|
|||
#ifndef __QF_Vulkan_qf_particles_h
|
||||
#define __QF_Vulkan_qf_particles_h
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/image.h"
|
||||
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
||||
typedef struct qfv_particle_s {
|
||||
vec4f_t pos;
|
||||
vec4f_t vel;
|
||||
vec4f_t color;
|
||||
float texture;
|
||||
float ramp;
|
||||
float scale;
|
||||
float live;
|
||||
} qfv_particle_t;
|
||||
|
||||
typedef struct qfv_parameters_s {
|
||||
vec4f_t drag;
|
||||
vec4f_t ramp;
|
||||
} qfv_parameters_t;
|
||||
|
||||
typedef enum {
|
||||
QFV_particleTranslucent,
|
||||
|
||||
QFV_particleNumPasses
|
||||
} QFV_ParticleSubpass;
|
||||
|
||||
typedef struct particleframe_s {
|
||||
VkCommandBuffer compute;
|
||||
VkSemaphore physSem;
|
||||
VkSemaphore drawSem;
|
||||
VkSemaphore updateSem;
|
||||
VkBuffer state;
|
||||
VkBuffer params;
|
||||
VkBuffer system;
|
||||
|
||||
VkDescriptorSet descriptors;
|
||||
|
||||
qfv_cmdbufferset_t cmdSet;
|
||||
} particleframe_t;
|
||||
|
||||
typedef struct particleframeset_s
|
||||
DARRAY_TYPE (particleframe_t) particleframeset_t;
|
||||
|
||||
typedef struct particlectx_s {
|
||||
particleframeset_t frames;
|
||||
VkPipeline physics;
|
||||
VkPipeline update;
|
||||
VkPipeline draw;
|
||||
|
||||
VkDescriptorPool pool;
|
||||
VkDescriptorSetLayout setLayout;
|
||||
VkPipelineLayout physics_layout;
|
||||
VkPipelineLayout update_layout;
|
||||
VkPipelineLayout draw_layout;
|
||||
} particlectx_t;
|
||||
|
||||
struct cvar_s;
|
||||
struct vulkan_ctx_s;;
|
||||
|
||||
|
@ -11,6 +65,7 @@ void Vulkan_InitParticles (struct vulkan_ctx_s *ctx);
|
|||
void Vulkan_r_easter_eggs_f (struct cvar_s *var, struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_r_particles_style_f (struct cvar_s *var, struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Particles_Init (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Particles_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_DrawParticles (struct vulkan_ctx_s *ctx);
|
||||
|
||||
#endif//__QF_Vulkan_qf_particles_h
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef struct vulkan_ctx_s {
|
|||
struct matrixctx_s *matrix_context;
|
||||
struct aliasctx_s *alias_context;
|
||||
struct bspctx_s *bsp_context;
|
||||
struct particlectx_s *particle_context;
|
||||
struct spritectx_s *sprite_context;
|
||||
struct drawctx_s *draw_context;
|
||||
struct lightingctx_s *lighting_context;
|
||||
|
|
|
@ -289,6 +289,16 @@ vkparse_plist = \
|
|||
|
||||
vkshaderpath = libs/video/renderer/vulkan/shader
|
||||
|
||||
partphysicsc_src = $(vkshaderpath)/partphysics.comp
|
||||
partphysicsc_c = $(vkshaderpath)/partphysics.comp.spvc
|
||||
partupdatec_src = $(vkshaderpath)/partupdate.comp
|
||||
partupdatec_c = $(vkshaderpath)/partupdate.comp.spvc
|
||||
particlev_src = $(vkshaderpath)/particle.vert
|
||||
particlev_c = $(vkshaderpath)/particle.vert.spvc
|
||||
particleg_src = $(vkshaderpath)/particle.geom
|
||||
particleg_c = $(vkshaderpath)/particle.geom.spvc
|
||||
particlef_src = $(vkshaderpath)/particle.frag
|
||||
particlef_c = $(vkshaderpath)/particle.frag.spvc
|
||||
sprite_gbufv_src = $(vkshaderpath)/sprite_gbuf.vert
|
||||
sprite_gbufv_c = $(vkshaderpath)/sprite_gbuf.vert.spvc
|
||||
sprite_gbuff_src = $(vkshaderpath)/sprite_gbuf.frag
|
||||
|
@ -341,6 +351,12 @@ pushcolor_c = $(vkshaderpath)/pushcolor.frag.spvc
|
|||
shadow_src = $(vkshaderpath)/shadow.geom
|
||||
shadow_c = $(vkshaderpath)/shadow.geom.spvc
|
||||
|
||||
$(partphysicsc_c): $(partphysicsc_src)
|
||||
$(partupdatec_c): $(partupdatec_src)
|
||||
$(particlev_c): $(particlev_src)
|
||||
$(particleg_c): $(particleg_src)
|
||||
$(particlef_c): $(particlef_src)
|
||||
|
||||
$(sprite_gbufv_c): $(sprite_gbufv_src)
|
||||
|
||||
$(sprite_gbuff_c): $(sprite_gbuff_src)
|
||||
|
@ -392,6 +408,11 @@ $(pushcolor_c): $(pushcolor_src)
|
|||
$(shadow_c): $(shadow_src)
|
||||
|
||||
vkshader_c = \
|
||||
$(partphysicsc_c) \
|
||||
$(partupdatec_c) \
|
||||
$(particlev_c) \
|
||||
$(particleg_c) \
|
||||
$(particlef_c) \
|
||||
$(sprite_gbufv_c) \
|
||||
$(sprite_gbuff_c) \
|
||||
$(sprite_depthv_c) \
|
||||
|
|
|
@ -104,9 +104,9 @@ vulkan_R_Init (void)
|
|||
Vulkan_Matrix_Init (vulkan_ctx);
|
||||
Vulkan_Alias_Init (vulkan_ctx);
|
||||
Vulkan_Bsp_Init (vulkan_ctx);
|
||||
Vulkan_Particles_Init (vulkan_ctx);
|
||||
Vulkan_Sprite_Init (vulkan_ctx);
|
||||
Vulkan_Draw_Init (vulkan_ctx);
|
||||
Vulkan_Particles_Init (vulkan_ctx);
|
||||
Vulkan_Lighting_Init (vulkan_ctx);
|
||||
Vulkan_Compose_Init (vulkan_ctx);
|
||||
|
||||
|
@ -631,6 +631,7 @@ vulkan_vid_render_shutdown (void)
|
|||
Vulkan_Lighting_Shutdown (vulkan_ctx);
|
||||
Vulkan_Draw_Shutdown (vulkan_ctx);
|
||||
Vulkan_Sprite_Shutdown (vulkan_ctx);
|
||||
Vulkan_Particles_Shutdown (vulkan_ctx);
|
||||
Vulkan_Bsp_Shutdown (vulkan_ctx);
|
||||
Vulkan_Alias_Shutdown (vulkan_ctx);
|
||||
Vulkan_Matrix_Shutdown (vulkan_ctx);
|
||||
|
|
|
@ -112,6 +112,16 @@
|
|||
},
|
||||
);
|
||||
};
|
||||
particle_pool = {
|
||||
flags = 0;
|
||||
maxSets = $frames.size;
|
||||
bindings = (
|
||||
{
|
||||
type = storage_buffer;
|
||||
descriptorCount = 3;
|
||||
},
|
||||
);
|
||||
};
|
||||
sprite_pool = {
|
||||
flags = free_descriptor_set;
|
||||
maxSets = 64; //FIXME cvar?
|
||||
|
@ -295,6 +305,28 @@
|
|||
},
|
||||
);
|
||||
};
|
||||
particle_set = {
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
descriptorType = storage_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = compute;
|
||||
},
|
||||
{
|
||||
binding = 1;
|
||||
descriptorType = storage_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = compute;
|
||||
},
|
||||
{
|
||||
binding = 2;
|
||||
descriptorType = storage_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = compute;
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
pipelineLayouts = {
|
||||
twod_layout = {
|
||||
|
@ -351,6 +383,29 @@
|
|||
compose_layout = {
|
||||
setLayouts = (compose_attach);
|
||||
};
|
||||
partphysics_layout = {
|
||||
setLayouts = (particle_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = compute;
|
||||
offset = 0;
|
||||
size = "16 * 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
partupdate_layout = {
|
||||
setLayouts = (particle_set, particle_set, particle_set);
|
||||
};
|
||||
partdraw_layout = {
|
||||
setLayouts = (matrix_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
offset = 0;
|
||||
size = "16 * 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
depthStencil = {
|
||||
|
@ -424,6 +479,17 @@
|
|||
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
);
|
||||
};
|
||||
particle = {
|
||||
bindings = (
|
||||
{ binding = 0; stride = "4 * 4 * 4"; inputRate = vertex; },
|
||||
);
|
||||
attributes = (
|
||||
{ location = 0; binding = 0; format = r32g32b32a32_sfloat; offset = 0; },
|
||||
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
{ location = 2; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
{ location = 3; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
);
|
||||
};
|
||||
twod = {
|
||||
bindings = (
|
||||
{ binding = 0; stride = "2 * 4 * 4"; inputRate = vertex; },
|
||||
|
@ -856,6 +922,38 @@
|
|||
layout = quakebsp_layout;
|
||||
renderPass = renderpass;
|
||||
};
|
||||
partdraw = {
|
||||
subpass = 1;
|
||||
stages = (
|
||||
{
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/particle.vert;
|
||||
},
|
||||
{
|
||||
stage = geometry;
|
||||
name = main;
|
||||
module = $builtin/particle.geom;
|
||||
},
|
||||
{
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/particle.frag;
|
||||
},
|
||||
);
|
||||
vertexInput = $properties.vertexInput.particle;
|
||||
inputAssembly = $properties.inputAssembly.sprite;
|
||||
viewport = $properties.viewport;
|
||||
rasterization = $properties.rasterization.cw_cull_back;
|
||||
multisample = $properties.multisample;
|
||||
depthStencil = $properties.depthStencil.test_only;
|
||||
colorBlend = $properties.pipelines.bsp_turb.colorBlend;
|
||||
dynamic = {
|
||||
dynamicState = ( viewport, scissor, blend_constants );
|
||||
};
|
||||
layout = partdraw_layout;
|
||||
renderPass = renderpass;
|
||||
};
|
||||
sprite_gbuf = {
|
||||
subpass = 2;
|
||||
stages = (
|
||||
|
@ -1000,5 +1098,21 @@
|
|||
layout = compose_layout;
|
||||
renderPass = renderpass;
|
||||
};
|
||||
partphysics = {
|
||||
stage = {
|
||||
stage = compute;
|
||||
name = main;
|
||||
module = $builtin/partphysics.comp;
|
||||
};
|
||||
layout = partphysics_layout;
|
||||
};
|
||||
partupdate = {
|
||||
stage = {
|
||||
stage = compute;
|
||||
name = main;
|
||||
module = $builtin/partupdate.comp;
|
||||
};
|
||||
layout = partupdate_layout;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -54,6 +54,16 @@
|
|||
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/particle.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/particle.geom.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/particle.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/partphysics.comp.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/partupdate.comp.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/sprite_gbuf.vert.spvc"
|
||||
static
|
||||
|
@ -112,6 +122,11 @@ typedef struct shaderdata_s {
|
|||
} shaderdata_t;
|
||||
|
||||
static shaderdata_t builtin_shaders[] = {
|
||||
{ "particle.vert", particle_vert, sizeof (particle_vert) },
|
||||
{ "particle.geom", particle_geom, sizeof (particle_geom) },
|
||||
{ "particle.frag", particle_frag, sizeof (particle_frag) },
|
||||
{ "partphysics.comp", partphysics_comp, sizeof (partphysics_comp) },
|
||||
{ "partupdate.comp", partupdate_comp, sizeof (partupdate_comp) },
|
||||
{ "sprite_gbuf.vert", sprite_gbuf_vert, sizeof (sprite_gbuf_vert) },
|
||||
{ "sprite_gbuf.frag", sprite_gbuf_frag, sizeof (sprite_gbuf_frag) },
|
||||
{ "sprite_depth.vert", sprite_depth_vert, sizeof (sprite_depth_vert) },
|
||||
|
|
22
libs/video/renderer/vulkan/shader/particle.frag
Normal file
22
libs/video/renderer/vulkan/shader/particle.frag
Normal file
|
@ -0,0 +1,22 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (location = 0) in vec4 uv_tr;
|
||||
layout (location = 1) in vec4 color;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 c = color;
|
||||
vec2 x = uv_tr.xy;
|
||||
|
||||
float a = 1 - dot (x, x);
|
||||
if (a <= 0) {
|
||||
discard;
|
||||
}
|
||||
c.a *= sqrt (a);
|
||||
frag_color = c;
|
||||
}
|
57
libs/video/renderer/vulkan/shader/particle.geom
Normal file
57
libs/video/renderer/vulkan/shader/particle.geom
Normal file
|
@ -0,0 +1,57 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 Projection3d;
|
||||
mat4 View;
|
||||
mat4 Sky;
|
||||
mat4 Projection2d;
|
||||
};
|
||||
|
||||
layout (points) in;
|
||||
layout (triangle_strip, max_vertices = 4) out;
|
||||
layout (location = 0) in vec4 velocity[];
|
||||
layout (location = 1) in vec4 color[];
|
||||
layout (location = 2) in vec4 ramp[];
|
||||
|
||||
layout (location = 0) out vec4 uv_tr;
|
||||
layout (location = 1) out vec4 o_color;
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
vec4 pos = gl_in[0].gl_Position;
|
||||
vec4 tr = vec4 (0, 0, ramp[0].xy);
|
||||
float s = ramp[0].z;
|
||||
vec4 d, p;
|
||||
vec4 c = color[0];
|
||||
|
||||
d = vec4 (-1, 1, 0, 0);
|
||||
p = pos + s * d;
|
||||
gl_Position = Projection3d * p;
|
||||
uv_tr = d + tr;
|
||||
o_color = c;
|
||||
EmitVertex ();
|
||||
|
||||
d = vec4 (-1, -1, 0, 0);
|
||||
p = pos + s * d;
|
||||
gl_Position = Projection3d * p;
|
||||
uv_tr = d + tr;
|
||||
o_color = c;
|
||||
EmitVertex ();
|
||||
|
||||
d = vec4 (1, 1, 0, 0);
|
||||
p = pos + s * d;
|
||||
gl_Position = Projection3d * p;
|
||||
uv_tr = d + tr;
|
||||
o_color = c;
|
||||
EmitVertex ();
|
||||
|
||||
d = vec4 (1, -1, 0, 0);
|
||||
p = pos + s * d;
|
||||
gl_Position = Projection3d * p;
|
||||
uv_tr = d + tr;
|
||||
o_color = c;
|
||||
EmitVertex ();
|
||||
|
||||
EndPrimitive ();
|
||||
}
|
31
libs/video/renderer/vulkan/shader/particle.vert
Normal file
31
libs/video/renderer/vulkan/shader/particle.vert
Normal file
|
@ -0,0 +1,31 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 Projection3d;
|
||||
mat4 View;
|
||||
mat4 Sky;
|
||||
mat4 Projection2d;
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
mat4 Model;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 position;
|
||||
layout (location = 1) in vec4 velocity;
|
||||
layout (location = 2) in vec4 color;
|
||||
layout (location = 3) in vec4 ramp;
|
||||
|
||||
layout (location = 0) out vec4 o_velocity;
|
||||
layout (location = 1) out vec4 o_color;
|
||||
layout (location = 2) out vec4 o_ramp;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
// geometry shader will take care of Projection and View
|
||||
gl_Position = Model * position;
|
||||
o_velocity = Model * velocity;
|
||||
o_color = color;
|
||||
o_ramp = ramp;
|
||||
}
|
56
libs/video/renderer/vulkan/shader/partphysics.comp
Normal file
56
libs/video/renderer/vulkan/shader/partphysics.comp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#version 450
|
||||
|
||||
layout (local_size_x = 32, local_size_y = 32) in;
|
||||
|
||||
struct Particle {
|
||||
vec4 pos;
|
||||
vec4 vel;
|
||||
vec4 color;
|
||||
float tex;
|
||||
float ramp;
|
||||
float scale;
|
||||
float live;
|
||||
};
|
||||
|
||||
struct Parameters {
|
||||
vec4 drag; // [dx, dy, dz, grav scale]
|
||||
vec4 ramp; // [rate, max, alpha rate, scale rate]
|
||||
};
|
||||
|
||||
layout(std140, set = 0, binding = 0) buffer ParticleStates {
|
||||
Particle particles[];
|
||||
};
|
||||
|
||||
layout(std140, set = 0, binding = 1) buffer ParticleParameters {
|
||||
Parameters parameters[];
|
||||
};
|
||||
|
||||
layout(std140, set = 0, binding = 2) buffer ParticleSystem {
|
||||
uint particleCount;
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
vec4 gravity;
|
||||
float dT;
|
||||
};
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
uint ind = gl_GlobalInvocationID.x;
|
||||
if (ind >= particleCount) {
|
||||
return;
|
||||
}
|
||||
Particle part = particles[ind];
|
||||
Parameters parm = parameters[ind];
|
||||
|
||||
part.pos += dT * part.vel;
|
||||
part.vel += dT * (part.vel * parm.drag + gravity * parm.drag.w);
|
||||
|
||||
part.ramp += dT * parm.ramp.x;
|
||||
part.scale += dT * parm.ramp.z;
|
||||
part.color.a -= dT * parm.ramp.a;
|
||||
part.live -= dT;
|
||||
|
||||
particles[ind] = part;
|
||||
}
|
93
libs/video/renderer/vulkan/shader/partupdate.comp
Normal file
93
libs/video/renderer/vulkan/shader/partupdate.comp
Normal file
|
@ -0,0 +1,93 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxParticles = 2048;
|
||||
|
||||
layout (local_size_x = 1, local_size_y = 1) in;
|
||||
|
||||
struct Particle {
|
||||
vec4 pos;
|
||||
vec4 vel;
|
||||
vec4 color;
|
||||
float tex;
|
||||
float ramp;
|
||||
float scale;
|
||||
float live;
|
||||
};
|
||||
|
||||
struct Parameters {
|
||||
vec4 drag; // [dx, dy, dz, grav scale]
|
||||
vec4 ramp; // [rate, max, alpha rate, scale rate]
|
||||
};
|
||||
|
||||
layout(std140, set = 0, binding = 0) buffer InStates {
|
||||
Particle particles[];
|
||||
} inState;
|
||||
|
||||
layout(std140, set = 0, binding = 1) buffer InParameters {
|
||||
Parameters parameters[];
|
||||
} inParameters;
|
||||
|
||||
layout(std140, set = 0, binding = 2) buffer InSystem {
|
||||
uint particleCount;
|
||||
} inSystem;
|
||||
|
||||
layout(std140, set = 1, binding = 0) buffer OutStates {
|
||||
Particle particles[];
|
||||
} outStates;
|
||||
|
||||
layout(std140, set = 1, binding = 1) buffer OutParameters {
|
||||
Parameters parameters[];
|
||||
} outParameters;
|
||||
|
||||
layout(std140, set = 1, binding = 2) buffer OutSystem {
|
||||
uint particleCount;
|
||||
} outSystem;
|
||||
|
||||
layout(std140, set = 2, binding = 0) buffer NewStates {
|
||||
Particle particles[];
|
||||
} newStates;
|
||||
|
||||
layout(std140, set = 2, binding = 1) buffer NewParameters {
|
||||
Parameters parameters[];
|
||||
} newParameters;
|
||||
|
||||
layout(std140, set = 2, binding = 2) buffer NewSystem {
|
||||
uint particleCount;
|
||||
} newSystem;
|
||||
|
||||
bool
|
||||
is_dead (in Particle part, in Parameters parm)
|
||||
{
|
||||
if (part.live <= 0) {
|
||||
return true;
|
||||
}
|
||||
if (part.ramp >= parm.ramp.y || part.color.a <= 0 || part.scale <= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
uint j = 0;
|
||||
// compact existing partles removing dead particles
|
||||
for (uint i = 0; i < inSystem.particleCount; i++) {
|
||||
if (is_dead (inState.particles[i], inParameters.parameters[i])) {
|
||||
continue;
|
||||
}
|
||||
outStates.particles[j] = inState.particles[i];
|
||||
outParameters.parameters[j] = inParameters.parameters[i];
|
||||
j++;
|
||||
}
|
||||
// inject any new particles that aren't DOA
|
||||
for (uint i = 0; i < newSystem.particleCount && j < MaxParticles; i++) {
|
||||
if (is_dead (inState.particles[i], inParameters.parameters[i])) {
|
||||
continue;
|
||||
}
|
||||
outStates.particles[j] = newStates.particles[i];
|
||||
outParameters.parameters[j] = newParameters.parameters[i];
|
||||
j++;
|
||||
}
|
||||
outSystem.particleCount = j;
|
||||
}
|
|
@ -40,20 +40,29 @@
|
|||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
|
||||
#include "QF/Vulkan/debug.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
#include "QF/Vulkan/qf_particles.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
static const char * __attribute__((used)) particle_pass_names[] = {
|
||||
"draw",
|
||||
};
|
||||
|
||||
void
|
||||
Vulkan_ClearParticles (struct vulkan_ctx_s *ctx)
|
||||
Vulkan_ClearParticles (vulkan_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_InitParticles (struct vulkan_ctx_s *ctx)
|
||||
Vulkan_InitParticles (vulkan_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -217,7 +226,7 @@ static vid_particle_funcs_t vulkan_particles_QF = {
|
|||
};
|
||||
|
||||
void
|
||||
Vulkan_r_easter_eggs_f (cvar_t *var, struct vulkan_ctx_s *ctx)
|
||||
Vulkan_r_easter_eggs_f (cvar_t *var, vulkan_ctx_t *ctx)
|
||||
{
|
||||
if (!easter_eggs || !r_particles_style) {
|
||||
return;
|
||||
|
@ -239,35 +248,79 @@ Vulkan_r_easter_eggs_f (cvar_t *var, struct vulkan_ctx_s *ctx)
|
|||
}
|
||||
|
||||
void
|
||||
Vulkan_r_particles_style_f (cvar_t *var, struct vulkan_ctx_s *ctx)
|
||||
Vulkan_r_particles_style_f (cvar_t *var, vulkan_ctx_t *ctx)
|
||||
{
|
||||
Vulkan_r_easter_eggs_f (var, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DrawParticles (struct vulkan_ctx_s *ctx)
|
||||
Vulkan_DrawParticles (vulkan_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Particles_Init (struct vulkan_ctx_s *ctx)
|
||||
Vulkan_Particles_Init (vulkan_ctx_t *ctx)
|
||||
{
|
||||
/*
|
||||
easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, r_easter_eggs_f,
|
||||
"Enables easter eggs.");
|
||||
r_particles = Cvar_Get ("r_particles", "1", CVAR_ARCHIVE, r_particles_f,
|
||||
"Toggles drawing of particles.");
|
||||
r_particles_max = Cvar_Get ("r_particles_max", "2048", CVAR_ARCHIVE,
|
||||
r_particles_max_f, "Maximum amount of "
|
||||
"particles to display. No maximum, minimum "
|
||||
"is 0.");
|
||||
r_particles_nearclip = Cvar_Get ("r_particles_nearclip", "32",
|
||||
CVAR_ARCHIVE, r_particles_nearclip_f,
|
||||
"Distance of the particle near clipping "
|
||||
"plane from the player.");
|
||||
r_particles_style = Cvar_Get ("r_particles_style", "1", CVAR_ARCHIVE,
|
||||
r_particles_style_f, "Sets particle style. "
|
||||
"0 for Id, 1 for QF.");
|
||||
*/
|
||||
vulkan_vid_render_funcs.particles = &vulkan_particles_QF;
|
||||
|
||||
qfv_device_t *device = ctx->device;
|
||||
|
||||
qfvPushDebug (ctx, "particles init");
|
||||
|
||||
particlectx_t *pctx = calloc (1, sizeof (particlectx_t));
|
||||
ctx->particle_context = pctx;
|
||||
|
||||
size_t frames = ctx->frames.size;
|
||||
DARRAY_INIT (&pctx->frames, frames);
|
||||
DARRAY_RESIZE (&pctx->frames, frames);
|
||||
pctx->frames.grow = 0;
|
||||
|
||||
pctx->physics = Vulkan_CreateComputePipeline (ctx, "partphysics");
|
||||
pctx->update = Vulkan_CreateComputePipeline (ctx, "partupdate");
|
||||
pctx->draw = Vulkan_CreateGraphicsPipeline (ctx, "partdraw");
|
||||
pctx->physics_layout = Vulkan_CreatePipelineLayout (ctx,
|
||||
"partphysics_layout");
|
||||
pctx->update_layout = Vulkan_CreatePipelineLayout (ctx,
|
||||
"partupdate_layout");
|
||||
pctx->draw_layout = Vulkan_CreatePipelineLayout (ctx, "draw_layout");
|
||||
|
||||
pctx->pool = Vulkan_CreateDescriptorPool (ctx, "particle_pool");
|
||||
pctx->setLayout = Vulkan_CreateDescriptorSetLayout (ctx, "particle_set");
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
__auto_type pframe = &pctx->frames.a[i];
|
||||
|
||||
DARRAY_INIT (&pframe->cmdSet, QFV_particleNumPasses);
|
||||
DARRAY_RESIZE (&pframe->cmdSet, QFV_particleNumPasses);
|
||||
pframe->cmdSet.grow = 0;
|
||||
|
||||
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, &pframe->cmdSet);
|
||||
|
||||
for (int j = 0; j < QFV_particleNumPasses; j++) {
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
pframe->cmdSet.a[j],
|
||||
va (ctx->va_ctx, "cmd:particle:%zd:%s", i,
|
||||
particle_pass_names[j]));
|
||||
}
|
||||
}
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Particles_Shutdown (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
particlectx_t *pctx = ctx->particle_context;
|
||||
|
||||
for (size_t i = 0; i < pctx->frames.size; i++) {
|
||||
__auto_type pframe = &pctx->frames.a[i];
|
||||
free (pframe->cmdSet.a);
|
||||
}
|
||||
|
||||
dfunc->vkDestroyPipeline (device->dev, pctx->physics, 0);
|
||||
dfunc->vkDestroyPipeline (device->dev, pctx->update, 0);
|
||||
dfunc->vkDestroyPipeline (device->dev, pctx->draw, 0);
|
||||
free (pctx->frames.a);
|
||||
free (pctx);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue