You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshDispatchItem.h

111 lines
4.7 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/Feature/SkinnedMesh/SkinnedMeshInputBuffers.h>
#include <Atom/Feature/SkinnedMesh/SkinnedMeshShaderOptions.h>
#include <SkinnedMesh/SkinnedMeshShaderOptionsCache.h>
#include <Atom/RHI/DispatchItem.h>
#include <AtomCore/Instance/Instance.h>
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroup.h>
namespace AZ
{
namespace RHI
{
class BufferView;
class PipelineState;
}
namespace RPI
{
class Buffer;
class ModelLod;
class Shader;
class ShaderResourceGroup;
}
namespace Render
{
class SkinnedMeshFeatureProcessor;
//! Holds and manages an RHI DispatchItem for a specific skinned mesh, and the resources that are needed to build and maintain it.
class SkinnedMeshDispatchItem
: private SkinnedMeshShaderOptionNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(SkinnedMeshDispatchItem, AZ::SystemAllocator, 0);
SkinnedMeshDispatchItem() = delete;
//! Create one dispatch item per mesh for each actor instance
explicit SkinnedMeshDispatchItem(
AZStd::intrusive_ptr<SkinnedMeshInputBuffers> inputBuffers,
const AZStd::vector<uint32_t>& outputBufferOffsetsInBytes,
size_t lodIndex,
Data::Instance<RPI::Buffer> skinningMatrices,
const SkinnedMeshShaderOptions& shaderOptions,
SkinnedMeshFeatureProcessor* skinnedMeshFeatureProcessor,
MorphTargetInstanceMetaData morphTargetInstanceMetaData,
float morphTargetDeltaIntegerEncoding
);
~SkinnedMeshDispatchItem();
// The event handler cannot be copied
AZ_DISABLE_COPY_MOVE(SkinnedMeshDispatchItem);
bool Init();
const RHI::DispatchItem& GetRHIDispatchItem() const;
Data::Instance<RPI::Buffer> GetBoneTransforms() const;
AZStd::array_view<RHI::Ptr<RHI::BufferView>> GetSourceUnskinnedBufferViews() const;
AZStd::array_view<RHI::Ptr<RHI::BufferView>> GetTargetSkinnedBufferViews() const;
size_t GetVertexCount() const;
private:
// SkinnedMeshShaderOptionNotificationBus::Handler
void OnShaderReinitialized(const CachedSkinnedMeshShaderOptions* cachedShaderOptions) override;
RHI::DispatchItem m_dispatchItem;
// The skinning shader used for this instance
Data::Instance<RPI::Shader> m_skinningShader;
// Offsets into the SkinnedMeshOutputVertexStream where the lod streams start
AZStd::vector<uint32_t> m_outputBufferOffsetsInBytes;
// The unskinned vertices used as the source of the skinning
AZStd::intrusive_ptr<SkinnedMeshInputBuffers> m_inputBuffers;
// The index of the lod within m_inputBuffers that is represented by the DispatchItem
size_t m_lodIndex;
// The per-object shader resource group
Data::Instance<RPI::ShaderResourceGroup> m_instanceSrg;
// Writable buffer views used for writing the per-actorInstance skinning data in the skinning shader
AZStd::array<AZ::RHI::Ptr<RHI::BufferView>, static_cast<uint8_t>(SkinnedMeshOutputVertexStreams::NumVertexStreams)> m_actorInstanceBufferViews;
Data::Instance<RPI::Buffer> m_boneTransforms;
// Options for the skinning shader
SkinnedMeshShaderOptions m_shaderOptions;
RPI::ShaderOptionGroup m_shaderOptionGroup;
// MetaData for the morph target that is specific to this instance
MorphTargetInstanceMetaData m_morphTargetInstanceMetaData;
// A conservative value for encoding/decoding the accumulated deltas
float m_morphTargetDeltaIntegerEncoding;
};
//! The skinned mesh compute shader has Nx1x1 threads per group and dispatches a total number of threads greater than or equal to the number of vertices in the mesh, with one vertex skinned per thread.
//! We increase the total number of threads along the x dimension until it overflows what can fit in that dimension,
//! and subsequently increment the total number of threads in the y dimension as much as needed for the total number of threads to equal or exceed the vertex count.
void CalculateSkinnedMeshTotalThreadsPerDimension(uint32_t vertexCount, uint32_t& xThreads, uint32_t& yThreads);
} // namespace Render
} // namespace AZ