From 9094c3adb0ab064fd27865212382a259ed48ec8d Mon Sep 17 00:00:00 2001 From: Vladislav Belov Date: Wed, 6 Nov 2024 15:41:19 +0100 Subject: [PATCH] Batches update and upload passes for model renderers. --- source/renderer/CPUSkinnedModelRenderer.cpp | 22 +++++++++++++++++++++ source/renderer/CPUSkinnedModelRenderer.h | 18 +++++++++++++---- source/renderer/InstancingModelRenderer.cpp | 9 +++++---- source/renderer/InstancingModelRenderer.h | 11 +++++++---- source/renderer/ModelRenderer.cpp | 18 ++++++++--------- source/renderer/ModelRenderer.h | 6 ++++-- source/renderer/ModelVertexRenderer.h | 19 ++++++++++-------- source/renderer/SceneRenderer.cpp | 8 ++++---- 8 files changed, 76 insertions(+), 35 deletions(-) diff --git a/source/renderer/CPUSkinnedModelRenderer.cpp b/source/renderer/CPUSkinnedModelRenderer.cpp index a8bf1feeeb..b3cbb20fde 100644 --- a/source/renderer/CPUSkinnedModelRenderer.cpp +++ b/source/renderer/CPUSkinnedModelRenderer.cpp @@ -188,6 +188,17 @@ CModelRData* CPUSkinnedModelVertexRenderer::CreateModelData(const void* key, CMo return modelRData; } +void CPUSkinnedModelVertexRenderer::UpdateModelsData( + Renderer::Backend::IDeviceCommandContext* UNUSED(deviceCommandContext), + PS::span models) +{ + for (CModel* model : models) + { + CModelRData* rdata = static_cast(model->GetRenderData()); + UpdateModelData(model, rdata, rdata->m_UpdateFlags); + } +} + // Fill in and upload dynamic vertex array void CPUSkinnedModelVertexRenderer::UpdateModelData(CModel* model, CModelRData* data, int updateflags) { @@ -208,6 +219,17 @@ void CPUSkinnedModelVertexRenderer::UpdateModelData(CModel* model, CModelRData* modelRData->m_Array.PrepareForRendering(); } +void CPUSkinnedModelVertexRenderer::UploadModelsData( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + PS::span models) +{ + for (CModel* model : models) + { + CModelRData* rdata = static_cast(model->GetRenderData()); + UploadModelData(deviceCommandContext, model, rdata); + } +} + void CPUSkinnedModelVertexRenderer::UploadModelData( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, CModel* model, CModelRData* data) diff --git a/source/renderer/CPUSkinnedModelRenderer.h b/source/renderer/CPUSkinnedModelRenderer.h index 70b80d7b9e..361c9c8fe5 100644 --- a/source/renderer/CPUSkinnedModelRenderer.h +++ b/source/renderer/CPUSkinnedModelRenderer.h @@ -35,11 +35,14 @@ public: ~CPUSkinnedModelVertexRenderer(); CModelRData* CreateModelData(const void* key, CModel* model) override; - void UpdateModelData(CModel* model, CModelRData* data, int updateflags) override; - - void UploadModelData( + void UpdateModelsData( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, - CModel* model, CModelRData* data) override; + PS::span models) override; + + void UploadModelsData( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + PS::span models) override; + void PrepareModelDef( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CModelDef& def) override; @@ -48,6 +51,13 @@ public: Renderer::Backend::IShaderProgram* shader, CModel* model, CModelRData* data) override; protected: + void UpdateModelData( + CModel* model, CModelRData* data, int updateflags); + + void UploadModelData( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + CModel* model, CModelRData* data); + struct Internals; std::unique_ptr m; }; diff --git a/source/renderer/InstancingModelRenderer.cpp b/source/renderer/InstancingModelRenderer.cpp index 6a7acef871..663a1077db 100644 --- a/source/renderer/InstancingModelRenderer.cpp +++ b/source/renderer/InstancingModelRenderer.cpp @@ -334,15 +334,16 @@ CModelRData* InstancingModelRenderer::CreateModelData(const void* key, CModel* m return new CModelRData(key); } - -void InstancingModelRenderer::UpdateModelData(CModel* UNUSED(model), CModelRData* UNUSED(data), int UNUSED(updateflags)) +void InstancingModelRenderer::UpdateModelsData( + Renderer::Backend::IDeviceCommandContext* UNUSED(deviceCommandContext), + PS::span UNUSED(models)) { // We have no per-CModel data } -void InstancingModelRenderer::UploadModelData( +void InstancingModelRenderer::UploadModelsData( Renderer::Backend::IDeviceCommandContext* UNUSED(deviceCommandContext), - CModel* UNUSED(model), CModelRData* UNUSED(data)) + PS::span UNUSED(models)) { // Data uploaded once during creation as we don't update it dynamically. } diff --git a/source/renderer/InstancingModelRenderer.h b/source/renderer/InstancingModelRenderer.h index a8278dbd41..41e99fffb4 100644 --- a/source/renderer/InstancingModelRenderer.h +++ b/source/renderer/InstancingModelRenderer.h @@ -40,11 +40,14 @@ public: // Implementations CModelRData* CreateModelData(const void* key, CModel* model) override; - void UpdateModelData(CModel* model, CModelRData* data, int updateflags) override; - - void UploadModelData( + void UpdateModelsData( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, - CModel* model, CModelRData* data) override; + PS::span models) override; + + void UploadModelsData( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + PS::span models) override; + void PrepareModelDef( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CModelDef& def) override; diff --git a/source/renderer/ModelRenderer.cpp b/source/renderer/ModelRenderer.cpp index 95a35cc1af..b793aead57 100644 --- a/source/renderer/ModelRenderer.cpp +++ b/source/renderer/ModelRenderer.cpp @@ -229,7 +229,8 @@ void ShaderModelRenderer::Submit(int cullGroup, CModel* model) // Call update for all submitted models and enter the rendering phase -void ShaderModelRenderer::PrepareModels() +void ShaderModelRenderer::PrepareModels( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) { for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup) { @@ -239,8 +240,13 @@ void ShaderModelRenderer::PrepareModels() CModelRData* rdata = static_cast(model->GetRenderData()); ENSURE(rdata->GetKey() == m->vertexRenderer.get()); + } - m->vertexRenderer->UpdateModelData(model, rdata, rdata->m_UpdateFlags); + m->vertexRenderer->UpdateModelsData(deviceCommandContext, m->submissions[cullGroup]); + + for (CModel* model : m->submissions[cullGroup]) + { + CModelRData* rdata = static_cast(model->GetRenderData()); rdata->m_UpdateFlags = 0; } } @@ -251,13 +257,7 @@ void ShaderModelRenderer::UploadModels( { for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup) { - for (CModel* model : m->submissions[cullGroup]) - { - CModelRData* rdata = static_cast(model->GetRenderData()); - ENSURE(rdata->GetKey() == m->vertexRenderer.get()); - - m->vertexRenderer->UploadModelData(deviceCommandContext, model, rdata); - } + m->vertexRenderer->UploadModelsData(deviceCommandContext, m->submissions[cullGroup]); } } diff --git a/source/renderer/ModelRenderer.h b/source/renderer/ModelRenderer.h index 4359f2b76f..c0cd477667 100644 --- a/source/renderer/ModelRenderer.h +++ b/source/renderer/ModelRenderer.h @@ -133,7 +133,8 @@ public: * Must be called before any rendering calls and after all models * for this frame have been submitted. */ - virtual void PrepareModels() = 0; + virtual void PrepareModels( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) = 0; /** * Upload renderer data for all previously submitted models to backend. @@ -271,7 +272,8 @@ public: // Batching implementations void Submit(int cullGroup, CModel* model) override; - void PrepareModels() override; + void PrepareModels( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) override; void UploadModels( Renderer::Backend::IDeviceCommandContext* deviceCommandContext) override; void EndFrame() override; diff --git a/source/renderer/ModelVertexRenderer.h b/source/renderer/ModelVertexRenderer.h index 3f1cc2ee33..cb7e14183b 100644 --- a/source/renderer/ModelVertexRenderer.h +++ b/source/renderer/ModelVertexRenderer.h @@ -25,6 +25,7 @@ #include "graphics/MeshManager.h" #include "graphics/ShaderProgramPtr.h" +#include "ps/containers/Span.h" #include "renderer/backend/IDeviceCommandContext.h" #include "renderer/backend/IShaderProgram.h" @@ -78,13 +79,12 @@ public: * perform software vertex transforms and potentially other per-frame * calculations. * - * @param model The model. - * @param data Private data as returned by CreateModelData. - * @param updateflags Flags indicating which data has changed during - * the frame. The value is the same as the value of the model's - * CRenderData::m_UpdateFlags. + * @param deviceCommandContext context for backend commands (f.e. uploading). + * @param models models. */ - virtual void UpdateModelData(CModel* model, CModelRData* data, int updateflags) = 0; + virtual void UpdateModelsData( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + PS::span models) = 0; /** * Upload per-model data to backend. @@ -94,10 +94,13 @@ public: * * ModelVertexRenderer implementations should use this function to * upload all needed data to backend. + * + * @param deviceCommandContext context for backend commands (f.e. uploading). + * @param models models. */ - virtual void UploadModelData( + virtual void UploadModelsData( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, - CModel* model, CModelRData* data) = 0; + PS::span models) = 0; /** * PrepareModelDef: Setup backend state for rendering of models that diff --git a/source/renderer/SceneRenderer.cpp b/source/renderer/SceneRenderer.cpp index 3f039455ce..932f0f3d3b 100644 --- a/source/renderer/SceneRenderer.cpp +++ b/source/renderer/SceneRenderer.cpp @@ -789,12 +789,12 @@ void CSceneRenderer::PrepareSubmissions( // Prepare model renderers { PROFILE3("prepare models"); - m->Model.NormalSkinned->PrepareModels(); - m->Model.TranspSkinned->PrepareModels(); + m->Model.NormalSkinned->PrepareModels(deviceCommandContext); + m->Model.TranspSkinned->PrepareModels(deviceCommandContext); if (m->Model.NormalUnskinned != m->Model.NormalSkinned) - m->Model.NormalUnskinned->PrepareModels(); + m->Model.NormalUnskinned->PrepareModels(deviceCommandContext); if (m->Model.TranspUnskinned != m->Model.TranspSkinned) - m->Model.TranspUnskinned->PrepareModels(); + m->Model.TranspUnskinned->PrepareModels(deviceCommandContext); } m->terrainRenderer.PrepareForRendering();