Browse Source

"Dr PIX": Force early Z (#467)

PIX has the ability to turn on early z and show you the performance difference with and without.
This pass implements the DXIL side of it.
Jeff Noyle 8 years ago
parent
commit
d3f53b7f3e

+ 2 - 0
include/dxc/HLSL/DxilGenerationPass.h

@@ -56,6 +56,7 @@ ModulePass *createDxilAddPixelHitInstrumentationPass();
 ModulePass *createDxilOutputColorBecomesConstantPass();
 ModulePass *createDxilOutputColorBecomesConstantPass();
 ModulePass *createDxilRemoveDiscardsPass();
 ModulePass *createDxilRemoveDiscardsPass();
 ModulePass *createDxilReduceMSAAToSingleSamplePass();
 ModulePass *createDxilReduceMSAAToSingleSamplePass();
+ModulePass *createDxilForceEarlyZPass();
 
 
 void initializeDxilCondenseResourcesPass(llvm::PassRegistry&);
 void initializeDxilCondenseResourcesPass(llvm::PassRegistry&);
 void initializeDxilEliminateOutputDynamicIndexingPass(llvm::PassRegistry&);
 void initializeDxilEliminateOutputDynamicIndexingPass(llvm::PassRegistry&);
@@ -76,6 +77,7 @@ void initializeDxilAddPixelHitInstrumentationPass(llvm::PassRegistry&);
 void initializeDxilOutputColorBecomesConstantPass(llvm::PassRegistry&);
 void initializeDxilOutputColorBecomesConstantPass(llvm::PassRegistry&);
 void initializeDxilRemoveDiscardsPass(llvm::PassRegistry&);
 void initializeDxilRemoveDiscardsPass(llvm::PassRegistry&);
 void initializeDxilReduceMSAAToSingleSamplePass(llvm::PassRegistry&);
 void initializeDxilReduceMSAAToSingleSamplePass(llvm::PassRegistry&);
+void initializeDxilForceEarlyZPass(llvm::PassRegistry&);
 
 
 bool AreDxilResourcesDense(llvm::Module *M, hlsl::DxilResourceBase **ppNonDense);
 bool AreDxilResourcesDense(llvm::Module *M, hlsl::DxilResourceBase **ppNonDense);
 
 

+ 1 - 0
lib/HLSL/CMakeLists.txt

@@ -12,6 +12,7 @@ add_llvm_library(LLVMHLSL
   DxilContainerReflection.cpp
   DxilContainerReflection.cpp
   DxilEliminateOutputDynamicIndexing.cpp
   DxilEliminateOutputDynamicIndexing.cpp
   DxilExpandTrigIntrinsics.cpp
   DxilExpandTrigIntrinsics.cpp
+  DxilForceEarlyZ.cpp
   DxilGenerationPass.cpp
   DxilGenerationPass.cpp
   DxilInterpolationMode.cpp
   DxilInterpolationMode.cpp
   DxilLegalizeSampleOffsetPass.cpp
   DxilLegalizeSampleOffsetPass.cpp

+ 1 - 0
lib/HLSL/DxcOptimizer.cpp

@@ -87,6 +87,7 @@ HRESULT SetupRegistryPassForHLSL() {
     initializeDxilEliminateOutputDynamicIndexingPass(Registry);
     initializeDxilEliminateOutputDynamicIndexingPass(Registry);
     initializeDxilEmitMetadataPass(Registry);
     initializeDxilEmitMetadataPass(Registry);
     initializeDxilExpandTrigIntrinsicsPass(Registry);
     initializeDxilExpandTrigIntrinsicsPass(Registry);
+    initializeDxilForceEarlyZPass(Registry);
     initializeDxilGenerationPassPass(Registry);
     initializeDxilGenerationPassPass(Registry);
     initializeDxilLegalizeEvalOperationsPass(Registry);
     initializeDxilLegalizeEvalOperationsPass(Registry);
     initializeDxilLegalizeResourceUsePassPass(Registry);
     initializeDxilLegalizeResourceUsePassPass(Registry);

+ 48 - 0
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)

+ 11 - 0
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);
+}

+ 5 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -432,6 +432,7 @@ public:
   TEST_METHOD(PixConstantColorOtherSIVs)
   TEST_METHOD(PixConstantColorOtherSIVs)
   TEST_METHOD(PixConstantColorFromCB)
   TEST_METHOD(PixConstantColorFromCB)
   TEST_METHOD(PixConstantColorFromCBint)
   TEST_METHOD(PixConstantColorFromCBint)
+  TEST_METHOD(PixForceEarlyZ)
 
 
   TEST_METHOD(CodeGenAbs1)
   TEST_METHOD(CodeGenAbs1)
   TEST_METHOD(CodeGenAbs2)
   TEST_METHOD(CodeGenAbs2)
@@ -2772,6 +2773,10 @@ TEST_F(CompilerTest, PixConstantColorFromCBint) {
   CodeGenTestCheck(L"pix\\constantcolorFromCBint.hlsl");
   CodeGenTestCheck(L"pix\\constantcolorFromCBint.hlsl");
 }
 }
 
 
+TEST_F(CompilerTest, PixForceEarlyZ) {
+  CodeGenTestCheck(L"pix\\forceEarlyZ.hlsl");
+}
+
 TEST_F(CompilerTest, CodeGenAbs1) {
 TEST_F(CompilerTest, CodeGenAbs1) {
   CodeGenTestCheck(L"..\\CodeGenHLSL\\abs1.hlsl");
   CodeGenTestCheck(L"..\\CodeGenHLSL\\abs1.hlsl");
 }
 }

+ 1 - 0
utils/hct/hctdb.py

@@ -1280,6 +1280,7 @@ class db_dxil(object):
             {'n':'constant-blue','t':'float','c':1},
             {'n':'constant-blue','t':'float','c':1},
             {'n':'constant-alpha','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-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-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-dxilemit', 'DxilEmitMetadata', 'HLSL DXIL Metadata Emit', [])
         add_pass('hlsl-dxilload', 'DxilLoadMetadata', 'HLSL DXIL Metadata Load', [])
         add_pass('hlsl-dxilload', 'DxilLoadMetadata', 'HLSL DXIL Metadata Load', [])