Fixed missing moves in SHBatch move constructor and assignment as well as added isAnimated check with base 0-index identity matrix for bones
This commit is contained in:
parent
af3e4a3cfd
commit
62e0e5e1ad
|
@ -42,12 +42,16 @@ namespace SHADE
|
|||
if (!pipeline)
|
||||
throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!");
|
||||
|
||||
// Check the pipeline and flag it depending on whether or not it is animated
|
||||
isAnimated = checkIfIsAnimatedPipeline(pipeline);
|
||||
|
||||
// Mark all as dirty
|
||||
setAllDirtyFlags();
|
||||
}
|
||||
|
||||
SHBatch::SHBatch(SHBatch&& rhs)
|
||||
: device { rhs.device }
|
||||
, isAnimated { rhs.isAnimated }
|
||||
, pipeline { rhs.pipeline }
|
||||
, referencedMatInstances { std::move(rhs.referencedMatInstances) }
|
||||
, matBufferDirty { std::move(rhs.matBufferDirty) }
|
||||
|
@ -60,17 +64,23 @@ namespace SHADE
|
|||
, matPropsDataSize { rhs.matPropsDataSize }
|
||||
, singleMatPropAlignedSize { rhs.singleMatPropAlignedSize }
|
||||
, singleMatPropSize { rhs.singleMatPropSize }
|
||||
, boneMatrixData { std::move(rhs.boneMatrixData) }
|
||||
, boneMatrixIndices { std::move(rhs.boneMatrixIndices) }
|
||||
, isCPUBuffersDirty { rhs.isCPUBuffersDirty }
|
||||
, drawDataBuffer { rhs.drawDataBuffer }
|
||||
, transformDataBuffer { rhs.transformDataBuffer }
|
||||
, instancedIntegerBuffer { rhs.instancedIntegerBuffer }
|
||||
, matPropsBuffer { rhs.matPropsBuffer }
|
||||
, boneMatrixBuffer { rhs.boneMatrixBuffer }
|
||||
, boneMatrixFirstIndexBuffer { rhs.boneMatrixFirstIndexBuffer }
|
||||
, instanceDataDescSet { rhs.instanceDataDescSet }
|
||||
{
|
||||
rhs.drawDataBuffer = {};
|
||||
rhs.transformDataBuffer = {};
|
||||
rhs.instancedIntegerBuffer = {};
|
||||
rhs.matPropsBuffer = {};
|
||||
rhs.boneMatrixBuffer = {};
|
||||
rhs.boneMatrixFirstIndexBuffer = {};
|
||||
rhs.instanceDataDescSet = {};
|
||||
}
|
||||
|
||||
|
@ -80,6 +90,7 @@ namespace SHADE
|
|||
return *this;
|
||||
|
||||
device = rhs.device ;
|
||||
isAnimated = rhs.isAnimated ;
|
||||
pipeline = rhs.pipeline ;
|
||||
referencedMatInstances = std::move(rhs.referencedMatInstances);
|
||||
matBufferDirty = std::move(rhs.matBufferDirty) ;
|
||||
|
@ -92,11 +103,15 @@ namespace SHADE
|
|||
matPropsDataSize = rhs.matPropsDataSize ;
|
||||
singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ;
|
||||
singleMatPropSize = rhs.singleMatPropSize ;
|
||||
boneMatrixData = std::move(rhs.boneMatrixData) ;
|
||||
boneMatrixIndices = std::move(rhs.boneMatrixIndices) ;
|
||||
isCPUBuffersDirty = rhs.isCPUBuffersDirty ;
|
||||
drawDataBuffer = rhs.drawDataBuffer ;
|
||||
transformDataBuffer = rhs.transformDataBuffer ;
|
||||
instancedIntegerBuffer = rhs.instancedIntegerBuffer ;
|
||||
matPropsBuffer = rhs.matPropsBuffer ;
|
||||
boneMatrixBuffer = rhs.boneMatrixBuffer ;
|
||||
boneMatrixFirstIndexBuffer = rhs.boneMatrixFirstIndexBuffer ;
|
||||
instanceDataDescSet = rhs.instanceDataDescSet ;
|
||||
|
||||
// Unset values
|
||||
|
@ -104,6 +119,8 @@ namespace SHADE
|
|||
rhs.transformDataBuffer = {};
|
||||
rhs.instancedIntegerBuffer = {};
|
||||
rhs.matPropsBuffer = {};
|
||||
rhs.boneMatrixBuffer = {};
|
||||
rhs.boneMatrixFirstIndexBuffer = {};
|
||||
rhs.instanceDataDescSet = {};
|
||||
|
||||
return *this;
|
||||
|
@ -382,6 +399,10 @@ namespace SHADE
|
|||
|
||||
void SHBatch::UpdateAnimationBuffer(uint32_t frameIndex)
|
||||
{
|
||||
// Not animated pipeline, we skip
|
||||
if (!isAnimated)
|
||||
return;
|
||||
|
||||
// Frame Index check
|
||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||
{
|
||||
|
@ -392,6 +413,9 @@ namespace SHADE
|
|||
// Reset Animation Matrix Data
|
||||
boneMatrixData.clear();
|
||||
|
||||
// Add the first identity matrix into the bone matrix data
|
||||
boneMatrixData.emplace_back(SHMatrix::Identity);
|
||||
|
||||
// Populate on the CPU
|
||||
for (auto& subBatch : subBatches)
|
||||
for (auto rendId : subBatch.Renderables)
|
||||
|
@ -402,6 +426,7 @@ namespace SHADE
|
|||
const auto& MATRICES = animator->GetBoneMatrices();
|
||||
boneMatrixData.insert(boneMatrixData.end(), MATRICES.cbegin(), MATRICES.cend());
|
||||
}
|
||||
// We don't have to account for missing animators or reset indices as the renderable list are not updated at this point
|
||||
}
|
||||
|
||||
// Update GPU Buffers
|
||||
|
@ -446,13 +471,21 @@ namespace SHADE
|
|||
// - EID data
|
||||
instancedIntegerData.reserve(numTotalElements);
|
||||
instancedIntegerData.clear();
|
||||
if (isAnimated)
|
||||
{
|
||||
// - Bone Data
|
||||
boneMatrixData.clear();
|
||||
boneMatrixIndices.clear();
|
||||
|
||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
// Add the first identity matrix into the bone matrix data
|
||||
boneMatrixData.emplace_back(SHMatrix::Identity);
|
||||
}
|
||||
|
||||
// - Material Properties Data
|
||||
auto const& DESC_MAPPINGS = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
|
||||
(
|
||||
descMappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
|
||||
DESC_MAPPINGS.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
||||
vk::ShaderStageFlagBits::eFragment
|
||||
);
|
||||
|
@ -470,9 +503,12 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
// - Bone Data
|
||||
if (isAnimated)
|
||||
{
|
||||
boneMatrixData.clear();
|
||||
boneMatrixIndices.clear();
|
||||
boneMatrixIndices.reserve(numTotalElements);
|
||||
}
|
||||
|
||||
// Build Sub Batches
|
||||
uint32_t nextInstanceIndex = 0;
|
||||
|
@ -548,6 +584,8 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Bone Data
|
||||
if (isAnimated)
|
||||
{
|
||||
auto animator = SHComponentManager::GetComponent_s<SHAnimatorComponent>(rendId);
|
||||
if (animator)
|
||||
{
|
||||
|
@ -555,6 +593,12 @@ namespace SHADE
|
|||
const auto& BONE_MATRICES = animator->GetBoneMatrices();
|
||||
boneMatrixData.insert(boneMatrixData.end(), BONE_MATRICES.cbegin(), BONE_MATRICES.cend());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take the first matrix which is always identity
|
||||
boneMatrixIndices.emplace_back(static_cast<uint32_t>(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,7 +634,7 @@ namespace SHADE
|
|||
"Batch Instance Data Buffer"
|
||||
);
|
||||
// - Bone Matrix Indices
|
||||
if (!boneMatrixIndices.empty())
|
||||
if (isAnimated)
|
||||
{
|
||||
const uint32_t BMI_DATA_BYTES = static_cast<uint32_t>(boneMatrixIndices.size() * sizeof(uint32_t));
|
||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||
|
@ -625,7 +669,7 @@ namespace SHADE
|
|||
|
||||
// Bind all required objects before drawing
|
||||
std::vector<uint32_t> dynamicOffset{ 0 };
|
||||
if (!boneMatrixData.empty())
|
||||
if (isAnimated)
|
||||
{
|
||||
dynamicOffset.emplace_back(0);
|
||||
}
|
||||
|
@ -633,7 +677,7 @@ namespace SHADE
|
|||
cmdBuffer->BindPipeline(pipeline);
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
||||
if (boneMatrixFirstIndexBuffer[frameIndex])
|
||||
if (isAnimated && boneMatrixFirstIndexBuffer[frameIndex])
|
||||
{
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_MATRIX_FIRST_INDEX, boneMatrixFirstIndexBuffer[frameIndex], 0);
|
||||
}
|
||||
|
@ -701,12 +745,14 @@ namespace SHADE
|
|||
{
|
||||
layoutTypes = PreDefDescLayoutType::MATERIALS;
|
||||
}
|
||||
if (!boneMatrixData.empty())
|
||||
if (isAnimated)
|
||||
{
|
||||
layoutTypes = PreDefDescLayoutType::MATERIAL_AND_BONES;
|
||||
}
|
||||
|
||||
if (matPropsData || !boneMatrixData.empty())
|
||||
const bool MUST_BUILD_ANIM_BUFFER = isAnimated && !boneMatrixData.empty();
|
||||
|
||||
if (matPropsData || MUST_BUILD_ANIM_BUFFER)
|
||||
{
|
||||
// Make sure that we have a descriptor set if we don't already have one
|
||||
if (!instanceDataDescSet[frameIndex])
|
||||
|
@ -756,7 +802,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
/* Animation Bone Data */
|
||||
if (!boneMatrixData.empty())
|
||||
if (MUST_BUILD_ANIM_BUFFER)
|
||||
{
|
||||
// Update GPU Buffers
|
||||
const uint32_t BONE_MTX_DATA_BYTES = static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix));
|
||||
|
@ -786,4 +832,21 @@ namespace SHADE
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool SHBatch::checkIfIsAnimatedPipeline(Handle<SHVkPipeline> pipeline)
|
||||
{
|
||||
if (!pipeline || !pipeline->GetPipelineLayout())
|
||||
return false;
|
||||
|
||||
// Grab the pipeline descriptor set layouts
|
||||
auto pipelineDescLayouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline();
|
||||
|
||||
// Check if they contain the material and bones layout, that indicates it is
|
||||
using GfxPreDefType = SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes;
|
||||
const Handle<SHVkDescriptorSetLayout> BONE_DESC_SET_LAYOUT = SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(GfxPreDefType::MATERIAL_AND_BONES)[0];
|
||||
return std::find_if(pipelineDescLayouts.begin(), pipelineDescLayouts.end(), [BONE_DESC_SET_LAYOUT](Handle<SHVkDescriptorSetLayout> layout)
|
||||
{
|
||||
return BONE_DESC_SET_LAYOUT == layout;
|
||||
}) != pipelineDescLayouts.end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,8 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
// Resources
|
||||
Handle<SHVkLogicalDevice> device;
|
||||
// Config
|
||||
bool isAnimated; // Whether the material supports animation
|
||||
// Batch Properties
|
||||
Handle<SHVkPipeline> pipeline;
|
||||
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
||||
|
@ -126,7 +128,7 @@ namespace SHADE
|
|||
Byte matPropsDataSize = 0;
|
||||
Byte singleMatPropAlignedSize = 0;
|
||||
Byte singleMatPropSize = 0;
|
||||
std::vector<SHMatrix> boneMatrixData;
|
||||
std::vector<SHMatrix> boneMatrixData; // 0th element is always an identity matrix
|
||||
std::vector<uint32_t> boneMatrixIndices;
|
||||
bool isCPUBuffersDirty = true;
|
||||
// GPU Buffers
|
||||
|
@ -143,5 +145,6 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
void setAllDirtyFlags();
|
||||
void rebuildDescriptorSetBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||
static bool checkIfIsAnimatedPipeline(Handle<SHVkPipeline> pipeline);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -173,6 +173,7 @@ namespace SHADE
|
|||
}
|
||||
else
|
||||
{
|
||||
// Automatically set to index 0, which will be an identity matrix
|
||||
vertBoneIdxStorage.resize(vertBoneIdxStorage.size() + addJob.VertexCount);
|
||||
}
|
||||
if (addJob.VertexBoneWeights)
|
||||
|
|
Loading…
Reference in New Issue