/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.google.common.collect.ImmutableList * com.google.common.collect.ImmutableList$Builder * com.google.common.collect.Sets * com.google.common.collect.Sets$SetView * org.jspecify.annotations.Nullable */ package net.minecraft.client.renderer; import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.framegraph.FrameGraphBuilder; import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.resource.GraphicsResourceAllocator; import com.mojang.blaze3d.resource.RenderTargetDescriptor; import com.mojang.blaze3d.resource.ResourceHandle; import com.mojang.blaze3d.shaders.UniformType; import java.lang.runtime.SwitchBootstraps; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import net.minecraft.client.renderer.CachedOrthoProjectionMatrixBuffer; import net.minecraft.client.renderer.PostChainConfig; import net.minecraft.client.renderer.PostPass; import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.renderer.ShaderManager; import net.minecraft.client.renderer.texture.AbstractTexture; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.resources.Identifier; import org.jspecify.annotations.Nullable; public class PostChain implements AutoCloseable { public static final Identifier MAIN_TARGET_ID = Identifier.withDefaultNamespace("main"); private final List passes; private final Map internalTargets; private final Set externalTargets; private final Map persistentTargets = new HashMap(); private final CachedOrthoProjectionMatrixBuffer projectionMatrixBuffer; private PostChain(List passes, Map internalTargets, Set externalTargets, CachedOrthoProjectionMatrixBuffer projectionMatrixBuffer) { this.passes = passes; this.internalTargets = internalTargets; this.externalTargets = externalTargets; this.projectionMatrixBuffer = projectionMatrixBuffer; } public static PostChain load(PostChainConfig config, TextureManager textureManager, Set allowedExternalTargets, Identifier id, CachedOrthoProjectionMatrixBuffer projectionMatrixBuffer) throws ShaderManager.CompilationException { Stream referencedTargets = config.passes().stream().flatMap(PostChainConfig.Pass::referencedTargets); Set referencedExternalTargets = referencedTargets.filter(targetId -> !config.internalTargets().containsKey(targetId)).collect(Collectors.toSet()); Sets.SetView invalidExternalTargets = Sets.difference(referencedExternalTargets, allowedExternalTargets); if (!invalidExternalTargets.isEmpty()) { throw new ShaderManager.CompilationException("Referenced external targets are not available in this context: " + String.valueOf(invalidExternalTargets)); } ImmutableList.Builder passes = ImmutableList.builder(); for (int i = 0; i < config.passes().size(); ++i) { PostChainConfig.Pass pass = config.passes().get(i); passes.add((Object)PostChain.createPass(textureManager, pass, id.withSuffix("/" + i))); } return new PostChain((List)passes.build(), config.internalTargets(), referencedExternalTargets, projectionMatrixBuffer); } /* * Enabled aggressive block sorting * Enabled unnecessary exception pruning * Enabled aggressive exception aggregation */ private static PostPass createPass(TextureManager textureManager, PostChainConfig.Pass config, Identifier id) throws ShaderManager.CompilationException { RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder(RenderPipelines.POST_PROCESSING_SNIPPET).withFragmentShader(config.fragmentShaderId()).withVertexShader(config.vertexShaderId()).withLocation(id); for (PostChainConfig.Input input : config.inputs()) { pipelineBuilder.withSampler(input.samplerName() + "Sampler"); } pipelineBuilder.withUniform("SamplerInfo", UniformType.UNIFORM_BUFFER); for (String uniformGroupName : config.uniforms().keySet()) { pipelineBuilder.withUniform(uniformGroupName, UniformType.UNIFORM_BUFFER); } RenderPipeline pipeline = pipelineBuilder.build(); ArrayList inputs = new ArrayList(); Iterator iterator = config.inputs().iterator(); block9: while (true) { PostChainConfig.Input input2; if (!iterator.hasNext()) { return new PostPass(pipeline, config.outputTarget(), config.uniforms(), inputs); } PostChainConfig.Input input = iterator.next(); Objects.requireNonNull(input); int n = 0; switch (SwitchBootstraps.typeSwitch("typeSwitch", new Object[]{PostChainConfig.TextureInput.class, PostChainConfig.TargetInput.class}, (Object)input2, n)) { case 0: { boolean bl2; Object object; PostChainConfig.TextureInput textureInput = (PostChainConfig.TextureInput)input2; Object samplerName = object = textureInput.samplerName(); Object location = object = textureInput.location(); boolean width = bl2 = textureInput.width(); boolean height = bl2 = textureInput.height(); boolean bilinear = bl2 = (boolean)textureInput.bilinear(); AbstractTexture texture = textureManager.getTexture(((Identifier)location).withPath(path -> "textures/effect/" + path + ".png")); inputs.add(new PostPass.TextureInput((String)samplerName, texture, width ? 1 : 0, height ? 1 : 0, bilinear)); continue block9; } case 1: { Object object = (PostChainConfig.TargetInput)input2; try { boolean bl; Object object2 = ((PostChainConfig.TargetInput)object).samplerName(); String samplerName = object2; Object targetId = object2 = ((PostChainConfig.TargetInput)object).targetId(); boolean useDepthBuffer = bl = ((PostChainConfig.TargetInput)object).useDepthBuffer(); boolean bilinear = bl = ((PostChainConfig.TargetInput)object).bilinear(); inputs.add(new PostPass.TargetInput(samplerName, (Identifier)targetId, useDepthBuffer, bilinear)); } catch (Throwable throwable) { throw new MatchException(throwable.toString(), throwable); } continue block9; } } break; } throw new MatchException(null, null); } public void addToFrame(FrameGraphBuilder frame, int screenWidth, int screenHeight, TargetBundle providedTargets) { GpuBufferSlice projectionBuffer = this.projectionMatrixBuffer.getBuffer(screenWidth, screenHeight); HashMap> targets = new HashMap>(this.internalTargets.size() + this.externalTargets.size()); for (Identifier identifier : this.externalTargets) { targets.put(identifier, providedTargets.getOrThrow(identifier)); } for (Map.Entry entry : this.internalTargets.entrySet()) { Identifier id = (Identifier)entry.getKey(); PostChainConfig.InternalTarget target = (PostChainConfig.InternalTarget)entry.getValue(); RenderTargetDescriptor descriptor = new RenderTargetDescriptor(target.width().orElse(screenWidth), target.height().orElse(screenHeight), true, target.clearColor()); if (target.persistent()) { RenderTarget persistentTarget = this.getOrCreatePersistentTarget(id, descriptor); targets.put(id, frame.importExternal(id.toString(), persistentTarget)); continue; } targets.put(id, frame.createInternal(id.toString(), descriptor)); } for (PostPass postPass : this.passes) { postPass.addToFrame(frame, targets, projectionBuffer); } for (Identifier identifier : this.externalTargets) { providedTargets.replace(identifier, (ResourceHandle)targets.get(identifier)); } } @Deprecated public void process(RenderTarget mainTarget, GraphicsResourceAllocator resourceAllocator) { FrameGraphBuilder frame = new FrameGraphBuilder(); TargetBundle targets = TargetBundle.of(MAIN_TARGET_ID, frame.importExternal("main", mainTarget)); this.addToFrame(frame, mainTarget.width, mainTarget.height, targets); frame.execute(resourceAllocator); } private RenderTarget getOrCreatePersistentTarget(Identifier id, RenderTargetDescriptor descriptor) { RenderTarget target = this.persistentTargets.get(id); if (target == null || target.width != descriptor.width() || target.height != descriptor.height()) { if (target != null) { target.destroyBuffers(); } target = descriptor.allocate(); descriptor.prepare(target); this.persistentTargets.put(id, target); } return target; } @Override public void close() { this.persistentTargets.values().forEach(RenderTarget::destroyBuffers); this.persistentTargets.clear(); for (PostPass pass : this.passes) { pass.close(); } } public static interface TargetBundle { public static TargetBundle of(final Identifier targetId, final ResourceHandle target) { return new TargetBundle(){ private ResourceHandle handle; { this.handle = target; } @Override public void replace(Identifier id, ResourceHandle handle) { if (!id.equals(targetId)) { throw new IllegalArgumentException("No target with id " + String.valueOf(id)); } this.handle = handle; } @Override public @Nullable ResourceHandle get(Identifier id) { return id.equals(targetId) ? this.handle : null; } }; } public void replace(Identifier var1, ResourceHandle var2); public @Nullable ResourceHandle get(Identifier var1); default public ResourceHandle getOrThrow(Identifier id) { ResourceHandle handle = this.get(id); if (handle == null) { throw new IllegalArgumentException("Missing target with id " + String.valueOf(id)); } return handle; } } }