From b65448bcbe76ad8e39c3a492fb0a38d1540f476b Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Sun, 9 Apr 2017 11:08:35 -0700 Subject: [PATCH] Trying to improve the Job/Task classes and testing it with the ZoneRenderer --- interface/src/Application.cpp | 4 +- .../src/EntityTreeRenderer.cpp | 2 +- .../render-utils/src/RenderDeferredTask.cpp | 84 ++++++++++--------- .../render-utils/src/RenderDeferredTask.h | 7 +- .../render-utils/src/RenderForwardTask.cpp | 16 ++-- .../render-utils/src/RenderForwardTask.h | 7 +- .../render-utils/src/RenderShadowTask.cpp | 16 ++-- libraries/render-utils/src/RenderShadowTask.h | 5 +- libraries/render-utils/src/ZoneRenderer.cpp | 8 +- libraries/render-utils/src/ZoneRenderer.h | 6 +- libraries/render/src/render/Engine.cpp | 3 + libraries/render/src/render/Engine.h | 1 + libraries/render/src/render/FilterTask.cpp | 1 + .../src/render/RenderFetchCullSortTask.cpp | 22 ++--- .../src/render/RenderFetchCullSortTask.h | 6 +- libraries/render/src/render/Task.h | 47 +++++++---- .../utilities/render/debugDeferredLighting.js | 2 +- .../utilities/render/deferredLighting.qml | 5 ++ tests/render-perf/src/main.cpp | 4 +- 19 files changed, 143 insertions(+), 103 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 342d325f58..778df09588 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1880,9 +1880,9 @@ void Application::initializeGL() { assert(items.canCast()); static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD"; if (QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD)) { - _renderEngine->addJob("Forward", items.get()); + _renderEngine->addJob("Forward", items); } else { - _renderEngine->addJob("RenderDeferredTask", items.get()); + _renderEngine->addJob("RenderDeferredTask", items); } _renderEngine->load(); _renderEngine->registerScene(_main3DScene); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 176ba9a4d8..63684dcf0f 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -368,7 +368,7 @@ bool EntityTreeRenderer::applyLayeredZones() { qCWarning(entitiesrenderer) << "EntityTreeRenderer::applyLayeredZones(), Unexpected null scene, possibly during application shutdown"; } - + return true; } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 97b7568546..4e9203ad4f 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -50,7 +50,9 @@ using namespace render; extern void initOverlay3DPipelines(render::ShapePlumber& plumber); extern void initDeferredPipelines(render::ShapePlumber& plumber); -RenderDeferredTask::RenderDeferredTask(RenderFetchCullSortTask::Output items) { +void RenderDeferredTask::build(render::Task& task, const render::Varying& input, render::Varying& output) { + auto items = input.get(); + // Prepare the ShapePipelines ShapePlumberPointer shapePlumber = std::make_shared(); initDeferredPipelines(*shapePlumber); @@ -67,130 +69,130 @@ RenderDeferredTask::RenderDeferredTask(RenderFetchCullSortTask::Output items) { // Filter the non antialiaased overlays const int LAYER_NO_AA = 3; - const auto nonAAOverlays = addJob("Filter2DWebOverlays", overlayOpaques, LAYER_NO_AA); + const auto nonAAOverlays = task.addJob("Filter2DWebOverlays", overlayOpaques, LAYER_NO_AA); // Prepare deferred, generate the shared Deferred Frame Transform - const auto deferredFrameTransform = addJob("DeferredFrameTransform"); - const auto lightingModel = addJob("LightingModel"); + const auto deferredFrameTransform = task.addJob("DeferredFrameTransform"); + const auto lightingModel = task.addJob("LightingModel"); // GPU jobs: Start preparing the primary, deferred and lighting buffer - const auto primaryFramebuffer = addJob("PreparePrimaryBuffer"); + const auto primaryFramebuffer = task.addJob("PreparePrimaryBuffer"); - const auto opaqueRangeTimer = addJob("BeginOpaqueRangeTimer", "DrawOpaques"); + const auto opaqueRangeTimer = task.addJob("BeginOpaqueRangeTimer", "DrawOpaques"); const auto prepareDeferredInputs = PrepareDeferred::Inputs(primaryFramebuffer, lightingModel).hasVarying(); - const auto prepareDeferredOutputs = addJob("PrepareDeferred", prepareDeferredInputs); + const auto prepareDeferredOutputs = task.addJob("PrepareDeferred", prepareDeferredInputs); const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); const auto lightingFramebuffer = prepareDeferredOutputs.getN(1); // Render opaque objects in DeferredBuffer const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); - addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); + task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); // Once opaque is all rendered create stencil background - addJob("DrawOpaqueStencil", deferredFramebuffer); + task.addJob("DrawOpaqueStencil", deferredFramebuffer); - addJob("OpaqueRangeTimer", opaqueRangeTimer); + task.addJob("OpaqueRangeTimer", opaqueRangeTimer); // Opaque all rendered // Linear Depth Pass const auto linearDepthPassInputs = LinearDepthPass::Inputs(deferredFrameTransform, deferredFramebuffer).hasVarying(); - const auto linearDepthPassOutputs = addJob("LinearDepth", linearDepthPassInputs); + const auto linearDepthPassOutputs = task.addJob("LinearDepth", linearDepthPassInputs); const auto linearDepthTarget = linearDepthPassOutputs.getN(0); // Curvature pass const auto surfaceGeometryPassInputs = SurfaceGeometryPass::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying(); - const auto surfaceGeometryPassOutputs = addJob("SurfaceGeometry", surfaceGeometryPassInputs); + const auto surfaceGeometryPassOutputs = task.addJob("SurfaceGeometry", surfaceGeometryPassInputs); const auto surfaceGeometryFramebuffer = surfaceGeometryPassOutputs.getN(0); const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN(1); const auto midCurvatureNormalFramebuffer = surfaceGeometryPassOutputs.getN(2); const auto lowCurvatureNormalFramebuffer = surfaceGeometryPassOutputs.getN(3); // Simply update the scattering resource - const auto scatteringResource = addJob("Scattering"); + const auto scatteringResource = task.addJob("Scattering"); // AO job const auto ambientOcclusionInputs = AmbientOcclusionEffect::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying(); - const auto ambientOcclusionOutputs = addJob("AmbientOcclusion", ambientOcclusionInputs); + const auto ambientOcclusionOutputs = task.addJob("AmbientOcclusion", ambientOcclusionInputs); const auto ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN(0); const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN(1); // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. - addJob("DrawLight", lights); + task.addJob("DrawLight", lights); // Light Clustering // Create the cluster grid of lights, cpu job for now const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).hasVarying(); - const auto lightClusters = addJob("LightClustering", lightClusteringPassInputs); + const auto lightClusters = task.addJob("LightClustering", lightClusteringPassInputs); // DeferredBuffer is complete, now let's shade it into the LightingBuffer const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).hasVarying(); - addJob("RenderDeferred", deferredLightingInputs); + task.addJob("RenderDeferred", deferredLightingInputs); // Use Stencil and draw background in Lighting buffer to complete filling in the opaque const auto backgroundInputs = DrawBackgroundDeferred::Inputs(background, lightingModel).hasVarying(); - addJob("DrawBackgroundDeferred", backgroundInputs); + task.addJob("DrawBackgroundDeferred", backgroundInputs); // Render transparent objects forward in LightingBuffer const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).hasVarying(); - addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber); + task.addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber); // LIght Cluster Grid Debuging job { const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget, lightClusters).hasVarying(); - addJob("DebugLightClusters", debugLightClustersInputs); + task.addJob("DebugLightClusters", debugLightClustersInputs); } - const auto toneAndPostRangeTimer = addJob("BeginToneAndPostRangeTimer", "PostToneOverlaysAntialiasing"); + const auto toneAndPostRangeTimer = task.addJob("BeginToneAndPostRangeTimer", "PostToneOverlaysAntialiasing"); // Lighting Buffer ready for tone mapping const auto toneMappingInputs = render::Varying(ToneMappingDeferred::Inputs(lightingFramebuffer, primaryFramebuffer)); - addJob("ToneMapping", toneMappingInputs); + task.addJob("ToneMapping", toneMappingInputs); { // DEbug the bounds of the rendered items, still look at the zbuffer - addJob("DrawMetaBounds", metas); - addJob("DrawOpaqueBounds", opaques); - addJob("DrawTransparentBounds", transparents); + task.addJob("DrawMetaBounds", metas); + task.addJob("DrawOpaqueBounds", opaques); + task.addJob("DrawTransparentBounds", transparents); + + task.addJob("ZoneRenderer", opaques); } // Overlays const auto overlayOpaquesInputs = DrawOverlay3D::Inputs(overlayOpaques, lightingModel).hasVarying(); const auto overlayTransparentsInputs = DrawOverlay3D::Inputs(overlayTransparents, lightingModel).hasVarying(); - addJob("DrawOverlay3DOpaque", overlayOpaquesInputs, true); - addJob("DrawOverlay3DTransparent", overlayTransparentsInputs, false); + task.addJob("DrawOverlay3DOpaque", overlayOpaquesInputs, true); + task.addJob("DrawOverlay3DTransparent", overlayTransparentsInputs, false); { // DEbug the bounds of the rendered OVERLAY items, still look at the zbuffer - addJob("DrawOverlayOpaqueBounds", overlayOpaques); - addJob("DrawOverlayTransparentBounds", overlayTransparents); + task.addJob("DrawOverlayOpaqueBounds", overlayOpaques); + task.addJob("DrawOverlayTransparentBounds", overlayTransparents); } // Debugging stages { // Debugging Deferred buffer job const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer)); - addJob("DebugDeferredBuffer", debugFramebuffers); + task.addJob("DebugDeferredBuffer", debugFramebuffers); const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).hasVarying(); - addJob("DebugScattering", debugSubsurfaceScatteringInputs); + task.addJob("DebugScattering", debugSubsurfaceScatteringInputs); const auto debugAmbientOcclusionInputs = DebugAmbientOcclusion::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget, ambientOcclusionUniforms).hasVarying(); - addJob("DebugAmbientOcclusion", debugAmbientOcclusionInputs); - - addJob("ZoneRenderer", opaques); + task.addJob("DebugAmbientOcclusion", debugAmbientOcclusionInputs); // Scene Octree Debugging job { - addJob("DrawSceneOctree", spatialSelection); - addJob("DrawItemSelection", spatialSelection); + task.addJob("DrawSceneOctree", spatialSelection); + task.addJob("DrawItemSelection", spatialSelection); } // Status icon rendering job @@ -198,22 +200,22 @@ RenderDeferredTask::RenderDeferredTask(RenderFetchCullSortTask::Output items) { // Grab a texture map representing the different status icons and assign that to the drawStatsuJob auto iconMapPath = PathUtils::resourcesPath() + "icons/statusIconAtlas.svg"; auto statusIconMap = DependencyManager::get()->getImageTexture(iconMapPath, NetworkTexture::STRICT_TEXTURE); - addJob("DrawStatus", opaques, DrawStatus(statusIconMap)); + task.addJob("DrawStatus", opaques, DrawStatus(statusIconMap)); } } // AA job to be revisited - addJob("Antialiasing", primaryFramebuffer); + task.addJob("Antialiasing", primaryFramebuffer); // Draw 2DWeb non AA const auto nonAAOverlaysInputs = DrawOverlay3D::Inputs(nonAAOverlays, lightingModel).hasVarying(); - addJob("Draw2DWebSurfaces", nonAAOverlaysInputs, false); + task.addJob("Draw2DWebSurfaces", nonAAOverlaysInputs, false); - addJob("ToneAndPostRangeTimer", toneAndPostRangeTimer); + task.addJob("ToneAndPostRangeTimer", toneAndPostRangeTimer); // Blit! - addJob("Blit", primaryFramebuffer); + task.addJob("Blit", primaryFramebuffer); } void BeginGPURangeTimer::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) { diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 8a95447e67..9ad61b8f1e 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -194,9 +194,12 @@ public: class RenderDeferredTask : public render::Task { public: - using JobModel = Model; + using Input = RenderFetchCullSortTask::Output; + using JobModel = render::Task::ModelI; - RenderDeferredTask(RenderFetchCullSortTask::Output items); + RenderDeferredTask() {} + + void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs); }; #endif // hifi_RenderDeferredTask_h diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 49090c2f5f..630146c698 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -29,7 +29,9 @@ using namespace render; extern void initForwardPipelines(ShapePlumber& plumber); -RenderForwardTask::RenderForwardTask(RenderFetchCullSortTask::Output items) { +void RenderForwardTask::build(render::Task& task, const render::Varying& input, render::Varying& output) { + auto items = input.get(); + // Prepare the ShapePipelines ShapePlumberPointer shapePlumber = std::make_shared(); initForwardPipelines(*shapePlumber); @@ -44,17 +46,17 @@ RenderForwardTask::RenderForwardTask(RenderFetchCullSortTask::Output items) { const auto background = items[RenderFetchCullSortTask::BACKGROUND]; const auto spatialSelection = items[RenderFetchCullSortTask::SPATIAL_SELECTION]; - const auto framebuffer = addJob("PrepareFramebuffer"); + const auto framebuffer = task.addJob("PrepareFramebuffer"); - addJob("DrawOpaques", opaques, shapePlumber); - addJob("Stencil"); - addJob("DrawBackground", background); + task.addJob("DrawOpaques", opaques, shapePlumber); + task.addJob("Stencil"); + task.addJob("DrawBackground", background); // Bounds do not draw on stencil buffer, so they must come last - addJob("DrawBounds", opaques); + task.addJob("DrawBounds", opaques); // Blit! - addJob("Blit", framebuffer); + task.addJob("Blit", framebuffer); } void PrepareFramebuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, diff --git a/libraries/render-utils/src/RenderForwardTask.h b/libraries/render-utils/src/RenderForwardTask.h index 62cbca4382..3fcf1b398f 100755 --- a/libraries/render-utils/src/RenderForwardTask.h +++ b/libraries/render-utils/src/RenderForwardTask.h @@ -18,9 +18,12 @@ class RenderForwardTask : public render::Task { public: - using JobModel = Model; + using Input = RenderFetchCullSortTask::Output; + using JobModel = render::Task::ModelI; - RenderForwardTask(RenderFetchCullSortTask::Output items); + RenderForwardTask() {} + + void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs); }; class PrepareFramebuffer { diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index eb46b8f46e..04e054c921 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -90,7 +90,7 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const }); } -RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) { +void RenderShadowTask::build(render::Task& task, const render::Varying& input, render::Varying& output, CullFunctor cullFunctor) { cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; // Prepare the ShapePipeline @@ -115,22 +115,22 @@ RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) { skinProgram, state); } - const auto cachedMode = addJob("Setup"); + const auto cachedMode = task.addJob("Setup"); // CPU jobs: // Fetch and cull the items from the scene auto shadowFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered(); - const auto shadowSelection = addJob("FetchShadowSelection", shadowFilter); - const auto culledShadowSelection = addJob("CullShadowSelection", shadowSelection, cullFunctor, RenderDetails::SHADOW, shadowFilter); + const auto shadowSelection = task.addJob("FetchShadowSelection", shadowFilter); + const auto culledShadowSelection = task.addJob("CullShadowSelection", shadowSelection, cullFunctor, RenderDetails::SHADOW, shadowFilter); // Sort - const auto sortedPipelines = addJob("PipelineSortShadowSort", culledShadowSelection); - const auto sortedShapes = addJob("DepthSortShadowMap", sortedPipelines); + const auto sortedPipelines = task.addJob("PipelineSortShadowSort", culledShadowSelection); + const auto sortedShapes = task.addJob("DepthSortShadowMap", sortedPipelines); // GPU jobs: Render to shadow map - addJob("RenderShadowMap", sortedShapes, shapePlumber); + task.addJob("RenderShadowMap", sortedShapes, shapePlumber); - addJob("Teardown", cachedMode); + task.addJob("Teardown", cachedMode); } void RenderShadowTask::configure(const Config& configuration) { diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index d2e58f8362..a4b71308e1 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -44,9 +44,10 @@ signals: class RenderShadowTask : public render::Task { public: using Config = RenderShadowTaskConfig; - using JobModel = Model; + using JobModel = render::Task::Model; - RenderShadowTask(render::CullFunctor shouldRender); + RenderShadowTask() {} + void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor shouldRender); void configure(const Config& configuration); }; diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 12252743a7..cdcad638af 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -17,13 +17,11 @@ using namespace render; const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; -ZoneRendererTask::ZoneRendererTask(const Inputs& inputs) { +void ZoneRendererTask::build(render::Task& task, const Varying& input, Varying& ouput) { - const auto zoneItems = addJob("FilterZones", inputs, ZONES_SELECTION); + const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); // just draw them... - addJob("DrawZones", zoneItems); - + task.addJob("DrawZones", zoneItems); } - diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 941a99772d..a5585644d5 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -14,7 +14,7 @@ #include "render/Engine.h" -class ZoneRendererConfig : public render::Job::Config { +class ZoneRendererConfig : public render::Task::Config { Q_OBJECT Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) public: @@ -37,7 +37,9 @@ public: using Config = ZoneRendererConfig; using JobModel = Model; - ZoneRendererTask(const Inputs& inputs); + ZoneRendererTask() {} + + void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs); void configure(const Config& config) { _maxDrawn = config.maxDrawn; } diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 970cc142e0..15dafce29b 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -25,6 +25,9 @@ using namespace render; Engine::Engine() : _sceneContext(std::make_shared()), _renderContext(std::make_shared()) { +} + +void Engine::build() { addJob("Stats"); } diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index de8340c33e..f513912f4f 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -25,6 +25,7 @@ namespace render { public: Engine(); + void build(); ~Engine() = default; // Load any persisted settings, and set up the presets diff --git a/libraries/render/src/render/FilterTask.cpp b/libraries/render/src/render/FilterTask.cpp index 1c044d2db4..68422a021c 100644 --- a/libraries/render/src/render/FilterTask.cpp +++ b/libraries/render/src/render/FilterTask.cpp @@ -57,6 +57,7 @@ void SliceItems::run(const SceneContextPointer& sceneContext, const RenderContex void SelectItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) { auto& scene = sceneContext->_scene; + outItems.clear(); auto selection = scene->getSelection(_name); const auto& selectedItems = selection.getItems(); if (!selectedItems.empty()) { diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index 671cdfff8f..f3d9db7a88 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -17,17 +17,17 @@ using namespace render; -RenderFetchCullSortTask::RenderFetchCullSortTask(CullFunctor cullFunctor) { +void RenderFetchCullSortTask::build(Task& task, const Varying& input, Varying& output, CullFunctor cullFunctor) { cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; // CPU jobs: // Fetch and cull the items from the scene auto spatialFilter = ItemFilter::Builder::visibleWorldItems().withoutLayered(); - const auto spatialSelection = addJob("FetchSceneSelection", spatialFilter); - const auto culledSpatialSelection = addJob("CullSceneSelection", spatialSelection, cullFunctor, RenderDetails::ITEM, spatialFilter); + const auto spatialSelection = task.addJob("FetchSceneSelection", spatialFilter); + const auto culledSpatialSelection = task.addJob("CullSceneSelection", spatialSelection, cullFunctor, RenderDetails::ITEM, spatialFilter); // Overlays are not culled - const auto nonspatialSelection = addJob("FetchOverlaySelection"); + const auto nonspatialSelection = task.addJob("FetchOverlaySelection"); // Multi filter visible items into different buckets const int NUM_SPATIAL_FILTERS = 4; @@ -49,22 +49,22 @@ RenderFetchCullSortTask::RenderFetchCullSortTask(CullFunctor cullFunctor) { ItemFilter::Builder::background() } }; const auto filteredSpatialBuckets = - addJob>("FilterSceneSelection", culledSpatialSelection, spatialFilters) + task.addJob>("FilterSceneSelection", culledSpatialSelection, spatialFilters) .get::ItemBoundsArray>(); const auto filteredNonspatialBuckets = - addJob>("FilterOverlaySelection", nonspatialSelection, nonspatialFilters) + task.addJob>("FilterOverlaySelection", nonspatialSelection, nonspatialFilters) .get::ItemBoundsArray>(); // Extract opaques / transparents / lights / overlays - const auto opaques = addJob("DepthSortOpaque", filteredSpatialBuckets[OPAQUE_SHAPE_BUCKET]); - const auto transparents = addJob("DepthSortTransparent", filteredSpatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false)); + const auto opaques = task.addJob("DepthSortOpaque", filteredSpatialBuckets[OPAQUE_SHAPE_BUCKET]); + const auto transparents = task.addJob("DepthSortTransparent", filteredSpatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false)); const auto lights = filteredSpatialBuckets[LIGHT_BUCKET]; const auto metas = filteredSpatialBuckets[META_BUCKET]; - const auto overlayOpaques = addJob("DepthSortOverlayOpaque", filteredNonspatialBuckets[OPAQUE_SHAPE_BUCKET]); - const auto overlayTransparents = addJob("DepthSortOverlayTransparent", filteredNonspatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false)); + const auto overlayOpaques = task.addJob("DepthSortOverlayOpaque", filteredNonspatialBuckets[OPAQUE_SHAPE_BUCKET]); + const auto overlayTransparents = task.addJob("DepthSortOverlayTransparent", filteredNonspatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false)); const auto background = filteredNonspatialBuckets[BACKGROUND_BUCKET]; - setOutput(Output{{ + output = Varying(Output{{ opaques, transparents, lights, metas, overlayOpaques, overlayTransparents, background, spatialSelection }}); } diff --git a/libraries/render/src/render/RenderFetchCullSortTask.h b/libraries/render/src/render/RenderFetchCullSortTask.h index 1af74939c9..a5db245228 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.h +++ b/libraries/render/src/render/RenderFetchCullSortTask.h @@ -34,9 +34,11 @@ public: }; using Output = std::array; - using JobModel = ModelO; + using JobModel = render::Task::ModelO; - RenderFetchCullSortTask(render::CullFunctor cullFunctor); + RenderFetchCullSortTask() {} + + void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor); }; #endif // hifi_RenderFetchCullSortTask_h diff --git a/libraries/render/src/render/Task.h b/libraries/render/src/render/Task.h index 4e3aa79c8d..4370d7956f 100644 --- a/libraries/render/src/render/Task.h +++ b/libraries/render/src/render/Task.h @@ -542,7 +542,10 @@ public: template Model(const Varying& input, A&&... args) : - Concept(std::make_shared()), _data(Data(std::forward(args)...)), _input(input), _output(Output()) { + Concept(std::make_shared()), + _data(Data(std::forward(args)...)), + _input(input), + _output(Output()) { applyConfiguration(); } @@ -585,31 +588,47 @@ public: _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0); } - protected: +protected: ConceptPointer _concept; std::string _name = ""; }; + +template void jobBuild(T& data, const Varying& input, Varying& output, A&&... args) { + data.build(*(dynamic_cast(&data)), input, output, std::forward(args)...); +} + // A task is a specialized job to run a collection of other jobs // It is defined with JobModel = Task::Model class Task { public: using Config = TaskConfig; using QConfigPointer = Job::QConfigPointer; + using None = Job::None; + using Concept = Job::Concept; + using Jobs = std::vector; - template class Model : public Job::Concept { + template class Model : public Concept { public: using Data = T; - using Config = C; - using Input = Job::None; + using Input = I; + using Output = O; Data _data; + Varying _input; + Varying _output; - const Varying getOutput() const override { return _data._output; } + const Varying getInput() const override { return _input; } + const Varying getOutput() const override { return _output; } template Model(const Varying& input, A&&... args) : - Concept(nullptr), _data(Data(std::forward(args)...)) { + Concept(nullptr), + _data(Data()), + _input(input) { + + jobBuild(_data, _input, _output, std::forward(args)...); + // Recreate the Config to use the templated type _data.template createConfiguration(); _config = _data.getConfiguration(); @@ -621,7 +640,7 @@ public: } void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) override { - auto config = std::static_pointer_cast(_config); + auto config = std::static_pointer_cast(_config); if (config->alwaysEnabled || config->enabled) { for (auto job : _data._jobs) { job.run(sceneContext, renderContext); @@ -629,9 +648,9 @@ public: } } }; - template using ModelO = Model; - - using Jobs = std::vector; + template using ModelI = Model; + template using ModelO = Model; + template using ModelIO = Model; // Create a new job in the container's queue; returns the job's output template const Varying addJob(std::string name, const Varying& input, A&&... args) { @@ -656,7 +675,7 @@ public: } template void setOutput(O&& output) { - _output = Varying(output); + _concept->_output = Varying(output); } template void createConfiguration() { @@ -688,7 +707,6 @@ public: void configure(const QObject& configuration) { for (auto& job : _jobs) { job.applyConfiguration(); - } } @@ -698,12 +716,11 @@ public: } } + protected: - template friend class Model; QConfigPointer _config; Jobs _jobs; - Varying _output; }; } diff --git a/scripts/developer/utilities/render/debugDeferredLighting.js b/scripts/developer/utilities/render/debugDeferredLighting.js index 625f71f8a4..bffa3a2e15 100644 --- a/scripts/developer/utilities/render/debugDeferredLighting.js +++ b/scripts/developer/utilities/render/debugDeferredLighting.js @@ -13,7 +13,7 @@ var qml = Script.resolvePath('deferredLighting.qml'); var window = new OverlayWindow({ title: 'Lighting', source: qml, - width: 400, height:280, + width: 400, height:350, }); window.setPosition(Window.innerWidth - 420, 50); window.closed.connect(function() { Script.stop(); }); diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 778e0e1905..5be37b2b89 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -189,6 +189,11 @@ Column { checked: Render.getConfig("DrawOverlayTransparentBounds")["enabled"] onCheckedChanged: { Render.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked } } + CheckBox { + text: "Zones" + checked: Render.getConfig("DrawZones")["enabled"] + onCheckedChanged: { Render.getConfig("DrawZones")["enabled"] = checked } + } } } diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index b76776b1ab..f407e97a10 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -543,9 +543,9 @@ public: assert(items.canCast()); static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD"; if (QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD)) { - _renderEngine->addJob("RenderForwardTask", items.get()); + _renderEngine->addJob("RenderForwardTask", items); } else { - _renderEngine->addJob("RenderDeferredTask", items.get()); + _renderEngine->addJob("RenderDeferredTask", items); } _renderEngine->load(); _renderEngine->registerScene(_main3DScene);