summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr55 <[email protected]>2020-10-11 16:12:46 +0100
committersr55 <[email protected]>2020-10-11 16:13:02 +0100
commitd5a58c985dcb0a9e3326a724b567c8fc1dcb6cb4 (patch)
tree3465adf7ede04ff5a2ff01fb9b34eba4b6cb07d9
parent1883642eb32a2808924c2ef5db06f105657413f6 (diff)
WinGui: Support allocation of work across multiple Intel GPU's
-rw-r--r--win/CS/HandBrake.sln.DotSettings1
-rw-r--r--win/CS/HandBrakeWPF/Services/Queue/QueueResourceService.cs72
-rw-r--r--win/CS/HandBrakeWPF/Services/Queue/QueueService.cs10
3 files changed, 69 insertions, 14 deletions
diff --git a/win/CS/HandBrake.sln.DotSettings b/win/CS/HandBrake.sln.DotSettings
index 0882a1550..bb5657d87 100644
--- a/win/CS/HandBrake.sln.DotSettings
+++ b/win/CS/HandBrake.sln.DotSettings
@@ -791,6 +791,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AC/@EntryIndexedValue">AC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DTS/@EntryIndexedValue">DTS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DTSHD/@EntryIndexedValue">DTSHD</s:String>
+ <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GPU/@EntryIndexedValue">GPU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HD/@EntryIndexedValue">HD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MP/@EntryIndexedValue">MP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RF/@EntryIndexedValue">RF</s:String>
diff --git a/win/CS/HandBrakeWPF/Services/Queue/QueueResourceService.cs b/win/CS/HandBrakeWPF/Services/Queue/QueueResourceService.cs
index cbd97029d..889007311 100644
--- a/win/CS/HandBrakeWPF/Services/Queue/QueueResourceService.cs
+++ b/win/CS/HandBrakeWPF/Services/Queue/QueueResourceService.cs
@@ -12,35 +12,48 @@ namespace HandBrakeWPF.Services.Queue
using System;
using System.Collections.Generic;
+ using HandBrake.Interop.Interop;
using HandBrake.Interop.Interop.Model.Encoding;
+ using HandBrakeWPF.Services.Encode.Model;
+ using HandBrakeWPF.Services.Interfaces;
+
public class QueueResourceService
{
+ private readonly IUserSettingService userSettingService;
+
private readonly object lockOjb = new object();
- private HashSet<Guid> qsvInstances = new HashSet<Guid>();
- private HashSet<Guid> nvencInstances = new HashSet<Guid>();
- private HashSet<Guid> vceInstances = new HashSet<Guid>();
+ private readonly HashSet<Guid> qsvInstances = new HashSet<Guid>();
+ private readonly HashSet<Guid> nvencInstances = new HashSet<Guid>();
+ private readonly HashSet<Guid> vceInstances = new HashSet<Guid>();
private List<int> qsvGpus = new List<int>();
-
+ private int intelGpuCounter = -1; // Always default to the first card when allocating.
+
+ public QueueResourceService(IUserSettingService userSettingService)
+ {
+ this.userSettingService = userSettingService;
+ }
+
public void Init()
{
- // TODO Coming Soon!
- // List<int> qsvGpus = hbFunctions.hb_qsv_adapters_list();
+ this.qsvGpus = HandBrakeEncoderHelpers.GetQsvAdaptorList();
}
- public Guid? GetHardwareLock(VideoEncoder encoder)
+ public Guid? GetHardwareLock(EncodeTask task)
{
lock (this.lockOjb)
{
- switch (encoder)
+ switch (task.VideoEncoder)
{
case VideoEncoder.QuickSync:
case VideoEncoder.QuickSyncH265:
case VideoEncoder.QuickSyncH26510b:
if (this.qsvInstances.Count < 3)
{
+ this.AllocateIntelGPU(task);
+
Guid guid = Guid.NewGuid();
this.qsvInstances.Add(guid);
return guid;
@@ -121,5 +134,48 @@ namespace HandBrakeWPF.Services.Queue
}
}
}
+
+ public void AllocateIntelGPU(EncodeTask task)
+ {
+ // Validation checks.
+ if (task.VideoEncoder != VideoEncoder.QuickSync && task.VideoEncoder != VideoEncoder.QuickSyncH265 && task.VideoEncoder != VideoEncoder.QuickSyncH26510b)
+ {
+ return; // Not a QSV job.
+ }
+
+ if (this.qsvGpus.Count <= 1)
+ {
+ return; // Not a multi-Intel-GPU system.
+ }
+
+ if (task.ExtraAdvancedArguments.Contains("gpu"))
+ {
+ return; // Users choice
+ }
+
+ if (!this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ProcessIsolationEnabled))
+ {
+ return; // Multi-Process encoding is disabled.
+ }
+
+ if (this.userSettingService.GetUserSetting<int>(UserSettingConstants.SimultaneousEncodes) <= 1)
+ {
+ return; // Multi-Process encoding is disabled.
+ }
+
+ this.intelGpuCounter = this.intelGpuCounter + 1;
+ int modulus = this.intelGpuCounter % 2;
+
+ // For now, it's not expected we'll see users with more than 2 Intel GPUs. Typically 1 CPU, 1 Discrete will likely be the norm.
+ // Use the modulus of the above counter to flip between the 2 Intel encoders.
+ // We don't set GPU for the jobs 1, 3, 5, 7, 9 .... etc (Default to first)
+ // We do set the GPU for jobs 2, 4, 5, 8, 10 .... etc
+ if (modulus == 1)
+ {
+ task.ExtraAdvancedArguments = string.IsNullOrEmpty(task.ExtraAdvancedArguments)
+ ? string.Format("gpu={0}", this.qsvGpus[1])
+ : string.Format("{0}:gpu={1}", task.ExtraAdvancedArguments, this.qsvGpus[1]);
+ }
+ }
}
}
diff --git a/win/CS/HandBrakeWPF/Services/Queue/QueueService.cs b/win/CS/HandBrakeWPF/Services/Queue/QueueService.cs
index 1c7746cb6..3ccb41044 100644
--- a/win/CS/HandBrakeWPF/Services/Queue/QueueService.cs
+++ b/win/CS/HandBrakeWPF/Services/Queue/QueueService.cs
@@ -58,7 +58,7 @@ namespace HandBrakeWPF.Services.Queue
private readonly string queueFile;
private readonly object queueFileLock = new object();
- private readonly QueueResourceService hardwareEncoderResourceManager = new QueueResourceService();
+ private readonly QueueResourceService hardwareEncoderResourceManager;
private int allowedInstances;
private int jobIdCounter = 0;
@@ -69,6 +69,7 @@ namespace HandBrakeWPF.Services.Queue
public QueueService(IUserSettingService userSettingService, ILog logService, IErrorService errorService, ILogInstanceManager logInstanceManager, IPortService portService)
{
this.userSettingService = userSettingService;
+ this.hardwareEncoderResourceManager = new QueueResourceService(userSettingService);
this.logService = logService;
this.errorService = errorService;
this.logInstanceManager = logInstanceManager;
@@ -353,7 +354,7 @@ namespace HandBrakeWPF.Services.Queue
QueueTask task = this.queue.FirstOrDefault(q => q.Status == QueueItemStatus.Waiting);
if (task != null)
{
- task.HardwareResourceToken = this.hardwareEncoderResourceManager.GetHardwareLock(task.Task.VideoEncoder);
+ task.HardwareResourceToken = this.hardwareEncoderResourceManager.GetHardwareLock(task.Task);
return task;
}
}
@@ -687,10 +688,7 @@ namespace HandBrakeWPF.Services.Queue
this.IsProcessing = false;
EventHandler handler = this.QueuePaused;
- if (handler != null)
- {
- handler(this, e);
- }
+ handler?.Invoke(this, e);
}
private string GetQueueJson(List<EncodeTask> tasks, HBConfiguration configuration)