Skip to content

Commit

Permalink
Move GpuSceneParticleEmitter to its own array
Browse files Browse the repository at this point in the history
  • Loading branch information
godlikepanos committed Jul 20, 2024
1 parent ebbda6e commit 898ae65
Show file tree
Hide file tree
Showing 22 changed files with 155 additions and 164 deletions.
1 change: 1 addition & 0 deletions AnKi/Renderer/Utils/Drawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ void RenderableDrawer::setState(const RenderableDrawerArguments& args, CommandBu
cmdb.bindStorageBuffer(ANKI_REG(ANKI_MATERIAL_REGISTER_RENDERABLES), GpuSceneArrays::Renderable::getSingleton().getBufferView());
cmdb.bindStorageBuffer(ANKI_REG(ANKI_MATERIAL_REGISTER_MESH_LODS), GpuSceneArrays::MeshLod::getSingleton().getBufferView());
cmdb.bindStorageBuffer(ANKI_REG(ANKI_MATERIAL_REGISTER_TRANSFORMS), GpuSceneArrays::Transform::getSingleton().getBufferView());
cmdb.bindStorageBuffer(ANKI_REG(ANKI_MATERIAL_REGISTER_PARTICLE_EMITTERS), GpuSceneArrays::ParticleEmitter::getSingleton().getBufferViewSafe());
cmdb.bindTexture(ANKI_REG(ANKI_MATERIAL_REGISTER_HZB_TEXTURE),
(args.m_hzbTexture.isValid()) ? args.m_hzbTexture
: TextureView(&getRenderer().getDummyTexture2d(), TextureSubresourceDesc::all()));
Expand Down
2 changes: 1 addition & 1 deletion AnKi/Renderer/Utils/GpuVisibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ void GpuVisibility::populateRenderGraphInternal(Bool distanceBased, BaseGpuVisib
cmdb.bindStorageBuffer(ANKI_REG(t1), GpuSceneArrays::Renderable::getSingleton().getBufferView());
cmdb.bindStorageBuffer(ANKI_REG(t2), GpuSceneArrays::MeshLod::getSingleton().getBufferView());
cmdb.bindStorageBuffer(ANKI_REG(t3), GpuSceneArrays::Transform::getSingleton().getBufferView());
cmdb.bindStorageBuffer(ANKI_REG(t4), GpuSceneBuffer::getSingleton().getBufferView());
cmdb.bindStorageBuffer(ANKI_REG(t4), GpuSceneArrays::ParticleEmitter::getSingleton().getBufferViewSafe());
if(gatherType & 1u)
{
cmdb.bindStorageBuffer(ANKI_REG(u0), out.m_legacy.m_renderableInstancesBuffer);
Expand Down
1 change: 1 addition & 0 deletions AnKi/Scene/Components/ModelComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
gpuRenderable.m_uniformsOffset = m_patchInfos[i].m_gpuSceneUniformsOffset;
gpuRenderable.m_meshLodsIndex = m_patchInfos[i].m_gpuSceneMeshLods.getIndex() * kMaxLodCount;
gpuRenderable.m_boneTransformsOffset = (hasSkin) ? m_skinComponent->getBoneTransformsGpuSceneOffset() : 0;
gpuRenderable.m_particleEmitterIndex = kMaxU32;
if(!!(mtl.getRenderingTechniques() & RenderingTechniqueBit::kRtShadow))
{
const RenderingKey key(RenderingTechnique::kRtShadow, 0, false, false, false);
Expand Down
4 changes: 2 additions & 2 deletions AnKi/Scene/Components/ParticleEmitterComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,11 +396,11 @@ Error ParticleEmitterComponent::update(SceneComponentUpdateInfo& info, Bool& upd
m_gpuSceneMeshLods.uploadToGpuScene(meshLods);

// Upload the GpuSceneRenderable
GpuSceneRenderable renderable;
GpuSceneRenderable renderable = {};
renderable.m_boneTransformsOffset = 0;
renderable.m_uniformsOffset = m_gpuSceneUniforms.getOffset();
renderable.m_meshLodsIndex = m_gpuSceneMeshLods.getIndex() * kMaxLodCount;
renderable.m_particleEmitterOffset = m_gpuSceneParticleEmitter.getGpuSceneOffset();
renderable.m_particleEmitterIndex = m_gpuSceneParticleEmitter.getIndex();
renderable.m_worldTransformsIndex = 0;
renderable.m_uuid = SceneGraph::getSingleton().getNewUuid();
if(!m_gpuSceneRenderable.isValid())
Expand Down
13 changes: 13 additions & 0 deletions AnKi/Scene/GpuSceneArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ class GpuSceneArray : public MakeSingleton<GpuSceneArray<TGpuSceneObject, kId>>
return {&GpuSceneBuffer::getSingleton().getBuffer(), getGpuSceneOffsetOfArrayBase(), getBufferRange()};
}

/// @note Thread-safe
BufferView getBufferViewSafe() const
{
PtrSize range = getBufferRange();
if(range == 0)
{
// Just set something
range = getElementSize();
}

return {&GpuSceneBuffer::getSingleton().getBuffer(), getGpuSceneOffsetOfArrayBase(), range};
}

/// Some bookeeping. Needs to be called once per frame.
/// @note Thread-safe
void flush()
Expand Down
8 changes: 4 additions & 4 deletions AnKi/Shaders/ForwardShadingParticles.ankiprog
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ struct VertOut

VertOut main(VertIn input)
{
const GpuSceneRenderableInstance renderable = unpackGpuSceneRenderableVertex(input.m_gpuSceneRenderable);
const GpuSceneParticleEmitter particles = g_gpuScene.Load<GpuSceneParticleEmitter>(renderable.m_boneTransformsOrParticleEmitterOffset);
const GpuSceneMeshLod meshLod = g_meshLods[renderable.m_meshLodIndex];
const GpuSceneRenderableInstance instance = unpackGpuSceneRenderableVertex(input.m_gpuSceneRenderable);
const GpuSceneParticleEmitter particles = g_particleEmitters[instance.m_boneTransformsOffsetOrParticleEmitterIndex];
const GpuSceneMeshLod meshLod = g_meshLods[instance.m_meshLodIndex];

const U32 particleId = input.m_svVertexId / meshLod.m_indexCount;
const U32 vertexId = g_unifiedGeom_R16_Uint[meshLod.m_firstIndex + input.m_svVertexId % meshLod.m_indexCount];
Expand All @@ -62,7 +62,7 @@ VertOut main(VertIn input)
output.m_svPosition = mul(g_globalUniforms.m_viewProjectionMatrix, Vec4(output.m_worldPos, 1.0));

output.m_alpha = particleAlpha;
output.m_uniformsOffset = renderable.m_uniformsOffset;
output.m_uniformsOffset = instance.m_uniformsOffset;

return output;
}
Expand Down
8 changes: 4 additions & 4 deletions AnKi/Shaders/GBufferGeneric.ankiprog
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ VertOut main(VertIn input)

const U32 uniformsOffset = instance.m_uniformsOffset;
const U32 worldTransformsIndex = instance.m_worldTransformsIndex_25bit_meshletPrimitiveCount_7bit >> 7u;
const U32 boneTransformsOrParticleEmitterOffset = instance.m_boneTransformsOrParticleEmitterOffset;
const U32 boneTransformsOffset = instance.m_boneTransformsOffsetOrParticleEmitterIndex;

# if VISUALIZE_MESHLETS
output.m_meshletIndex = instance.m_meshletGeometryDescriptorIndex;
Expand All @@ -278,9 +278,9 @@ VertOut main(VertIn input)

const U32 uniformsOffset = instance.m_uniformsOffset;
const U32 worldTransformsIndex = instance.m_worldTransformsIndex;
const U32 boneTransformsOrParticleEmitterOffset = instance.m_boneTransformsOrParticleEmitterOffset;
const U32 boneTransformsOffset = instance.m_boneTransformsOffsetOrParticleEmitterIndex;
# endif // SW_MESHLETS
ANKI_MAYBE_UNUSED(boneTransformsOrParticleEmitterOffset);
ANKI_MAYBE_UNUSED(boneTransformsOffset);

const Mat3x4 worldTransform = g_transforms[worldTransformsIndex];
const Mat3x4 prevWorldTransform = g_transforms[worldTransformsIndex + 1u];
Expand All @@ -295,7 +295,7 @@ VertOut main(VertIn input)

// Do stuff
# if ANKI_BONES
skinning(vert, boneTransformsOrParticleEmitterOffset, vert.m_position, prevPos, vert.m_normal);
skinning(vert, boneTransformsOffset, vert.m_position, prevPos, vert.m_normal);
# endif

const Vec3 worldPos = mul(worldTransform, Vec4(vert.m_position, 1.0));
Expand Down
2 changes: 1 addition & 1 deletion AnKi/Shaders/GBufferGpuParticles.ankiprog
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ VertOut main(VertIn input)
VertOut output;

const GpuSceneRenderableInstance renderable = unpackGpuSceneRenderableVertex(input.m_gpuSceneRenderable);
const GpuSceneParticleEmitter particles = g_gpuScene.Load<GpuSceneParticleEmitter>(renderable.m_boneTransformsOrParticleEmitterOffset);
const GpuSceneParticleEmitter particles = g_particleEmitters[renderable.m_boneTransformsOffsetOrParticleEmitterIndex];

// Read vertex
const U32 particleId = input.m_svVertexId;
Expand Down
8 changes: 4 additions & 4 deletions AnKi/Shaders/GpuVisibility.ankiprog
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ StructuredBuffer<GpuSceneRenderableBoundingVolume> g_renderableBoundingVolumes :
StructuredBuffer<GpuSceneRenderable> g_renderables : register(t1);
StructuredBuffer<GpuSceneMeshLod> g_meshLods : register(t2);
StructuredBuffer<Mat3x4> g_transforms : register(t3);
ByteAddressBuffer g_gpuScene : register(t4);
StructuredBuffer<GpuSceneParticleEmitter> g_particleEmitters : register(t4);

#if GATHER_MDI
// These 3 have the same size
Expand Down Expand Up @@ -162,7 +162,7 @@ RWStructuredBuffer<GpuVisibilityHash> g_hash : register(u7);
const U32 meshLodIndex = renderable.m_meshLodsIndex + lod;
const GpuSceneMeshLod meshLod = g_meshLods[meshLodIndex];

const Bool isParticleEmitter = renderable.m_particleEmitterOffset != 0;
const Bool isParticleEmitter = renderable.m_particleEmitterIndex < kMaxU32;
ANKI_MAYBE_UNUSED(isParticleEmitter);

const Bool usesMeshShaders = meshLod.m_meshletCount != 0u;
Expand Down Expand Up @@ -238,7 +238,7 @@ RWStructuredBuffer<GpuVisibilityHash> g_hash : register(u7);
}
else
{
const GpuSceneParticleEmitter emitter = g_gpuScene.Load<GpuSceneParticleEmitter>(renderable.m_particleEmitterOffset);
const GpuSceneParticleEmitter emitter = g_particleEmitters[renderable.m_particleEmitterIndex];

DrawIndirectArgsWithPadding indirect;
indirect.m_vertexCount = emitter.m_aliveParticleCount * meshLod.m_indexCount;
Expand All @@ -252,7 +252,7 @@ RWStructuredBuffer<GpuVisibilityHash> g_hash : register(u7);
instanceVertex.x = renderable.m_worldTransformsIndex;
instanceVertex.y = renderable.m_uniformsOffset;
instanceVertex.z = meshLodIndex;
instanceVertex.w = renderable.m_particleEmitterOffset;
instanceVertex.w = renderable.m_particleEmitterIndex;
g_instanceRateRenderables[indirectIdx] = instanceVertex;
}
}
Expand Down
4 changes: 2 additions & 2 deletions AnKi/Shaders/GpuVisibilityMeshlet.ankiprog
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ ANKI_PUSH_CONSTANTS(Consts, g_unis)
instance.m_worldTransformsIndex_25bit_meshletPrimitiveCount_7bit = renderable.m_worldTransformsIndex << 7u;
instance.m_worldTransformsIndex_25bit_meshletPrimitiveCount_7bit |= meshletBoundingVol.m_primitiveCount;
instance.m_uniformsOffset = renderable.m_uniformsOffset;
instance.m_boneTransformsOrParticleEmitterOffset =
(renderable.m_boneTransformsOffset) ? renderable.m_boneTransformsOffset : renderable.m_particleEmitterOffset;
instance.m_boneTransformsOffsetOrParticleEmitterIndex =
(renderable.m_boneTransformsOffset) ? renderable.m_boneTransformsOffset : renderable.m_particleEmitterIndex;

g_meshletInstances[g_unis.m_firstMeshlet + instanceIdx] = instance;
}
Expand Down
4 changes: 2 additions & 2 deletions AnKi/Shaders/Include/GpuSceneFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ inline GpuSceneRenderableInstance unpackGpuSceneRenderableVertex(UVec4 x)
o.m_worldTransformsIndex = x[0];
o.m_uniformsOffset = x[1];
o.m_meshLodIndex = x[2];
o.m_boneTransformsOrParticleEmitterOffset = x[3];
o.m_boneTransformsOffsetOrParticleEmitterIndex = x[3];
return o;
}

Expand All @@ -25,7 +25,7 @@ inline GpuSceneMeshletInstance unpackGpuSceneMeshletInstance(UVec4 x)
o.m_worldTransformsIndex_25bit_meshletPrimitiveCount_7bit = x[0];
o.m_uniformsOffset = x[1];
o.m_meshletGeometryDescriptorIndex = x[2];
o.m_boneTransformsOrParticleEmitterOffset = x[3];
o.m_boneTransformsOffsetOrParticleEmitterIndex = x[3];
return o;
}

Expand Down
6 changes: 3 additions & 3 deletions AnKi/Shaders/Include/GpuSceneTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct GpuSceneRenderable
U32 m_uniformsOffset;
U32 m_meshLodsIndex; ///< Points to the array of GpuSceneMeshLod. kMaxLodCount are reserved for each renderable.
U32 m_boneTransformsOffset; ///< Array of Mat3x4 or 0 if its not a skin.
U32 m_particleEmitterOffset; ///< Offset to GpuSceneParticleEmitter or 0 if it's not an emitter.
U32 m_particleEmitterIndex; ///< Index to the GpuSceneParticleEmitter array or kMaxU32 if it's not an emitter.
U32 m_rtShadowsShaderHandleIndex; ///< The index of the shader handle in the array of library's handles.
U32 m_uuid;
};
Expand All @@ -34,7 +34,7 @@ struct GpuSceneRenderableInstance
U32 m_worldTransformsIndex;
U32 m_uniformsOffset;
U32 m_meshLodIndex; ///< Points to a single GpuSceneMeshLod in the mesh lods.
U32 m_boneTransformsOrParticleEmitterOffset;
U32 m_boneTransformsOffsetOrParticleEmitterIndex;
};
static_assert(sizeof(GpuSceneRenderableInstance) == sizeof(UVec4));

Expand All @@ -51,7 +51,7 @@ struct GpuSceneMeshletInstance
U32 m_worldTransformsIndex_25bit_meshletPrimitiveCount_7bit;
U32 m_uniformsOffset;
U32 m_meshletGeometryDescriptorIndex; ///< Index in the UGB.
U32 m_boneTransformsOrParticleEmitterOffset;
U32 m_boneTransformsOffsetOrParticleEmitterIndex;
};
static_assert(kMaxPrimitivesPerMeshlet < ((1u << 7u) - 1));

Expand Down
19 changes: 10 additions & 9 deletions AnKi/Shaders/Include/MaterialTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,23 @@ static_assert(sizeof(MaterialGlobalUniforms) == 16 * sizeof(Vec4));
#define ANKI_MATERIAL_REGISTER_MESHLET_GROUPS t3
#define ANKI_MATERIAL_REGISTER_RENDERABLES t4
#define ANKI_MATERIAL_REGISTER_MESH_LODS t5
#define ANKI_MATERIAL_REGISTER_TRANSFORMS t6
#define ANKI_MATERIAL_REGISTER_HZB_TEXTURE t7
#define ANKI_MATERIAL_REGISTER_PARTICLE_EMITTERS t6
#define ANKI_MATERIAL_REGISTER_TRANSFORMS t7
#define ANKI_MATERIAL_REGISTER_HZB_TEXTURE t8
#define ANKI_MATERIAL_REGISTER_NEAREST_CLAMP_SAMPLER s1

// For FW shading:
#define ANKI_MATERIAL_REGISTER_LINEAR_CLAMP_SAMPLER s2
#define ANKI_MATERIAL_REGISTER_SHADOW_SAMPLER s3
#define ANKI_MATERIAL_REGISTER_SCENE_DEPTH t8
#define ANKI_MATERIAL_REGISTER_LIGHT_VOLUME t9
#define ANKI_MATERIAL_REGISTER_SCENE_DEPTH t9
#define ANKI_MATERIAL_REGISTER_LIGHT_VOLUME t10
#define ANKI_MATERIAL_REGISTER_CLUSTER_SHADING_UNIFORMS b1
#define ANKI_MATERIAL_REGISTER_CLUSTER_SHADING_POINT_LIGHTS t10
#define ANKI_MATERIAL_REGISTER_CLUSTER_SHADING_SPOT_LIGHTS t11
#define ANKI_MATERIAL_REGISTER_SHADOW_ATLAS t12
#define ANKI_MATERIAL_REGISTER_CLUSTERS t13
#define ANKI_MATERIAL_REGISTER_CLUSTER_SHADING_POINT_LIGHTS t11
#define ANKI_MATERIAL_REGISTER_CLUSTER_SHADING_SPOT_LIGHTS t12
#define ANKI_MATERIAL_REGISTER_SHADOW_ATLAS t13
#define ANKI_MATERIAL_REGISTER_CLUSTERS t14

// Always last because it's variable. Texture buffer bindings pointing to unified geom buffer:
#define ANKI_MATERIAL_REGISTER_UNIFIED_GEOMETRY_START t14
#define ANKI_MATERIAL_REGISTER_UNIFIED_GEOMETRY_START t15

ANKI_END_NAMESPACE
1 change: 1 addition & 0 deletions AnKi/Shaders/MaterialShadersCommon.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ StructuredBuffer<GpuSceneMeshLod> g_meshLods : register(ANKI_MATERIAL_REGISTER_M
StructuredBuffer<Mat3x4> g_transforms : register(ANKI_MATERIAL_REGISTER_TRANSFORMS);
Texture2D<Vec4> g_hzbTexture : register(ANKI_MATERIAL_REGISTER_HZB_TEXTURE);
SamplerState g_nearestClampSampler : register(ANKI_MATERIAL_REGISTER_NEAREST_CLAMP_SAMPLER);
StructuredBuffer<GpuSceneParticleEmitter> g_particleEmitters : register(ANKI_MATERIAL_REGISTER_PARTICLE_EMITTERS);

// FW shading specific
#if defined(FORWARD_SHADING)
Expand Down
Binary file not shown.
Loading

0 comments on commit 898ae65

Please sign in to comment.