Optimize development-only shaders and rendering code to compile it out in Release game builds

This commit is contained in:
2026-06-25 11:21:13 +02:00
parent be87583cb2
commit a3694203a2
64 changed files with 252 additions and 121 deletions
@@ -387,6 +387,7 @@ void PS_Depth(PixelInput input)
// Pixel Shader function for Quad Overdraw Pass (editor-only)
[earlydepthstencil]
META_PS(USE_EDITOR, FEATURE_LEVEL_SM5)
META_FLAG(DevelopmentOnly)
void PS_QuadOverdraw(float4 svPos : SV_Position, uint primId : SV_PrimitiveID)
{
DoQuadOverdraw(svPos, primId);
@@ -690,6 +690,7 @@ void PS_Depth(PixelInput input)
// Pixel Shader function for Quad Overdraw Pass (editor-only)
[earlydepthstencil]
META_PS(USE_EDITOR, FEATURE_LEVEL_SM5)
META_FLAG(DevelopmentOnly)
void PS_QuadOverdraw(float4 svPos : SV_Position, uint primId : SV_PrimitiveID)
{
DoQuadOverdraw(svPos, primId);
@@ -594,6 +594,7 @@ void PS_Depth(PixelInput input)
// Pixel Shader function for Quad Overdraw Pass (editor-only)
[earlydepthstencil]
META_PS(USE_EDITOR, FEATURE_LEVEL_SM5)
META_FLAG(DevelopmentOnly)
void PS_QuadOverdraw(float4 svPos : SV_Position, uint primId : SV_PrimitiveID)
{
DoQuadOverdraw(svPos, primId);
@@ -471,6 +471,7 @@ void PS_Depth(PixelInput input)
// Pixel Shader function for Quad Overdraw Pass (editor-only)
[earlydepthstencil]
META_PS(USE_EDITOR, FEATURE_LEVEL_SM5)
META_FLAG(DevelopmentOnly)
void PS_QuadOverdraw(float4 svPos : SV_Position, uint primId : SV_PrimitiveID)
{
DoQuadOverdraw(svPos, primId);
+1 -1
View File
@@ -4,7 +4,7 @@
"Major": 1,
"Minor": 13,
"Revision": 0,
"Build": 7006
"Build": 7007
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
@@ -242,6 +242,11 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
LOG(Info, "{0} option has been modified.", TEXT("ShadersReverseZ"));
invalidateShaders = true;
}
if ((data.Configuration != BuildConfiguration::Release) != Settings.Global.ShadersDevelopment)
{
LOG(Info, "{0} option has been modified.", TEXT("ShadersDevelopment"));
invalidateShaders = true;
}
#if PLATFORM_TOOLS_WINDOWS
if (data.Platform == BuildPlatform::Windows32 || data.Platform == BuildPlatform::Windows64)
{
@@ -432,6 +437,7 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
options.NoOptimize = data.Cache.Settings.Global.ShadersNoOptimize;
options.GenerateDebugData = data.Cache.Settings.Global.ShadersGenerateDebugData;
options.TreatWarningsAsErrors = false;
options.DevelopmentShaders = data.Cache.Settings.Global.ShadersDevelopment;
options.Output = &cacheStream;
options.Platform = data.Data.Tools->GetPlatform();
Array<String> includes;
@@ -1086,6 +1092,7 @@ bool CookAssetsStep::Perform(CookingData& data)
cache.Settings.Global.ShadersNoOptimize = buildSettings->ShadersNoOptimize;
cache.Settings.Global.ShadersGenerateDebugData = buildSettings->ShadersGenerateDebugData;
cache.Settings.Global.ShadersReverseZ = REVERSE_Z;
cache.Settings.Global.ShadersDevelopment = data.Configuration != BuildConfiguration::Release;
cache.Settings.Global.StreamingSettingsAssetId = gameSettings->Streaming;
cache.Settings.Global.ShadersVersion = GPU_SHADER_CACHE_VERSION;
cache.Settings.Global.MaterialGraphVersion = MATERIAL_GRAPH_VERSION;
@@ -98,6 +98,7 @@ public:
bool ShadersNoOptimize;
bool ShadersGenerateDebugData;
bool ShadersReverseZ;
bool ShadersDevelopment;
Guid StreamingSettingsAssetId;
int32 ShadersVersion;
int32 MaterialGraphVersion;
@@ -417,6 +417,13 @@ bool DeployDataStep::Perform(CookingData& data)
data.AddRootEngineAsset(TEXT("Shaders/SSR"));
data.AddRootEngineAsset(TEXT("Shaders/SDF"));
data.AddRootEngineAsset(TEXT("Shaders/VolumetricFog"));
if (data.Configuration != BuildConfiguration::Release)
{
data.AddRootEngineAsset(TEXT("Shaders/Editor/LightmapUVsDensity"));
data.AddRootEngineAsset(TEXT("Shaders/Editor/MaterialComplexity"));
data.AddRootEngineAsset(TEXT("Shaders/Editor/QuadOverdraw"));
data.AddRootEngineAsset(TEXT("Shaders/Editor/VertexColors"));
}
data.AddRootEngineAsset(TEXT("Engine/DefaultMaterial"));
data.AddRootEngineAsset(TEXT("Engine/DefaultDeformableMaterial"));
data.AddRootEngineAsset(TEXT("Engine/DefaultTerrainMaterial"));
+2
View File
@@ -177,6 +177,8 @@ namespace FlaxEditor.Windows
{
// Focus back the input field as user want to modify command from history
Owner.HideHistory();
if (Owner == null)
return true;
Owner.HideSearch();
Owner.RootWindow.Focus();
Owner.Focus();
+3
View File
@@ -91,6 +91,9 @@
// True if use debug tools and flow for shaders
#define GPU_ENABLE_SHADERS_DEBUG_LAYER (BUILD_DEBUG)
// True if use development features for graphics (eg. debug view shaders)
#define GPU_ENABLE_DEVELOPMENT (!BUILD_RELEASE || USE_EDITOR)
// Maximum size of the texture that is supported by the engine (specific platforms can have lower limit)
#define GPU_MAX_TEXTURE_SIZE 16384
#define GPU_MAX_TEXTURE_MIP_LEVELS 15
+10
View File
@@ -172,6 +172,11 @@ API_ENUM() enum class ShaderProfileFeatures
/// </summary>
TessellationShaders = 4,
/// <summary>
/// Development-only shaders are supported. Enabled in Editor or non-Release builds.
/// </summary>
DevelopmentShaders = 8,
API_ENUM(Attributes = "HideInEditor")
MAX
};
@@ -1250,6 +1255,11 @@ enum class ShaderFlags : uint32
/// Indicates that vertex shader function outputs data for the geometry shader.
/// </summary>
VertexToGeometryShader = 4,
/// <summary>
/// Marks shader as used only in development builds: non-release or in editor. Shader won't be compiled for final game release build.
/// </summary>
DevelopmentOnly = 8,
};
DECLARE_ENUM_OPERATORS(ShaderFlags);
+5 -1
View File
@@ -107,6 +107,10 @@ void GPUPipelineState::GetDebugName(DebugName& name) const
bool GPUPipelineState::Init(const Description& desc)
{
#if GPU_ENABLE_DEVELOPMENT
CHECK_RETURN(desc.VS, true);
#endif
// Cache description in development builds
#if !BUILD_RELEASE
DebugDesc = desc;
@@ -128,7 +132,7 @@ bool GPUPipelineState::Init(const Description& desc)
CHECK_STAGE(PS);
#undef CHECK_STAGE
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
// Estimate somehow performance cost of this pipeline state for the content profiling
const int32 textureLookupCost = 20;
const int32 tessCost = 300;
+1 -1
View File
@@ -186,7 +186,7 @@ public:
typedef Array<char, InlinedAllocation<200>> DebugName;
void GetDebugName(DebugName& name) const;
#endif
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
int32 Complexity;
#endif
@@ -87,7 +87,7 @@ void DeferredMaterialShader::Bind(BindParameters& params)
const auto cache = params.Instanced ? &_cacheInstanced : &_cache;
PipelineStateCache* psCache = cache->GetPS(view.Pass, useLightmap, useSkinning, usePerBoneMotionBlur);
ASSERT(psCache);
GPUPipelineState* state = psCache->GetPS(cullMode, wireframe);
GPUPipelineState* state = psCache->GetPS(this, cullMode, wireframe);
// Bind pipeline
context->SetState(state);
@@ -165,7 +165,7 @@ bool DeferredMaterialShader::Load()
psDesc.StencilEnable = false;
psDesc.StencilPassOp = StencilOperation::Keep;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (_shader->HasShader("PS_QuadOverdraw"))
{
// Quad Overdraw
@@ -20,7 +20,7 @@ private:
PipelineStateCache MotionVectors;
PipelineStateCache MotionVectorsSkinned;
PipelineStateCache MotionVectorsSkinnedPerBone;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
PipelineStateCache QuadOverdraw;
PipelineStateCache QuadOverdrawSkinned;
#endif
@@ -37,7 +37,7 @@ private:
return useLightmap ? &DefaultLightmap : (useSkinning ? &DefaultSkinned : &Default);
case DrawPass::MotionVectors:
return useSkinning ? (perBoneMotionBlur ? &MotionVectorsSkinnedPerBone : &MotionVectorsSkinned) : &MotionVectors;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
case DrawPass::QuadOverdraw:
return useSkinning ? &QuadOverdrawSkinned : &QuadOverdraw;
#endif
@@ -55,7 +55,7 @@ private:
DepthSkinned.Release();
MotionVectors.Release();
MotionVectorsSkinned.Release();
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
QuadOverdraw.Release();
QuadOverdrawSkinned.Release();
#endif
@@ -91,7 +91,7 @@ void DeformableMaterialShader::Bind(BindParameters& params)
}
PipelineStateCache* psCache = _cache.GetPS(view.Pass);
ASSERT(psCache);
GPUPipelineState* state = psCache->GetPS(cullMode, wireframe);
GPUPipelineState* state = psCache->GetPS(this, cullMode, wireframe);
// Bind pipeline
context->SetState(state);
@@ -123,7 +123,7 @@ bool DeformableMaterialShader::Load()
}
#endif
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (_shader->HasShader("PS_QuadOverdraw"))
{
// Quad Overdraw
@@ -178,11 +178,7 @@ bool DeformableMaterialShader::Load()
psDesc.DepthClipEnable = false;
psDesc.DepthWriteEnable = true;
psDesc.DepthEnable = true;
#if REVERSE_Z
psDesc.DepthFunc = ComparisonFunc::Greater;
#else
psDesc.DepthFunc = ComparisonFunc::Less;
#endif
psDesc.DepthFunc = ComparisonFunc::Default;
psDesc.HS = nullptr;
psDesc.DS = nullptr;
_cache.Depth.Init(psDesc);
@@ -14,7 +14,7 @@ private:
{
PipelineStateCache Default;
PipelineStateCache Depth;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
PipelineStateCache QuadOverdraw;
#endif
@@ -29,7 +29,7 @@ private:
case DrawPass::GlobalSurfaceAtlas:
case DrawPass::Forward:
return &Default;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
case DrawPass::QuadOverdraw:
return &QuadOverdraw;
#endif
@@ -42,7 +42,7 @@ private:
{
Default.Release();
Depth.Release();
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
QuadOverdraw.Release();
#endif
}
@@ -87,7 +87,7 @@ void ForwardMaterialShader::Bind(BindParameters& params)
const auto cacheObj = params.Instanced ? &_cacheInstanced : &_cache;
PipelineStateCache* psCache = cacheObj->GetPS(view.Pass, useSkinning);
ASSERT(psCache);
GPUPipelineState* state = psCache->GetPS(cullMode, wireframe);
GPUPipelineState* state = psCache->GetPS(this, cullMode, wireframe);
// Bind pipeline
context->SetState(state);
@@ -120,7 +120,7 @@ bool ForwardMaterialShader::Load()
}
#endif
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (_shader->HasShader("PS_QuadOverdraw"))
{
// Quad Overdraw
@@ -18,7 +18,7 @@ private:
PipelineStateCache DepthSkinned;
PipelineStateCache Distortion;
PipelineStateCache DistortionSkinned;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
PipelineStateCache QuadOverdraw;
PipelineStateCache QuadOverdrawSkinned;
#endif
@@ -33,7 +33,7 @@ private:
return useSkinning ? &DistortionSkinned : &Distortion;
case DrawPass::Forward:
return useSkinning ? &DefaultSkinned : &Default;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
case DrawPass::QuadOverdraw:
return useSkinning ? &QuadOverdrawSkinned : &QuadOverdraw;
#endif
@@ -50,6 +50,10 @@ private:
DepthSkinned.Release();
Distortion.Release();
DistortionSkinned.Release();
#if GPU_ENABLE_DEVELOPMENT
QuadOverdraw.Release();
QuadOverdrawSkinned.Release();
#endif
}
};
@@ -117,12 +117,21 @@ void IMaterial::BindParameters::BindDrawData()
GPUContext->BindCB(2, PerDrawConstants);
}
GPUPipelineState* MaterialShader::PipelineStateCache::InitPS(CullMode mode, bool wireframe)
GPUPipelineState* MaterialShader::PipelineStateCache::InitPS(const MaterialShader* owner, CullMode mode, bool wireframe)
{
Desc.CullMode = mode;
Desc.Wireframe = wireframe;
auto ps = GPUDevice::Instance->CreatePipelineState();
ps->Init(Desc);
if (ps->Init(Desc))
{
#if GPU_ENABLE_RESOURCE_NAMING
LOG(Error, "Failed to initialize PSO for material '{}'", owner->GetShader()->GetName());
#else
LOG(Error, "Failed to initialize PSO");
#endif
SAFE_DELETE_GPU_RESOURCE(ps);
return nullptr;
}
return ps;
}
@@ -36,24 +36,24 @@ protected:
PipelineStateCache()
{
Platform::MemoryClear(PS, sizeof(PS));
Platform::MemoryClear(this, sizeof(*this));
}
void Init(GPUPipelineState::Description& desc)
void Init(const GPUPipelineState::Description& desc)
{
Desc = desc;
}
GPUPipelineState* GetPS(CullMode mode, bool wireframe)
GPUPipelineState* GetPS(const MaterialShader* owner, CullMode mode, bool wireframe)
{
const int32 index = static_cast<int32>(mode) + (wireframe ? 3 : 0);
auto ps = PS[index];
if (!ps)
PS[index] = ps = InitPS(mode, wireframe);
PS[index] = ps = InitPS(owner, mode, wireframe);
return ps;
}
GPUPipelineState* InitPS(CullMode mode, bool wireframe);
GPUPipelineState* InitPS(const MaterialShader* owner, CullMode mode, bool wireframe);
void Release()
{
@@ -125,7 +125,7 @@ bool LightmapFeature::Bind(MaterialShader::BindParameters& params, Span<byte>& c
auto& drawCall = *params.DrawCall;
const bool useLightmap = EnumHasAnyFlags(params.RenderContext.View.Flags, ViewFlags::GI)
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
&& EnableLightmapsUsage
#endif
&& drawCall.Surface.Lightmap != nullptr;
@@ -160,7 +160,7 @@ void ParticleMaterialShader::Bind(BindParameters& params)
}
}
ASSERT(psCache);
GPUPipelineState* state = psCache->GetPS(cullMode, wireframe);
GPUPipelineState* state = psCache->GetPS(this, cullMode, wireframe);
// Bind constants
if (_cb)
@@ -195,7 +195,7 @@ bool ParticleMaterialShader::Load()
auto vsMesh = _shader->GetVS("VS_Model");
auto vsRibbon = _shader->GetVS("VS_Ribbon");
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (_shader->HasShader("PS_QuadOverdraw"))
{
// Quad Overdraw
@@ -15,7 +15,7 @@ private:
PipelineStateCache Default;
PipelineStateCache Depth;
PipelineStateCache Distortion;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
PipelineStateCache QuadOverdraw;
#endif
@@ -29,7 +29,7 @@ private:
return &Distortion;
case DrawPass::Forward:
return &Default;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
case DrawPass::QuadOverdraw:
return &QuadOverdraw;
#endif
@@ -43,7 +43,7 @@ private:
Default.Release();
Depth.Release();
Distortion.Release();
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
QuadOverdraw.Release();
#endif
}
@@ -115,7 +115,7 @@ void TerrainMaterialShader::Bind(BindParameters& params)
}
const PipelineStateCache* psCache = _cache.GetPS(view.Pass, useLightmap);
ASSERT(psCache);
GPUPipelineState* state = ((PipelineStateCache*)psCache)->GetPS(cullMode, wireframe);
GPUPipelineState* state = ((PipelineStateCache*)psCache)->GetPS(this, cullMode, wireframe);
// Bind pipeline
context->SetState(state);
@@ -174,7 +174,7 @@ bool TerrainMaterialShader::Load()
psDesc.PS = _shader->GetPS("PS_GBuffer", 1);
_cache.DefaultLightmap.Init(psDesc);
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (_shader->HasShader("PS_QuadOverdraw"))
{
// Quad Overdraw
@@ -15,7 +15,7 @@ private:
PipelineStateCache Default;
PipelineStateCache DefaultLightmap;
PipelineStateCache Depth;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
PipelineStateCache QuadOverdraw;
#endif
@@ -29,7 +29,7 @@ private:
case DrawPass::GBuffer | DrawPass::GlobalSurfaceAtlas:
case DrawPass::GlobalSurfaceAtlas:
return useLightmap ? &DefaultLightmap : &Default;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
case DrawPass::QuadOverdraw:
return &QuadOverdraw;
#endif
@@ -43,7 +43,7 @@ private:
Default.Release();
DefaultLightmap.Release();
Depth.Release();
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
QuadOverdraw.Release();
#endif
}
+4 -4
View File
@@ -15,7 +15,7 @@
#include "Engine/Scripting/ManagedCLR/MCore.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Profiler/ProfilerMemory.h"
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Renderer/GBufferPass.h"
#endif
@@ -242,7 +242,7 @@ void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, cons
drawCall.Surface.PrevWorld = world;
drawCall.PerInstanceRandom = perInstanceRandom;
drawCall.StencilValue = stencilValue;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
const ViewMode viewMode = renderContext.View.Mode;
if (viewMode == ViewMode::LightmapUVsDensity || viewMode == ViewMode::LODPreview)
GBufferPass::AddIndexBufferToModelLOD(_indexBuffer, &((Model*)_model)->LODs[_lodIndex]);
@@ -309,7 +309,7 @@ void Mesh::Draw(const RenderContext& renderContext, const DrawInfo& info, float
drawCall.Surface.LODDitherFactor = (byte)(lodDitherFactor * 255);
drawCall.PerInstanceRandom = info.PerInstanceRandom;
drawCall.StencilValue = info.StencilValue;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
const ViewMode viewMode = renderContext.View.Mode;
if (viewMode == ViewMode::LightmapUVsDensity || viewMode == ViewMode::LODPreview)
GBufferPass::AddIndexBufferToModelLOD(_indexBuffer, &((Model*)_model)->LODs[_lodIndex]);
@@ -372,7 +372,7 @@ void Mesh::Draw(const RenderContextBatch& renderContextBatch, const DrawInfo& in
drawCall.Surface.LODDitherFactor = (byte)(lodDitherFactor * 255);
drawCall.PerInstanceRandom = info.PerInstanceRandom;
drawCall.StencilValue = info.StencilValue;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
const ViewMode viewMode = renderContextBatch.GetMainContext().View.Mode;
if (viewMode == ViewMode::LightmapUVsDensity || viewMode == ViewMode::LODPreview)
GBufferPass::AddIndexBufferToModelLOD(_indexBuffer, &((Model*)_model)->LODs[_lodIndex]);
+2 -2
View File
@@ -428,7 +428,7 @@ public:
/// </summary>
int8 SortOrder;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
float LightmapScale;
#endif
@@ -437,7 +437,7 @@ public:
{
Platform::MemoryClear(this, sizeof(DrawInfo));
ForcedLOD = -1;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
LightmapScale = -1;
#endif
}
@@ -252,6 +252,7 @@ bool ShaderAssetBase::LoadShaderCache(ShaderCacheResult& result)
options.SourceLength = sourceLength;
options.Profile = shaderProfile;
options.Output = &cacheStream;
options.DevelopmentShaders = GPU_ENABLE_DEVELOPMENT;
if (CommandLine::Options.ShaderDebug.IsTrue())
{
options.GenerateDebugData = true;
+2 -2
View File
@@ -402,7 +402,7 @@ void StaticModel::Draw(RenderContext& renderContext)
draw.SortOrder = _sortOrder;
draw.VertexColors = _vertexColorsCount ? _vertexColorsBuffer : nullptr;
draw.SetStencilValue(_layer);
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (HasStaticFlag(StaticFlags::Lightmap))
draw.LightmapScale = _scaleInLightmap;
#endif
@@ -439,7 +439,7 @@ void StaticModel::Draw(RenderContextBatch& renderContextBatch)
draw.SortOrder = _sortOrder;
draw.VertexColors = _vertexColorsCount ? _vertexColorsBuffer : nullptr;
draw.SetStencilValue(_layer);
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (HasStaticFlag(StaticFlags::Lightmap))
draw.LightmapScale = _scaleInLightmap;
#endif
+3 -2
View File
@@ -1,8 +1,9 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#if USE_EDITOR
#include "LODPreview.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Core/Types/Variant.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/Assets/Model.h"
+3 -1
View File
@@ -2,7 +2,9 @@
#pragma once
#if USE_EDITOR
#include "Engine/Graphics/Config.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Content/AssetReference.h"
#include "Engine/Content/Assets/Material.h"
@@ -1,8 +1,9 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#if USE_EDITOR
#include "LightmapUVsDensity.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Content/Content.h"
#include "Engine/Content/Assets/Model.h"
#include "Engine/Graphics/GPUDevice.h"
@@ -2,7 +2,9 @@
#pragma once
#if USE_EDITOR
#include "Engine/Graphics/Config.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Content/AssetReference.h"
#include "Engine/Content/Assets/Shader.h"
@@ -1,8 +1,9 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#if USE_EDITOR
#include "MaterialComplexity.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Core/Types/Variant.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/Assets/Model.h"
@@ -2,7 +2,9 @@
#pragma once
#if USE_EDITOR
#include "Engine/Graphics/Config.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Content/AssetReference.h"
#include "Engine/Content/Assets/Material.h"
@@ -1,8 +1,9 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#if USE_EDITOR
#include "QuadOverdrawPass.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Engine/Time.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/Assets/Material.h"
@@ -2,7 +2,9 @@
#pragma once
#if USE_EDITOR
#include "Engine/Graphics/Config.h"
#if GPU_ENABLE_DEVELOPMENT
#include "../RendererPass.h"
@@ -1,8 +1,9 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#if USE_EDITOR
#include "VertexColors.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Content/Content.h"
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/GPUContext.h"
+3 -1
View File
@@ -2,7 +2,9 @@
#pragma once
#if USE_EDITOR
#include "Engine/Graphics/Config.h"
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Content/AssetReference.h"
#include "Engine/Content/Assets/Shader.h"
+6 -6
View File
@@ -2,7 +2,7 @@
#include "GBufferPass.h"
#include "RenderList.h"
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
#include "Engine/Renderer/Editor/VertexColors.h"
#include "Engine/Renderer/Editor/LightmapUVsDensity.h"
#include "Engine/Renderer/Editor/LODPreview.h"
@@ -31,7 +31,7 @@ GPU_CB_STRUCT(GBufferPassData {
int32 ViewMode;
});
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
Dictionary<GPUBuffer*, const ModelLOD*> GBufferPass::IndexBufferToModelLOD;
CriticalSection GBufferPass::Locker;
#endif
@@ -104,7 +104,7 @@ void GBufferPass::Dispose()
_gBufferShader = nullptr;
_skyModel = nullptr;
_boxModel = nullptr;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
SAFE_DELETE(_lightmapUVsDensity);
SAFE_DELETE(_vertexColors);
SAFE_DELETE(_lodPreview);
@@ -113,7 +113,7 @@ void GBufferPass::Dispose()
#endif
}
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
void DebugOverrideDrawCallsMaterial(const RenderContext& renderContext, IMaterial* material)
{
@@ -193,7 +193,7 @@ void GBufferPass::Fill(RenderContext& renderContext, GPUTexture* lightBuffer)
if (checkIfSkipPass())
return;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
// Special debug drawing
if (renderContext.View.Mode == ViewMode::MaterialComplexity)
{
@@ -371,7 +371,7 @@ GPUTextureView* GBufferPass::RenderSkybox(RenderContext& renderContext, GPUConte
return result;
}
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
void GBufferPass::PreOverrideDrawCalls(RenderContext& renderContext)
{
+2 -2
View File
@@ -19,7 +19,7 @@ private:
GPUPipelineState* _psLinearToSrgb = nullptr;
AssetReference<Model> _skyModel;
AssetReference<Model> _boxModel;
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
class LightmapUVsDensityMaterialShader* _lightmapUVsDensity = nullptr;
class VertexColorsMaterialShader* _vertexColors = nullptr;
class LODPreviewMaterialShader* _lodPreview = nullptr;
@@ -57,7 +57,7 @@ public:
/// <returns>Rendered cubemap or null if not ready or failed.</returns>
GPUTextureView* RenderSkybox(RenderContext& renderContext, GPUContext* context);
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
// Temporary cache for faster debug previews drawing (used only during frame rendering).
static Dictionary<GPUBuffer*, const ModelLOD*> IndexBufferToModelLOD;
static CriticalSection Locker;
@@ -313,7 +313,7 @@ void DynamicDiffuseGlobalIlluminationPass::Dispose()
_shader = nullptr;
SAFE_DELETE_GPU_RESOURCE(_psIndirectLighting[0]);
SAFE_DELETE_GPU_RESOURCE(_psIndirectLighting[1]);
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
_debugModel = nullptr;
_debugMaterial = nullptr;
#endif
@@ -833,7 +833,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
context->DrawFullscreenTriangle();
}
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
// Probes debug drawing
if (renderContext.View.Mode == ViewMode::GlobalIllumination && lightBuffer)
{
@@ -49,7 +49,7 @@ private:
GPUShaderProgramCS* _csUpdateProbesIrradiance;
GPUShaderProgramCS* _csUpdateProbesDistance;
GPUPipelineState* _psIndirectLighting[2] = {};
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
AssetReference<Model> _debugModel;
AssetReference<MaterialBase> _debugMaterial;
#endif
@@ -804,6 +804,7 @@ bool GlobalSurfaceAtlasPass::setupResources()
// Create pipeline state
GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle;
#if GPU_ENABLE_DEVELOPMENT
if (!_psDebug0)
{
_psDebug0 = device->CreatePipelineState();
@@ -815,6 +816,7 @@ bool GlobalSurfaceAtlasPass::setupResources()
if (_psDebug1->Init(psDesc))
return true;
}
#endif
psDesc.DepthEnable = true;
psDesc.DepthWriteEnable = true;
psDesc.DepthFunc = ComparisonFunc::Always;
@@ -874,8 +876,10 @@ void GlobalSurfaceAtlasPass::OnShaderReloading(Asset* obj)
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting0);
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting1);
SAFE_DELETE_GPU_RESOURCE(_psIndirectLighting);
#if GPU_ENABLE_DEVELOPMENT
SAFE_DELETE_GPU_RESOURCE(_psDebug0);
SAFE_DELETE_GPU_RESOURCE(_psDebug1);
#endif
invalidateResources();
}
@@ -894,8 +898,10 @@ void GlobalSurfaceAtlasPass::Dispose()
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting0);
SAFE_DELETE_GPU_RESOURCE(_psDirectLighting1);
SAFE_DELETE_GPU_RESOURCE(_psIndirectLighting);
#if GPU_ENABLE_DEVELOPMENT
SAFE_DELETE_GPU_RESOURCE(_psDebug0);
SAFE_DELETE_GPU_RESOURCE(_psDebug1);
#endif
_cb0 = nullptr;
_shader = nullptr;
}
@@ -1711,6 +1717,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
return notReady;
}
#if GPU_ENABLE_DEVELOPMENT
void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output)
{
// Render all dependant effects before
@@ -1807,6 +1815,8 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex
}
}
#endif
void GlobalSurfaceAtlasPass::GetCullingData(Vector4& cullingPosDistance) const
{
cullingPosDistance = _surfaceAtlasData->CullingPosDistance;
@@ -49,8 +49,10 @@ private:
GPUPipelineState* _psDirectLighting0 = nullptr;
GPUPipelineState* _psDirectLighting1 = nullptr;
GPUPipelineState* _psIndirectLighting = nullptr;
#if GPU_ENABLE_DEVELOPMENT
GPUPipelineState* _psDebug0 = nullptr;
GPUPipelineState* _psDebug1 = nullptr;
#endif
GPUConstantBuffer* _cb0 = nullptr;
GPUShaderProgramCS* _csCullObjects;
@@ -85,6 +87,7 @@ public:
/// <returns>True if failed to render (platform doesn't support it, out of video memory, disabled feature or effect is not ready), otherwise false.</returns>
bool Render(RenderContext& renderContext, GPUContext* context, BindingData& result);
#if GPU_ENABLE_DEVELOPMENT
/// <summary>
/// Renders the debug view.
/// </summary>
@@ -92,6 +95,7 @@ public:
/// <param name="context">The GPU context.</param>
/// <param name="output">The output buffer.</param>
void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output);
#endif
// Gets the culling view position (xyz) and view distance (w)
void GetCullingData(Vector4& cullingPosDistance) const;
@@ -704,8 +704,6 @@ bool GlobalSignDistanceFieldPass::setupResources()
}
if (!_shader->IsLoaded())
return true;
const auto device = GPUDevice::Instance;
const auto shader = _shader->GPU;
// Check shader
@@ -723,25 +721,6 @@ bool GlobalSignDistanceFieldPass::setupResources()
if (!_objectsBuffer)
_objectsBuffer = New<DynamicStructuredBuffer>(0, (uint32)sizeof(ObjectRasterizeData), false, TEXT("GlobalSDF.ObjectsBuffer"));
// Create pipeline state
// TODO: don't compile those shaders in Release builds (and skip PSOs)
GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle;
if (!_psDebug)
{
_psDebug = device->CreatePipelineState();
psDesc.PS = shader->GetPS("PS_Debug");
if (_psDebug->Init(psDesc))
return true;
}
if (!_psOverdraw)
{
_psOverdraw = device->CreatePipelineState();
psDesc.PS = shader->GetPS("PS_Overdraw");
psDesc.BlendMode = BlendingMode::AlphaBlend;
if (_psOverdraw->Init(psDesc))
return true;
}
return false;
}
@@ -749,8 +728,10 @@ bool GlobalSignDistanceFieldPass::setupResources()
void GlobalSignDistanceFieldPass::OnShaderReloading(Asset* obj)
{
#if GPU_ENABLE_DEVELOPMENT
SAFE_DELETE_GPU_RESOURCE(_psDebug);
SAFE_DELETE_GPU_RESOURCE(_psOverdraw);
#endif
_csRasterizeModel0 = nullptr;
_csRasterizeModel1 = nullptr;
_csRasterizeHeightfield = nullptr;
@@ -769,7 +750,10 @@ void GlobalSignDistanceFieldPass::Dispose()
// Cleanup
SAFE_DELETE(_objectsBuffer);
#if GPU_ENABLE_DEVELOPMENT
SAFE_DELETE_GPU_RESOURCE(_psDebug);
SAFE_DELETE_GPU_RESOURCE(_psOverdraw);
#endif
_shader = nullptr;
}
@@ -1178,6 +1162,8 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
return false;
}
#if GPU_ENABLE_DEVELOPMENT
void GlobalSignDistanceFieldPass::RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output)
{
BindingData bindingData;
@@ -1186,6 +1172,18 @@ void GlobalSignDistanceFieldPass::RenderDebug(RenderContext& renderContext, GPUC
context->Draw(output, renderContext.Buffers->GBuffer0);
return;
}
if (!_psDebug)
{
// Lazy init PSOs
auto psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle;
_psDebug = GPUDevice::Instance->CreatePipelineState();
psDesc.PS = _shader->GPU->GetPS("PS_Debug");
_psDebug->Init(psDesc);
_psOverdraw = GPUDevice::Instance->CreatePipelineState();
psDesc.PS = _shader->GPU->GetPS("PS_Overdraw");
psDesc.BlendMode = BlendingMode::AlphaBlend;
_psOverdraw->Init(psDesc);
}
PROFILE_GPU_CPU("Global SDF Debug");
const Float2 outputSize(output->Size());
@@ -1276,6 +1274,8 @@ void GlobalSignDistanceFieldPass::RenderDebug(RenderContext& renderContext, GPUC
}
}
#endif
void GlobalSignDistanceFieldPass::GetCullingData(BoundingBox& bounds) const
{
auto& cascade = *CurrentCascade.Get();
@@ -33,8 +33,10 @@ public:
private:
bool _supported = false;
AssetReference<Shader> _shader;
#if GPU_ENABLE_DEVELOPMENT
GPUPipelineState* _psDebug = nullptr;
GPUPipelineState* _psOverdraw = nullptr;
#endif
GPUShaderProgramCS* _csRasterizeModel0 = nullptr;
GPUShaderProgramCS* _csRasterizeModel1 = nullptr;
GPUShaderProgramCS* _csRasterizeHeightfield = nullptr;
@@ -68,6 +70,7 @@ public:
/// <returns>True if failed to render (platform doesn't support it, out of video memory, disabled feature or effect is not ready), otherwise false.</returns>
bool Render(RenderContext& renderContext, GPUContext* context, BindingData& result);
#if GPU_ENABLE_DEVELOPMENT
/// <summary>
/// Renders the debug view.
/// </summary>
@@ -75,6 +78,7 @@ public:
/// <param name="context">The GPU context.</param>
/// <param name="output">The output buffer.</param>
void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output);
#endif
void GetCullingData(BoundingBox& bounds) const;
+4
View File
@@ -408,6 +408,8 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
context->ResetCB();
}
#if GPU_ENABLE_DEVELOPMENT
// Config for light complexity
#define LIGHT_COMPLEXITY_DIR_COST 0.05f
#define LIGHT_COMPLEXITY_LOCAL_COST 0.08f
@@ -492,3 +494,5 @@ void LightPass::RenderDebugSphere(RenderContext& renderContext, GPUContext* cont
context->SetState(_psLightOverlap[isViewInside]);
_sphereModel->LODs[0].Meshes[0].Render(context);
}
#endif
+4
View File
@@ -40,6 +40,7 @@ public:
/// <param name="lightBuffer">The light accumulation buffer (input and output).</param>
void RenderLights(RenderContextBatch& renderContextBatch, GPUTextureView* lightBuffer);
#if GPU_ENABLE_DEVELOPMENT
/// <summary>
/// Renders the debug view.
/// </summary>
@@ -47,6 +48,7 @@ public:
/// <param name="context">The GPU context.</param>
/// <param name="output">The output buffer.</param>
void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output);
#endif
private:
#if COMPILE_WITH_DEV_ENV
@@ -65,7 +67,9 @@ private:
invalidateResources();
}
#endif
#if GPU_ENABLE_DEVELOPMENT
void RenderDebugSphere(RenderContext& renderContext, GPUContext* context, const struct RenderLightData& light, float radius) const;
#endif
public:
// [RendererPass]
+2
View File
@@ -10,6 +10,8 @@
// Additional options used in editor for lightmaps baking
extern bool IsRunningRadiancePass;
extern bool IsBakingLightmaps;
#endif
#if GPU_ENABLE_DEVELOPMENT
extern bool EnableLightmapsUsage;
#endif
+10
View File
@@ -50,7 +50,9 @@ bool MotionBlurPass::Init()
{
// Create pipeline states
_psCameraMotionVectors = GPUDevice::Instance->CreatePipelineState();
#if GPU_ENABLE_DEVELOPMENT
_psMotionVectorsDebug = GPUDevice::Instance->CreatePipelineState();
#endif
_psTileMax = GPUDevice::Instance->CreatePipelineState();
_psTileMaxVariable = GPUDevice::Instance->CreatePipelineState();
_psNeighborMax = GPUDevice::Instance->CreatePipelineState();
@@ -96,12 +98,14 @@ bool MotionBlurPass::setupResources()
if (_psCameraMotionVectors->Init(psDesc))
return true;
}
#if GPU_ENABLE_DEVELOPMENT
if (!_psMotionVectorsDebug->IsValid())
{
psDesc.PS = shader->GetPS("PS_MotionVectorsDebug");
if (_psMotionVectorsDebug->Init(psDesc))
return true;
}
#endif
if (!_psTileMax->IsValid())
{
psDesc.PS = shader->GetPS("PS_TileMax");
@@ -137,7 +141,9 @@ void MotionBlurPass::Dispose()
// Cleanup
SAFE_DELETE_GPU_RESOURCE(_psCameraMotionVectors);
#if GPU_ENABLE_DEVELOPMENT
SAFE_DELETE_GPU_RESOURCE(_psMotionVectorsDebug);
#endif
SAFE_DELETE_GPU_RESOURCE(_psTileMax);
SAFE_DELETE_GPU_RESOURCE(_psTileMaxVariable);
SAFE_DELETE_GPU_RESOURCE(_psNeighborMax);
@@ -234,6 +240,8 @@ void MotionBlurPass::RenderMotionVectors(RenderContext& renderContext)
}
}
#if GPU_ENABLE_DEVELOPMENT
void MotionBlurPass::RenderDebug(RenderContext& renderContext, GPUTextureView* frame)
{
auto outputView = renderContext.Task->GetOutputView();
@@ -275,6 +283,8 @@ void MotionBlurPass::RenderDebug(RenderContext& renderContext, GPUTextureView* f
RenderTargetPool::Release(motionObjectsDepth);
}
#endif
void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& frame, GPUTexture*& tmp)
{
const bool isCameraCut = renderContext.Task->IsCameraCut;
+6
View File
@@ -14,7 +14,9 @@ private:
PixelFormat _motionVectorsFormat;
AssetReference<Shader> _shader;
GPUPipelineState* _psCameraMotionVectors = nullptr;
#if GPU_ENABLE_DEVELOPMENT
GPUPipelineState* _psMotionVectorsDebug = nullptr;
#endif
GPUPipelineState* _psTileMax = nullptr;
GPUPipelineState* _psTileMaxVariable = nullptr;
GPUPipelineState* _psNeighborMax = nullptr;
@@ -35,12 +37,14 @@ public:
/// <param name="renderContext">The rendering context.</param>
void RenderMotionVectors(RenderContext& renderContext);
#if GPU_ENABLE_DEVELOPMENT
/// <summary>
/// Renders the motion vectors debug view.
/// </summary>
/// <param name="renderContext">The rendering context.</param>
/// <param name="frame">The source frame.</param>
void RenderDebug(RenderContext& renderContext, GPUTextureView* frame);
#endif
/// <summary>
/// Renders the motion blur. Swaps the input with output if rendering is performed. Does nothing if rendering is not performed.
@@ -56,7 +60,9 @@ private:
void OnShaderReloading(Asset* obj)
{
_psCameraMotionVectors->ReleaseGPU();
#if GPU_ENABLE_DEVELOPMENT
_psMotionVectorsDebug->ReleaseGPU();
#endif
_psTileMax->ReleaseGPU();
_psTileMaxVariable->ReleaseGPU();
_psNeighborMax->ReleaseGPU();
+19 -15
View File
@@ -41,6 +41,8 @@
#include "Engine/Profiler/ProfilerMemory.h"
#if USE_EDITOR
#include "Editor/Editor.h"
#endif
#if GPU_ENABLE_DEVELOPMENT
#include "Editor/QuadOverdrawPass.h"
#endif
@@ -48,6 +50,8 @@
// Additional options used in editor for lightmaps baking
bool IsRunningRadiancePass = false;
bool IsBakingLightmaps = false;
#endif
#if GPU_ENABLE_DEVELOPMENT
bool EnableLightmapsUsage = true;
#endif
@@ -97,17 +101,15 @@ bool RendererService::Init()
PassList.Add(GlobalSignDistanceFieldPass::Instance());
PassList.Add(GlobalSurfaceAtlasPass::Instance());
PassList.Add(DynamicDiffuseGlobalIlluminationPass::Instance());
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
PassList.Add(QuadOverdrawPass::Instance());
#endif
#if GPU_ENABLE_PRELOADING_RESOURCES
// Skip when using Null renderer
if (GPUDevice::Instance->GetRendererType() == RendererType::Null)
{
return false;
}
#if GPU_ENABLE_PRELOADING_RESOURCES
// Init child services
for (int32 i = 0; i < PassList.Count(); i++)
{
@@ -471,7 +473,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
LightPass::Instance()->SetupLights(renderContext, renderContextBatch);
if (setup.UseShadows)
ShadowsPass::Instance()->SetupShadows(renderContext, renderContextBatch);
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
GBufferPass::Instance()->PreOverrideDrawCalls(renderContext);
#endif
@@ -498,7 +500,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
renderContextBatch.Contexts[i].List->DrainDelayedDraws(context, renderContextBatch, i);
renderContext.List->PostDraw(context, renderContextBatch);
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
GBufferPass::Instance()->OverrideDrawCalls(renderContext);
#endif
}
@@ -578,7 +580,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
auto lightBuffer = RenderTargetPool::Get(tempDesc);
RENDER_TARGET_POOL_SET_NAME(lightBuffer, "LightBuffer");
#if USE_EDITOR
#if GPU_ENABLE_DEVELOPMENT
if (renderContext.View.Mode == ViewMode::QuadOverdraw)
{
QuadOverdrawPass::Instance()->Render(renderContext, context, lightBuffer->View());
@@ -602,8 +604,13 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
GBufferPass::Instance()->Fill(renderContext, lightBuffer);
// Debug drawing
#if GPU_ENABLE_DEVELOPMENT
switch (renderContext.View.Mode)
{
case ViewMode::MaterialComplexity:
GBufferPass::Instance()->DrawMaterialComplexity(renderContext, context, lightBuffer->View());
RenderTargetPool::Release(lightBuffer);
return;
case ViewMode::LightOverlap:
LightPass::Instance()->RenderDebug(renderContext, context, lightBuffer);
break;
@@ -622,6 +629,9 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
renderContext.View.Mode == ViewMode::GlobalSurfaceAtlas ||
renderContext.View.Mode == ViewMode::GlobalSDF ||
renderContext.View.Mode == ViewMode::GlobalSDFOverdraw)
#else
if (renderContext.View.Mode == ViewMode::Emissive)
#endif
{
context->ResetRenderTarget();
context->SetRenderTarget(task->GetOutputView());
@@ -630,14 +640,6 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
RenderTargetPool::Release(lightBuffer);
return;
}
#if USE_EDITOR
if (renderContext.View.Mode == ViewMode::MaterialComplexity)
{
GBufferPass::Instance()->DrawMaterialComplexity(renderContext, context, lightBuffer->View());
RenderTargetPool::Release(lightBuffer);
return;
}
#endif
// Render motion vectors
MotionBlurPass::Instance()->RenderMotionVectors(renderContext);
@@ -806,6 +808,7 @@ PRAGMA_ENABLE_DEPRECATION_WARNINGS
context->ResetSR();
context->FlushState();
#if GPU_ENABLE_DEVELOPMENT
// Debug motion vectors
if (renderContext.View.Mode == ViewMode::MotionVectors)
{
@@ -814,6 +817,7 @@ PRAGMA_ENABLE_DEPRECATION_WARNINGS
RenderTargetPool::Release(frameBuffer);
return;
}
#endif
// Anti Aliasing
GPUTextureView* outputView = task->GetOutputView();
@@ -61,6 +61,11 @@ public:
/// </summary>
bool TreatWarningsAsErrors = false;
/// <summary>
/// Enables compilation of development-only shaders for. Used in non-release or editor builds.
/// </summary>
bool DevelopmentShaders = true;
/// <summary>
/// Custom macros for the shader compilation
/// </summary>
@@ -391,6 +391,7 @@ namespace ShaderProcessing
{ FeatureLevel::ES3_1, "FEATURE_LEVEL_ES3_1" },
{ FeatureLevel::SM4, "FEATURE_LEVEL_SM4" },
{ FeatureLevel::SM5, "FEATURE_LEVEL_SM5" },
{ FeatureLevel::SM6, "FEATURE_LEVEL_SM6" },
};
bool missing = true;
for (int32 i = 0; i < ARRAY_COUNT(levels); i++)
@@ -430,10 +431,14 @@ namespace ShaderProcessing
current.Permutations.Add(ShaderPermutation());
}
// Development-only shaders need a flag from the parser (setup by compilation pipeline)
if (EnumHasAllFlags(current.Flags, ShaderFlags::DevelopmentOnly))
current.MinFeatures |= ShaderProfileFeatures::DevelopmentShaders;
// Check if use this shader program
if ((current.Flags & ShaderFlags::Hidden) == (ShaderFlags)0 &&
current.MinFeatureLevel <= parser->GetFeatureLevel() &&
EnumHasAllFlags(parser->GetFeatures(), current.MinFeatures))
if ((current.Flags & ShaderFlags::Hidden) == (ShaderFlags)0 && // Is not hidden
current.MinFeatureLevel <= parser->GetFeatureLevel() && // Matches minimum Feature Level
EnumHasAllFlags(parser->GetFeatures(), current.MinFeatures)) // All GPU features are supported
{
// Cache read function
ShaderMetaReaderType::_cache.Add(current);
@@ -146,8 +146,8 @@ ShaderFlags ShaderProcessing::ParseShaderFlags(const Token& token)
_PARSE_ENTRY(Hidden),
_PARSE_ENTRY(NoFastMath),
_PARSE_ENTRY(VertexToGeometryShader),
_PARSE_ENTRY(DevelopmentOnly),
};
static_assert(ARRAY_COUNT(data) == 4, "Invalid amount of Shader Flag data entries.");
#undef _PARSE_ENTRY
for (int32 i = 0; i < ARRAY_COUNT(data); i++)
@@ -18,13 +18,13 @@
#include "ShaderFunctionReader.CS.h"
#include "Config.h"
ShaderProcessing::Parser::Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile)
ShaderProcessing::Parser::Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderProfileFeatures features)
: failed(false)
, targetName(targetName)
, text(source, sourceLength)
, _macros(macros)
, _featureLevel(RenderTools::GetFeatureLevel(profile))
, _features(RenderTools::GetShaderProfileFeatures(profile))
, _features(features)
{
}
@@ -32,10 +32,10 @@ ShaderProcessing::Parser::~Parser()
{
}
bool ShaderProcessing::Parser::Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderMeta* result)
bool ShaderProcessing::Parser::Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderProfileFeatures features, ShaderMeta* result)
{
PROFILE_CPU_NAMED("Shader.Parse");
Parser parser(targetName, source, sourceLength, macros, profile);
Parser parser(targetName, source, sourceLength, macros, profile, features);
parser.Process(result);
return parser.Failed();
}
@@ -30,7 +30,7 @@ namespace ShaderProcessing
ShaderProfileFeatures _features;
private:
Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile);
Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderProfileFeatures features);
~Parser();
public:
@@ -42,9 +42,10 @@ namespace ShaderProcessing
/// <param name="sourceLength">Amount of characters in the source code</param>
/// <param name="macros">The input macros.</param>
/// <param name="profile">The target shader profile.</param>
/// <param name="features">The target shader features.</param>
/// <param name="result">Output result with metadata</param>
/// <returns>True if cannot process the file (too many errors), otherwise false</returns>
static bool Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderMeta* result);
static bool Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderProfileFeatures features, ShaderMeta* result);
public:
/// <summary>
@@ -155,7 +155,10 @@ bool ShadersCompilation::Compile(ShaderCompilationOptions& options)
// Process shader source to collect metadata
ShaderMeta meta;
if (ShaderProcessing::Parser::Process(options.TargetName, options.Source, options.SourceLength, options.Macros, options.Profile, &meta))
auto shaderFeatures = RenderTools::GetShaderProfileFeatures(options.Profile);
if (options.DevelopmentShaders)
shaderFeatures |= ShaderProfileFeatures::DevelopmentShaders;
if (ShaderProcessing::Parser::Process(options.TargetName, options.Source, options.SourceLength, options.Macros, options.Profile, shaderFeatures , &meta))
{
LOG(Warning, "Failed to parse source code.");
return true;
@@ -337,6 +337,7 @@ TextureCube Skybox : register(t7);
// Pixel shader for Global Surface Atlas debug drawing
META_PS(true, FEATURE_LEVEL_SM5)
META_FLAG(DevelopmentOnly)
META_PERMUTATION_1(GLOBAL_SURFACE_ATLAS_DEBUG_MODE=0)
META_PERMUTATION_1(GLOBAL_SURFACE_ATLAS_DEBUG_MODE=1)
float4 PS_Debug(Quad_VS2PS input) : SV_Target
@@ -288,6 +288,7 @@ Texture3D<snorm float> GlobalSDFMip : register(t1);
// Pixel shader for Global SDF debug drawing
META_PS(true, FEATURE_LEVEL_SM5)
META_FLAG(DevelopmentOnly)
float4 PS_Debug(Quad_VS2PS input) : SV_Target
{
#if 0
@@ -402,6 +403,7 @@ float4 GetHeatmap(float value)
// Pixel shader for Global SDF overdraw drawing
META_PS(true, FEATURE_LEVEL_SM5)
META_FLAG(DevelopmentOnly)
float4 PS_Overdraw(Quad_VS2PS input) : SV_Target
{
// Use over-exposed diffuse as a base for scene identification
+2
View File
@@ -134,6 +134,7 @@ float4 PS_Sky(Model_VS2PS input) : SV_Target0
// Pixel shader for light overlap rendering
META_PS(true, FEATURE_LEVEL_ES2)
META_FLAG(DevelopmentOnly)
float4 PS_Overlap(Model_VS2PS input) : SV_Target0
{
return Light.Radius.xxxx;
@@ -145,6 +146,7 @@ float4 PS_Overlap(Model_VS2PS input) : SV_Target0
// Pixel shader for light complexity rendering
META_PS(true, FEATURE_LEVEL_ES2)
META_FLAG(DevelopmentOnly)
float4 PS_Complexity(Quad_VS2PS input) : SV_Target0
{
// Make depth-based outlines
+1
View File
@@ -69,6 +69,7 @@ float4 MotionVectorToColor(float2 v)
// Pixel shader for motion vectors debug view
META_PS(true, FEATURE_LEVEL_ES2)
META_FLAG(DevelopmentOnly)
float4 PS_MotionVectorsDebug(Quad_VS2PS input) : SV_Target
{
float4 color = SAMPLE_RT(Input0, input.TexCoord);