GlDevice.java

com.mojang.blaze3d.opengl.GlDevice

信息

  • 全限定名:com.mojang.blaze3d.opengl.GlDevice
  • 类型:package-private class
  • 包:com.mojang.blaze3d.opengl
  • 源码路径:src/main/java/com/mojang/blaze3d/opengl/GlDevice.java
  • 起始行号:L47
  • 实现:GpuDeviceBackend
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L48
    • 说明:

      TODO

  • USE_GL_ARB_vertex_attrib_binding

    • 类型: boolean
    • 修饰符: protected static
    • 源码定位: L49
    • 说明:

      TODO

  • USE_GL_KHR_debug

    • 类型: boolean
    • 修饰符: protected static
    • 源码定位: L50
    • 说明:

      TODO

  • USE_GL_EXT_debug_label

    • 类型: boolean
    • 修饰符: protected static
    • 源码定位: L51
    • 说明:

      TODO

  • USE_GL_ARB_debug_output

    • 类型: boolean
    • 修饰符: protected static
    • 源码定位: L52
    • 说明:

      TODO

  • USE_GL_ARB_direct_state_access

    • 类型: boolean
    • 修饰符: protected static
    • 源码定位: L53
    • 说明:

      TODO

  • USE_GL_ARB_buffer_storage

    • 类型: boolean
    • 修饰符: protected static
    • 源码定位: L54
    • 说明:

      TODO

  • encoder

    • 类型: CommandEncoderBackend
    • 修饰符: private final
    • 源码定位: L55
    • 说明:

      TODO

  • debugLog

    • 类型: GlDebug
    • 修饰符: private final
    • 源码定位: L56
    • 说明:

      TODO

  • debugLabels

    • 类型: GlDebugLabel
    • 修饰符: private final
    • 源码定位: L57
    • 说明:

      TODO

  • maxSupportedTextureSize

    • 类型: int
    • 修饰符: private final
    • 源码定位: L58
    • 说明:

      TODO

  • directStateAccess

    • 类型: DirectStateAccess
    • 修饰符: private final
    • 源码定位: L59
    • 说明:

      TODO

  • defaultShaderSource

    • 类型: ShaderSource
    • 修饰符: private final
    • 源码定位: L60
    • 说明:

      TODO

  • pipelineCache

    • 类型: Map<RenderPipeline,GlRenderPipeline>
    • 修饰符: private final
    • 源码定位: L61
    • 说明:

      TODO

  • shaderCache

    • 类型: Map<GlDevice.ShaderCompilationKey,GlShaderModule>
    • 修饰符: private final
    • 源码定位: L62
    • 说明:

      TODO

  • vertexArrayCache

    • 类型: VertexArrayCache
    • 修饰符: private final
    • 源码定位: L63
    • 说明:

      TODO

  • bufferStorage

    • 类型: BufferStorage
    • 修饰符: private final
    • 源码定位: L64
    • 说明:

      TODO

  • enabledExtensions

    • 类型: Set<String>
    • 修饰符: private final
    • 源码定位: L65
    • 说明:

      TODO

  • uniformOffsetAlignment

    • 类型: int
    • 修饰符: private final
    • 源码定位: L66
    • 说明:

      TODO

  • maxSupportedAnisotropy

    • 类型: int
    • 修饰符: private final
    • 源码定位: L67
    • 说明:

      TODO

  • windowHandle

    • 类型: long
    • 修饰符: private final
    • 源码定位: L68
    • 说明:

      TODO

内部类/嵌套类型

  • com.mojang.blaze3d.opengl.GlDevice.ShaderCompilationKey
    • 类型: record
    • 修饰符: private
    • 源码定位: L422
    • 说明:

      TODO

构造器

public GlDevice(long windowHandle, ShaderSource defaultShaderSource, GpuDebugOptions debugOptions) @ L70

  • 构造器名:GlDevice
  • 源码定位:L70
  • 修饰符:public

参数:

  • windowHandle: long
  • defaultShaderSource: ShaderSource
  • debugOptions: GpuDebugOptions

说明:

TODO

方法

下面的方法块按源码顺序生成。

public GlDebugLabel debugLabels() @ L96

  • 方法名:debugLabels
  • 源码定位:L96
  • 返回类型:GlDebugLabel
  • 修饰符:public

参数:

说明:

TODO

public CommandEncoderBackend createCommandEncoder() @ L100

  • 方法名:createCommandEncoder
  • 源码定位:L100
  • 返回类型:CommandEncoderBackend
  • 修饰符:public

参数:

说明:

TODO

public int getMaxSupportedAnisotropy() @ L105

  • 方法名:getMaxSupportedAnisotropy
  • 源码定位:L105
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public GpuSampler createSampler(AddressMode addressModeU, AddressMode addressModeV, FilterMode minFilter, FilterMode magFilter, int maxAnisotropy, OptionalDouble maxLod) @ L110

  • 方法名:createSampler
  • 源码定位:L110
  • 返回类型:GpuSampler
  • 修饰符:public

参数:

  • addressModeU: AddressMode
  • addressModeV: AddressMode
  • minFilter: FilterMode
  • magFilter: FilterMode
  • maxAnisotropy: int
  • maxLod: OptionalDouble

说明:

TODO

public GpuTexture createTexture(Supplier<String> label, int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels) @ L117

  • 方法名:createTexture
  • 源码定位:L117
  • 返回类型:GpuTexture
  • 修饰符:public

参数:

  • label: Supplier
  • usage: int
  • format: TextureFormat
  • width: int
  • height: int
  • depthOrLayers: int
  • mipLevels: int

说明:

TODO

public GpuTexture createTexture(String label, int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels) @ L124

  • 方法名:createTexture
  • 源码定位:L124
  • 返回类型:GpuTexture
  • 修饰符:public

参数:

  • label: String
  • usage: int
  • format: TextureFormat
  • width: int
  • height: int
  • depthOrLayers: int
  • mipLevels: int

说明:

TODO

public GpuTextureView createTextureView(GpuTexture texture) @ L187

  • 方法名:createTextureView
  • 源码定位:L187
  • 返回类型:GpuTextureView
  • 修饰符:public

参数:

  • texture: GpuTexture

说明:

TODO

public GpuTextureView createTextureView(GpuTexture texture, int baseMipLevel, int mipLevels) @ L192

  • 方法名:createTextureView
  • 源码定位:L192
  • 返回类型:GpuTextureView
  • 修饰符:public

参数:

  • texture: GpuTexture
  • baseMipLevel: int
  • mipLevels: int

说明:

TODO

public GpuBuffer createBuffer(Supplier<String> label, int usage, long size) @ L197

  • 方法名:createBuffer
  • 源码定位:L197
  • 返回类型:GpuBuffer
  • 修饰符:public

参数:

  • label: Supplier
  • usage: int
  • size: long

说明:

TODO

public GpuBuffer createBuffer(Supplier<String> label, int usage, ByteBuffer data) @ L212

  • 方法名:createBuffer
  • 源码定位:L212
  • 返回类型:GpuBuffer
  • 修饰符:public

参数:

  • label: Supplier
  • usage: int
  • data: ByteBuffer

说明:

TODO

public String getImplementationInformation() @ L228

  • 方法名:getImplementationInformation
  • 源码定位:L228
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public List<String> getLastDebugMessages() @ L235

  • 方法名:getLastDebugMessages
  • 源码定位:L235
  • 返回类型:List
  • 修饰符:public

参数:

说明:

TODO

public boolean isDebuggingEnabled() @ L240

  • 方法名:isDebuggingEnabled
  • 源码定位:L240
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public String getRenderer() @ L245

  • 方法名:getRenderer
  • 源码定位:L245
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public String getVendor() @ L250

  • 方法名:getVendor
  • 源码定位:L250
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public String getBackendName() @ L255

  • 方法名:getBackendName
  • 源码定位:L255
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public String getVersion() @ L260

  • 方法名:getVersion
  • 源码定位:L260
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

private static int getMaxSupportedTextureSize() @ L265

  • 方法名:getMaxSupportedTextureSize
  • 源码定位:L265
  • 返回类型:int
  • 修饰符:private static

参数:

说明:

TODO

public int getMaxTextureSize() @ L281

  • 方法名:getMaxTextureSize
  • 源码定位:L281
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getUniformOffsetAlignment() @ L286

  • 方法名:getUniformOffsetAlignment
  • 源码定位:L286
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void clearPipelineCache() @ L291

  • 方法名:clearPipelineCache
  • 源码定位:L291
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private static void sacrificeShaderToOpenGlAndAmd() @ L314

  • 方法名:sacrificeShaderToOpenGlAndAmd
  • 源码定位:L314
  • 返回类型:void
  • 修饰符:private static

参数:

说明:

TODO

public List<String> getEnabledExtensions() @ L322

  • 方法名:getEnabledExtensions
  • 源码定位:L322
  • 返回类型:List
  • 修饰符:public

参数:

说明:

TODO

public void close() @ L327

  • 方法名:close
  • 源码定位:L327
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void setVsync(boolean enabled) @ L332

  • 方法名:setVsync
  • 源码定位:L332
  • 返回类型:void
  • 修饰符:public

参数:

  • enabled: boolean

说明:

TODO

public void presentFrame() @ L337

  • 方法名:presentFrame
  • 源码定位:L337
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public boolean isZZeroToOne() @ L342

  • 方法名:isZZeroToOne
  • 源码定位:L342
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public DirectStateAccess directStateAccess() @ L347

  • 方法名:directStateAccess
  • 源码定位:L347
  • 返回类型:DirectStateAccess
  • 修饰符:public

参数:

说明:

TODO

protected GlRenderPipeline getOrCompilePipeline(RenderPipeline pipeline) @ L351

  • 方法名:getOrCompilePipeline
  • 源码定位:L351
  • 返回类型:GlRenderPipeline
  • 修饰符:protected

参数:

  • pipeline: RenderPipeline

说明:

TODO

protected GlShaderModule getOrCompileShader(Identifier id, ShaderType type, ShaderDefines defines, ShaderSource shaderSource) @ L355

  • 方法名:getOrCompileShader
  • 源码定位:L355
  • 返回类型:GlShaderModule
  • 修饰符:protected

参数:

  • id: Identifier
  • type: ShaderType
  • defines: ShaderDefines
  • shaderSource: ShaderSource

说明:

TODO

public GlRenderPipeline precompilePipeline(RenderPipeline pipeline, ShaderSource customShaderSource) @ L360

  • 方法名:precompilePipeline
  • 源码定位:L360
  • 返回类型:GlRenderPipeline
  • 修饰符:public

参数:

  • pipeline: RenderPipeline
  • customShaderSource: ShaderSource

说明:

TODO

private GlShaderModule compileShader(GlDevice.ShaderCompilationKey key, ShaderSource shaderSource) @ L365

  • 方法名:compileShader
  • 源码定位:L365
  • 返回类型:GlShaderModule
  • 修饰符:private

参数:

  • key: GlDevice.ShaderCompilationKey
  • shaderSource: ShaderSource

说明:

TODO

private GlProgram compileProgram(RenderPipeline pipeline, ShaderSource shaderSource) @ L387

  • 方法名:compileProgram
  • 源码定位:L387
  • 返回类型:GlProgram
  • 修饰符:private

参数:

  • pipeline: RenderPipeline
  • shaderSource: ShaderSource

说明:

TODO

private GlRenderPipeline compilePipeline(RenderPipeline pipeline, ShaderSource shaderSource) @ L409

  • 方法名:compilePipeline
  • 源码定位:L409
  • 返回类型:GlRenderPipeline
  • 修饰符:private

参数:

  • pipeline: RenderPipeline
  • shaderSource: ShaderSource

说明:

TODO

public VertexArrayCache vertexArrayCache() @ L413

  • 方法名:vertexArrayCache
  • 源码定位:L413
  • 返回类型:VertexArrayCache
  • 修饰符:public

参数:

说明:

TODO

public BufferStorage getBufferStorage() @ L417

  • 方法名:getBufferStorage
  • 源码定位:L417
  • 返回类型:BufferStorage
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
class GlDevice implements GpuDeviceBackend {
    private static final Logger LOGGER = LogUtils.getLogger();
    protected static boolean USE_GL_ARB_vertex_attrib_binding = true;
    protected static boolean USE_GL_KHR_debug = true;
    protected static boolean USE_GL_EXT_debug_label = true;
    protected static boolean USE_GL_ARB_debug_output = true;
    protected static boolean USE_GL_ARB_direct_state_access = true;
    protected static boolean USE_GL_ARB_buffer_storage = true;
    private final CommandEncoderBackend encoder;
    private final @Nullable GlDebug debugLog;
    private final GlDebugLabel debugLabels;
    private final int maxSupportedTextureSize;
    private final DirectStateAccess directStateAccess;
    private final ShaderSource defaultShaderSource;
    private final Map<RenderPipeline, GlRenderPipeline> pipelineCache = new IdentityHashMap<>();
    private final Map<GlDevice.ShaderCompilationKey, GlShaderModule> shaderCache = new HashMap<>();
    private final VertexArrayCache vertexArrayCache;
    private final BufferStorage bufferStorage;
    private final Set<String> enabledExtensions = new HashSet<>();
    private final int uniformOffsetAlignment;
    private final int maxSupportedAnisotropy;
    private final long windowHandle;
 
    public GlDevice(long windowHandle, ShaderSource defaultShaderSource, GpuDebugOptions debugOptions) {
        GLFW.glfwMakeContextCurrent(windowHandle);
        GLCapabilities capabilities = GL.createCapabilities();
        int maxSize = getMaxSupportedTextureSize();
        GLFW.glfwSetWindowSizeLimits(windowHandle, -1, -1, maxSize, maxSize);
        GraphicsWorkarounds workarounds = GraphicsWorkarounds.get(new GpuDevice(this));
        this.windowHandle = windowHandle;
        this.debugLog = GlDebug.enableDebugCallback(debugOptions.logLevel(), debugOptions.synchronousLogs(), this.enabledExtensions);
        this.debugLabels = GlDebugLabel.create(capabilities, debugOptions.useLabels(), this.enabledExtensions);
        this.vertexArrayCache = VertexArrayCache.create(capabilities, this.debugLabels, this.enabledExtensions);
        this.bufferStorage = BufferStorage.create(capabilities, this.enabledExtensions);
        this.directStateAccess = DirectStateAccess.create(capabilities, this.enabledExtensions, workarounds);
        this.maxSupportedTextureSize = maxSize;
        this.defaultShaderSource = defaultShaderSource;
        this.encoder = new GlCommandEncoder(this);
        this.uniformOffsetAlignment = GL11.glGetInteger(35380);
        GL11.glEnable(34895);
        GL11.glEnable(34370);
        if (capabilities.GL_EXT_texture_filter_anisotropic) {
            this.maxSupportedAnisotropy = Mth.floor(GL11.glGetFloat(34047));
            this.enabledExtensions.add("GL_EXT_texture_filter_anisotropic");
        } else {
            this.maxSupportedAnisotropy = 1;
        }
    }
 
    public GlDebugLabel debugLabels() {
        return this.debugLabels;
    }
 
    @Override
    public CommandEncoderBackend createCommandEncoder() {
        return this.encoder;
    }
 
    @Override
    public int getMaxSupportedAnisotropy() {
        return this.maxSupportedAnisotropy;
    }
 
    @Override
    public GpuSampler createSampler(
        AddressMode addressModeU, AddressMode addressModeV, FilterMode minFilter, FilterMode magFilter, int maxAnisotropy, OptionalDouble maxLod
    ) {
        return new GlSampler(addressModeU, addressModeV, minFilter, magFilter, maxAnisotropy, maxLod);
    }
 
    @Override
    public GpuTexture createTexture(
        @Nullable Supplier<String> label, @GpuTexture.Usage int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels
    ) {
        return this.createTexture(this.debugLabels.exists() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels);
    }
 
    @Override
    public GpuTexture createTexture(
        @Nullable String label, @GpuTexture.Usage int usage, TextureFormat format, int width, int height, int depthOrLayers, int mipLevels
    ) {
        GlStateManager.clearGlErrors();
        int id = GlStateManager._genTexture();
        if (label == null) {
            label = String.valueOf(id);
        }
 
        boolean isCubemap = (usage & 16) != 0;
        int target;
        if (isCubemap) {
            GL11.glBindTexture(34067, id);
            target = 34067;
        } else {
            GlStateManager._bindTexture(id);
            target = 3553;
        }
 
        GlStateManager._texParameter(target, 33085, mipLevels - 1);
        GlStateManager._texParameter(target, 33082, 0);
        GlStateManager._texParameter(target, 33083, mipLevels - 1);
        if (format.hasDepthAspect()) {
            GlStateManager._texParameter(target, 34892, 0);
        }
 
        if (isCubemap) {
            for (int cubeTarget : GlConst.CUBEMAP_TARGETS) {
                for (int i = 0; i < mipLevels; i++) {
                    GlStateManager._texImage2D(
                        cubeTarget,
                        i,
                        GlConst.toGlInternalId(format),
                        width >> i,
                        height >> i,
                        0,
                        GlConst.toGlExternalId(format),
                        GlConst.toGlType(format),
                        null
                    );
                }
            }
        } else {
            for (int i = 0; i < mipLevels; i++) {
                GlStateManager._texImage2D(
                    target, i, GlConst.toGlInternalId(format), width >> i, height >> i, 0, GlConst.toGlExternalId(format), GlConst.toGlType(format), null
                );
            }
        }
 
        int error = GlStateManager._getError();
        if (error == 1285) {
            throw new GpuOutOfMemoryException("Could not allocate texture of " + width + "x" + height + " for " + label);
        } else if (error != 0) {
            throw new IllegalStateException("OpenGL error " + error);
        } else {
            GlTexture texture = new GlTexture(usage, label, format, width, height, depthOrLayers, mipLevels, id);
            this.debugLabels.applyLabel(texture);
            return texture;
        }
    }
 
    @Override
    public GpuTextureView createTextureView(GpuTexture texture) {
        return this.createTextureView(texture, 0, texture.getMipLevels());
    }
 
    @Override
    public GpuTextureView createTextureView(GpuTexture texture, int baseMipLevel, int mipLevels) {
        return new GlTextureView((GlTexture)texture, baseMipLevel, mipLevels);
    }
 
    @Override
    public GpuBuffer createBuffer(@Nullable Supplier<String> label, @GpuBuffer.Usage int usage, long size) {
        GlStateManager.clearGlErrors();
        GlBuffer buffer = this.bufferStorage.createBuffer(this.directStateAccess, label, usage, size);
        int error = GlStateManager._getError();
        if (error == 1285) {
            throw new GpuOutOfMemoryException("Could not allocate buffer of " + size + " for " + label);
        } else if (error != 0) {
            throw new IllegalStateException("OpenGL error " + error);
        } else {
            this.debugLabels.applyLabel(buffer);
            return buffer;
        }
    }
 
    @Override
    public GpuBuffer createBuffer(@Nullable Supplier<String> label, @GpuBuffer.Usage int usage, ByteBuffer data) {
        GlStateManager.clearGlErrors();
        long size = data.remaining();
        GlBuffer buffer = this.bufferStorage.createBuffer(this.directStateAccess, label, usage, data);
        int error = GlStateManager._getError();
        if (error == 1285) {
            throw new GpuOutOfMemoryException("Could not allocate buffer of " + size + " for " + label);
        } else if (error != 0) {
            throw new IllegalStateException("OpenGL error " + error);
        } else {
            this.debugLabels.applyLabel(buffer);
            return buffer;
        }
    }
 
    @Override
    public String getImplementationInformation() {
        return GLFW.glfwGetCurrentContext() == 0L
            ? "NO CONTEXT"
            : GlStateManager._getString(7937) + " GL version " + GlStateManager._getString(7938) + ", " + GlStateManager._getString(7936);
    }
 
    @Override
    public List<String> getLastDebugMessages() {
        return this.debugLog == null ? Collections.emptyList() : this.debugLog.getLastOpenGlDebugMessages();
    }
 
    @Override
    public boolean isDebuggingEnabled() {
        return this.debugLog != null;
    }
 
    @Override
    public String getRenderer() {
        return GlStateManager._getString(7937);
    }
 
    @Override
    public String getVendor() {
        return GlStateManager._getString(7936);
    }
 
    @Override
    public String getBackendName() {
        return "OpenGL";
    }
 
    @Override
    public String getVersion() {
        return GlStateManager._getString(7938);
    }
 
    private static int getMaxSupportedTextureSize() {
        int maxReported = GlStateManager._getInteger(3379);
 
        for (int texSize = Math.max(32768, maxReported); texSize >= 1024; texSize >>= 1) {
            GlStateManager._texImage2D(32868, 0, 6408, texSize, texSize, 0, 6408, 5121, null);
            int width = GlStateManager._getTexLevelParameter(32868, 0, 4096);
            if (width != 0) {
                return texSize;
            }
        }
 
        int maxSupportedTextureSize = Math.max(maxReported, 1024);
        LOGGER.info("Failed to determine maximum texture size by probing, trying GL_MAX_TEXTURE_SIZE = {}", maxSupportedTextureSize);
        return maxSupportedTextureSize;
    }
 
    @Override
    public int getMaxTextureSize() {
        return this.maxSupportedTextureSize;
    }
 
    @Override
    public int getUniformOffsetAlignment() {
        return this.uniformOffsetAlignment;
    }
 
    @Override
    public void clearPipelineCache() {
        for (GlRenderPipeline pipeline : this.pipelineCache.values()) {
            if (pipeline.program() != GlProgram.INVALID_PROGRAM) {
                pipeline.program().close();
            }
        }
 
        this.pipelineCache.clear();
 
        for (GlShaderModule shader : this.shaderCache.values()) {
            if (shader != GlShaderModule.INVALID_SHADER) {
                shader.close();
            }
        }
 
        this.shaderCache.clear();
        String glRenderer = GlStateManager._getString(7937);
        if (glRenderer.contains("AMD")) {
            sacrificeShaderToOpenGlAndAmd();
        }
    }
 
    private static void sacrificeShaderToOpenGlAndAmd() {
        int shader = GlStateManager.glCreateShader(35633);
        int program = GlStateManager.glCreateProgram();
        GlStateManager.glAttachShader(program, shader);
        GlStateManager.glDeleteShader(shader);
        GlStateManager.glDeleteProgram(program);
    }
 
    @Override
    public List<String> getEnabledExtensions() {
        return new ArrayList<>(this.enabledExtensions);
    }
 
    @Override
    public void close() {
        this.clearPipelineCache();
    }
 
    @Override
    public void setVsync(boolean enabled) {
        GLFW.glfwSwapInterval(enabled ? 1 : 0);
    }
 
    @Override
    public void presentFrame() {
        GLFW.glfwSwapBuffers(this.windowHandle);
    }
 
    @Override
    public boolean isZZeroToOne() {
        return false;
    }
 
    public DirectStateAccess directStateAccess() {
        return this.directStateAccess;
    }
 
    protected GlRenderPipeline getOrCompilePipeline(RenderPipeline pipeline) {
        return this.pipelineCache.computeIfAbsent(pipeline, p -> this.compilePipeline(p, this.defaultShaderSource));
    }
 
    protected GlShaderModule getOrCompileShader(Identifier id, ShaderType type, ShaderDefines defines, ShaderSource shaderSource) {
        GlDevice.ShaderCompilationKey key = new GlDevice.ShaderCompilationKey(id, type, defines);
        return this.shaderCache.computeIfAbsent(key, k -> this.compileShader(k, shaderSource));
    }
 
    public GlRenderPipeline precompilePipeline(RenderPipeline pipeline, @Nullable ShaderSource customShaderSource) {
        ShaderSource shaderSource = customShaderSource == null ? this.defaultShaderSource : customShaderSource;
        return this.pipelineCache.computeIfAbsent(pipeline, p -> this.compilePipeline(p, shaderSource));
    }
 
    private GlShaderModule compileShader(GlDevice.ShaderCompilationKey key, ShaderSource shaderSource) {
        String source = shaderSource.get(key.id, key.type);
        if (source == null) {
            LOGGER.error("Couldn't find source for {} shader ({})", key.type, key.id);
            return GlShaderModule.INVALID_SHADER;
        } else {
            String sourceWithDefines = GlslPreprocessor.injectDefines(source, key.defines);
            int shaderId = GlStateManager.glCreateShader(GlConst.toGl(key.type));
            GlStateManager.glShaderSource(shaderId, sourceWithDefines);
            GlStateManager.glCompileShader(shaderId);
            if (GlStateManager.glGetShaderi(shaderId, 35713) == 0) {
                String logInfo = StringUtils.trim(GlStateManager.glGetShaderInfoLog(shaderId, 32768));
                LOGGER.error("Couldn't compile {} shader ({}): {}", key.type.getName(), key.id, logInfo);
                return GlShaderModule.INVALID_SHADER;
            } else {
                GlShaderModule module = new GlShaderModule(shaderId, key.id, key.type);
                this.debugLabels.applyLabel(module);
                return module;
            }
        }
    }
 
    private GlProgram compileProgram(RenderPipeline pipeline, ShaderSource shaderSource) {
        GlShaderModule vertexShader = this.getOrCompileShader(pipeline.getVertexShader(), ShaderType.VERTEX, pipeline.getShaderDefines(), shaderSource);
        GlShaderModule fragmentShader = this.getOrCompileShader(pipeline.getFragmentShader(), ShaderType.FRAGMENT, pipeline.getShaderDefines(), shaderSource);
        if (vertexShader == GlShaderModule.INVALID_SHADER) {
            LOGGER.error("Couldn't compile pipeline {}: vertex shader {} was invalid", pipeline.getLocation(), pipeline.getVertexShader());
            return GlProgram.INVALID_PROGRAM;
        } else if (fragmentShader == GlShaderModule.INVALID_SHADER) {
            LOGGER.error("Couldn't compile pipeline {}: fragment shader {} was invalid", pipeline.getLocation(), pipeline.getFragmentShader());
            return GlProgram.INVALID_PROGRAM;
        } else {
            try {
                GlProgram compiled = GlProgram.link(vertexShader, fragmentShader, pipeline.getVertexFormat(), pipeline.getLocation().toString());
                compiled.setupUniforms(pipeline.getUniforms(), pipeline.getSamplers());
                this.debugLabels.applyLabel(compiled);
                return compiled;
            } catch (ShaderManager.CompilationException var6) {
                LOGGER.error("Couldn't compile program for pipeline {}: {}", pipeline.getLocation(), var6);
                return GlProgram.INVALID_PROGRAM;
            }
        }
    }
 
    private GlRenderPipeline compilePipeline(RenderPipeline pipeline, ShaderSource shaderSource) {
        return new GlRenderPipeline(pipeline, this.compileProgram(pipeline, shaderSource));
    }
 
    public VertexArrayCache vertexArrayCache() {
        return this.vertexArrayCache;
    }
 
    public BufferStorage getBufferStorage() {
        return this.bufferStorage;
    }
 
    @OnlyIn(Dist.CLIENT)
    private record ShaderCompilationKey(Identifier id, ShaderType type, ShaderDefines defines) {
        @Override
        public String toString() {
            String string = this.id + " (" + this.type + ")";
            return !this.defines.isEmpty() ? string + " with " + this.defines : string;
        }
    }
}

引用的其他类

  • GpuOutOfMemoryException

    • 引用位置: 构造调用
    • 关联成员: GpuOutOfMemoryException()
  • GraphicsWorkarounds

    • 引用位置: 方法调用
    • 关联成员: GraphicsWorkarounds.get()
  • GpuBuffer

    • 引用位置: 返回值
  • BufferStorage

    • 引用位置: 字段/方法调用/返回值
    • 关联成员: BufferStorage.create()
  • DirectStateAccess

    • 引用位置: 字段/方法调用/返回值
    • 关联成员: DirectStateAccess.create()
  • GlCommandEncoder

    • 引用位置: 构造调用
    • 关联成员: GlCommandEncoder()
  • GlConst

    • 引用位置: 方法调用
    • 关联成员: GlConst.toGl(), GlConst.toGlExternalId(), GlConst.toGlInternalId(), GlConst.toGlType()
  • GlDebug

    • 引用位置: 字段/方法调用
    • 关联成员: GlDebug.enableDebugCallback()
  • GlDebugLabel

    • 引用位置: 字段/方法调用/返回值
    • 关联成员: GlDebugLabel.create()
  • GlProgram

    • 引用位置: 方法调用/返回值
    • 关联成员: GlProgram.link()
  • GlRenderPipeline

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: GlRenderPipeline()
  • GlSampler

    • 引用位置: 构造调用
    • 关联成员: GlSampler()
  • GlShaderModule

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: GlShaderModule()
  • GlStateManager

    • 引用位置: 方法调用
    • 关联成员: GlStateManager._bindTexture(), GlStateManager._genTexture(), GlStateManager._getError(), GlStateManager._getInteger(), GlStateManager._getString(), GlStateManager._getTexLevelParameter(), GlStateManager._texImage2D(), GlStateManager._texParameter(), GlStateManager.clearGlErrors(), GlStateManager.glAttachShader(), GlStateManager.glCompileShader(), GlStateManager.glCreateProgram(), GlStateManager.glCreateShader(), GlStateManager.glDeleteProgram(), GlStateManager.glDeleteShader(), GlStateManager.glGetShaderInfoLog(), GlStateManager.glGetShaderi(), GlStateManager.glShaderSource()
  • GlTexture

    • 引用位置: 构造调用
    • 关联成员: GlTexture()
  • GlTextureView

    • 引用位置: 构造调用
    • 关联成员: GlTextureView()
  • VertexArrayCache

    • 引用位置: 字段/方法调用/返回值
    • 关联成员: VertexArrayCache.create()
  • RenderPipeline

    • 引用位置: 参数/字段
  • GlslPreprocessor

    • 引用位置: 方法调用
    • 关联成员: GlslPreprocessor.injectDefines()
  • GpuDebugOptions

    • 引用位置: 参数
  • ShaderSource

    • 引用位置: 参数/字段
  • ShaderType

    • 引用位置: 参数
  • CommandEncoderBackend

    • 引用位置: 字段/返回值
  • GpuDevice

    • 引用位置: 构造调用
    • 关联成员: GpuDevice()
  • GpuDeviceBackend

    • 引用位置: 实现
  • AddressMode

    • 引用位置: 参数
  • FilterMode

    • 引用位置: 参数
  • GpuSampler

    • 引用位置: 返回值
  • GpuTexture

    • 引用位置: 参数/返回值
  • GpuTextureView

    • 引用位置: 返回值
  • TextureFormat

    • 引用位置: 参数
  • ShaderDefines

    • 引用位置: 参数
  • Identifier

    • 引用位置: 参数
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.floor()