mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-27 22:21:00 +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
include/QF/Vulkan
libs/video/renderer/vulkan
|
@ -192,6 +192,8 @@ DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdBindIndexBuffer)
|
||||||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdBindDescriptorSets)
|
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdBindDescriptorSets)
|
||||||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDraw)
|
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDraw)
|
||||||
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDrawIndexed)
|
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDrawIndexed)
|
||||||
|
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDrawIndexedIndirect)
|
||||||
|
DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdDrawIndirect)
|
||||||
|
|
||||||
#undef DEVICE_LEVEL_VULKAN_FUNCTION
|
#undef DEVICE_LEVEL_VULKAN_FUNCTION
|
||||||
|
|
||||||
|
|
|
@ -69,16 +69,17 @@ typedef struct particlectx_s {
|
||||||
VkPipelineLayout update_layout;
|
VkPipelineLayout update_layout;
|
||||||
VkPipelineLayout draw_layout;
|
VkPipelineLayout draw_layout;
|
||||||
|
|
||||||
psystem_t psystem;
|
psystem_t *psystem;
|
||||||
} particlectx_t;
|
} particlectx_t;
|
||||||
|
|
||||||
struct cvar_s;
|
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);
|
struct psystem_s *Vulkan_ParticleSystem (struct vulkan_ctx_s *ctx);
|
||||||
void Vulkan_Particles_Init (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_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);
|
void Vulkan_Particles_CreateRenderPasses (struct vulkan_ctx_s *ctx);
|
||||||
|
|
||||||
#endif//__QF_Vulkan_qf_particles_h
|
#endif//__QF_Vulkan_qf_particles_h
|
||||||
|
|
|
@ -567,6 +567,10 @@
|
||||||
topology = triangle_strip;
|
topology = triangle_strip;
|
||||||
primitiveRestartEnable = true;
|
primitiveRestartEnable = true;
|
||||||
};
|
};
|
||||||
|
point = {
|
||||||
|
topology = point_list;
|
||||||
|
primitiveRestartEnable = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
vertexInput = {
|
vertexInput = {
|
||||||
|
@ -646,13 +650,13 @@
|
||||||
};
|
};
|
||||||
particle = {
|
particle = {
|
||||||
bindings = (
|
bindings = (
|
||||||
{ binding = 0; stride = "4 * 4 * 4"; inputRate = vertex; },
|
{ binding = 0; stride = "4 * 4 * 4"; inputRate = instance; },
|
||||||
);
|
);
|
||||||
attributes = (
|
attributes = (
|
||||||
{ location = 0; binding = 0; format = r32g32b32a32_sfloat; offset = 0; },
|
{ location = 0; binding = 0; format = r32g32b32a32_sfloat; offset = 0; },
|
||||||
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||||
{ location = 2; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
{ location = 2; binding = 0; format = r32g32b32a32_sfloat; offset = 32; },
|
||||||
{ location = 3; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
{ location = 3; binding = 0; format = r32g32b32a32_sfloat; offset = 48; },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
twod = {
|
twod = {
|
||||||
|
@ -1085,7 +1089,7 @@
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
vertexInput = $properties.vertexInput.particle;
|
vertexInput = $properties.vertexInput.particle;
|
||||||
inputAssembly = $properties.inputAssembly.sprite;
|
inputAssembly = $properties.inputAssembly.point;
|
||||||
layout = partdraw_layout;
|
layout = partdraw_layout;
|
||||||
};
|
};
|
||||||
sprite_gbuf = {
|
sprite_gbuf = {
|
||||||
|
|
|
@ -43,13 +43,9 @@ fogBlend (vec4 color)
|
||||||
void
|
void
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
vec4 c = vec4 (0);
|
vec2 st = warp_st (tl_st.xy, time);
|
||||||
vec4 e;
|
vec4 c = texture (Texture, vec3(st, 0));
|
||||||
vec3 t_st = vec3 (warp_st (tl_st.xy, time), 0);
|
vec4 e = texture (Texture, vec3(st, 1));
|
||||||
vec3 e_st = vec3 (warp_st (tl_st.xy, time), 1);
|
|
||||||
|
|
||||||
c = texture (Texture, t_st);
|
|
||||||
e = texture (Texture, e_st);
|
|
||||||
float a = c.a * e.a * alpha;
|
float a = c.a * e.a * alpha;
|
||||||
c += e;
|
c += e;
|
||||||
c.a = a;
|
c.a = a;
|
||||||
|
|
|
@ -8,7 +8,7 @@ layout (location = 0) out vec4 frag_color;
|
||||||
void
|
void
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
vec4 c = color;
|
vec4 c = vec4 (1,1,1,1);//color;
|
||||||
vec2 x = uv_tr.xy;
|
vec2 x = uv_tr.xy;
|
||||||
|
|
||||||
float a = 1 - dot (x, x);
|
float a = 1 - dot (x, x);
|
||||||
|
|
|
@ -21,9 +21,9 @@ layout (location = 2) out vec4 o_ramp;
|
||||||
void
|
void
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
// geometry shader will take care of Projection and View
|
// geometry shader will take care of Projection
|
||||||
gl_Position = Model * position;
|
gl_Position = View * (Model * position);
|
||||||
o_velocity = Model * velocity;
|
o_velocity = View * (Model * velocity);
|
||||||
o_color = color;
|
o_color = color;
|
||||||
o_ramp = ramp;
|
o_ramp = ramp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,7 @@ Vulkan_RenderView (qfv_renderframe_t *rFrame)
|
||||||
Vulkan_DrawViewModel (ctx);
|
Vulkan_DrawViewModel (ctx);
|
||||||
}
|
}
|
||||||
Vulkan_DrawWaterSurfaces (rFrame);
|
Vulkan_DrawWaterSurfaces (rFrame);
|
||||||
|
Vulkan_DrawParticles (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);
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "QF/Vulkan/instance.h"
|
#include "QF/Vulkan/instance.h"
|
||||||
#include "QF/Vulkan/resource.h"
|
#include "QF/Vulkan/resource.h"
|
||||||
#include "QF/Vulkan/staging.h"
|
#include "QF/Vulkan/staging.h"
|
||||||
|
#include "QF/Vulkan/qf_matrices.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"
|
||||||
|
|
||||||
|
@ -67,9 +68,83 @@ static const char * __attribute__((used)) particle_pass_names[] = {
|
||||||
"draw",
|
"draw",
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
static void
|
||||||
Vulkan_DrawParticles (vulkan_ctx_t *ctx)
|
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
|
static void
|
||||||
|
@ -175,6 +250,7 @@ Vulkan_Particles_Init (vulkan_ctx_t *ctx)
|
||||||
|
|
||||||
particlectx_t *pctx = calloc (1, sizeof (particlectx_t));
|
particlectx_t *pctx = calloc (1, sizeof (particlectx_t));
|
||||||
ctx->particle_context = pctx;
|
ctx->particle_context = pctx;
|
||||||
|
pctx->psystem = &r_psystem;
|
||||||
|
|
||||||
size_t frames = ctx->frames.size;
|
size_t frames = ctx->frames.size;
|
||||||
DARRAY_INIT (&pctx->frames, frames);
|
DARRAY_INIT (&pctx->frames, frames);
|
||||||
|
@ -262,7 +338,7 @@ Vulkan_Particles_Shutdown (vulkan_ctx_t *ctx)
|
||||||
psystem_t *__attribute__((pure))//FIXME?
|
psystem_t *__attribute__((pure))//FIXME?
|
||||||
Vulkan_ParticleSystem (vulkan_ctx_t *ctx)
|
Vulkan_ParticleSystem (vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
return &ctx->particle_context->psystem; //FIXME support more
|
return ctx->particle_context->psystem; //FIXME support more
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -280,7 +356,7 @@ particles_update (qfv_renderframe_t *rFrame)
|
||||||
VkMemoryRequirements req = {
|
VkMemoryRequirements req = {
|
||||||
.alignment = limits->minStorageBufferOffsetAlignment
|
.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 syssize = sizeof (qfv_particle_system_t);
|
||||||
size_t partoffs = QFV_NextOffset (syssize, &req);
|
size_t partoffs = QFV_NextOffset (syssize, &req);
|
||||||
size_t partsize = sizeof (qfv_particle_t) * numParticles;
|
size_t partsize = sizeof (qfv_particle_t) * numParticles;
|
||||||
|
@ -294,14 +370,14 @@ particles_update (qfv_renderframe_t *rFrame)
|
||||||
.particleCount = numParticles,
|
.particleCount = numParticles,
|
||||||
};
|
};
|
||||||
__auto_type particles = (qfv_particle_t *) ((byte *)system + partoffs);
|
__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);
|
qfv_parameters_t *params = (qfv_parameters_t *)((byte *)system + paramoffs);
|
||||||
memcpy (params, pctx->psystem.partparams, paramsize);
|
memcpy (params, pctx->psystem->partparams, paramsize);
|
||||||
|
|
||||||
VkDescriptorBufferInfo bufferInfo[] = {
|
VkDescriptorBufferInfo bufferInfo[] = {
|
||||||
{ packet->stage->buffer, 0, syssize },
|
|
||||||
{ packet->stage->buffer, partoffs, partsize ? partsize : 1},
|
{ packet->stage->buffer, partoffs, partsize ? partsize : 1},
|
||||||
{ packet->stage->buffer, paramoffs, paramsize ? paramsize : 1},
|
{ packet->stage->buffer, paramoffs, paramsize ? paramsize : 1},
|
||||||
|
{ packet->stage->buffer, 0, syssize },
|
||||||
};
|
};
|
||||||
VkWriteDescriptorSet write[] = {
|
VkWriteDescriptorSet write[] = {
|
||||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
{ 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);
|
pctx->physics_layout, 0, 1, set, 0, 0);
|
||||||
|
|
||||||
particle_push_constants_t constants = {
|
particle_push_constants_t constants = {
|
||||||
.gravity = pctx->psystem.gravity,
|
.gravity = pctx->psystem->gravity,
|
||||||
.dT = vr_data.frametime,
|
.dT = vr_data.frametime,
|
||||||
};
|
};
|
||||||
qfv_push_constants_t push_constants[] = {
|
qfv_push_constants_t push_constants[] = {
|
||||||
|
@ -377,6 +453,8 @@ particles_update (qfv_renderframe_t *rFrame)
|
||||||
dfunc->vkCmdSetEvent (packet->cmd, pframe->physicsEvent,
|
dfunc->vkCmdSetEvent (packet->cmd, pframe->physicsEvent,
|
||||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
QFV_PacketSubmit (packet);
|
QFV_PacketSubmit (packet);
|
||||||
|
|
||||||
|
pctx->psystem->numparticles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue