Moves tracking of requiring update models to upper

We need to track models to update in a single place. SceneRenderer in
that case. It allows us to make ModelVertexRenderer implementations more
straightforward.
This commit is contained in:
Vladislav Belov
2026-09-10 15:27:09 +02:00
parent a374411279
commit e933d18a36
4 changed files with 41 additions and 62 deletions
+2 -11
View File
@@ -198,17 +198,8 @@ void CPUSkinnedModelVertexRenderer::UpdateModelsData(Renderer::Backend::IDeviceC
{
for (CModel* model : models)
{
CModelRData* rdata = static_cast<CModelRData*>(model->GetRenderData());
UpdateModelData(model, rdata, rdata->m_UpdateFlags);
}
}
// Fill in and upload dynamic vertex array
void CPUSkinnedModelVertexRenderer::UpdateModelData(CModel* model, CModelRData* data, int updateflags)
{
if (updateflags & RENDERDATA_UPDATE_VERTICES)
{
ModelRData* modelRData = static_cast<ModelRData*>(data);
CModelRData* rdata{static_cast<CModelRData*>(model->GetRenderData())};
ModelRData* modelRData{static_cast<ModelRData*>(rdata)};
// build vertices
VertexArrayIterator<CVector3D> Position = modelRData->m_Position.GetIterator<CVector3D>();
@@ -62,9 +62,6 @@ public:
void PrepareForRendering(std::span<CModel*> models);
protected:
void UpdateModelData(
CModel* model, CModelRData* data, int updateflags);
void UploadModelData(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
CModel* model, CModelRData* data);
+23 -26
View File
@@ -423,34 +423,31 @@ void GPUSkinnedModelModelRenderer::UpdateModelData(
ModelDefRData* modelDefRData{static_cast<ModelDefRData*>(modelDef->GetRenderData(m.get()))};
ModelRData* modelRData{static_cast<ModelRData*>(data)};
if (updateflags & RENDERDATA_UPDATE_VERTICES)
{
constexpr uint32_t threadGroupWorkRegionDim{64};
const uint32_t vertexCount{static_cast<uint32_t>(modelRData->m_PositionHandle->m_Count)};
const uint32_t dispatchGroupCountX{DivideRoundUp(vertexCount, threadGroupWorkRegionDim)};
constexpr uint32_t threadGroupWorkRegionDim{64};
const uint32_t vertexCount{static_cast<uint32_t>(modelRData->m_PositionHandle->m_Count)};
const uint32_t dispatchGroupCountX{DivideRoundUp(vertexCount, threadGroupWorkRegionDim)};
// Bind matrices for current animation state.
// Add 1 to NumBones because of the special 'root' bone.
deviceCommandContext->SetUniform(
shaderProgram->GetBindingSlot(str_skinBlendMatrices),
std::span<const float>(
model->GetAnimatedBoneMatrices()[0]._data,
model->GetAnimatedBoneMatrices()[0].AsFloatArray().size() * (modelDef->GetNumBones() + 1)));
// Bind matrices for current animation state.
// Add 1 to NumBones because of the special 'root' bone.
deviceCommandContext->SetUniform(
shaderProgram->GetBindingSlot(str_skinBlendMatrices),
std::span<const float>(
model->GetAnimatedBoneMatrices()[0]._data,
model->GetAnimatedBoneMatrices()[0].AsFloatArray().size() * (modelDef->GetNumBones() + 1)));
ENSURE(modelRData->m_PositionHandle->m_Count == modelRData->m_NormalTangentHandle->m_Count);
deviceCommandContext->SetUniform(shaderProgram->GetBindingSlot(str_vertexCount),
static_cast<float>(vertexCount));
deviceCommandContext->SetUniform(shaderProgram->GetBindingSlot(str_offset),
static_cast<float>(modelDefRData->m_Array.GetOffset()),
static_cast<float>(modelDefRData->m_BlendArray.GetOffset()),
static_cast<float>(modelRData->m_PositionHandle->m_Index),
static_cast<float>(modelRData->m_NormalTangentHandle->m_Index));
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_InputVertices), modelDefRData->m_Array.GetBuffer());
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_SkinData), modelDefRData->m_BlendArray.GetBuffer());
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_OutputPositions), modelRData->m_PositionHandle->m_Owner->GetBuffer());
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_OutputNormalsTangents), modelRData->m_NormalTangentHandle->m_Owner->GetBuffer());
deviceCommandContext->Dispatch(dispatchGroupCountX, 1, 1);
}
ENSURE(modelRData->m_PositionHandle->m_Count == modelRData->m_NormalTangentHandle->m_Count);
deviceCommandContext->SetUniform(shaderProgram->GetBindingSlot(str_vertexCount),
static_cast<float>(vertexCount));
deviceCommandContext->SetUniform(shaderProgram->GetBindingSlot(str_offset),
static_cast<float>(modelDefRData->m_Array.GetOffset()),
static_cast<float>(modelDefRData->m_BlendArray.GetOffset()),
static_cast<float>(modelRData->m_PositionHandle->m_Index),
static_cast<float>(modelRData->m_NormalTangentHandle->m_Index));
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_InputVertices), modelDefRData->m_Array.GetBuffer());
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_SkinData), modelDefRData->m_BlendArray.GetBuffer());
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_OutputPositions), modelRData->m_PositionHandle->m_Owner->GetBuffer());
deviceCommandContext->SetStorageBuffer(shaderProgram->GetBindingSlot(str_OutputNormalsTangents), modelRData->m_NormalTangentHandle->m_Owner->GetBuffer());
deviceCommandContext->Dispatch(dispatchGroupCountX, 1, 1);
}
void GPUSkinnedModelModelRenderer::UploadModelsData(Renderer::Backend::IDeviceCommandContext*,
+16 -22
View File
@@ -139,6 +139,8 @@ public:
Submissions TransparentSkinned;
Submissions TransparentUnskinned;
std::vector<CModel*> uniqueSkinnedSubmissionsForUpdate;
ModelRenderer modelRenderer;
InstancingModelRenderer VertexInstancingShader;
@@ -168,12 +170,7 @@ public:
Model.GPUSkinningEnabled
? static_cast<ModelVertexRenderer&>(*Model.VertexGPUSkinningShader)
: static_cast<ModelVertexRenderer&>(Model.VertexCPUSkinningShader)};
for (int cullGroup{0}; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup)
{
modelVertexSkinningRenderer.UploadModelsData(deviceCommandContext, Model.OpaqueSkinned.submissions[cullGroup]);
modelVertexSkinningRenderer.UploadModelsData(deviceCommandContext, Model.TransparentSkinned.submissions[cullGroup]);
}
modelVertexSkinningRenderer.UploadModelsData(deviceCommandContext, Model.uniqueSkinnedSubmissionsForUpdate);
for (int cullGroup{0}; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup)
{
@@ -201,10 +198,12 @@ public:
for (int cullGroup{0}; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup)
{
PrepareModels(deviceCommandContext, modelVertexSkinningRenderer, Model.OpaqueSkinned.submissions[cullGroup]);
PrepareModels(deviceCommandContext, modelVertexSkinningRenderer, Model.TransparentSkinned.submissions[cullGroup]);
PrepareModels(modelVertexSkinningRenderer, Model.OpaqueSkinned.submissions[cullGroup]);
PrepareModels(modelVertexSkinningRenderer, Model.TransparentSkinned.submissions[cullGroup]);
}
modelVertexSkinningRenderer.UpdateModelsData(deviceCommandContext, Model.uniqueSkinnedSubmissionsForUpdate);
// See CPUSkinnedModelVertexRenderer::PrepareForRendering comment.
if (!Model.GPUSkinningEnabled)
{
@@ -215,30 +214,24 @@ public:
}
}
for (int cullGroup{0}; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup)
{
PrepareModels(deviceCommandContext, Model.VertexInstancingShader, Model.OpaqueUnskinned.submissions[cullGroup]);
PrepareModels(deviceCommandContext, Model.VertexInstancingShader, Model.TransparentUnskinned.submissions[cullGroup]);
}
// We don't need to update unskinned models.
}
void PrepareModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext, ModelVertexRenderer& modelVertexRenderer, std::span<CModel*> submissions)
ModelVertexRenderer& modelVertexRenderer, std::span<CModel*> submissions)
{
for (CModel* model : submissions)
{
model->ValidatePosition();
CModelRData* rdata = static_cast<CModelRData*>(model->GetRenderData());
CModelRData* rdata{static_cast<CModelRData*>(model->GetRenderData())};
ENSURE(rdata->GetKey() == &modelVertexRenderer);
}
modelVertexRenderer.UpdateModelsData(deviceCommandContext, submissions);
for (CModel* model : submissions)
{
CModelRData* rdata = static_cast<CModelRData*>(model->GetRenderData());
rdata->m_UpdateFlags = 0;
if (rdata->m_UpdateFlags & RENDERDATA_UPDATE_VERTICES)
{
Model.uniqueSkinnedSubmissionsForUpdate.emplace_back(model);
rdata->m_UpdateFlags = 0;
}
}
}
@@ -1010,6 +1003,7 @@ void CSceneRenderer::EndFrame()
m->Model.OpaqueUnskinned.submissions[cullGroup].clear();
m->Model.TransparentUnskinned.submissions[cullGroup].clear();
}
m->Model.uniqueSkinnedSubmissionsForUpdate.clear();
}
void CSceneRenderer::DisplayFrustum(Renderer::Backend::IDeviceCommandContext& deviceCommandContext)