From 02b3cdad94e06163c2ea3829a87e2ecc9c8fb323 Mon Sep 17 00:00:00 2001 From: isurmin Date: Mon, 27 Aug 2018 04:24:45 +0300 Subject: [PATCH] Implement support for Intel performance counters --- renderdoc.sln | 113 ++ renderdoc/driver/d3d11/d3d11_counters.cpp | 106 +- renderdoc/driver/d3d11/d3d11_replay.cpp | 19 + renderdoc/driver/d3d11/d3d11_replay.h | 5 + .../driver/d3d11/renderdoc_d3d11.vcxproj | 3 + renderdoc/driver/ihv/intel/Intel.vcxproj | 130 ++ .../driver/ihv/intel/driver_store_path.cpp | 383 ++++++ .../driver/ihv/intel/driver_store_path.h | 40 + renderdoc/driver/ihv/intel/intel_counters.cpp | 423 ++++++ renderdoc/driver/ihv/intel/intel_counters.h | 95 ++ .../driver/ihv/intel/metrics_discovery_api.h | 1184 +++++++++++++++++ renderdoc/renderdoc.vcxproj | 2 +- 12 files changed, 2501 insertions(+), 2 deletions(-) create mode 100644 renderdoc/driver/ihv/intel/Intel.vcxproj create mode 100644 renderdoc/driver/ihv/intel/driver_store_path.cpp create mode 100644 renderdoc/driver/ihv/intel/driver_store_path.h create mode 100644 renderdoc/driver/ihv/intel/intel_counters.cpp create mode 100644 renderdoc/driver/ihv/intel/intel_counters.h create mode 100644 renderdoc/driver/ihv/intel/metrics_discovery_api.h diff --git a/renderdoc.sln b/renderdoc.sln index 4997e4305..ec339f2f3 100644 --- a/renderdoc.sln +++ b/renderdoc.sln @@ -81,14 +81,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NV", "renderdoc\driver\ihv\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD_RGP", "renderdoc\driver\ihv\amd\AMD_RGP.vcxproj", "{B33F8FFD-3C04-4779-9C3B-E2858387971B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Intel", "renderdoc\driver\ihv\intel\Intel.vcxproj", "{7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Development|x64 = Development|x64 Development|x86 = Development|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Debug|x64.ActiveCfg = QTDebug|x64 + {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Debug|x64.Build.0 = QTDebug|x64 + {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Debug|x86.ActiveCfg = QTDebug|Win32 + {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Debug|x86.Build.0 = QTDebug|Win32 {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Development|x64.ActiveCfg = Development|x64 {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Development|x64.Build.0 = Development|x64 {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Development|x86.ActiveCfg = Development|Win32 @@ -97,6 +105,10 @@ Global {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Release|x64.Build.0 = Release|x64 {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Release|x86.ActiveCfg = Release|Win32 {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B}.Release|x86.Build.0 = Release|Win32 + {E2B46D67-90E2-40B6-9597-72930E7845E5}.Debug|x64.ActiveCfg = Development|x64 + {E2B46D67-90E2-40B6-9597-72930E7845E5}.Debug|x64.Build.0 = Development|x64 + {E2B46D67-90E2-40B6-9597-72930E7845E5}.Debug|x86.ActiveCfg = Development|Win32 + {E2B46D67-90E2-40B6-9597-72930E7845E5}.Debug|x86.Build.0 = Development|Win32 {E2B46D67-90E2-40B6-9597-72930E7845E5}.Development|x64.ActiveCfg = Development|x64 {E2B46D67-90E2-40B6-9597-72930E7845E5}.Development|x64.Build.0 = Development|x64 {E2B46D67-90E2-40B6-9597-72930E7845E5}.Development|x86.ActiveCfg = Development|Win32 @@ -105,6 +117,10 @@ Global {E2B46D67-90E2-40B6-9597-72930E7845E5}.Release|x64.Build.0 = Release|x64 {E2B46D67-90E2-40B6-9597-72930E7845E5}.Release|x86.ActiveCfg = Release|Win32 {E2B46D67-90E2-40B6-9597-72930E7845E5}.Release|x86.Build.0 = Release|Win32 + {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Debug|x64.ActiveCfg = Development|x64 + {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Debug|x64.Build.0 = Development|x64 + {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Debug|x86.ActiveCfg = Development|Win32 + {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Debug|x86.Build.0 = Development|Win32 {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Development|x64.ActiveCfg = Development|x64 {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Development|x64.Build.0 = Development|x64 {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Development|x86.ActiveCfg = Development|Win32 @@ -113,30 +129,50 @@ Global {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Release|x64.Build.0 = Release|x64 {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Release|x86.ActiveCfg = Release|Win32 {D03DF2F9-513C-4084-BBDD-1DEE8D9250D7}.Release|x86.Build.0 = Release|Win32 + {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Debug|x64.ActiveCfg = Development|x64 + {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Debug|x64.Build.0 = Development|x64 + {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Debug|x86.ActiveCfg = Development|Win32 + {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Debug|x86.Build.0 = Development|Win32 {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Development|x64.ActiveCfg = Development|x64 {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Development|x86.ActiveCfg = Development|Win32 {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Release|x64.ActiveCfg = Release|x64 {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Release|x64.Build.0 = Release|x64 {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Release|x86.ActiveCfg = Release|Win32 {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}.Release|x86.Build.0 = Release|Win32 + {EC847717-119A-2391-0477-212E1140082C}.Debug|x64.ActiveCfg = Development|x64 + {EC847717-119A-2391-0477-212E1140082C}.Debug|x64.Build.0 = Development|x64 + {EC847717-119A-2391-0477-212E1140082C}.Debug|x86.ActiveCfg = Development|Win32 + {EC847717-119A-2391-0477-212E1140082C}.Debug|x86.Build.0 = Development|Win32 {EC847717-119A-2391-0477-212E1140082C}.Development|x64.ActiveCfg = Development|x64 {EC847717-119A-2391-0477-212E1140082C}.Development|x86.ActiveCfg = Development|Win32 {EC847717-119A-2391-0477-212E1140082C}.Release|x64.ActiveCfg = Release|x64 {EC847717-119A-2391-0477-212E1140082C}.Release|x64.Build.0 = Release|x64 {EC847717-119A-2391-0477-212E1140082C}.Release|x86.ActiveCfg = Release|Win32 {EC847717-119A-2391-0477-212E1140082C}.Release|x86.Build.0 = Release|Win32 + {7893E300-3ED0-7F4C-158F-67EA63934C57}.Debug|x64.ActiveCfg = Development|x64 + {7893E300-3ED0-7F4C-158F-67EA63934C57}.Debug|x64.Build.0 = Development|x64 + {7893E300-3ED0-7F4C-158F-67EA63934C57}.Debug|x86.ActiveCfg = Development|Win32 + {7893E300-3ED0-7F4C-158F-67EA63934C57}.Debug|x86.Build.0 = Development|Win32 {7893E300-3ED0-7F4C-158F-67EA63934C57}.Development|x64.ActiveCfg = Development|x64 {7893E300-3ED0-7F4C-158F-67EA63934C57}.Development|x86.ActiveCfg = Development|Win32 {7893E300-3ED0-7F4C-158F-67EA63934C57}.Release|x64.ActiveCfg = Release|x64 {7893E300-3ED0-7F4C-158F-67EA63934C57}.Release|x64.Build.0 = Release|x64 {7893E300-3ED0-7F4C-158F-67EA63934C57}.Release|x86.ActiveCfg = Release|Win32 {7893E300-3ED0-7F4C-158F-67EA63934C57}.Release|x86.Build.0 = Release|Win32 + {B7399F39-300F-450E-F471-9490F959D2A7}.Debug|x64.ActiveCfg = Development|x64 + {B7399F39-300F-450E-F471-9490F959D2A7}.Debug|x64.Build.0 = Development|x64 + {B7399F39-300F-450E-F471-9490F959D2A7}.Debug|x86.ActiveCfg = Development|Win32 + {B7399F39-300F-450E-F471-9490F959D2A7}.Debug|x86.Build.0 = Development|Win32 {B7399F39-300F-450E-F471-9490F959D2A7}.Development|x64.ActiveCfg = Development|x64 {B7399F39-300F-450E-F471-9490F959D2A7}.Development|x86.ActiveCfg = Development|Win32 {B7399F39-300F-450E-F471-9490F959D2A7}.Release|x64.ActiveCfg = Release|x64 {B7399F39-300F-450E-F471-9490F959D2A7}.Release|x64.Build.0 = Release|x64 {B7399F39-300F-450E-F471-9490F959D2A7}.Release|x86.ActiveCfg = Release|Win32 {B7399F39-300F-450E-F471-9490F959D2A7}.Release|x86.Build.0 = Release|Win32 + {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Debug|x64.ActiveCfg = Development|x64 + {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Debug|x64.Build.0 = Development|x64 + {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Debug|x86.ActiveCfg = Development|Win32 + {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Debug|x86.Build.0 = Development|Win32 {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Development|x64.ActiveCfg = Development|x64 {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Development|x64.Build.0 = Development|x64 {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Development|x86.ActiveCfg = Development|Win32 @@ -145,6 +181,10 @@ Global {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Release|x64.Build.0 = Release|x64 {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Release|x86.ActiveCfg = Release|Win32 {6DEE3F12-F2F8-42CA-865A-578D0FD11387}.Release|x86.Build.0 = Release|Win32 + {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Debug|x64.ActiveCfg = Development|x64 + {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Debug|x64.Build.0 = Development|x64 + {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Debug|x86.ActiveCfg = Development|Win32 + {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Debug|x86.Build.0 = Development|Win32 {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x64.ActiveCfg = Development|x64 {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x64.Build.0 = Development|x64 {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x86.ActiveCfg = Development|Win32 @@ -153,6 +193,10 @@ Global {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Release|x64.Build.0 = Release|x64 {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Release|x86.ActiveCfg = Release|Win32 {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Release|x86.Build.0 = Release|Win32 + {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Debug|x64.ActiveCfg = Development|x64 + {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Debug|x64.Build.0 = Development|x64 + {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Debug|x86.ActiveCfg = Development|Win32 + {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Debug|x86.Build.0 = Development|Win32 {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Development|x64.ActiveCfg = Development|x64 {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Development|x64.Build.0 = Development|x64 {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Development|x86.ActiveCfg = Development|Win32 @@ -161,6 +205,10 @@ Global {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Release|x64.Build.0 = Release|x64 {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Release|x86.ActiveCfg = Release|Win32 {0AAE0AD1-371B-4A36-9ED1-80E10E960605}.Release|x86.Build.0 = Release|Win32 + {2A793574-BD3C-46D4-9788-C339D9550CE1}.Debug|x64.ActiveCfg = Development|x64 + {2A793574-BD3C-46D4-9788-C339D9550CE1}.Debug|x64.Build.0 = Development|x64 + {2A793574-BD3C-46D4-9788-C339D9550CE1}.Debug|x86.ActiveCfg = Development|Win32 + {2A793574-BD3C-46D4-9788-C339D9550CE1}.Debug|x86.Build.0 = Development|Win32 {2A793574-BD3C-46D4-9788-C339D9550CE1}.Development|x64.ActiveCfg = Development|x64 {2A793574-BD3C-46D4-9788-C339D9550CE1}.Development|x64.Build.0 = Development|x64 {2A793574-BD3C-46D4-9788-C339D9550CE1}.Development|x86.ActiveCfg = Development|Win32 @@ -169,6 +217,10 @@ Global {2A793574-BD3C-46D4-9788-C339D9550CE1}.Release|x64.Build.0 = Release|x64 {2A793574-BD3C-46D4-9788-C339D9550CE1}.Release|x86.ActiveCfg = Release|Win32 {2A793574-BD3C-46D4-9788-C339D9550CE1}.Release|x86.Build.0 = Release|Win32 + {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Debug|x64.ActiveCfg = Development|x64 + {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Debug|x64.Build.0 = Development|x64 + {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Debug|x86.ActiveCfg = Development|Win32 + {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Debug|x86.Build.0 = Development|Win32 {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Development|x64.ActiveCfg = Development|x64 {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Development|x64.Build.0 = Development|x64 {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Development|x86.ActiveCfg = Development|Win32 @@ -177,6 +229,10 @@ Global {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Release|x64.Build.0 = Release|x64 {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Release|x86.ActiveCfg = Release|Win32 {C43FF27E-A155-4852-88EC-5CE9334C07A8}.Release|x86.Build.0 = Release|Win32 + {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Debug|x64.ActiveCfg = Development|x64 + {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Debug|x64.Build.0 = Development|x64 + {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Debug|x86.ActiveCfg = Development|Win32 + {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Debug|x86.Build.0 = Development|Win32 {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Development|x64.ActiveCfg = Development|x64 {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Development|x64.Build.0 = Development|x64 {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Development|x86.ActiveCfg = Development|Win32 @@ -185,6 +241,10 @@ Global {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Release|x64.Build.0 = Release|x64 {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Release|x86.ActiveCfg = Release|Win32 {F1E59A05-60D4-4927-9E57-DD191EAE90EF}.Release|x86.Build.0 = Release|Win32 + {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Debug|x64.ActiveCfg = Development|x64 + {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Debug|x64.Build.0 = Development|x64 + {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Debug|x86.ActiveCfg = Development|Win32 + {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Debug|x86.Build.0 = Development|Win32 {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Development|x64.ActiveCfg = Development|x64 {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Development|x64.Build.0 = Development|x64 {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Development|x86.ActiveCfg = Development|Win32 @@ -193,6 +253,10 @@ Global {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Release|x64.Build.0 = Release|x64 {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Release|x86.ActiveCfg = Release|Win32 {9C4487E8-EEB0-4A7F-BD81-23F81CD24E22}.Release|x86.Build.0 = Release|Win32 + {44044776-9469-4079-B587-ABFFF6574AA4}.Debug|x64.ActiveCfg = Development|x64 + {44044776-9469-4079-B587-ABFFF6574AA4}.Debug|x64.Build.0 = Development|x64 + {44044776-9469-4079-B587-ABFFF6574AA4}.Debug|x86.ActiveCfg = Development|Win32 + {44044776-9469-4079-B587-ABFFF6574AA4}.Debug|x86.Build.0 = Development|Win32 {44044776-9469-4079-B587-ABFFF6574AA4}.Development|x64.ActiveCfg = Development|x64 {44044776-9469-4079-B587-ABFFF6574AA4}.Development|x64.Build.0 = Development|x64 {44044776-9469-4079-B587-ABFFF6574AA4}.Development|x86.ActiveCfg = Development|Win32 @@ -201,6 +265,10 @@ Global {44044776-9469-4079-B587-ABFFF6574AA4}.Release|x64.Build.0 = Release|x64 {44044776-9469-4079-B587-ABFFF6574AA4}.Release|x86.ActiveCfg = Release|Win32 {44044776-9469-4079-B587-ABFFF6574AA4}.Release|x86.Build.0 = Release|Win32 + {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Debug|x64.ActiveCfg = Development|x64 + {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Debug|x64.Build.0 = Development|x64 + {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Debug|x86.ActiveCfg = Development|Win32 + {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Debug|x86.Build.0 = Development|Win32 {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Development|x64.ActiveCfg = Development|x64 {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Development|x64.Build.0 = Development|x64 {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Development|x86.ActiveCfg = Development|Win32 @@ -209,6 +277,10 @@ Global {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Release|x64.Build.0 = Release|x64 {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Release|x86.ActiveCfg = Release|Win32 {88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Release|x86.Build.0 = Release|Win32 + {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Debug|x64.ActiveCfg = Development|x64 + {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Debug|x64.Build.0 = Development|x64 + {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Debug|x86.ActiveCfg = Development|Win32 + {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Debug|x86.Build.0 = Development|Win32 {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Development|x64.ActiveCfg = Development|x64 {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Development|x64.Build.0 = Development|x64 {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Development|x86.ActiveCfg = Development|Win32 @@ -217,6 +289,10 @@ Global {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Release|x64.Build.0 = Release|x64 {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Release|x86.ActiveCfg = Release|Win32 {F92FCDA6-A261-4EEC-9CD0-73A11FBCC459}.Release|x86.Build.0 = Release|Win32 + {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Debug|x64.ActiveCfg = Development|x64 + {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Debug|x64.Build.0 = Development|x64 + {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Debug|x86.ActiveCfg = Development|Win32 + {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Debug|x86.Build.0 = Development|Win32 {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Development|x64.ActiveCfg = Development|x64 {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Development|x64.Build.0 = Development|x64 {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Development|x86.ActiveCfg = Development|Win32 @@ -225,6 +301,10 @@ Global {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Release|x64.Build.0 = Release|x64 {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Release|x86.ActiveCfg = Release|Win32 {9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Release|x86.Build.0 = Release|Win32 + {A8998B2D-652A-47F8-955B-5654B222B4EB}.Debug|x64.ActiveCfg = Development|x64 + {A8998B2D-652A-47F8-955B-5654B222B4EB}.Debug|x64.Build.0 = Development|x64 + {A8998B2D-652A-47F8-955B-5654B222B4EB}.Debug|x86.ActiveCfg = Development|Win32 + {A8998B2D-652A-47F8-955B-5654B222B4EB}.Debug|x86.Build.0 = Development|Win32 {A8998B2D-652A-47F8-955B-5654B222B4EB}.Development|x64.ActiveCfg = Development|x64 {A8998B2D-652A-47F8-955B-5654B222B4EB}.Development|x64.Build.0 = Development|x64 {A8998B2D-652A-47F8-955B-5654B222B4EB}.Development|x86.ActiveCfg = Development|Win32 @@ -233,6 +313,10 @@ Global {A8998B2D-652A-47F8-955B-5654B222B4EB}.Release|x64.Build.0 = Release|x64 {A8998B2D-652A-47F8-955B-5654B222B4EB}.Release|x86.ActiveCfg = Release|Win32 {A8998B2D-652A-47F8-955B-5654B222B4EB}.Release|x86.Build.0 = Release|Win32 + {61157930-78C3-4355-8B49-4CC91B98F17B}.Debug|x64.ActiveCfg = Development|x64 + {61157930-78C3-4355-8B49-4CC91B98F17B}.Debug|x64.Build.0 = Development|x64 + {61157930-78C3-4355-8B49-4CC91B98F17B}.Debug|x86.ActiveCfg = Development|Win32 + {61157930-78C3-4355-8B49-4CC91B98F17B}.Debug|x86.Build.0 = Development|Win32 {61157930-78C3-4355-8B49-4CC91B98F17B}.Development|x64.ActiveCfg = Development|x64 {61157930-78C3-4355-8B49-4CC91B98F17B}.Development|x64.Build.0 = Development|x64 {61157930-78C3-4355-8B49-4CC91B98F17B}.Development|x86.ActiveCfg = Development|Win32 @@ -241,6 +325,10 @@ Global {61157930-78C3-4355-8B49-4CC91B98F17B}.Release|x64.Build.0 = Release|x64 {61157930-78C3-4355-8B49-4CC91B98F17B}.Release|x86.ActiveCfg = Release|Win32 {61157930-78C3-4355-8B49-4CC91B98F17B}.Release|x86.Build.0 = Release|Win32 + {257FD75C-4D17-4A23-A754-23BFD85887A0}.Debug|x64.ActiveCfg = Development|x64 + {257FD75C-4D17-4A23-A754-23BFD85887A0}.Debug|x64.Build.0 = Development|x64 + {257FD75C-4D17-4A23-A754-23BFD85887A0}.Debug|x86.ActiveCfg = Development|Win32 + {257FD75C-4D17-4A23-A754-23BFD85887A0}.Debug|x86.Build.0 = Development|Win32 {257FD75C-4D17-4A23-A754-23BFD85887A0}.Development|x64.ActiveCfg = Development|x64 {257FD75C-4D17-4A23-A754-23BFD85887A0}.Development|x64.Build.0 = Development|x64 {257FD75C-4D17-4A23-A754-23BFD85887A0}.Development|x86.ActiveCfg = Development|Win32 @@ -249,6 +337,10 @@ Global {257FD75C-4D17-4A23-A754-23BFD85887A0}.Release|x64.Build.0 = Release|x64 {257FD75C-4D17-4A23-A754-23BFD85887A0}.Release|x86.ActiveCfg = Release|Win32 {257FD75C-4D17-4A23-A754-23BFD85887A0}.Release|x86.Build.0 = Release|Win32 + {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Debug|x64.ActiveCfg = Development|x64 + {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Debug|x64.Build.0 = Development|x64 + {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Debug|x86.ActiveCfg = Development|Win32 + {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Debug|x86.Build.0 = Development|Win32 {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Development|x64.ActiveCfg = Development|x64 {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Development|x64.Build.0 = Development|x64 {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Development|x86.ActiveCfg = Development|Win32 @@ -257,6 +349,10 @@ Global {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Release|x64.Build.0 = Release|x64 {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Release|x86.ActiveCfg = Release|Win32 {37955C79-D91D-423F-8C6C-8F5BCF4F28D4}.Release|x86.Build.0 = Release|Win32 + {40349AD9-5558-4DF4-84E2-11934DE90A11}.Debug|x64.ActiveCfg = Development|x64 + {40349AD9-5558-4DF4-84E2-11934DE90A11}.Debug|x64.Build.0 = Development|x64 + {40349AD9-5558-4DF4-84E2-11934DE90A11}.Debug|x86.ActiveCfg = Development|Win32 + {40349AD9-5558-4DF4-84E2-11934DE90A11}.Debug|x86.Build.0 = Development|Win32 {40349AD9-5558-4DF4-84E2-11934DE90A11}.Development|x64.ActiveCfg = Development|x64 {40349AD9-5558-4DF4-84E2-11934DE90A11}.Development|x64.Build.0 = Development|x64 {40349AD9-5558-4DF4-84E2-11934DE90A11}.Development|x86.ActiveCfg = Development|Win32 @@ -265,6 +361,10 @@ Global {40349AD9-5558-4DF4-84E2-11934DE90A11}.Release|x64.Build.0 = Release|x64 {40349AD9-5558-4DF4-84E2-11934DE90A11}.Release|x86.ActiveCfg = Release|Win32 {40349AD9-5558-4DF4-84E2-11934DE90A11}.Release|x86.Build.0 = Release|Win32 + {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Debug|x64.ActiveCfg = Development|x64 + {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Debug|x64.Build.0 = Development|x64 + {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Debug|x86.ActiveCfg = Development|Win32 + {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Debug|x86.Build.0 = Development|Win32 {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Development|x64.ActiveCfg = Development|x64 {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Development|x64.Build.0 = Development|x64 {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Development|x86.ActiveCfg = Development|Win32 @@ -273,6 +373,18 @@ Global {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Release|x64.Build.0 = Release|x64 {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Release|x86.ActiveCfg = Release|Win32 {B33F8FFD-3C04-4779-9C3B-E2858387971B}.Release|x86.Build.0 = Release|Win32 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Debug|x64.ActiveCfg = Debug|x64 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Debug|x64.Build.0 = Debug|x64 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Debug|x86.ActiveCfg = Debug|Win32 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Debug|x86.Build.0 = Debug|Win32 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Development|x64.ActiveCfg = Debug|x64 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Development|x64.Build.0 = Debug|x64 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Development|x86.ActiveCfg = Debug|Win32 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Development|x86.Build.0 = Debug|Win32 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Release|x64.ActiveCfg = Release|x64 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Release|x64.Build.0 = Release|x64 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Release|x86.ActiveCfg = Release|Win32 + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -307,5 +419,6 @@ Global {37955C79-D91D-423F-8C6C-8F5BCF4F28D4} = {B5A783D9-AEB9-420D-8E77-D4D930F8D88C} {40349AD9-5558-4DF4-84E2-11934DE90A11} = {4DA2F3E3-9A65-45DD-A69B-82C7757D4904} {B33F8FFD-3C04-4779-9C3B-E2858387971B} = {4DA2F3E3-9A65-45DD-A69B-82C7757D4904} + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5} = {4DA2F3E3-9A65-45DD-A69B-82C7757D4904} EndGlobalSection EndGlobal diff --git a/renderdoc/driver/d3d11/d3d11_counters.cpp b/renderdoc/driver/d3d11/d3d11_counters.cpp index b47bbae1e..63bd2859a 100644 --- a/renderdoc/driver/d3d11/d3d11_counters.cpp +++ b/renderdoc/driver/d3d11/d3d11_counters.cpp @@ -26,6 +26,7 @@ #include #include "common/common.h" #include "driver/ihv/amd/amd_counters.h" +#include "driver/ihv/intel/intel_counters.h" #include "driver/ihv/nv/nv_counters.h" #include "d3d11_context.h" #include "d3d11_debug.h" @@ -61,6 +62,12 @@ vector D3D11Replay::EnumerateCounters() ret.insert(ret.end(), nvCounters.begin(), nvCounters.end()); } + if(m_pIntelCounters) + { + vector intelCounters = m_pIntelCounters->GetPublicCounterIds(); + ret.insert(ret.end(), intelCounters.begin(), intelCounters.end()); + } + return ret; } @@ -87,6 +94,15 @@ CounterDescription D3D11Replay::DescribeCounter(GPUCounter counterID) } } + // Intel + if(IsIntelCounter(counterID)) + { + if(m_pIntelCounters) + { + return m_pIntelCounters->GetCounterDescription(counterID); + } + } + // 448A0516-B50E-4312-A6DC-CFE7222FC1AC desc.uuid.words[0] = 0x448A0516; desc.uuid.words[1] = 0xB50E4312; @@ -383,6 +399,41 @@ void D3D11Replay::FillTimersNV(uint32_t &eventStartID, uint32_t &sampleIndex, } } +void D3D11Replay::FillTimersIntel(uint32_t &eventStartID, uint32_t &sampleIndex, + vector &eventIDs, const DrawcallDescription &drawnode) +{ + if(drawnode.children.empty()) + return; + + for(size_t i = 0; i < drawnode.children.size(); i++) + { + const DrawcallDescription &d = drawnode.children[i]; + + FillTimersIntel(eventStartID, sampleIndex, eventIDs, drawnode.children[i]); + + if(d.events.empty() || (!(drawnode.children[i].flags & DrawFlags::Drawcall) && + !(drawnode.children[i].flags & DrawFlags::Dispatch))) + continue; + + eventIDs.push_back(d.eventId); + + m_pDevice->ReplayLog(eventStartID, d.eventId, eReplay_WithoutDraw); + + SerializeImmediateContext(); + + m_pIntelCounters->BeginSample(); + + m_pDevice->ReplayLog(eventStartID, d.eventId, eReplay_OnlyDraw); + + SerializeImmediateContext(); + + m_pIntelCounters->EndSample(); + + eventStartID = d.eventId + 1; + sampleIndex++; + } +} + vector D3D11Replay::FetchCountersAMD(const vector &counters) { ID3D11Device *d3dDevice = m_pDevice->GetReal(); @@ -472,6 +523,45 @@ vector D3D11Replay::FetchCountersNV(const vector &cou return ret; } +vector D3D11Replay::FetchCountersIntel(const vector &counters) +{ + m_pIntelCounters->DisableAllCounters(); + + // enable counters it needs + for(size_t i = 0; i < counters.size(); i++) + { + // This function is only called internally, and violating this assertion means our + // caller has invoked this method incorrectly + RDCASSERT(IsIntelCounter(counters[i])); + m_pIntelCounters->EnableCounter(counters[i]); + } + + m_pIntelCounters->BeginSession(); + + uint32_t passCount = m_pIntelCounters->GetPassCount(); + + uint32_t sampleIndex = 0; + + vector eventIDs; + + for(uint32_t p = 0; p < passCount; p++) + { + m_pIntelCounters->BeginPass(); + uint32_t eventStartID = 0; + + sampleIndex = 0; + + eventIDs.clear(); + + FillTimersIntel(eventStartID, sampleIndex, eventIDs, m_pImmediateContext->GetRootDraw()); + m_pIntelCounters->EndPass(); + } + + m_pIntelCounters->EndSesssion(); + + return m_pIntelCounters->GetCounterData(eventIDs, counters); +} + vector D3D11Replay::FetchCounters(const vector &counters) { vector ret; @@ -486,7 +576,9 @@ vector D3D11Replay::FetchCounters(const vector &count vector d3dCounters; std::copy_if(counters.begin(), counters.end(), std::back_inserter(d3dCounters), - [](const GPUCounter &c) { return !IsAMDCounter(c) && !IsNvidiaCounter(c); }); + [](const GPUCounter &c) { + return !IsAMDCounter(c) && !IsNvidiaCounter(c) && !IsIntelCounter(c); + }); if(m_pAMDCounters) { @@ -514,6 +606,18 @@ vector D3D11Replay::FetchCounters(const vector &count } } + if(m_pIntelCounters) + { + vector intelCounters; + std::copy_if(counters.begin(), counters.end(), std::back_inserter(intelCounters), + [](const GPUCounter &c) { return IsIntelCounter(c); }); + + if(!intelCounters.empty()) + { + ret = FetchCountersIntel(intelCounters); + } + } + if(d3dCounters.empty()) { return ret; diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 0a04d84fb..796f78013 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -26,6 +26,7 @@ #include "d3d11_replay.h" #include "driver/dx/official/d3dcompiler.h" #include "driver/ihv/amd/amd_counters.h" +#include "driver/ihv/intel/intel_counters.h" #include "driver/ihv/nv/nv_counters.h" #include "driver/shaders/dxbc/dxbc_debug.h" #include "maths/camera.h" @@ -159,6 +160,7 @@ void D3D11Replay::CreateResources() AMDCounters *countersAMD = NULL; NVCounters *countersNV = NULL; + IntelCounters *countersIntel = NULL; if(m_Vendor == GPUVendor::AMD) { @@ -170,6 +172,11 @@ void D3D11Replay::CreateResources() RDCLOG("nVidia GPU detected - trying to initialise nVidia counters"); countersNV = new NVCounters(); } + else if(m_Vendor == GPUVendor::Intel) + { + RDCLOG("Intel GPU detected - trying to initialize Intel counters"); + countersIntel = new IntelCounters(); + } else { RDCLOG("%s GPU detected - no counters available", ToStr(m_Vendor).c_str()); @@ -196,6 +203,17 @@ void D3D11Replay::CreateResources() delete countersNV; m_pNVCounters = NULL; } + + if(countersIntel && countersIntel->Init(d3dDevice)) + { + m_pIntelCounters = countersIntel; + } + else + { + delete countersIntel; + m_pIntelCounters = NULL; + } + RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 1.0f); } @@ -214,6 +232,7 @@ void D3D11Replay::DestroyResources() SAFE_DELETE(m_pAMDCounters); SAFE_DELETE(m_pNVCounters); + SAFE_DELETE(m_pIntelCounters); ShutdownStreamOut(); ClearPostVSCache(); diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index c411df9d8..fa183f2c5 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -38,6 +38,7 @@ class WrappedID3D11DeviceContext; class AMDCounters; class NVCounters; +class IntelCounters; struct D3D11CounterContext; struct D3D11PostVSData @@ -255,12 +256,15 @@ private: std::vector FetchCountersAMD(const vector &counters); std::vector FetchCountersNV(const vector &counters); + std::vector FetchCountersIntel(const vector &counters); void FillTimers(D3D11CounterContext &ctx, const DrawcallDescription &drawnode); void FillTimersAMD(uint32_t &eventStartID, uint32_t &sampleIndex, vector &eventIDs, const DrawcallDescription &drawnode); void FillTimersNV(uint32_t &eventStartID, uint32_t &sampleIndex, vector &eventIDs, const DrawcallDescription &drawnode); + void FillTimersIntel(uint32_t &eventStartID, uint32_t &sampleIndex, vector &eventIDs, + const DrawcallDescription &drawnode); void SerializeImmediateContext(); @@ -301,6 +305,7 @@ private: AMDCounters *m_pAMDCounters = NULL; NVCounters *m_pNVCounters = NULL; + IntelCounters *m_pIntelCounters = NULL; WrappedID3D11Device *m_pDevice = NULL; WrappedID3D11DeviceContext *m_pImmediateContext = NULL; diff --git a/renderdoc/driver/d3d11/renderdoc_d3d11.vcxproj b/renderdoc/driver/d3d11/renderdoc_d3d11.vcxproj index 26ba82a7e..f9b51daca 100644 --- a/renderdoc/driver/d3d11/renderdoc_d3d11.vcxproj +++ b/renderdoc/driver/d3d11/renderdoc_d3d11.vcxproj @@ -158,6 +158,9 @@ {5de5a561-548a-4dd7-90f0-06a2b39eae9a} + + {7fcb5fc5-1dbd-4da6-83a0-6ba4e945bda5} + {c43ff27e-a155-4852-88ec-5ce9334c07a8} false diff --git a/renderdoc/driver/ihv/intel/Intel.vcxproj b/renderdoc/driver/ihv/intel/Intel.vcxproj new file mode 100644 index 000000000..9713dac25 --- /dev/null +++ b/renderdoc/driver/ihv/intel/Intel.vcxproj @@ -0,0 +1,130 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {7FCB5FC5-1DBD-4DA6-83A0-6BA4E945BDA5} + Intel + 8.1 + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + Application + true + v140 + MultiByte + + + StaticLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + driver_$(ProjectName) + $(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\ + + + + Level3 + Disabled + true + + + + + Level3 + Disabled + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + Level3 + Disabled + true + true + true + $(SolutionDir)renderdoc\ + RENDERDOC_EXPORTS;RENDERDOC_PLATFORM_WIN32;WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renderdoc/driver/ihv/intel/driver_store_path.cpp b/renderdoc/driver/ihv/intel/driver_store_path.cpp new file mode 100644 index 000000000..697399b0d --- /dev/null +++ b/renderdoc/driver/ihv/intel/driver_store_path.cpp @@ -0,0 +1,383 @@ +/*****************************************************************************\ + + Copyright (C) 2018, Intel Corporation + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +\*****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include "driver_store_path.h" + +#define VENDORNAME L"intel" + +#if DEBUG +#define DBG(std, fmt, ...) fprintf_s(std, fmt, __VA_ARGS__) +#else +#define DBG(std, fmt, ...) +#endif + +/********************************************************************************************/ +/* GetPropertyFromDevice */ +/* */ +/* This function can be used to request a value of any device property. */ +/* There are many types of properties values. Refer to devpkey.h for more details. */ +/* Function SetupDiGetDeviceProperty() inside GetPropertyFromDevice() fills a propery value */ +/* in a correct format, but always returs the value as a pointer to a string of bytes. */ +/* The string of bytes must be casted outside of the function GetPropertyFromDevice() */ +/* to get a value in a format suitable for the given type of property. */ +/* */ +/********************************************************************************************/ +bool GetPropertyFromDevice(void *pDevInfo, PSP_DEVINFO_DATA pDevInfoData, + const DEVPROPKEY *pPropertyKey, unsigned char **ppStringOut, + unsigned long *pStringOutSize) +{ + unsigned long propertyType = 0; + unsigned long propertySize = 0; + + // request a size, in bytes, required for a buffer in which property value will be stored + // SetupDiGetDeviceProperty() returns false and ERROR_INSUFFICIENT_BUFFER for the call + if(SetupDiGetDevicePropertyW(pDevInfo, pDevInfoData, pPropertyKey, &propertyType, NULL, 0, + &propertySize, 0)) + { + DBG(stderr, "%s [%d] ---> SetupDiGetDevicePropertyW() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + return false; + } + + if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + DBG(stderr, "%s [%d] ---> SetupDiGetDevicePropertyW() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + return false; + } + + if(!ppStringOut) + { + SetLastError(ERROR_INVALID_HANDLE); + DBG(stderr, "%s [%d] ---> Error: input parameter ppStringOut = NULL\n", __FUNCTION__, __LINE__); + return false; + } + + // allocate memory for the buffer + *ppStringOut = new(std::nothrow) unsigned char[propertySize]; + if(*ppStringOut == NULL) + { + SetLastError(ERROR_INVALID_HANDLE); + DBG(stderr, "%s [%d] ---> Error: *ppStringOut = NULL\n", __FUNCTION__, __LINE__); + return false; + } + + // fill in the buffer with property value + if(!SetupDiGetDevicePropertyW(pDevInfo, pDevInfoData, pPropertyKey, &propertyType, *ppStringOut, + propertySize, NULL, 0)) + { + DBG(stderr, "%s [%d] ---> SetupDiGetDevicePropertyW() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + delete[] * ppStringOut; + *ppStringOut = NULL; + return false; + } + + if(pStringOutSize) + { + *pStringOutSize = propertySize; + } + + return true; +} + +/************************************************************************/ +/* GetIntelDriverStoreFullPath */ +/************************************************************************/ +bool GetIntelDriverStoreFullPath(wchar_t *pDriverStorePath, + unsigned long driverStorePathSizeInCharacters, + unsigned long *pDriverStorePathLengthInCharacters) +{ + bool result = false; + // allocated memory must be freed with delete operation + unsigned char *pPropertyInfName = NULL; + // allocated memory must be freed with delete operation + unsigned char *pPropertyDevServiceName = NULL; + unsigned long StringOutSize = 0; + + // guid defined for display adapters + const GUID guid = GUID_DISPLAY_DEVICE_ARRIVAL; + + // create device information set containing dispaly adapters which support interfaces and are + // currently present in the system + void *pDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + if(pDevInfo == INVALID_HANDLE_VALUE) + { + DBG(stderr, + "%s [%d] ---> SetupDiGetClassDevs() failed with the error code 0x%02x, pDevInfo = " + "INVALID_HANDLE_VALUE\n", + __FUNCTION__, __LINE__, GetLastError()); + goto END; + } + + unsigned long deviceIndex = 0; + unsigned long interfaceIndex = 0; + unsigned long driverStorePathLengthInCharacters = 0; + + // enumerate dispaly adapters + while(true) + { + SP_DEVINFO_DATA devInfoData = {}; + devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + if(!SetupDiEnumDeviceInfo(pDevInfo, deviceIndex, &devInfoData)) + { + if(GetLastError() != ERROR_NO_MORE_ITEMS) + { + DBG(stderr, "%s [%d] ---> SetupDiEnumDeviceInfo() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + } + + deviceIndex = 0; + goto END; + } + + // enumerate interfaces of display adapters + while(true) + { + SP_DEVICE_INTERFACE_DATA deviceInterfaceData = {}; + deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + if(!SetupDiEnumDeviceInterfaces(pDevInfo, &devInfoData, &guid, interfaceIndex, + &deviceInterfaceData)) + { + if(GetLastError() == ERROR_NO_MORE_ITEMS) + { + interfaceIndex = 0; + break; + } + else + { + DBG(stderr, + "%s [%d] ---> SetupDiEnumDeviceInterfaces() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + interfaceIndex = 0; + goto END; + } + } + + // get an inf file name for a display adapter + if(!GetPropertyFromDevice(pDevInfo, &devInfoData, &DEVPKEY_Device_DriverInfPath, + &pPropertyInfName, NULL)) + { + DBG(stderr, "%s [%d] ---> GetPropertyFromDevice() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + goto END; + } + + // to read DEVPKEY_Device_DriverInfPath property value correctly just cast unsigned char* (means PBYTE) to const wchar_t* + const wchar_t *pInfName = reinterpret_cast(pPropertyInfName); + DBG(stdout, "\n"); + DBG(stdout, "pPropertyInfName = %ws\n", pInfName); + wchar_t driverStorePath[MAX_PATH] = {}; + + // get a fully qualified name of an inf file (directory path and file name) + if(!SetupGetInfDriverStoreLocationW(pInfName, NULL, NULL, driverStorePath, + ARRAYSIZE(driverStorePath), NULL)) + { + // SetupGetInfDriverStoreLocationW doesn't work in Universal Windows Platform apps. Try to + // get driverStorePath through the env variable + if(!GetEnvironmentVariableW(L"DRV_INST_PATH", driverStorePath, MAX_PATH)) + { + DBG(stderr, + "%s [%d] ---> SetupGetInfDriverStoreLocation() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + goto END; + } + } + + // remove backslash and file name from the fully qualified name + PathRemoveFileSpecW(driverStorePath); + DBG(stdout, "driverStorePath = %ws\n", driverStorePath); + driverStorePathLengthInCharacters = + (unsigned long)wcsnlen_s(driverStorePath, ARRAYSIZE(driverStorePath)); + DBG(stdout, "driverStorePathLengthInCharacters = %d\n", driverStorePathLengthInCharacters); + + // get service name for a display adapter + if(!GetPropertyFromDevice(pDevInfo, &devInfoData, &DEVPKEY_Device_Manufacturer, + &pPropertyDevServiceName, &StringOutSize)) + { + DBG(stderr, "%s [%d] ---> GetPropertyFromDevice() failed with the error code 0x%02x\n", + __FUNCTION__, __LINE__, GetLastError()); + goto END; + } + + // to read DEVPKEY_Device_Service property value correctly just cast unsigned char* (means PBYTE) to const wchar_t* + StringOutSize = (unsigned long)wcsnlen_s(reinterpret_cast(pPropertyDevServiceName), + (size_t)StringOutSize); + _wcslwr_s(reinterpret_cast(pPropertyDevServiceName), StringOutSize + 1); + + wchar_t *pDevServiceName = reinterpret_cast(pPropertyDevServiceName); + DBG(stdout, "pDevServiceName = %ws\n", pDevServiceName); + + // check if a given display adapter is from intel based on driver device service name "igfx" + // check if pDevServiceName contains "igfx" name + if((wcsncmp(pDevServiceName, VENDORNAME, wcslen(VENDORNAME)) == 0)) + { + // display adapter is from Intel + DBG(stdout, "this display adapter is from Intel\n"); + + if(!pDriverStorePath) + { + DBG(stderr, "%s [%d] ---> Error: input parameter pDriverStorePath = NULL\n", __FUNCTION__, + __LINE__); + goto END; + } + + if(driverStorePathSizeInCharacters < driverStorePathLengthInCharacters + 1) + { + DBG(stderr, + "%s [%d] ---> Error: input parameter driverStorePathSizeInCharacters = %d is too " + "small, the required size is %d\n", + __FUNCTION__, __LINE__, driverStorePathSizeInCharacters, + driverStorePathLengthInCharacters + 1); + goto END; + } + + wcscpy_s(pDriverStorePath, driverStorePathSizeInCharacters, driverStorePath); + + if(pDriverStorePathLengthInCharacters) + { + *pDriverStorePathLengthInCharacters = driverStorePathLengthInCharacters; + } + + result = (driverStorePathLengthInCharacters > 0) ? true : false; + if(!result) + { + SetLastError(ERROR_BAD_LENGTH); + DBG(stderr, "%s [%d] ---> Error: driverStorePathLengthInCharacters = 0, result = false\n", + __FUNCTION__, __LINE__); + } + goto END; + } + else + { + // display adapter is from other vendor + DBG(stdout, "this display adapter is NOT from Intel\n"); + + if(pPropertyDevServiceName) + { + delete[] pPropertyDevServiceName; + pPropertyDevServiceName = NULL; + } + + if(pPropertyInfName) + { + delete[] pPropertyInfName; + pPropertyInfName = NULL; + } + } + + ++interfaceIndex; + } + + ++deviceIndex; + } + +END: + DBG(stdout, "\n"); + + if(pPropertyDevServiceName) + { + delete[] pPropertyDevServiceName; + pPropertyDevServiceName = NULL; + } + + if(pPropertyInfName) + { + delete[] pPropertyInfName; + pPropertyInfName = NULL; + } + + if(pDevInfo) + { + SetupDiDestroyDeviceInfoList(pDevInfo); + pDevInfo = NULL; + } + + return result; +} + +/************************************************************************/ +/* LoadDynamicLibrary */ +/************************************************************************/ +HMODULE LoadDynamicLibrary(const wchar_t *pFileName, HANDLE hFile, unsigned long flags) +{ + HMODULE hModule = NULL; + unsigned long driverStorePathLengthInCharacters = 0; + // contains fully qualified name of DriverStore (directory path only without backslash at the end) + // for Intel display driver for example: + // C:\Windows\System32\DriverStore\FileRepository\igdlh64.inf_amd64_1d1d318ad2d391db + wchar_t driverStorePath[MAX_PATH] = {0}; + + // find fully qualified name of DriverStore for Intel graphics driver + if(GetIntelDriverStoreFullPath(driverStorePath, ARRAYSIZE(driverStorePath), + &driverStorePathLengthInCharacters)) + { + std::wstring driverStoreFullPath(driverStorePath); + + if(driverStorePathLengthInCharacters) + { + driverStoreFullPath += L"\\"; + driverStoreFullPath += pFileName; + } + + DBG(stdout, "full path: %ws\n\n", driverStoreFullPath.c_str()); + + // load dll from DriverStore full path + hModule = LoadLibraryExW(driverStoreFullPath.c_str(), NULL, 0); + } + else + { + DBG(stderr, "%s [%d] ---> GetIntelDriverStoreFullPath() failed\n", __FUNCTION__, __LINE__); + hModule = NULL; + } + + return hModule; +} + +/************************************************************************/ +/* UnloadDynamicLibrary */ +/************************************************************************/ +bool UnloadDynamicLibrary(HMODULE *phModule) +{ + if(phModule) + { + return FreeLibrary(*phModule) ? true : false; + } + else + { + DBG(stderr, "%s [%d] ---> Error: input parameter phModule = NULL\n", __FUNCTION__, __LINE__); + return false; + } +} diff --git a/renderdoc/driver/ihv/intel/driver_store_path.h b/renderdoc/driver/ihv/intel/driver_store_path.h new file mode 100644 index 000000000..dfdc33657 --- /dev/null +++ b/renderdoc/driver/ihv/intel/driver_store_path.h @@ -0,0 +1,40 @@ +/*****************************************************************************\ + + Copyright (C) 2018, Intel Corporation + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +\*****************************************************************************/ + +#pragma once + +#include +#include + +bool GetPropertyFromDevice(void *pDevInfo, PSP_DEVINFO_DATA pDevInfoData, + const DEVPROPKEY *pPropertyKey, unsigned char **ppStringOut, + unsigned long *pStringOutSize); + +bool GetIntelDriverStoreFullPath(wchar_t *pDriverStorePath, + unsigned long driverStorePathSizeInCharacters, + unsigned long *pDriverStorePathLengthInCharacters); + +HMODULE LoadDynamicLibrary(const wchar_t *pFileName, HANDLE hFile = NULL, unsigned long flags = 0); + +bool UnloadDynamicLibrary(HMODULE *phModule); diff --git a/renderdoc/driver/ihv/intel/intel_counters.cpp b/renderdoc/driver/ihv/intel/intel_counters.cpp new file mode 100644 index 000000000..83f555e53 --- /dev/null +++ b/renderdoc/driver/ihv/intel/intel_counters.cpp @@ -0,0 +1,423 @@ +/*****************************************************************************\ + + Copyright (C) 2018, Intel Corporation + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +\*****************************************************************************/ + +#include "common/common.h" + +#include "intel_counters.h" +#include "driver_store_path.h" + +#include + +const static std::vector metricSetBlacklist = {"TestOa"}; + +IntelCounters::IntelCounters() + : m_MDLibraryHandle(nullptr), + m_metricsDevice(nullptr), + m_device(nullptr), + m_deviceContext(nullptr), + m_counter(nullptr), + m_passIndex(0), + m_sampleIndex(0) +{ +} + +IntelCounters::~IntelCounters() +{ + if(CloseMetricsDevice) + CloseMetricsDevice(m_metricsDevice); + + if(m_MDLibraryHandle) + FreeLibrary(m_MDLibraryHandle); +} + +bool IntelCounters::Init(void *pContext) +{ + if(!pContext) + return false; + + m_device = (ID3D11Device *)pContext; + m_device->GetImmediateContext(&m_deviceContext); + if(!m_deviceContext) + return false; + + m_MDLibraryHandle = LoadDynamicLibrary(L"igdmd64.dll", nullptr, 0); + if(!m_MDLibraryHandle) + return false; + + OpenMetricsDevice = (OpenMetricsDevice_fn)GetProcAddress(m_MDLibraryHandle, "OpenMetricsDevice"); + if(!OpenMetricsDevice) + return false; + + CloseMetricsDevice = + (CloseMetricsDevice_fn)GetProcAddress(m_MDLibraryHandle, "CloseMetricsDevice"); + if(!CloseMetricsDevice) + return false; + + TCompletionCode result = OpenMetricsDevice(&m_metricsDevice); + if(result != CC_OK) + return false; + + TMetricsDeviceParams_1_2 *deviceParams = m_metricsDevice->GetParams(); + if(deviceParams->Version.MajorNumber < 1 || + (deviceParams->Version.MajorNumber == 1 && deviceParams->Version.MinorNumber < 1)) + { + CloseMetricsDevice(m_metricsDevice); + FreeLibrary(m_MDLibraryHandle); + m_metricsDevice = nullptr; + m_MDLibraryHandle = (HMODULE)0; + return false; + } + + m_Counters = EnumerateCounters(); + + return true; +} + +CounterDescription IntelCounters::GetCounterDescription(GPUCounter counter) +{ + return m_Counters[GPUCounterToCounterIndex(counter)]; +} + +std::vector IntelCounters::EnumerateCounters() +{ + m_Counters.clear(); + m_allMetricSets.clear(); + std::set addedMetrics; + TMetricsDeviceParams_1_2 *deviceParams = m_metricsDevice->GetParams(); + for(unsigned int i = 0; i < deviceParams->ConcurrentGroupsCount; ++i) + { + IConcurrentGroup_1_1 *concurrentGroup = m_metricsDevice->GetConcurrentGroup(i); + TConcurrentGroupParams_1_0 *groupParams = concurrentGroup->GetParams(); + if(strcmp(groupParams->SymbolName, "OA") != 0) + continue; + + m_subscribedMetricsByCounterSet.resize(groupParams->MetricSetsCount); + + for(unsigned int j = 0; j < groupParams->MetricSetsCount; ++j) + { + IMetricSet_1_1 *metricSet = concurrentGroup->GetMetricSet(j); + metricSet->SetApiFiltering(API_TYPE_DX11); + m_allMetricSets.push_back(metricSet); + TMetricSetParams_1_0 *setParams = metricSet->GetParams(); + + if(std::find(metricSetBlacklist.begin(), metricSetBlacklist.end(), setParams->SymbolName) != + metricSetBlacklist.end()) + continue; + + for(unsigned int k = 0; k < setParams->MetricsCount; ++k) + { + IMetric_1_0 *metric = metricSet->GetMetric(k); + TMetricParams_1_0 *metricParams = metric->GetParams(); + + if((metricParams->UsageFlagsMask & EMetricUsageFlag::USAGE_FLAG_OVERVIEW) == 0) + continue; + + if(metricParams->ResultType == TMetricResultType::RESULT_BOOL) + continue; + + if(addedMetrics.count(metricParams->ShortName) > 0) + continue; + + CounterDescription counterDesc; + counterDesc.name = metricParams->ShortName; + counterDesc.description = metricParams->LongName; + counterDesc.category = metricParams->GroupName; + counterDesc.resultByteWidth = 8; + counterDesc.resultType = CompType::Double; + switch(metricParams->ResultType) + { + case RESULT_UINT32: + counterDesc.resultType = CompType::UInt; + counterDesc.resultByteWidth = sizeof(uint32_t); + break; + case RESULT_UINT64: + counterDesc.resultType = CompType::UInt; + counterDesc.resultByteWidth = sizeof(uint64_t); + break; + case RESULT_FLOAT: + counterDesc.resultType = CompType::Float; + counterDesc.resultByteWidth = sizeof(float); + break; + default: break; + } + + counterDesc.unit = CounterUnit::Absolute; + if(strcmp(metricParams->MetricResultUnits, "cycles") == 0) + counterDesc.unit = CounterUnit::Cycles; + else if(strcmp(metricParams->MetricResultUnits, "bytes") == 0) + counterDesc.unit = CounterUnit::Bytes; + else if(strcmp(metricParams->MetricResultUnits, "percent") == 0) + counterDesc.unit = CounterUnit::Percentage; + else if(strcmp(metricParams->MetricResultUnits, "ns") == 0) + counterDesc.unit = CounterUnit::Seconds; + + uint32_t counterId = (uint32_t)GPUCounter::FirstIntel + (uint32_t)m_Counters.size(); + counterDesc.counter = (GPUCounter)counterId; + m_Counters.push_back(counterDesc); + addedMetrics.insert(counterDesc.name); + m_metricLocation[(GPUCounter)counterId] = std::pair(j, k); + m_counterIds.push_back((GPUCounter)counterId); + } + } + } + + return m_Counters; +} + +uint32_t IntelCounters::GetPassCount() +{ + return (uint32_t)m_subscribedMetricSets.size(); +} + +uint32_t IntelCounters::BeginSession() +{ + if(!m_metricsDevice) + return 0; + + m_passIndex = 0; + TMetricsDeviceParams_1_2 *deviceParams = m_metricsDevice->GetParams(); + if(deviceParams->Version.MajorNumber < 1 || + (deviceParams->Version.MajorNumber == 1 && deviceParams->Version.MinorNumber < 2)) + return 0; + + IOverride_1_2 *frequencyOverride = m_metricsDevice->GetOverrideByName("FrequencyOverride"); + if(!frequencyOverride) + return 0; + + TTypedValue_1_0 *maxFreqSymbol = + m_metricsDevice->GetGlobalSymbolValueByName("GpuMaxFrequencyMHz"); + if(!maxFreqSymbol) + return 0; + + TSetFrequencyOverrideParams_1_2 params; + params.Enable = true; + params.FrequencyMhz = maxFreqSymbol->ValueUInt32; + params.Pid = 0; + frequencyOverride->SetOverride(¶ms, sizeof(params)); + Sleep(500); + + return 0; +} + +void IntelCounters::EndSesssion() +{ + if(!m_metricsDevice) + return; + + TMetricsDeviceParams_1_2 *deviceParams = m_metricsDevice->GetParams(); + if(deviceParams->Version.MajorNumber > 1 || + (deviceParams->Version.MajorNumber == 1 && deviceParams->Version.MinorNumber >= 2)) + { + IOverride_1_2 *frequencyOverride = m_metricsDevice->GetOverrideByName("FrequencyOverride"); + + if(frequencyOverride) + { + TSetFrequencyOverrideParams_1_2 params; + params.Enable = false; + params.Pid = 0; + frequencyOverride->SetOverride(¶ms, sizeof(params)); + } + } +} + +void IntelCounters::BeginPass() +{ + m_sampleIndex = 0; + TMetricSetParams_1_0 *metricSetParams = m_subscribedMetricSets[m_passIndex]->GetParams(); + m_queryResult.resize(metricSetParams->MetricsCount + metricSetParams->InformationCount); +} + +void IntelCounters::EndPass() +{ + m_passIndex++; +} + +void IntelCounters::EnableCounter(GPUCounter index) +{ + uint32_t metricSetIdx = m_metricLocation[index].first; + IMetricSet_1_1 *metricSet = m_allMetricSets[metricSetIdx]; + auto iter = std::find(m_subscribedMetricSets.begin(), m_subscribedMetricSets.end(), metricSet); + if(iter == m_subscribedMetricSets.end()) + { + m_subscribedMetricSets.push_back(metricSet); + metricSetIdx = (uint32_t)m_subscribedMetricSets.size() - 1; + } + else + { + metricSetIdx = (uint32_t)(iter - m_subscribedMetricSets.begin()); + } + m_subscribedMetricsByCounterSet[metricSetIdx].push_back(index); +} + +void IntelCounters::DisableAllCounters() +{ + m_subscribedMetricSets.clear(); + for(size_t i = 0; i < m_subscribedMetricsByCounterSet.size(); i++) + m_subscribedMetricsByCounterSet[i].clear(); +} + +void IntelCounters::BeginSample() +{ + if(!m_metricsDevice) + return; + + D3D11_COUNTER_DESC counter_desc; + counter_desc.MiscFlags = 0; + counter_desc.Counter = + (D3D11_COUNTER)m_subscribedMetricSets[m_passIndex]->GetParams()->ApiSpecificId.D3D1XDevDependentId; + + if(counter_desc.Counter == 0) + return; + + TCompletionCode res = m_subscribedMetricSets[m_passIndex]->Activate(); + if(res != TCompletionCode::CC_OK) + return; + + HRESULT hr = m_device->CreateCounter(&counter_desc, &m_counter); + if(FAILED(hr)) + { + m_subscribedMetricSets[m_passIndex]->Deactivate(); + return; + } + + res = m_subscribedMetricSets[m_passIndex]->Deactivate(); + if(res != TCompletionCode::CC_OK) + return; + + m_deviceContext->Begin(m_counter); +} + +void IntelCounters::EndSample() +{ + if(!m_metricsDevice) + return; + + m_deviceContext->End(m_counter); + HRESULT hr = S_OK; + uint32_t iteration = 0; + const uint32_t max_attempts = 0xFFFFFFFF; + void *counter_data = nullptr; + + do + { + uint32_t flags = (iteration == 0) ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH; + hr = m_deviceContext->GetData(m_counter, &counter_data, m_counter->GetDataSize(), flags); + iteration++; + } while(hr != S_OK && iteration < max_attempts); + m_counter->Release(); + + if(hr != S_OK) + return; + + IMetricSet_1_1 *metricSet = m_subscribedMetricSets[m_passIndex]; + TMetricSetParams_1_0 *metricSetParams = metricSet->GetParams(); + + uint32_t calculatedReportCount = 0; + TCompletionCode res = m_subscribedMetricSets[m_passIndex]->CalculateMetrics( + (const unsigned char *)counter_data, metricSetParams->QueryReportSize, m_queryResult.data(), + (uint32_t)m_queryResult.size() * sizeof(TTypedValue_1_0), &calculatedReportCount, false); + + if(res != TCompletionCode::CC_OK) + return; + + for(int i = 0; i < m_subscribedMetricsByCounterSet[m_passIndex].size(); i++) + { + GPUCounter counterId = m_subscribedMetricsByCounterSet[m_passIndex][i]; + uint32_t counterIndex = m_metricLocation[counterId].second; + + m_results[std::pair(counterId, m_sampleIndex)] = + m_queryResult[counterIndex]; + } + m_sampleIndex++; +} + +std::vector IntelCounters::GetCounterData(const std::vector &eventIDs, + const std::vector &counters) +{ + std::vector ret; + for(uint32_t sample = 0; sample < (uint32_t)eventIDs.size(); sample++) + { + for(size_t counter = 0; counter < counters.size(); counter++) + { + const CounterDescription desc = GetCounterDescription(counters[counter]); + + switch(desc.resultType) + { + case CompType::UInt: + { + if(desc.resultByteWidth == sizeof(uint32_t)) + { + uint32_t value = + m_results[std::pair(desc.counter, sample)].ValueUInt32; + if(desc.unit == CounterUnit::Percentage) + { + value = RDCCLAMP(value, 0U, 100U); + } + + ret.push_back(CounterResult(eventIDs[sample], counters[counter], value)); + } + else if(desc.resultByteWidth == sizeof(uint64_t)) + { + uint64_t value = + m_results[std::pair(desc.counter, sample)].ValueUInt64; + // RenderDoc expects time metrics in microceconds + if(desc.unit == CounterUnit::Seconds) + value /= 1000; + + if(desc.unit == CounterUnit::Percentage) + { + value = RDCCLAMP(value, 0ULL, 100ULL); + } + + ret.push_back(CounterResult(eventIDs[sample], counters[counter], value)); + } + else + { + RDCERR("Unexpected byte width %u", desc.resultByteWidth); + } + } + break; + case CompType::Float: + { + float value = m_results[std::pair(desc.counter, sample)].ValueFloat; + if(fabs(value) < 1e-9) + { + value = 0.0f; + } + + if(desc.unit == CounterUnit::Percentage) + { + value = RDCCLAMP(value, 0.0f, 100.0f); + } + + ret.push_back(CounterResult(eventIDs[sample], counters[counter], value)); + } + break; + default: RDCASSERT(0); break; + }; + } + } + + return ret; +} diff --git a/renderdoc/driver/ihv/intel/intel_counters.h b/renderdoc/driver/ihv/intel/intel_counters.h new file mode 100644 index 000000000..b70a94a11 --- /dev/null +++ b/renderdoc/driver/ihv/intel/intel_counters.h @@ -0,0 +1,95 @@ +/*****************************************************************************\ + + Copyright (C) 2018, Intel Corporation + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +\*****************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +#include "api/replay/renderdoc_replay.h" +#include "metrics_discovery_api.h" + +using namespace MetricsDiscovery; + +inline constexpr GPUCounter MakeIntelCounter(int index) +{ + return GPUCounter((int)GPUCounter::FirstIntel + index); +} + +class IntelCounters +{ +public: + IntelCounters(); + bool Init(void *pDevice); + ~IntelCounters(); + + std::vector GetPublicCounterIds() const { return m_counterIds; } + + CounterDescription GetCounterDescription(GPUCounter index); + + void EnableCounter(GPUCounter index); + void DisableAllCounters(); + + uint32_t GetPassCount(); + + uint32_t BeginSession(); + void EndSesssion(); + + void BeginPass(); + void EndPass(); + + void BeginSample(); + void EndSample(); + + std::vector GetCounterData(const std::vector &eventIDs, + const std::vector &counters); + +private: + static uint32_t GPUCounterToCounterIndex(GPUCounter counter) + { + return (uint32_t)(counter) - (uint32_t)(GPUCounter::FirstIntel); + } + + std::vector EnumerateCounters(); + std::vector m_counterIds; + std::vector m_Counters; + std::vector m_allMetricSets; + std::vector m_subscribedMetricSets; + std::map> m_metricLocation; + std::vector> m_subscribedMetricsByCounterSet; + ID3D11Device *m_device; + ID3D11DeviceContext *m_deviceContext; + ID3D11Counter *m_counter; + std::vector m_queryResult; + uint32_t m_passIndex; + uint32_t m_sampleIndex; + std::map, TTypedValue_1_0> m_results; + + HMODULE m_MDLibraryHandle; + IMetricsDevice_1_5 *m_metricsDevice; + OpenMetricsDevice_fn OpenMetricsDevice; + CloseMetricsDevice_fn CloseMetricsDevice; +}; diff --git a/renderdoc/driver/ihv/intel/metrics_discovery_api.h b/renderdoc/driver/ihv/intel/metrics_discovery_api.h new file mode 100644 index 000000000..4adf67162 --- /dev/null +++ b/renderdoc/driver/ihv/intel/metrics_discovery_api.h @@ -0,0 +1,1184 @@ +/*****************************************************************************\ + + Copyright (C) 2018, Intel Corporation + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +\*****************************************************************************/ + +#ifndef __METRICS_DISCOVERY_H_ +#define __METRICS_DISCOVERY_H_ + +#include + +#ifdef _MSC_VER +#define MD_STDCALL __stdcall +#else +#define MD_STDCALL +#endif // _MSC_VER + +namespace MetricsDiscovery +{ +//*****************************************************************************/ +// API major version number: +//*****************************************************************************/ +typedef enum EMD_API_MAJOR_VERSION +{ + MD_API_MAJOR_NUMBER_1 = 1, + MD_API_MAJOR_NUMBER_CURRENT = MD_API_MAJOR_NUMBER_1, + MD_API_MAJOR_NUMBER_CEIL = 0xFFFFFFFF + +} MD_API_MAJOR_VERSION; + +//*****************************************************************************/ +// API minor version number: +//*****************************************************************************/ +typedef enum EMD_API_MINOR_VERSION +{ + MD_API_MINOR_NUMBER_0 = 0, + MD_API_MINOR_NUMBER_1 = 1, // CalculationAPI + MD_API_MINOR_NUMBER_2 = 2, // OverridesAPI + MD_API_MINOR_NUMBER_3 = 3, // BatchBuffer Sampling (aka DMA Sampling) + MD_API_MINOR_NUMBER_4 = 4, // GT dependent MetricSets + MD_API_MINOR_NUMBER_5 = 5, // MaxValue calculation for CalculationAPI + MD_API_MINOR_NUMBER_CURRENT = MD_API_MINOR_NUMBER_5, + MD_API_MINOR_NUMBER_CEIL = 0xFFFFFFFF + +} MD_API_MINOR_VERSION; + +//*****************************************************************************/ +// API build number: +//*****************************************************************************/ +#define MD_API_BUILD_NUMBER_CURRENT 93 + +//*****************************************************************************/ +// Completion codes: +//*****************************************************************************/ +typedef enum ECompletionCode +{ + CC_OK = 0, + CC_READ_PENDING = 1, + CC_ALREADY_INITIALIZED = 2, + CC_STILL_INITIALIZED = 3, + CC_CONCURRENT_GROUP_LOCKED = 4, + CC_WAIT_TIMEOUT = 5, + CC_TRY_AGAIN = 6, + CC_INTERRUPTED = 7, + // ... + CC_ERROR_INVALID_PARAMETER = 40, + CC_ERROR_NO_MEMORY = 41, + CC_ERROR_GENERAL = 42, + CC_ERROR_FILE_NOT_FOUND = 43, + CC_ERROR_NOT_SUPPORTED = 44, + // ... + CC_LAST_1_0 = 45 + +} TCompletionCode; + +/* Forward declarations */ + +//*******************************************************************************/ +// Abstract interface for the GPU metrics root object. +//*******************************************************************************/ +class IMetricsDevice_1_0; +class IMetricsDevice_1_1; +class IMetricsDevice_1_2; +class IMetricsDevice_1_5; + +//*******************************************************************************/ +// Abstract interface for Metrics Device overrides. +//*******************************************************************************/ +class IOverride_1_2; + +//*******************************************************************************/ +// Abstract interface for the metrics groups that can be collected concurrently +// to another group. +//*******************************************************************************/ +class IConcurrentGroup_1_0; +class IConcurrentGroup_1_1; +class IConcurrentGroup_1_5; + +//*******************************************************************************/ +// Abstract interface for the metric sets mapping to different HW configuration +// that should be used exclusively to each other metric set in the concurrent +// group. +//*******************************************************************************/ +class IMetricSet_1_0; +class IMetricSet_1_1; +class IMetricSet_1_4; +class IMetricSet_1_5; + +//*******************************************************************************/ +// Abstract interface for the metric that is sampled. +//*******************************************************************************/ +class IMetric_1_0; + +//*******************************************************************************/ +// Abstract interface for the measurement information (report reason, etc.). +//*******************************************************************************/ +class IInformation_1_0; + +//*******************************************************************************/ +// Abstract interface for the metric read and normalization equation. +//*******************************************************************************/ +class IEquation_1_0; + +//*******************************************************************************/ +// Value types: +//*******************************************************************************/ +typedef enum EValueType +{ + VALUE_TYPE_UINT32, + VALUE_TYPE_UINT64, + VALUE_TYPE_FLOAT, + VALUE_TYPE_BOOL, + VALUE_TYPE_CSTRING, + // ... + VALUE_TYPE_LAST, + +} TValueType; + +//*******************************************************************************/ +// Typed value: +//*******************************************************************************/ +typedef struct STypedValue_1_0 +{ + TValueType ValueType; + union + { + uint32_t ValueUInt32; + uint64_t ValueUInt64; + struct + { + uint32_t Low; + uint32_t High; + } ValueUInt64Fields; + float ValueFloat; + bool ValueBool; + char *ValueCString; + }; + +} TTypedValue_1_0; + +//*******************************************************************************/ +// Global symbol: +// Global symbols will be available to describe SKU specific information. +// Example global symbols: +// "EuCoresTotalCount", "EuThreadsCount", "EuSlicesTotalCount", "EuSubslicesTotalCount", +// "SamplersTotalCount", "PciDeviceId", "NumberOfShadingUnits", "GpuTimestampFrequency", +// "MaxTimestamp", "GpuMinFrequencyMHz", "GpuMaxFrequencyMHz" +//*******************************************************************************/ +typedef struct SGlobalSymbol_1_0 +{ + const char *SymbolName; + TTypedValue_1_0 SymbolTypedValue; + +} TGlobalSymbol_1_0; + +//*******************************************************************************/ +// Global parameters of Metrics Device: +//*******************************************************************************/ +typedef struct SMetricsDeviceParams_1_0 +{ + // API version + struct SApiVersion + { + uint32_t MajorNumber; + uint32_t MinorNumber; + uint32_t BuildNumber; + } Version; + + uint32_t ConcurrentGroupsCount; + + uint32_t GlobalSymbolsCount; + uint32_t DeltaFunctionsCount; + uint32_t EquationElementTypesCount; + uint32_t EquationOperationsCount; + + const char *DeviceName; + +} TMetricsDeviceParams_1_0; + +//*******************************************************************************/ +// Global parameters of Metrics Device 1.2: +//*******************************************************************************/ +typedef struct SMetricsDeviceParams_1_2 : public SMetricsDeviceParams_1_0 +{ + uint32_t OverrideCount; + +} TMetricsDeviceParams_1_2; + +//*******************************************************************************/ +// Metric API types: +//*******************************************************************************/ +typedef enum EMetricApiType +{ + API_TYPE_IOSTREAM = 0x00000001, // API independent method + API_TYPE_DX9 = 0x00000002, + API_TYPE_DX10 = 0x00000004, + API_TYPE_DX11 = 0x00000008, + API_TYPE_OGL = 0x00000010, + API_TYPE_OGL4_X = 0x00000020, + API_TYPE_OCL = 0x00000040, + API_TYPE_MEDIA = 0x00000080, // Only option would be using DmaBuffer sampling + API_TYPE_DX12 = 0x00000100, + API_TYPE_BBSTREAM = 0x00000200, + API_TYPE_VULKAN = 0x00000400, + API_TYPE_RESERVED = 0x00000800, + API_TYPE_ALL = 0xffffffff + +} TMetricApiType; + +//*******************************************************************************/ +// Measurement types: +//*******************************************************************************/ +typedef enum EMeasurementType +{ + MEASUREMENT_TYPE_SNAPSHOT_IO = 0x00000001, + MEASUREMENT_TYPE_SNAPSHOT_QUERY = 0x00000002, + MEASUREMENT_TYPE_DELTA_QUERY = 0x00000004, + MEASUREMENT_TYPE_ALL = 0x0000ffff, + +} TMeasurementType; + +//*******************************************************************************/ +// Usage flags: +//*******************************************************************************/ +typedef enum EMetricUsageFlag +{ + USAGE_FLAG_OVERVIEW = 0x00000001, // GPU system overview metric + // Useful for high level workload characterization + USAGE_FLAG_INDICATE = 0x00000002, // Metric indicating a performance problem + // Useful when comparing with threshold + USAGE_FLAG_CORRELATE = 0x00000004, // Metric correlating with performance problem + // Useful for proving to false only + //... + USAGE_FLAG_SYSTEM = 0x00000020, // Metric useful at system level + USAGE_FLAG_FRAME = 0x00000040, // Metric useful at frame level + USAGE_FLAG_BATCH = 0x00000080, // Metric useful at batch level + USAGE_FLAG_DRAW = 0x00000100, // Metric useful at draw level + + // ... + USAGE_FLAG_TIER_1 = 0x00000400, + USAGE_FLAG_TIER_2 = 0x00000800, + USAGE_FLAG_TIER_3 = 0x00001000, + USAGE_FLAG_TIER_4 = 0x00002000, + USAGE_FLAG_GLASS_JAW = 0x00004000, + + USAGE_FLAG_ALL = 0x0000ffff, + +} TMetricUsageFlag; + +//*******************************************************************************/ +// Sampling types: +//*******************************************************************************/ +typedef enum ESamplingType +{ + SAMPLING_TYPE_OA_TIMER = 0x00000001, + SAMPLING_TYPE_OA_EVENT = 0x00000002, + SAMPLING_TYPE_GPU_QUERY = 0x00000004, + SAMPLING_TYPE_DMA_BUFFER = 0x00000008, // Possible future extension for media + SAMPLING_TYPE_ALL = 0x0000ffff, + +} TSamplingType; + +//*******************************************************************************/ +// Metric categories: +//*******************************************************************************/ +typedef enum EMetricCategory +{ + GPU_RENDER = 0x0001, + GPU_COMPUTE = 0x0002, + GPU_MEDIA = 0x0004, + GPU_GENERIC = 0x0008, // Does not belong to any specific category like memory traffic + +} TMetricCategory; + +//*******************************************************************************/ +// IoStream read flags: +//*******************************************************************************/ +typedef enum EIoReadFlag +{ + IO_READ_FLAG_DROP_OLD_REPORTS = 0x00000001, + IO_READ_FLAG_GET_CONTEXT_ID_TAGS = 0x00000002, + +} TIoReadFlag; + +//*******************************************************************************/ +// Override modes: +//*******************************************************************************/ +typedef enum EOverrideMode +{ + OVERRIDE_MODE_GLOBAL = 0x0001, + OVERRIDE_MODE_LOCAL = 0x0002, + +} TOverrideMode; + +//*******************************************************************************/ +// Global parameters of Concurrent Group: +//*******************************************************************************/ +typedef struct SConcurrentGroupParams_1_0 +{ + const char *SymbolName; // For example "PerfMon" or "OA" or "PipeStats" + const char *Description; // For example "PerfMon and ODLAT Uncore ring counters" + + uint32_t MeasurementTypeMask; + + uint32_t MetricSetsCount; + uint32_t IoMeasurementInformationCount; + uint32_t IoGpuContextInformationCount; + +} TConcurrentGroupParams_1_0; + +//*******************************************************************************/ +// Global parameters of an Override: +//*******************************************************************************/ +typedef struct SOverrideParams_1_2 +{ + const char *SymbolName; // For example "FrequencyOverride" + const char *Description; // For example "Overrides device GPU frequency with a static value." + + uint32_t ApiMask; + uint32_t PlatformMask; + + uint32_t OverrideModeMask; + +} TOverrideParams_1_2; + +//*******************************************************************************/ +// Base params of SetOverride method: +//*******************************************************************************/ +typedef struct SSetOverrideParams_1_2 +{ + bool Enable; + +} TSetOverrideParams_1_2; + +//*******************************************************************************/ +// Frequency override specific SetOverride params: +//*******************************************************************************/ +typedef struct SSetFrequencyOverrideParams_1_2 : SSetOverrideParams_1_2 +{ + uint32_t FrequencyMhz; + uint32_t Pid; + +} TSetFrequencyOverrideParams_1_2; + +//*******************************************************************************/ +// Query override specific SetOverride params: +//*******************************************************************************/ +typedef struct SSetQueryOverrideParams_1_2 : SSetOverrideParams_1_2 +{ + uint32_t Period; // Nanoseconds + +} TSetQueryOverrideParams_1_2; + +//*******************************************************************************/ +// Driver override params: +//*******************************************************************************/ +typedef struct SSetDriverOverrideParams_1_2 : SSetOverrideParams_1_2 +{ + uint32_t Value; + +} SSetDriverOverrideParams_1_2; + +//*******************************************************************************/ +// API specific id: +//*******************************************************************************/ +typedef struct SApiSpecificId_1_0 +{ + uint32_t D3D9QueryId; // D3D9 Query ID + uint32_t D3D9Fourcc; // D3D9 FourCC + uint32_t D3D1XQueryId; // D3D1X Query ID + uint32_t D3D1XDevDependentId; // D3D1X device dependent counter ID + const char *D3D1XDevDependentName; // Device dependent counter name + uint32_t OGLQueryIntelId; // Intel OGL query extension ID + const char *OGLQueryIntelName; // Intel OGL query extension name + uint32_t OGLQueryARBTargetId; // ARB OGL Query Target ID + uint32_t OCL; // OCL configuration ID + uint32_t HwConfigId; // Config ID for IO stream + uint32_t placeholder[1]; + +} TApiSpecificId_1_0; + +//*******************************************************************************/ +// Global parameters of Metric set: +//*******************************************************************************/ +typedef struct SMetricSetParams_1_0 +{ + const char *SymbolName; // For example "Dx11Tessellation" + const char *ShortName; // For example "DX11 Tessellation Metrics Set" + + uint32_t ApiMask; + uint32_t CategoryMask; + + uint32_t RawReportSize; // As in HW + uint32_t QueryReportSize; // As in Query API + + uint32_t MetricsCount; + uint32_t InformationCount; + uint32_t ComplementarySetsCount; + + TApiSpecificId_1_0 ApiSpecificId; + + uint32_t PlatformMask; + //... + +} TMetricSetParams_1_0; + +//*******************************************************************************/ +// GT differenced MetricSet params: +//*******************************************************************************/ +typedef struct SMetricSetParams_1_4 : SMetricSetParams_1_0 +{ + uint32_t GtMask; + +} TMetricSetParams_1_4; + +//*******************************************************************************/ +// Metric result types: +//*******************************************************************************/ +typedef enum EMetricResultType +{ + RESULT_UINT32, + RESULT_UINT64, + RESULT_BOOL, + RESULT_FLOAT, + // ... + RESULT_LAST + +} TMetricResultType; + +//*******************************************************************************/ +// Metric types: +//*******************************************************************************/ +typedef enum EMetricType +{ + METRIC_TYPE_DURATION, + METRIC_TYPE_EVENT, + METRIC_TYPE_EVENT_WITH_RANGE, + METRIC_TYPE_THROUGHPUT, + METRIC_TYPE_TIMESTAMP, + METRIC_TYPE_FLAG, + METRIC_TYPE_RATIO, + METRIC_TYPE_RAW, + // ... + METRIC_TYPE_LAST + +} TMetricType; + +//*******************************************************************************/ +// Information types: +//*******************************************************************************/ +typedef enum EInformationType +{ + INFORMATION_TYPE_REPORT_REASON, + INFORMATION_TYPE_VALUE, + INFORMATION_TYPE_FLAG, + INFORMATION_TYPE_TIMESTAMP, + INFORMATION_TYPE_CONTEXT_ID_TAG, + INFORMATION_TYPE_SAMPLE_PHASE, + INFORMATION_TYPE_GPU_NODE, + // ... + INFORMATION_TYPE_LAST + +} TInformationType; + +//*******************************************************************************/ +// Report reasons: +//*******************************************************************************/ +typedef enum EReportReason +{ + REPORT_REASON_UNDEFINED = 0x0000, + REPORT_REASON_INTERNAL_TIMER = 0x0001, + REPORT_REASON_INTERNAL_TRIGGER1 = 0x0002, + REPORT_REASON_INTERNAL_TRIGGER2 = 0x0004, + REPORT_REASON_INTERNAL_CONTEXT_SWITCH = 0x0008, + REPORT_REASON_INTERNAL_GO = 0x0010, + REPORT_REASON_INTERNAL_FREQUENCY_CHANGE = 0x0020, + REPORT_REASON_QUERY_DEFAULT = 0x0100, + REPORT_REASON_QUERY_INTERNAL_RESOLVE = 0x0200, + REPORT_REASON_QUERY_INTERNAL_CLEAR = 0x0400, + +} TReportReason; + +//*******************************************************************************/ +// Sample phase: +//*******************************************************************************/ +typedef enum ESamplePhase +{ + SAMPLE_PHASE_END, + SAMPLE_PHASE_BEGIN, + // ... + SAMPLE_PHASE_LAST + +} TSamplePhase; + +//*******************************************************************************/ +// Gpu Node: +//*******************************************************************************/ +typedef enum EInformationGpuNode +{ + INFORMATION_GPUNODE_3D = 0, // Available by default on all platform + INFORMATION_GPUNODE_VIDEO = 1, // Available on CTG+ + INFORMATION_GPUNODE_BLT = 2, // Available on GT + INFORMATION_GPUNODE_VE = 3, // Available on HSW+ (VideoEnhancement) + INFORMATION_GPUNODE_VCS2 = 4, // Available on BDW+ GT3+ + INFORMATION_GPUNODE_REAL_MAX = + 5, // All nodes beyond this are virtual nodes - they don't have an actual GPU engine + // ... + INFORMATION_GPUNODE_LAST + +} TInformationGpuNode; + +//*******************************************************************************/ +// Hardware unit types: +//*******************************************************************************/ +typedef enum EHwUnitType +{ + HW_UNIT_GPU, + HW_UNIT_SLICE, + HW_UNIT_SUBSLICE, + HW_UNIT_SUBSLICE_BANK, + HW_UNIT_EU_UNIT, + HW_UNIT_UNCORE, + // ... + HW_UNIT_LAST + +} THwUnitType; + +//*******************************************************************************/ +// Delta function types: +//*******************************************************************************/ +typedef enum EDeltaFunctionType +{ + DELTA_FUNCTION_NULL = 0, + DELTA_N_BITS, + DELTA_BOOL_OR, // Logic OR - good for exceptions + DELTA_BOOL_XOR, // Logic XOR - good to check if bits were changed + DELTA_GET_PREVIOUS, // Preserve previous value + DELTA_GET_LAST, // Preserve last value + DELTA_NS_TIME, // Delta for nanosecond timestamps (GPU timestamp wraps at 32 bits but was value multiplied by 80) + DELTA_FUNCTION_LAST_1_0 + +} TDeltaFunctionType; + +//*******************************************************************************/ +// Delta function: +//*******************************************************************************/ +typedef struct SDeltaFunction_1_0 +{ + TDeltaFunctionType FunctionType; + union + { + uint32_t BitsCount; // Used for DELTA_N_BITS to specify bits count + }; + +} TDeltaFunction_1_0; + +//*******************************************************************************/ +// Equation element types: +//*******************************************************************************/ +typedef enum EEquationElementType +{ + EQUATION_ELEM_OPERATION, // See TEquationOperation enumeration + + EQUATION_ELEM_RD_BITFIELD, + EQUATION_ELEM_RD_UINT8, + EQUATION_ELEM_RD_UINT16, + EQUATION_ELEM_RD_UINT32, + EQUATION_ELEM_RD_UINT64, + EQUATION_ELEM_RD_FLOAT, + + // Extended RD operation + EQUATION_ELEM_RD_40BIT_CNTR, // Assemble 40 bit counter that is in two locations, result in unsigned integer 64b + + EQUATION_ELEM_IMM_UINT64, + EQUATION_ELEM_IMM_FLOAT, + EQUATION_ELEM_SELF_COUNTER_VALUE, // Defined by $Self token, the UINT64 result of DeltaFunction for IO or QueryReadEquation + EQUATION_ELEM_GLOBAL_SYMBOL, // Defined by $"SymbolName", available in MetricsDevice SymbolTable + EQUATION_ELEM_LOCAL_COUNTER_SYMBOL, // Defined by $"SymbolName", refers to counter delta value in the local set + EQUATION_ELEM_OTHER_SET_COUNTER_SYMBOL, // Defined by concatenated string of + // $"setSymbolName/SymbolName", refers to counter Delta + // value in the other set + + EQUATION_ELEM_LOCAL_METRIC_SYMBOL, // Defined by $$"SymbolName", refers to metric normalized value in the local set + EQUATION_ELEM_OTHER_SET_METRIC_SYMBOL, // Defined by concatenated string of + // $$"setSymbolName/SymbolName", refers to metric + // Normalized value in the other set + + EQUATION_ELEM_INFORMATION_SYMBOL, // Defined by i$"SymbolName", refers to information value type only + + // Extended types - standard normalization functions + EQUATION_ELEM_STD_NORM_GPU_DURATION, // Action is $Self $GpuCoreClocks FDIV 100 FMUL + EQUATION_ELEM_STD_NORM_EU_AGGR_DURATION, // Action is $Self $GpuCoreClocks $EuCoresTotalCount UMUL FDIV 100 FMUL + + EQUATION_ELEM_LAST_1_0 + +} TEquationElementType; + +//*******************************************************************************/ +// Equation operations: +//*******************************************************************************/ +typedef enum EEquationOperation +{ + EQUATION_OPER_RSHIFT, // 64b unsigned integer right shift + EQUATION_OPER_LSHIFT, // 64b unsigned integer left shift + EQUATION_OPER_AND, // Bitwise AND of two unsigned integers, 64b each + EQUATION_OPER_OR, // Bitwise OR of two unsigned integers, 64b each + EQUATION_OPER_XOR, // Bitwise XOR of two unsigned integers, 64b each + EQUATION_OPER_XNOR, // Bitwise XNOR of two unsigned integers, 64b each + EQUATION_OPER_AND_L, // Logical AND (C-like "&&") of two unsigned integers, 64b each, result is + // true(1) if both values are true(greater than 0) + EQUATION_OPER_EQUALS, // Equality (C-like "==") of two unsigned integers, 64b each, result is true(1) or false(0) + EQUATION_OPER_UADD, // Unsigned integer add, arguments are casted to be 64b unsigned integers, + // result is unsigned integer 64b + EQUATION_OPER_USUB, // Unsigned integer subtract, arguments are casted to be 64b unsigned + // integers, result is unsigned integer 64b + EQUATION_OPER_UMUL, // Unsigned integer mul, arguments are casted to be 64b unsigned integers, + // result is unsigned integer 64b + EQUATION_OPER_UDIV, // Unsigned integer div, arguments are casted to be 64b unsigned integers, + // result is unsigned integer 64b + EQUATION_OPER_FADD, // Floating point add, arguments are casted to be 32b floating points, result is a 32b float + EQUATION_OPER_FSUB, // Floating point subtract, arguments are casted to be 32b floating points, result is a 32b float + EQUATION_OPER_FMUL, // Floating point multiply, arguments are casted to be 32b floating points, result is a 32b float + EQUATION_OPER_FDIV, // Floating point divide, arguments are casted to be 32b floating points, result is a 32b float + + EQUATION_OPER_UGT, // 64b unsigned integers comparison of is greater than, result is bool true(1) or false(0) + EQUATION_OPER_ULT, // 64b unsigned integers comparison of is less than, result is bool true(1) or false(0) + EQUATION_OPER_UGTE, // 64b unsigned integers comparison of is greater than or equal, result is bool true(1) or false(0) + EQUATION_OPER_ULTE, // 64b unsigned integers comparison of is less than or equal, result is bool true(1) or false(0) + + EQUATION_OPER_FGT, // 32b floating point numbers comparison of is greater than, result is bool true(1) or false(0) + EQUATION_OPER_FLT, // 32b floating point numbers comparison of is less than, result is bool true(1) or false(0) + EQUATION_OPER_FGTE, // 32b floating point numbers comparison of is greater than or equal, + // result is bool true(1) or false(0) + EQUATION_OPER_FLTE, // 32b floating point numbers comparison of is less than or equal, result is bool true(1) or false(0) + + EQUATION_OPER_UMIN, // Unsigned integer MIN function, arguments are casted to be 64b unsigned + // integers, result is unsigned integer 64b + EQUATION_OPER_UMAX, // Unsigned integer MAX function, arguments are casted to be 64b unsigned + // integers, result is unsigned integer 64b + + EQUATION_OPER_FMIN, // Floating point MIN function, arguments are casted to be 32b floating + // points, result is a 32b float + EQUATION_OPER_FMAX, // Floating point MAX function, arguments are casted to be 32b floating + // points, result is a 32b float + + EQUATION_OPER_LAST_1_0 + +} TEquationOperation; + +//*******************************************************************************/ +// Read params: +//*******************************************************************************/ +typedef struct SReadParams_1_0 +{ + uint32_t ByteOffset; + uint32_t BitOffset; + uint32_t BitsCount; + uint32_t ByteOffsetExt; + +} TReadParams_1_0; + +//*******************************************************************************/ +// Equation element: +//*******************************************************************************/ +typedef struct SEquationElement_1_0 +{ + TEquationElementType Type; + union + { + uint64_t ImmediateUInt64; + float ImmediateFloat; + TEquationOperation Operation; + TReadParams_1_0 ReadParams; + }; + char *SymbolName; + +} TEquationElement_1_0; + +/*****************************************************************************\ + +Class: + IEquation_1_0 + +Description: + Abstract interface for the equation object. + +\*****************************************************************************/ +class IEquation_1_0 +{ +public: + virtual ~IEquation_1_0(); + + virtual uint32_t GetEquationElementsCount(void); + virtual TEquationElement_1_0 *GetEquationElement(uint32_t index); +}; + +//*******************************************************************************/ +// Global parameters of Metric: +//*******************************************************************************/ +typedef struct SMetricParams_1_0 +{ + uint32_t IdInSet; // Position in the set + uint32_t GroupId; // Specific metric group id + const char *SymbolName; // Symbol name, used in equations + const char *ShortName; // Consistent metric name, not changed platform to platform + const char *GroupName; // VertexShader for example + const char *LongName; // Hint about the metric shown to users + + const char *DxToOglAlias; // To replace DX pixels with OGL fragments + + uint32_t UsageFlagsMask; + uint32_t ApiMask; + + TMetricResultType ResultType; + const char *MetricResultUnits; + TMetricType MetricType; + + uint64_t LowWatermark; // Low watermark for hotspot indication (USAGE_FLAG_INDICATE only) + uint64_t HighWatermark; // High watermark for hotspot indication (USAGE_FLAG_INDICATE only) + + THwUnitType HwUnitType; + + // Read equation specification for IO stream (accessing raw values potentially spread in report in several locations) + IEquation_1_0 *IoReadEquation; + // Read equation specification for query (accessing calculated delta values) + IEquation_1_0 *QueryReadEquation; + + TDeltaFunction_1_0 DeltaFunction; + + // Normalization equation to get normalized value to bytes transfered or to a percentage of utilization + IEquation_1_0 *NormEquation; + + // To calculate metrics max value as a function of other metrics and device parameters (e.g. 100 for percentage) + IEquation_1_0 *MaxValueEquation; + +} TMetricParams_1_0; + +//*******************************************************************************/ +// Global parameters of Information: +//*******************************************************************************/ +typedef struct SInformationParams_1_0 +{ + uint32_t IdInSet; // Position in the set + const char *SymbolName; // Symbol name, used in equations + const char *ShortName; // Consistent name, not changed platform to platform + const char *GroupName; // Some more global context of the information + const char *LongName; // Hint about the information shown to users + + uint32_t ApiMask; + + TInformationType InfoType; + const char *InfoUnits; + + // Read equation specification for IO stream (accessing raw values potentially spread in report in several locations) + IEquation_1_0 *IoReadEquation; + // Read equation specification for query (accessing calculated delta values) + IEquation_1_0 *QueryReadEquation; + + TDeltaFunction_1_0 OverflowFunction; + +} TInformationParams_1_0; + +/*****************************************************************************\ + +Class: + IInformation_1_0 + +Description: + Abstract interface for the measurement information parameter. + +\*****************************************************************************/ +class IInformation_1_0 +{ +public: + virtual ~IInformation_1_0(); + + virtual TInformationParams_1_0 *GetParams(); +}; + +/*****************************************************************************\ + +Class: + IMetric_1_0 + +Description: + Abstract interface for the metric that is sampled. + +\*****************************************************************************/ +class IMetric_1_0 +{ +public: + virtual ~IMetric_1_0(); + + virtual TMetricParams_1_0 *GetParams(); +}; + +/*****************************************************************************\ + +Class: + IMetricSet_1_0 + +Description: + Abstract interface for the metric sets mapping to different HW configuration that should be used + exclusively to each other metric set in the concurrent group. + +\*****************************************************************************/ +class IMetricSet_1_0 +{ +public: + virtual ~IMetricSet_1_0(); + + virtual TMetricSetParams_1_0 *GetParams(void); + + // To get particular metric + virtual IMetric_1_0 *GetMetric(uint32_t index); + + // To get particular information about measurement + virtual IInformation_1_0 *GetInformation(uint32_t index); + + // Below proposal to address multi-passes at the set level + virtual IMetricSet_1_0 *GetComplementaryMetricSet(uint32_t index); + + // To enable this configuration before query instance is created + virtual TCompletionCode Activate(void); + + // To disable this configuration after query instance is created + virtual TCompletionCode Deactivate(void); + + // To add an additional custom metric to this set + virtual IMetric_1_0 *AddCustomMetric( + const char *symbolName, const char *shortName, const char *groupName, const char *longName, + const char *dxToOglAlias, uint32_t usageFlagsMask, uint32_t apiMask, + TMetricResultType resultType, const char *resultUnits, TMetricType metricType, + int64_t loWatermark, int64_t hiWatermark, THwUnitType hwType, const char *ioReadEquation, + const char *deltaFunction, const char *queryReadEquation, const char *normalizationEquation, + const char *maxValueEquation, const char *signalName); +}; + +/*****************************************************************************\ + +Class: + IMetricSet_1_1 + +Description: + Updated 1.0 version to use with 1.1 interface version. + Introduces an ability to calculate metrics from raw data. + + New: + - SetApiFiltering + - CalculateMetrics + - CalculateIoMeasurementInformation + +\*****************************************************************************/ +class IMetricSet_1_1 : public IMetricSet_1_0 +{ +public: + virtual ~IMetricSet_1_1(); + + // To filter available metrics/information for the given API. Use TMetricApiType to build the mask. + virtual TCompletionCode SetApiFiltering(uint32_t apiMask); + + // To calculate normalized metrics/information from the raw data. + virtual TCompletionCode CalculateMetrics(const unsigned char *rawData, uint32_t rawDataSize, + TTypedValue_1_0 *out, uint32_t outSize, + uint32_t *outReportCount, bool enableContextFiltering); + + // To calculate additional information for stream measurements. + virtual TCompletionCode CalculateIoMeasurementInformation(TTypedValue_1_0 *out, uint32_t outSize); +}; + +/*****************************************************************************\ + +Class: + IMetricSet_1_4 + +Description: + Updated 1.1 version to use with 1.4 interface version. + Extends set params with gtType information. + + Updates: + - GetParams + +\*****************************************************************************/ +class IMetricSet_1_4 : public IMetricSet_1_1 +{ +public: + virtual ~IMetricSet_1_4(); + + virtual TMetricSetParams_1_4 *GetParams(void); +}; + +/*****************************************************************************\ + +Class: + IMetricSet_1_5 + +Description: + Updated 1.4 version to use with 1.5 interface version. + Adds an ability to calculate MaxValueEquations (maximal value) for each metric. + Param 'enableContextFiltering' becomes deprecated. + + Updates: + - GetComplementaryMetricSet + - CalculateMetrics + +\*****************************************************************************/ +class IMetricSet_1_5 : public IMetricSet_1_4 +{ +public: + // Update to 1.5 interface + virtual IMetricSet_1_5 *GetComplementaryMetricSet(uint32_t index); + + // CalculateMetrics extended with max values calculation. + // Optional param 'outMaxValues' should have a memory for at least 'MetricCount * RawReportCount' values, can be NULL. + virtual TCompletionCode CalculateMetrics(const unsigned char *rawData, uint32_t rawDataSize, + TTypedValue_1_0 *out, uint32_t outSize, + uint32_t *outReportCount, TTypedValue_1_0 *outMaxValues, + uint32_t outMaxValuesSize); +}; + +/*****************************************************************************\ + +Class: + IConcurrentGroup_1_0 + +Description: + Abstract interface for the metrics groups that can be collected concurrently to another group. + +\*****************************************************************************/ +class IConcurrentGroup_1_0 +{ +public: + virtual ~IConcurrentGroup_1_0(); + + virtual TConcurrentGroupParams_1_0 *GetParams(void); + virtual IMetricSet_1_0 *GetMetricSet(uint32_t index); + + virtual TCompletionCode OpenIoStream(IMetricSet_1_0 *metricSet, uint32_t processId, + uint32_t *nsTimerPeriod, uint32_t *oaBufferSize); + virtual TCompletionCode ReadIoStream(uint32_t *reportsCount, char *reportData, uint32_t readFlags); + virtual TCompletionCode CloseIoStream(void); + virtual TCompletionCode WaitForReports(uint32_t milliseconds); + virtual IInformation_1_0 *GetIoMeasurementInformation(uint32_t index); + virtual IInformation_1_0 *GetIoGpuContextInformation(uint32_t index); +}; + +/*****************************************************************************\ + +Class: + IConcurrentGroup_1_1 + +Description: + Updated 1.0 version to use with 1.1 interface version. + + Updates: + - GetMetricSet + +\*****************************************************************************/ +class IConcurrentGroup_1_1 : public IConcurrentGroup_1_0 +{ +public: + // Update to 1.1 interface + virtual IMetricSet_1_1 *GetMetricSet(uint32_t index); +}; + +/*****************************************************************************\ + +Class: + IConcurrentGroup_1_3 + +Description: + Updated 1.1 version to use with 1.3 interface version. + Introduces setting Stream Sampling Type. + + New: + - SetIoStreamSamplingType + +\*****************************************************************************/ +class IConcurrentGroup_1_3 : public IConcurrentGroup_1_1 +{ +public: + // To set sampling type during IoStream measurements + virtual TCompletionCode SetIoStreamSamplingType(TSamplingType type); +}; + +/*****************************************************************************\ + +Class: + IConcurrentGroup_1_5 + +Description: + Updated 1.3 version to use with 1.5 interface version. + + Updates: + - GetMetricSet + +\*****************************************************************************/ +class IConcurrentGroup_1_5 : public IConcurrentGroup_1_3 +{ +public: + // Update to 1.5 interface + virtual IMetricSet_1_5 *GetMetricSet(uint32_t index); +}; + +/*****************************************************************************\ + +Class: + IOverride_1_2 + +Description: + Abstract interface for Metrics Device overrides. + +\*****************************************************************************/ +class IOverride_1_2 +{ +public: + virtual ~IOverride_1_2(); + + // To get this Override params + virtual TOverrideParams_1_2 *GetParams(void); + + // To enable/disable this Override + virtual TCompletionCode SetOverride(TSetOverrideParams_1_2 *params, uint32_t paramsSize); +}; + +/*****************************************************************************\ + +Class: + IMetricsDevice_1_0 + +Description: + Abstract interface for the GPU metrics root object. + +\*****************************************************************************/ +class IMetricsDevice_1_0 +{ +public: + virtual ~IMetricsDevice_1_0(); + + // To get MetricsDevice params + virtual TMetricsDeviceParams_1_0 *GetParams(void); + + // Child objects are of IConcurrentGroup + virtual IConcurrentGroup_1_0 *GetConcurrentGroup(uint32_t index); + + // To get GlobalSymbol at the given index + virtual TGlobalSymbol_1_0 *GetGlobalSymbol(uint32_t index); + + // To get GlobalSymbol with the given name + virtual TTypedValue_1_0 *GetGlobalSymbolValueByName(const char *name); + + // To get last error from TCompletionCode enum + virtual TCompletionCode GetLastError(void); + + // To get both GPU and CPU timestamp at the same time + virtual TCompletionCode GetGpuCpuTimestamps(uint64_t *gpuTimestampNs, uint64_t *cpuTimestampNs, + uint32_t *cpuId); +}; + +/*****************************************************************************\ + +Class: + IMetricsDevice_1_1 + +Description: + Updated 1.0 version to use with 1.1 interface version. + + Updates: + - GetConcurrentGroup + +\*****************************************************************************/ +class IMetricsDevice_1_1 : public IMetricsDevice_1_0 +{ +public: + // Update to 1.1 interface + virtual IConcurrentGroup_1_1 *GetConcurrentGroup(uint32_t index); +}; + +/*****************************************************************************\ + +Class: + IMetricsDevice_1_2 + +Description: + Updated 1.1 version to use with 1.2 interface version. + Introduces an interface for getting overrides. + + Updates: + - GetParams + New: + - GetOverride + - GetOverrideByName + +\*****************************************************************************/ +class IMetricsDevice_1_2 : public IMetricsDevice_1_1 +{ +public: + // Update returned params + virtual TMetricsDeviceParams_1_2 *GetParams(void); + + // To get override at the given index + virtual IOverride_1_2 *GetOverride(uint32_t index); + + // To get override with the given name + virtual IOverride_1_2 *GetOverrideByName(const char *symbolName); +}; + +/*****************************************************************************\ + +Class: + IMetricsDevice_1_5 + +Description: + Updated 1.2 version to use with 1.5 interface version. + + Updates: + - GetConcurrentGroup + +\*****************************************************************************/ +class IMetricsDevice_1_5 : public IMetricsDevice_1_2 +{ +public: + // Update to 1.5 interface + virtual IConcurrentGroup_1_5 *GetConcurrentGroup(uint32_t index); +}; + +#ifdef __cplusplus +extern "C" { +#endif + +// Factory functions +typedef TCompletionCode(MD_STDCALL *OpenMetricsDevice_fn)(IMetricsDevice_1_5 **device); +typedef TCompletionCode(MD_STDCALL *OpenMetricsDeviceFromFile_fn)(const char *fileName, + void *openParams, + IMetricsDevice_1_5 **device); +typedef TCompletionCode(MD_STDCALL *CloseMetricsDevice_fn)(IMetricsDevice_1_5 *device); +typedef TCompletionCode(MD_STDCALL *SaveMetricsDeviceToFile_fn)(const char *fileName, + void *saveParams, + IMetricsDevice_1_5 *device); + +#ifdef __cplusplus +} +#endif + +}; // namespace MetricsDiscovery +#endif // __METRICS_DISCOVERY_H_ diff --git a/renderdoc/renderdoc.vcxproj b/renderdoc/renderdoc.vcxproj index 13b2fa5b5..aeb22f7ed 100644 --- a/renderdoc/renderdoc.vcxproj +++ b/renderdoc/renderdoc.vcxproj @@ -78,7 +78,7 @@ Windows - tdh.lib;ws2_32.lib;kernel32.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies) + tdh.lib;ws2_32.lib;kernel32.lib;user32.lib;shlwapi.lib;Setupapi.lib;Shlwapi.lib;%(AdditionalDependencies) $(ProjectDir)os\win32\comexport.def true tdh.dll