mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
[vulkan] Implement particle rendering
They sort of kind of maybe try to work, but there's plenty wrong. I suspect synchronization and probably other factors.
This commit is contained in:
parent
d9b0ee22e6
commit
30b38d7f3f
8 changed files with 108 additions and 26 deletions
|
@ -192,6 +192,8 @@ DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdBindIndexBuffer)
|
|||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdBindDescriptorSets)
|
||||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDraw)
|
||||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDrawIndexed)
|
||||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDrawIndexedIndirect)
|
||||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDrawIndirect)
|
||||
|
||||
#undef DEVICE_LEVEL_VULKAN_FUNCTION
|
||||
|
||||
|
|
|
@ -69,16 +69,17 @@ typedef struct particlectx_s {
|
|||
VkPipelineLayout update_layout;
|
||||
VkPipelineLayout draw_layout;
|
||||
|
||||
psystem_t psystem;
|
||||
psystem_t *psystem;
|
||||
} particlectx_t;
|
||||
|
||||
struct cvar_s;
|
||||
struct vulkan_ctx_s;;
|
||||
struct vulkan_ctx_s;
|
||||
struct qfv_renderframe_s;
|
||||
|
||||
struct psystem_s *Vulkan_ParticleSystem (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);
|
||||
void Vulkan_DrawParticles (struct qfv_renderframe_s *rFrame);
|
||||
void Vulkan_Particles_CreateRenderPasses (struct vulkan_ctx_s *ctx);
|
||||
|
||||
#endif//__QF_Vulkan_qf_particles_h
|
||||
|
|
|
@ -567,6 +567,10 @@
|
|||
topology = triangle_strip;
|
||||
primitiveRestartEnable = true;
|
||||
};
|
||||
point = {
|
||||
topology = point_list;
|
||||
primitiveRestartEnable = false;
|
||||
};
|
||||
};
|
||||
|
||||
vertexInput = {
|
||||
|
@ -646,13 +650,13 @@
|
|||
};
|
||||
particle = {
|
||||
bindings = (
|
||||
{ binding = 0; stride = "4 * 4 * 4"; inputRate = vertex; },
|
||||
{ binding = 0; stride = "4 * 4 * 4"; inputRate = instance; },
|
||||
);
|
||||
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; },
|
||||
{ location = 2; binding = 0; format = r32g32b32a32_sfloat; offset = 32; },
|
||||
{ location = 3; binding = 0; format = r32g32b32a32_sfloat; offset = 48; },
|
||||
);
|
||||
};
|
||||
twod = {
|
||||
|
@ -1085,7 +1089,7 @@
|
|||
},
|
||||
);
|
||||
vertexInput = $properties.vertexInput.particle;
|
||||
inputAssembly = $properties.inputAssembly.sprite;
|
||||
inputAssembly = $properties.inputAssembly.point;
|
||||
layout = partdraw_layout;
|
||||
};
|
||||
sprite_gbuf = {
|
||||
|
|
|
@ -43,13 +43,9 @@ fogBlend (vec4 color)
|
|||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 c = vec4 (0);
|
||||
vec4 e;
|
||||
vec3 t_st = vec3 (warp_st (tl_st.xy, time), 0);
|
||||
vec3 e_st = vec3 (warp_st (tl_st.xy, time), 1);
|
||||
|
||||
c = texture (Texture, t_st);
|
||||
e = texture (Texture, e_st);
|
||||
vec2 st = warp_st (tl_st.xy, time);
|
||||
vec4 c = texture (Texture, vec3(st, 0));
|
||||
vec4 e = texture (Texture, vec3(st, 1));
|
||||
float a = c.a * e.a * alpha;
|
||||
c += e;
|
||||
c.a = a;
|
||||
|
|
|
@ -8,7 +8,7 @@ layout (location = 0) out vec4 frag_color;
|
|||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 c = color;
|
||||
vec4 c = vec4 (1,1,1,1);//color;
|
||||
vec2 x = uv_tr.xy;
|
||||
|
||||
float a = 1 - dot (x, x);
|
||||
|
|
|
@ -21,9 +21,9 @@ 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;
|
||||
// geometry shader will take care of Projection
|
||||
gl_Position = View * (Model * position);
|
||||
o_velocity = View * (Model * velocity);
|
||||
o_color = color;
|
||||
o_ramp = ramp;
|
||||
}
|
||||
|
|
|
@ -136,6 +136,7 @@ Vulkan_RenderView (qfv_renderframe_t *rFrame)
|
|||
Vulkan_DrawViewModel (ctx);
|
||||
}
|
||||
Vulkan_DrawWaterSurfaces (rFrame);
|
||||
Vulkan_DrawParticles (rFrame);
|
||||
Vulkan_Bsp_Flush (ctx);
|
||||
Vulkan_RenderEntities (r_ent_queue, rFrame);
|
||||
Vulkan_Scene_Flush (ctx);
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "QF/Vulkan/instance.h"
|
||||
#include "QF/Vulkan/resource.h"
|
||||
#include "QF/Vulkan/staging.h"
|
||||
#include "QF/Vulkan/qf_matrices.h"
|
||||
#include "QF/Vulkan/qf_particles.h"
|
||||
#include "QF/Vulkan/qf_renderpass.h"
|
||||
|
||||
|
@ -67,9 +68,83 @@ static const char * __attribute__((used)) particle_pass_names[] = {
|
|||
"draw",
|
||||
};
|
||||
|
||||
void
|
||||
Vulkan_DrawParticles (vulkan_ctx_t *ctx)
|
||||
static void
|
||||
particle_begin_subpass (VkPipeline pipeline, qfv_renderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
particlectx_t *pctx = ctx->particle_context;
|
||||
uint32_t curFrame = ctx->curFrame;
|
||||
particleframe_t *pframe = &pctx->frames.a[curFrame];
|
||||
VkCommandBuffer cmd = pframe->cmdSet.a[0];
|
||||
|
||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
rFrame->renderpass->renderpass, QFV_passTranslucent,
|
||||
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, va (ctx->va_ctx, "particles:%s", "draw"),
|
||||
{ 0.6, 0.5, 0, 1});
|
||||
|
||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
VkDescriptorSet sets[] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pctx->draw_layout, 0, 1, sets, 0, 0);
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
||||
}
|
||||
|
||||
static void
|
||||
particle_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
QFV_duCmdEndLabel (device, cmd);
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DrawParticles (qfv_renderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
particlectx_t *pctx = ctx->particle_context;
|
||||
uint32_t curFrame = ctx->curFrame;
|
||||
particleframe_t *pframe = &pctx->frames.a[curFrame];
|
||||
VkCommandBuffer cmd = pframe->cmdSet.a[0];
|
||||
|
||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
|
||||
pframe->cmdSet.a[0]);
|
||||
|
||||
particle_begin_subpass (pctx->draw, rFrame);
|
||||
|
||||
mat4f_t mat;
|
||||
mat4fidentity (mat);
|
||||
qfv_push_constants_t push_constants[] = {
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof (mat4f_t), &mat },
|
||||
};
|
||||
QFV_PushConstants (device, cmd, pctx->draw_layout, 1, push_constants);
|
||||
VkDeviceSize offsets[] = { 0 };
|
||||
VkBuffer buffers[] = {
|
||||
pframe->states,
|
||||
};
|
||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, buffers, offsets);
|
||||
dfunc->vkCmdDrawIndirect (cmd, pframe->system, 0, 1,
|
||||
sizeof (qfv_particle_system_t));
|
||||
particle_end_subpass (cmd, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -175,6 +250,7 @@ Vulkan_Particles_Init (vulkan_ctx_t *ctx)
|
|||
|
||||
particlectx_t *pctx = calloc (1, sizeof (particlectx_t));
|
||||
ctx->particle_context = pctx;
|
||||
pctx->psystem = &r_psystem;
|
||||
|
||||
size_t frames = ctx->frames.size;
|
||||
DARRAY_INIT (&pctx->frames, frames);
|
||||
|
@ -262,7 +338,7 @@ Vulkan_Particles_Shutdown (vulkan_ctx_t *ctx)
|
|||
psystem_t *__attribute__((pure))//FIXME?
|
||||
Vulkan_ParticleSystem (vulkan_ctx_t *ctx)
|
||||
{
|
||||
return &ctx->particle_context->psystem; //FIXME support more
|
||||
return ctx->particle_context->psystem; //FIXME support more
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -280,7 +356,7 @@ particles_update (qfv_renderframe_t *rFrame)
|
|||
VkMemoryRequirements req = {
|
||||
.alignment = limits->minStorageBufferOffsetAlignment
|
||||
};
|
||||
uint32_t numParticles = min (MaxParticles, pctx->psystem.numparticles);
|
||||
uint32_t numParticles = min (MaxParticles, pctx->psystem->numparticles);
|
||||
size_t syssize = sizeof (qfv_particle_system_t);
|
||||
size_t partoffs = QFV_NextOffset (syssize, &req);
|
||||
size_t partsize = sizeof (qfv_particle_t) * numParticles;
|
||||
|
@ -294,14 +370,14 @@ particles_update (qfv_renderframe_t *rFrame)
|
|||
.particleCount = numParticles,
|
||||
};
|
||||
__auto_type particles = (qfv_particle_t *) ((byte *)system + partoffs);
|
||||
memcpy (particles, pctx->psystem.particles, partsize);
|
||||
memcpy (particles, pctx->psystem->particles, partsize);
|
||||
qfv_parameters_t *params = (qfv_parameters_t *)((byte *)system + paramoffs);
|
||||
memcpy (params, pctx->psystem.partparams, paramsize);
|
||||
memcpy (params, pctx->psystem->partparams, paramsize);
|
||||
|
||||
VkDescriptorBufferInfo bufferInfo[] = {
|
||||
{ packet->stage->buffer, 0, syssize },
|
||||
{ packet->stage->buffer, partoffs, partsize ? partsize : 1},
|
||||
{ packet->stage->buffer, paramoffs, paramsize ? paramsize : 1},
|
||||
{ packet->stage->buffer, 0, syssize },
|
||||
};
|
||||
VkWriteDescriptorSet write[] = {
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
|
@ -360,7 +436,7 @@ particles_update (qfv_renderframe_t *rFrame)
|
|||
pctx->physics_layout, 0, 1, set, 0, 0);
|
||||
|
||||
particle_push_constants_t constants = {
|
||||
.gravity = pctx->psystem.gravity,
|
||||
.gravity = pctx->psystem->gravity,
|
||||
.dT = vr_data.frametime,
|
||||
};
|
||||
qfv_push_constants_t push_constants[] = {
|
||||
|
@ -377,6 +453,8 @@ particles_update (qfv_renderframe_t *rFrame)
|
|||
dfunc->vkCmdSetEvent (packet->cmd, pframe->physicsEvent,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
QFV_PacketSubmit (packet);
|
||||
|
||||
pctx->psystem->numparticles = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue