@@ -58,10 +58,16 @@ public class SdsmFitter {
5858
5959 private final GL4 gl4 ;
6060 private final Renderer renderer ;
61+ private final AssetManager assetManager ;
6162 private int maxFrameLag = 3 ;
6263
63- private final ComputeShader depthReduceShader ;
64- private final ComputeShader fitFrustumsShader ;
64+ // Because the multisampling status of the depth texture may change anytime,
65+ // we store both ms and no-ms versions of the shaders, both initialized
66+ // lazily. This avoids recompiling the same set of shaders twice and also
67+ // compiling unnecessary shaders if the multisampling status does not
68+ // change.
69+ private InternalShaders shadersNoMultisampling ;
70+ private InternalShaders shadersMultisampling ;
6571
6672 private final LinkedList <SdsmResultHolder > resultHoldersInFlight = new LinkedList <>();
6773 private final LinkedList <SdsmResultHolder > resultHoldersReady = new LinkedList <>();
@@ -310,18 +316,58 @@ void cleanup() {
310316 }
311317 }
312318
319+ /**
320+ * Manages the pair of depth-reduce and fit-frustums shaders.
321+ */
322+ private class InternalShaders {
323+ public final ComputeShader depthReduceShader ;
324+ public final ComputeShader fitFrustumsShader ;
325+
326+ InternalShaders (AssetManager assetManager , boolean multisampling ) {
327+ String reduceSource = (String )assetManager .loadAsset (REDUCE_DEPTH_SHADER );
328+ String fitSource = (String )assetManager .loadAsset (FIT_FRUSTUMS_SHADER );
329+
330+ depthReduceShader = buildShader (reduceSource , multisampling );
331+ fitFrustumsShader = buildShader (fitSource , multisampling );
332+ }
333+
334+ private ComputeShader buildShader (String source , boolean multisampling ) {
335+ ComputeShader shader =
336+ multisampling
337+ ? new ComputeShader (gl4 , source , new String [][]{{"RESOLVE_DEPTH_MS" , "1" }})
338+ : new ComputeShader (gl4 , source );
339+ renderer .registerNativeObject (shader );
340+ return shader ;
341+ }
342+
343+ /**
344+ * Cleans up GPU resources.
345+ */
346+ public void cleanup (Renderer renderer ) {
347+ depthReduceShader .deleteObject (renderer );
348+ fitFrustumsShader .deleteObject (renderer );
349+ }
350+ }
351+
313352 public SdsmFitter (GL4 gl , Renderer renderer , AssetManager assetManager ) {
314353 this .gl4 = gl ;
315354 this .renderer = renderer ;
316-
317- // Load compute shaders
318- String reduceSource = (String )assetManager .loadAsset (REDUCE_DEPTH_SHADER );
319- String fitSource = (String )assetManager .loadAsset (FIT_FRUSTUMS_SHADER );
320-
321- depthReduceShader = new ComputeShader (gl , reduceSource );
322- renderer .registerNativeObject (depthReduceShader );
323- fitFrustumsShader = new ComputeShader (gl , fitSource );
324- renderer .registerNativeObject (fitFrustumsShader );
355+ this .assetManager = assetManager ;
356+ }
357+
358+ private InternalShaders initShaders (Texture depthTexture ) {
359+ boolean multisampling = depthTexture .getImage ().getMultiSamples () > 1 ;
360+ if (multisampling ) {
361+ if (shadersMultisampling == null ) {
362+ shadersMultisampling = new InternalShaders (assetManager , true );
363+ }
364+ return shadersMultisampling ;
365+ } else {
366+ if (shadersNoMultisampling == null ) {
367+ shadersNoMultisampling = new InternalShaders (assetManager , false );
368+ }
369+ return shadersNoMultisampling ;
370+ }
325371 }
326372
327373 /**
@@ -336,6 +382,12 @@ public SdsmFitter(GL4 gl, Renderer renderer, AssetManager assetManager) {
336382 public void fit (Texture depthTexture , int splitCount , Matrix4f cameraToLight ,
337383 float cameraNear , float cameraFar ) {
338384
385+ int depthMultiSamples = depthTexture .getImage ().getMultiSamples ();
386+
387+ InternalShaders shaders = initShaders (depthTexture );
388+ ComputeShader depthReduceShader = shaders .depthReduceShader ;
389+ ComputeShader fitFrustumsShader = shaders .fitFrustumsShader ;
390+
339391 SdsmResultHolder holder = getResultHolderForUse ();
340392 holder .parameters = new FitParameters (cameraToLight , splitCount , cameraNear , cameraFar );
341393
@@ -360,6 +412,8 @@ public void fit(Texture depthTexture, int splitCount, Matrix4f cameraToLight,
360412 } catch (TextureUnitException e ) {
361413 throw new RendererException (e );
362414 }
415+ int loc = depthReduceShader .getUniformLocation ("m_NumSamplesDepth" );
416+ depthReduceShader .setUniform (loc , depthMultiSamples );
363417 depthReduceShader .bindShaderStorageBuffer (1 , holder .minMaxDepthSsbo );
364418 depthReduceShader .dispatch (xGroups , yGroups , 1 );
365419 gl4 .glMemoryBarrier (GL4 .GL_SHADER_STORAGE_BARRIER_BIT );
@@ -373,6 +427,8 @@ public void fit(Texture depthTexture, int splitCount, Matrix4f cameraToLight,
373427 } catch (TextureUnitException e ) {
374428 throw new RendererException (e );
375429 }
430+ loc = fitFrustumsShader .getUniformLocation ("m_NumSamplesDepth" );
431+ fitFrustumsShader .setUniform (loc , depthMultiSamples );
376432 fitFrustumsShader .bindShaderStorageBuffer (1 , holder .minMaxDepthSsbo );
377433 fitFrustumsShader .bindShaderStorageBuffer (2 , holder .fitFrustumSsbo );
378434
@@ -437,11 +493,11 @@ public void cleanup() {
437493 }
438494 resultHoldersReady .clear ();
439495
440- if (depthReduceShader != null ) {
441- depthReduceShader . deleteObject (renderer );
496+ if (shadersMultisampling != null ) {
497+ shadersMultisampling . cleanup (renderer );
442498 }
443- if (fitFrustumsShader != null ) {
444- fitFrustumsShader . deleteObject (renderer );
499+ if (shadersNoMultisampling != null ) {
500+ shadersNoMultisampling . cleanup (renderer );
445501 }
446502 }
447503
0 commit comments