diff --git a/include/dxc/HLSL/DxilGenerationPass.h b/include/dxc/HLSL/DxilGenerationPass.h index 8278dd120..e2be2dbe4 100644 --- a/include/dxc/HLSL/DxilGenerationPass.h +++ b/include/dxc/HLSL/DxilGenerationPass.h @@ -56,6 +56,7 @@ ModulePass *createDxilAddPixelHitInstrumentationPass(); ModulePass *createDxilOutputColorBecomesConstantPass(); ModulePass *createDxilRemoveDiscardsPass(); ModulePass *createDxilReduceMSAAToSingleSamplePass(); +ModulePass *createDxilForceEarlyZPass(); void initializeDxilCondenseResourcesPass(llvm::PassRegistry&); void initializeDxilEliminateOutputDynamicIndexingPass(llvm::PassRegistry&); @@ -76,6 +77,7 @@ void initializeDxilAddPixelHitInstrumentationPass(llvm::PassRegistry&); void initializeDxilOutputColorBecomesConstantPass(llvm::PassRegistry&); void initializeDxilRemoveDiscardsPass(llvm::PassRegistry&); void initializeDxilReduceMSAAToSingleSamplePass(llvm::PassRegistry&); +void initializeDxilForceEarlyZPass(llvm::PassRegistry&); bool AreDxilResourcesDense(llvm::Module *M, hlsl::DxilResourceBase **ppNonDense); diff --git a/lib/HLSL/CMakeLists.txt b/lib/HLSL/CMakeLists.txt index 5373b4e6f..90824ece4 100644 --- a/lib/HLSL/CMakeLists.txt +++ b/lib/HLSL/CMakeLists.txt @@ -12,6 +12,7 @@ add_llvm_library(LLVMHLSL DxilContainerReflection.cpp DxilEliminateOutputDynamicIndexing.cpp DxilExpandTrigIntrinsics.cpp + DxilForceEarlyZ.cpp DxilGenerationPass.cpp DxilInterpolationMode.cpp DxilLegalizeSampleOffsetPass.cpp diff --git a/lib/HLSL/DxcOptimizer.cpp b/lib/HLSL/DxcOptimizer.cpp index d6cd5f70f..e21933b72 100644 --- a/lib/HLSL/DxcOptimizer.cpp +++ b/lib/HLSL/DxcOptimizer.cpp @@ -87,6 +87,7 @@ HRESULT SetupRegistryPassForHLSL() { initializeDxilEliminateOutputDynamicIndexingPass(Registry); initializeDxilEmitMetadataPass(Registry); initializeDxilExpandTrigIntrinsicsPass(Registry); + initializeDxilForceEarlyZPass(Registry); initializeDxilGenerationPassPass(Registry); initializeDxilLegalizeEvalOperationsPass(Registry); initializeDxilLegalizeResourceUsePassPass(Registry); diff --git a/lib/HLSL/DxilForceEarlyZ.cpp b/lib/HLSL/DxilForceEarlyZ.cpp new file mode 100644 index 000000000..d0c6fa49a --- /dev/null +++ b/lib/HLSL/DxilForceEarlyZ.cpp @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// DxilOutputColorBecomesConstant.cpp // +// Copyright (C) Microsoft Corporation. All rights reserved. // +// This file is distributed under the University of Illinois Open Source // +// License. See LICENSE.TXT for details. // +// // +// Provides a pass to turn on the early-z flag // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "dxc/HLSL/DxilGenerationPass.h" +#include "dxc/HLSL/DxilModule.h" +#include "llvm/IR/Module.h" + +using namespace llvm; +using namespace hlsl; + +class DxilForceEarlyZ : public ModulePass { + +public: + static char ID; // Pass identification, replacement for typeid + explicit DxilForceEarlyZ() : ModulePass(ID) {} + const char *getPassName() const override { return "DXIL Force Early Z"; } + bool runOnModule(Module &M) override; +}; + + +bool DxilForceEarlyZ::runOnModule(Module &M) +{ + // This pass adds the force-early-z flag + + DxilModule &DM = M.GetOrCreateDxilModule(); + + DM.m_ShaderFlags.SetForceEarlyDepthStencil(true); + + DM.ReEmitDxilResources(); + + return true; +} + +char DxilForceEarlyZ::ID = 0; + +ModulePass *llvm::createDxilForceEarlyZPass() { + return new DxilForceEarlyZ(); +} + +INITIALIZE_PASS(DxilForceEarlyZ, "hlsl-dxil-force-early-z", "HLSL DXIL Force the early Z global flag, if shader has no discard calls", false, false) diff --git a/tools/clang/test/HLSL/pix/forceEarlyZ.hlsl b/tools/clang/test/HLSL/pix/forceEarlyZ.hlsl new file mode 100644 index 000000000..42bc26f8d --- /dev/null +++ b/tools/clang/test/HLSL/pix/forceEarlyZ.hlsl @@ -0,0 +1,11 @@ +// RUN: %dxc -Emain -Tps_6_0 %s | %opt -S -hlsl-dxil-force-early-z | %FileCheck %s + +// Just check that the last line (which contains global flags) has the "8" meaning force-early-z: +// CHECK: !{i32 0, i64 8} +// Check there are no more entries (i.e. the above really was the last line) +// CHECK-NOT: !{ + +[RootSignature("")] +float4 main() : SV_Target { + return float4(0,0,0,0); +} \ No newline at end of file diff --git a/tools/clang/unittests/HLSL/CompilerTest.cpp b/tools/clang/unittests/HLSL/CompilerTest.cpp index 815ce9176..b9b2b0a73 100644 --- a/tools/clang/unittests/HLSL/CompilerTest.cpp +++ b/tools/clang/unittests/HLSL/CompilerTest.cpp @@ -432,6 +432,7 @@ public: TEST_METHOD(PixConstantColorOtherSIVs) TEST_METHOD(PixConstantColorFromCB) TEST_METHOD(PixConstantColorFromCBint) + TEST_METHOD(PixForceEarlyZ) TEST_METHOD(CodeGenAbs1) TEST_METHOD(CodeGenAbs2) @@ -2772,6 +2773,10 @@ TEST_F(CompilerTest, PixConstantColorFromCBint) { CodeGenTestCheck(L"pix\\constantcolorFromCBint.hlsl"); } +TEST_F(CompilerTest, PixForceEarlyZ) { + CodeGenTestCheck(L"pix\\forceEarlyZ.hlsl"); +} + TEST_F(CompilerTest, CodeGenAbs1) { CodeGenTestCheck(L"..\\CodeGenHLSL\\abs1.hlsl"); } diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index e80d5cbc0..8916f6f6c 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -1280,6 +1280,7 @@ class db_dxil(object): {'n':'constant-blue','t':'float','c':1}, {'n':'constant-alpha','t':'float','c':1}]) add_pass('hlsl-dxil-remove-discards', 'DxilRemoveDiscards', 'HLSL DXIL Remove all discard instructions', []) + add_pass('hlsl-dxil-force-early-z', 'DxilForceEarlyZ', 'HLSL DXIL Force the early Z global flag, if shader has no discard calls', []) add_pass('hlsl-dxil-reduce-msaa-to-single', 'DxilReduceMSAAToSingleSample', 'HLSL DXIL Reduce all MSAA reads to single-sample reads', []) add_pass('hlsl-dxilemit', 'DxilEmitMetadata', 'HLSL DXIL Metadata Emit', []) add_pass('hlsl-dxilload', 'DxilLoadMetadata', 'HLSL DXIL Metadata Load', [])