Material Clustering Benchmark
ADispatcher.cs
Go to the documentation of this file.
1using UnityEngine;
2using System;
3
5{
6 public abstract class ADispatcher : IDispatcher
7 {
8 // reported in the file
9 public bool doRandomizeEmptyClusters { get; private set; }
10 public int numIterations { get; private set; }
12
13 public abstract string name { get; }
14 private DispatcherParameters parameters;
15 public virtual DispatcherParameters abstractParameters => this.parameters;
16
17 public abstract bool usesStopCondition { get; }
18 public abstract bool doesReadback { get; }
19
20 private int _warningCounter;
21 public int warningCounter
22 {
23 get => _warningCounter;
24 private set { _warningCounter = value; }
25 }
26
27 // internal
28 public readonly ComputeShader computeShader;
29 private readonly int kernelHandleAttributeClusters;
30 private readonly int kernelUpdateClusterCenters;
31
32 /// <summary>
33 /// Takes ownership of the clusteringRTsAndBuffers
34 /// </summary>
35 protected ADispatcher(
36 ComputeShader computeShader,
37 int numIterations,
41 )
42 {
43 this.computeShader = computeShader;
44 this.kernelHandleAttributeClusters = this.computeShader.FindKernel("AttributeClusters");
45 this.kernelUpdateClusterCenters = computeShader.FindKernel("UpdateClusterCenters");
46 this.doRandomizeEmptyClusters = doRandomizeEmptyClusters;
47 this.numIterations = numIterations;
48 this.clusteringRTsAndBuffers = clusteringRTsAndBuffers;
49 this.useFullResTexRef = useFullResTexRef;
50 this.warningCounter = 0;
51 }
52
53 public abstract void RunClustering(ClusteringTextures clusteringTextures);
54
55 public void UpdateClusterCenters(ClusteringTextures clusteringTextures, bool rejectOld)
56 {
58
59 this.computeShader.SetBool("reject_old", rejectOld);
60 this.computeShader.SetInt("mip_level", clusteringTextures.mipLevel);
61 this.computeShader.SetInt("num_clusters", this.clusteringRTsAndBuffers.numClusters);
62
63 this.computeShader.SetTexture(
64 this.kernelUpdateClusterCenters,
65 "tex_arr_clusters_r",
66 clusteringTextures.rtArr
67 );
68 this.computeShader.SetTexture(
69 this.kernelUpdateClusterCenters,
70 "tex_input",
71 clusteringTextures.rtInput
72 );
73 this.computeShader.SetBuffer(
74 this.kernelUpdateClusterCenters,
75 "cbuf_cluster_centers",
77 );
78 this.computeShader.SetBuffer(
79 this.kernelUpdateClusterCenters,
80 "cbuf_random_positions",
82 );
83
84 this.computeShader.Dispatch(this.kernelUpdateClusterCenters, 1, 1, 1);
85 }
86
87 public void AttributeClustersKM(ClusteringTextures clusteringTextures)
88 {
89 this.computeShader.SetBool("KHM", false);
90 this.computeShader.SetInt("num_clusters", this.clusteringRTsAndBuffers.numClusters);
91
92 this.computeShader.SetTexture(
93 this.kernelHandleAttributeClusters,
94 "tex_input",
95 clusteringTextures.rtInput
96 );
97 this.computeShader.SetTexture(
98 this.kernelHandleAttributeClusters,
99 "tex_arr_clusters_rw",
100 clusteringTextures.rtArr
101 );
102 this.computeShader.SetBuffer(
103 this.kernelHandleAttributeClusters,
104 "cbuf_cluster_centers",
106 );
107
108 this.computeShader.Dispatch(
109 this.kernelHandleAttributeClusters,
110 Math.Max(clusteringTextures.size / ClusteringTest.kernelSize, 1),
111 Math.Max(clusteringTextures.size / ClusteringTest.kernelSize, 1),
112 1
113 );
114
115 clusteringTextures.rtArr.GenerateMips();
116 }
117
118 public void AttributeClustersKHM(ClusteringTextures clusteringTextures, float p)
119 {
120 this.computeShader.SetBool("KHM", true);
121 this.computeShader.SetFloat("p", p);
122 this.computeShader.SetInt("num_clusters", this.clusteringRTsAndBuffers.numClusters);
123
124 this.computeShader.SetTexture(
125 this.kernelHandleAttributeClusters,
126 "tex_input",
127 clusteringTextures.rtInput
128 );
129 this.computeShader.SetTexture(
130 this.kernelHandleAttributeClusters,
131 "tex_arr_clusters_rw",
132 clusteringTextures.rtArr
133 );
134 this.computeShader.SetBuffer(
135 this.kernelHandleAttributeClusters,
136 "cbuf_cluster_centers",
138 );
139
140 this.computeShader.Dispatch(
141 this.kernelHandleAttributeClusters,
142 Math.Max(clusteringTextures.size / ClusteringTest.kernelSize, 1),
143 Math.Max(clusteringTextures.size / ClusteringTest.kernelSize, 1),
144 1
145 );
146
147 clusteringTextures.rtArr.GenerateMips();
148 }
149
150 public bool useFullResTexRef { get; private set; }
151
152 public float? GetVariance()
153 {
154 using (ClusterCenters backupCenters = this.clusteringRTsAndBuffers.GetClusterCenters())
155 {
156 if (backupCenters.warning)
157 {
158 this.warningCounter++;
159 }
160
161 // We need to perform cluster centers update to get variance. However, we don't want to actually update cluster centers as it would interfere with the benchmarks. So we backup the current cluster centers and restore them afterwards.
162 ClusteringTextures refTextures = this.useFullResTexRef switch
163 {
165 false => this.clusteringRTsAndBuffers.texturesWorkRes
166 };
167
168 // Attribution to ensure cluster memberships match current cluster centers. It is techinically unnecessary if attribution was ran after the latest update of cluster centers, the algorithm used was KM, and the variance is computed on working resolution texture. For simplicity, we do not make a special case and always perform attribution.
169 this.AttributeClustersKM(clusteringTextures: refTextures);
170
171 this.UpdateClusterCenters(clusteringTextures: refTextures, rejectOld: false);
172
174 {
175 // Restore original cluster centers as to not interfere with the benchmark.
177
178 return centers.variance;
179 }
180 }
181 }
182
183 public virtual void Dispose()
184 {
186 }
187 }
188}
virtual DispatcherParameters abstractParameters
Definition: ADispatcher.cs:15
float? GetVariance()
Computes variance for the current cluster centers. Depending on this.useFullResTexRef uses either wor...
Definition: ADispatcher.cs:152
void AttributeClustersKHM(ClusteringTextures clusteringTextures, float p)
Definition: ADispatcher.cs:118
ClusteringRTsAndBuffers clusteringRTsAndBuffers
Definition: ADispatcher.cs:11
void AttributeClustersKM(ClusteringTextures clusteringTextures)
Definition: ADispatcher.cs:87
ADispatcher(ComputeShader computeShader, int numIterations, bool doRandomizeEmptyClusters, bool useFullResTexRef, ClusteringRTsAndBuffers clusteringRTsAndBuffers)
Takes ownership of the clusteringRTsAndBuffers
Definition: ADispatcher.cs:35
abstract void RunClustering(ClusteringTextures clusteringTextures)
void UpdateClusterCenters(ClusteringTextures clusteringTextures, bool rejectOld)
Definition: ADispatcher.cs:55
readonly ComputeShader computeShader
Definition: ADispatcher.cs:28
Call Dispose after using.
Call Allocate before using and Dispose after using.
ClusterCenters GetClusterCenters()
Get a pooled instance of ClusterCenters with a copy of the data from ComputeBuffer....
void SetClusterCenters(Vector4[] clusterCentersBufferData)
Reads the cluster centers data from the array and loads it into the ComputeBuffer.
const int kernelSize
Must match the shader.
Call Dispose after using.
readonly RenderTexture rtArr
readonly RenderTexture rtInput
Call Dispose after using.
Definition: IDispatcher.cs:9