CommandEncoder.java

com.mojang.blaze3d.systems.CommandEncoder

信息

  • 全限定名:com.mojang.blaze3d.systems.CommandEncoder
  • 类型:public class
  • 包:com.mojang.blaze3d.systems
  • 源码路径:src/main/java/com/mojang/blaze3d/systems/CommandEncoder.java
  • 起始行号:L20
  • 职责:

    TODO

字段/常量

  • LOGGER

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

      TODO

  • device

    • 类型: GpuDeviceBackend
    • 修饰符: private final
    • 源码定位: L22
    • 说明:

      TODO

  • backend

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

      TODO

内部类/嵌套类型

构造器

public CommandEncoder(GpuDeviceBackend device, CommandEncoderBackend backend) @ L25

  • 构造器名:CommandEncoder
  • 源码定位:L25
  • 修饰符:public

参数:

  • device: GpuDeviceBackend
  • backend: CommandEncoderBackend

说明:

TODO

方法

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

public RenderPass createRenderPass(Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor) @ L30

  • 方法名:createRenderPass
  • 源码定位:L30
  • 返回类型:RenderPass
  • 修饰符:public

参数:

  • label: Supplier
  • colorTexture: GpuTextureView
  • clearColor: OptionalInt

说明:

TODO

public RenderPass createRenderPass(Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor, GpuTextureView depthTexture, OptionalDouble clearDepth) @ L34

  • 方法名:createRenderPass
  • 源码定位:L34
  • 返回类型:RenderPass
  • 修饰符:public

参数:

  • label: Supplier
  • colorTexture: GpuTextureView
  • clearColor: OptionalInt
  • depthTexture: GpuTextureView
  • clearDepth: OptionalDouble

说明:

TODO

public void clearColorTexture(GpuTexture colorTexture, int clearColor) @ L70

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

参数:

  • colorTexture: GpuTexture
  • clearColor: int

说明:

TODO

public void clearColorAndDepthTextures(GpuTexture colorTexture, int clearColor, GpuTexture depthTexture, double clearDepth) @ L79

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

参数:

  • colorTexture: GpuTexture
  • clearColor: int
  • depthTexture: GpuTexture
  • clearDepth: double

说明:

TODO

public void clearColorAndDepthTextures(GpuTexture colorTexture, int clearColor, GpuTexture depthTexture, double clearDepth, int regionX, int regionY, int regionWidth, int regionHeight) @ L89

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

参数:

  • colorTexture: GpuTexture
  • clearColor: int
  • depthTexture: GpuTexture
  • clearDepth: double
  • regionX: int
  • regionY: int
  • regionWidth: int
  • regionHeight: int

说明:

TODO

public void clearDepthTexture(GpuTexture depthTexture, double clearDepth) @ L102

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

参数:

  • depthTexture: GpuTexture
  • clearDepth: double

说明:

TODO

public void writeToBuffer(GpuBufferSlice destination, ByteBuffer data) @ L111

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

参数:

  • destination: GpuBufferSlice
  • data: ByteBuffer

说明:

TODO

public GpuBuffer.MappedView mapBuffer(GpuBuffer buffer, boolean read, boolean write) @ L119

  • 方法名:mapBuffer
  • 源码定位:L119
  • 返回类型:GpuBuffer.MappedView
  • 修饰符:public

参数:

  • buffer: GpuBuffer
  • read: boolean
  • write: boolean

说明:

TODO

public GpuBuffer.MappedView mapBuffer(GpuBufferSlice slice, boolean read, boolean write) @ L123

  • 方法名:mapBuffer
  • 源码定位:L123
  • 返回类型:GpuBuffer.MappedView
  • 修饰符:public

参数:

  • slice: GpuBufferSlice
  • read: boolean
  • write: boolean

说明:

TODO

public void copyToBuffer(GpuBufferSlice source, GpuBufferSlice target) @ L152

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

参数:

  • source: GpuBufferSlice
  • target: GpuBufferSlice

说明:

TODO

public void writeToTexture(GpuTexture destination, NativeImage source) @ L198

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

参数:

  • destination: GpuTexture
  • source: NativeImage

说明:

TODO

public void writeToTexture(GpuTexture destination, NativeImage source, int mipLevel, int depthOrLayer, int destX, int destY, int width, int height, int sourceX, int sourceY) @ L214

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

参数:

  • destination: GpuTexture
  • source: NativeImage
  • mipLevel: int
  • depthOrLayer: int
  • destX: int
  • destY: int
  • width: int
  • height: int
  • sourceX: int
  • sourceY: int

说明:

TODO

public void writeToTexture(GpuTexture destination, ByteBuffer source, NativeImage.Format format, int mipLevel, int depthOrLayer, int destX, int destY, int width, int height) @ L267

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

参数:

  • destination: GpuTexture
  • source: ByteBuffer
  • format: NativeImage.Format
  • mipLevel: int
  • depthOrLayer: int
  • destX: int
  • destY: int
  • width: int
  • height: int

说明:

TODO

public void copyTextureToBuffer(GpuTexture source, GpuBuffer destination, long offset, Runnable callback, int mipLevel) @ L314

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

参数:

  • source: GpuTexture
  • destination: GpuBuffer
  • offset: long
  • callback: Runnable
  • mipLevel: int

说明:

TODO

public void copyTextureToBuffer(GpuTexture source, GpuBuffer destination, long offset, Runnable callback, int mipLevel, int x, int y, int width, int height) @ L322

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

参数:

  • source: GpuTexture
  • destination: GpuBuffer
  • offset: long
  • callback: Runnable
  • mipLevel: int
  • x: int
  • y: int
  • width: int
  • height: int

说明:

TODO

public void copyTextureToTexture(GpuTexture source, GpuTexture destination, int mipLevel, int destX, int destY, int sourceX, int sourceY, int width, int height) @ L372

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

参数:

  • source: GpuTexture
  • destination: GpuTexture
  • mipLevel: int
  • destX: int
  • destY: int
  • sourceX: int
  • sourceY: int
  • width: int
  • height: int

说明:

TODO

public void presentTexture(GpuTextureView textureView) @ L430

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

参数:

  • textureView: GpuTextureView

说明:

TODO

public GpuFence createFence() @ L444

  • 方法名:createFence
  • 源码定位:L444
  • 返回类型:GpuFence
  • 修饰符:public

参数:

说明:

TODO

public GpuQuery timerQueryBegin() @ L452

  • 方法名:timerQueryBegin
  • 源码定位:L452
  • 返回类型:GpuQuery
  • 修饰符:public

参数:

说明:

TODO

public void timerQueryEnd(GpuQuery query) @ L456

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

参数:

  • query: GpuQuery

说明:

TODO

private void verifyColorTexture(GpuTexture colorTexture) @ L460

  • 方法名:verifyColorTexture
  • 源码定位:L460
  • 返回类型:void
  • 修饰符:private

参数:

  • colorTexture: GpuTexture

说明:

TODO

private void verifyDepthTexture(GpuTexture depthTexture) @ L474

  • 方法名:verifyDepthTexture
  • 源码定位:L474
  • 返回类型:void
  • 修饰符:private

参数:

  • depthTexture: GpuTexture

说明:

TODO

private void verifyRegion(GpuTexture colorTexture, int regionX, int regionY, int regionWidth, int regionHeight) @ L488

  • 方法名:verifyRegion
  • 源码定位:L488
  • 返回类型:void
  • 修饰符:private

参数:

  • colorTexture: GpuTexture
  • regionX: int
  • regionY: int
  • regionWidth: int
  • regionHeight: int

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class CommandEncoder {
    private static final Logger LOGGER = LogUtils.getLogger();
    private final GpuDeviceBackend device;
    private final CommandEncoderBackend backend;
 
    public CommandEncoder(GpuDeviceBackend device, CommandEncoderBackend backend) {
        this.device = device;
        this.backend = backend;
    }
 
    public RenderPass createRenderPass(Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor) {
        return this.createRenderPass(label, colorTexture, clearColor, null, OptionalDouble.empty());
    }
 
    public RenderPass createRenderPass(
        Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor, @Nullable GpuTextureView depthTexture, OptionalDouble clearDepth
    ) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before creating a new one!");
        } else {
            if (clearDepth.isPresent() && depthTexture == null) {
                LOGGER.warn("Depth clear value was provided but no depth texture is being used");
            }
 
            if (colorTexture.isClosed()) {
                throw new IllegalStateException("Color texture is closed");
            } else if ((colorTexture.texture().usage() & 8) == 0) {
                throw new IllegalStateException("Color texture must have USAGE_RENDER_ATTACHMENT");
            } else if (colorTexture.texture().getDepthOrLayers() > 1) {
                throw new UnsupportedOperationException("Textures with multiple depths or layers are not yet supported as an attachment");
            } else {
                if (depthTexture != null) {
                    if (depthTexture.isClosed()) {
                        throw new IllegalStateException("Depth texture is closed");
                    }
 
                    if ((depthTexture.texture().usage() & 8) == 0) {
                        throw new IllegalStateException("Depth texture must have USAGE_RENDER_ATTACHMENT");
                    }
 
                    if (depthTexture.texture().getDepthOrLayers() > 1) {
                        throw new UnsupportedOperationException("Textures with multiple depths or layers are not yet supported as an attachment");
                    }
                }
 
                return new RenderPass(this.backend.createRenderPass(label, colorTexture, clearColor, depthTexture, clearDepth), this.device);
            }
        }
    }
 
    public void clearColorTexture(GpuTexture colorTexture, int clearColor) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before creating a new one!");
        } else {
            this.verifyColorTexture(colorTexture);
            this.backend.clearColorTexture(colorTexture, clearColor);
        }
    }
 
    public void clearColorAndDepthTextures(GpuTexture colorTexture, int clearColor, GpuTexture depthTexture, double clearDepth) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before creating a new one!");
        } else {
            this.verifyColorTexture(colorTexture);
            this.verifyDepthTexture(depthTexture);
            this.backend.clearColorAndDepthTextures(colorTexture, clearColor, depthTexture, clearDepth);
        }
    }
 
    public void clearColorAndDepthTextures(
        GpuTexture colorTexture, int clearColor, GpuTexture depthTexture, double clearDepth, int regionX, int regionY, int regionWidth, int regionHeight
    ) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before creating a new one!");
        } else {
            this.verifyColorTexture(colorTexture);
            this.verifyDepthTexture(depthTexture);
            this.verifyRegion(colorTexture, regionX, regionY, regionWidth, regionHeight);
            this.backend.clearColorAndDepthTextures(colorTexture, clearColor, depthTexture, clearDepth, regionX, regionY, regionWidth, regionHeight);
        }
    }
 
    public void clearDepthTexture(GpuTexture depthTexture, double clearDepth) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before creating a new one!");
        } else {
            this.verifyDepthTexture(depthTexture);
            this.backend.clearDepthTexture(depthTexture, clearDepth);
        }
    }
 
    public void writeToBuffer(GpuBufferSlice destination, ByteBuffer data) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else {
            this.backend.writeToBuffer(destination, data);
        }
    }
 
    public GpuBuffer.MappedView mapBuffer(GpuBuffer buffer, boolean read, boolean write) {
        return this.mapBuffer(buffer.slice(), read, write);
    }
 
    public GpuBuffer.MappedView mapBuffer(GpuBufferSlice slice, boolean read, boolean write) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else {
            GpuBuffer buffer = slice.buffer();
            if (buffer.isClosed()) {
                throw new IllegalStateException("Buffer already closed");
            } else if (!read && !write) {
                throw new IllegalArgumentException("At least read or write must be true");
            } else if (read && (buffer.usage() & 1) == 0) {
                throw new IllegalStateException("Buffer is not readable");
            } else if (write && (buffer.usage() & 2) == 0) {
                throw new IllegalStateException("Buffer is not writable");
            } else if (slice.offset() + slice.length() > buffer.size()) {
                throw new IllegalArgumentException(
                    "Cannot map more data than this buffer can hold (attempting to map "
                        + slice.length()
                        + " bytes at offset "
                        + slice.offset()
                        + " from "
                        + buffer.size()
                        + " size buffer)"
                );
            } else {
                return this.backend.mapBuffer(slice, read, write);
            }
        }
    }
 
    public void copyToBuffer(GpuBufferSlice source, GpuBufferSlice target) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else {
            GpuBuffer sourceBuffer = source.buffer();
            if (sourceBuffer.isClosed()) {
                throw new IllegalStateException("Source buffer already closed");
            } else if ((sourceBuffer.usage() & 16) == 0) {
                throw new IllegalStateException("Source buffer needs USAGE_COPY_SRC to be a source for a copy");
            } else {
                GpuBuffer targetBuffer = target.buffer();
                if (targetBuffer.isClosed()) {
                    throw new IllegalStateException("Target buffer already closed");
                } else if ((targetBuffer.usage() & 8) == 0) {
                    throw new IllegalStateException("Target buffer needs USAGE_COPY_DST to be a destination for a copy");
                } else if (source.length() != target.length()) {
                    throw new IllegalArgumentException(
                        "Cannot copy from slice of size " + source.length() + " to slice of size " + target.length() + ", they must be equal"
                    );
                } else if (source.offset() + source.length() > sourceBuffer.size()) {
                    throw new IllegalArgumentException(
                        "Cannot copy more data than the source buffer holds (attempting to copy "
                            + source.length()
                            + " bytes at offset "
                            + source.offset()
                            + " from "
                            + sourceBuffer.size()
                            + " size buffer)"
                    );
                } else if (target.offset() + target.length() > targetBuffer.size()) {
                    throw new IllegalArgumentException(
                        "Cannot copy more data than the target buffer can hold (attempting to copy "
                            + target.length()
                            + " bytes at offset "
                            + target.offset()
                            + " to "
                            + targetBuffer.size()
                            + " size buffer)"
                    );
                } else {
                    this.backend.copyToBuffer(source, target);
                }
            }
        }
    }
 
    public void writeToTexture(GpuTexture destination, NativeImage source) {
        int width = destination.getWidth(0);
        int height = destination.getHeight(0);
        if (source.getWidth() != width || source.getHeight() != height) {
            throw new IllegalArgumentException(
                "Cannot replace texture of size " + width + "x" + height + " with image of size " + source.getWidth() + "x" + source.getHeight()
            );
        } else if (destination.isClosed()) {
            throw new IllegalStateException("Destination texture is closed");
        } else if ((destination.usage() & 1) == 0) {
            throw new IllegalStateException("Color texture must have USAGE_COPY_DST to be a destination for a write");
        } else {
            this.writeToTexture(destination, source, 0, 0, 0, 0, width, height, 0, 0);
        }
    }
 
    public void writeToTexture(
        GpuTexture destination, NativeImage source, int mipLevel, int depthOrLayer, int destX, int destY, int width, int height, int sourceX, int sourceY
    ) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else if (mipLevel >= 0 && mipLevel < destination.getMipLevels()) {
            if (sourceX + width > source.getWidth() || sourceY + height > source.getHeight()) {
                throw new IllegalArgumentException(
                    "Copy source ("
                        + source.getWidth()
                        + "x"
                        + source.getHeight()
                        + ") is not large enough to read a rectangle of "
                        + width
                        + "x"
                        + height
                        + " from "
                        + sourceX
                        + "x"
                        + sourceY
                );
            } else if (destX + width > destination.getWidth(mipLevel) || destY + height > destination.getHeight(mipLevel)) {
                throw new IllegalArgumentException(
                    "Dest texture ("
                        + width
                        + "x"
                        + height
                        + ") is not large enough to write a rectangle of "
                        + width
                        + "x"
                        + height
                        + " at "
                        + destX
                        + "x"
                        + destY
                        + " (at mip level "
                        + mipLevel
                        + ")"
                );
            } else if (destination.isClosed()) {
                throw new IllegalStateException("Destination texture is closed");
            } else if ((destination.usage() & 1) == 0) {
                throw new IllegalStateException("Color texture must have USAGE_COPY_DST to be a destination for a write");
            } else if (depthOrLayer >= destination.getDepthOrLayers()) {
                throw new UnsupportedOperationException("Depth or layer is out of range, must be >= 0 and < " + destination.getDepthOrLayers());
            } else {
                this.backend.writeToTexture(destination, source, mipLevel, depthOrLayer, destX, destY, width, height, sourceX, sourceY);
            }
        } else {
            throw new IllegalArgumentException("Invalid mipLevel " + mipLevel + ", must be >= 0 and < " + destination.getMipLevels());
        }
    }
 
    public void writeToTexture(
        GpuTexture destination, ByteBuffer source, NativeImage.Format format, int mipLevel, int depthOrLayer, int destX, int destY, int width, int height
    ) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else if (mipLevel >= 0 && mipLevel < destination.getMipLevels()) {
            if (width * height * format.components() > source.remaining()) {
                throw new IllegalArgumentException(
                    "Copy would overrun the source buffer (remaining length of "
                        + source.remaining()
                        + ", but copy is "
                        + width
                        + "x"
                        + height
                        + " of format "
                        + format
                        + ")"
                );
            } else if (destX + width > destination.getWidth(mipLevel) || destY + height > destination.getHeight(mipLevel)) {
                throw new IllegalArgumentException(
                    "Dest texture ("
                        + destination.getWidth(mipLevel)
                        + "x"
                        + destination.getHeight(mipLevel)
                        + ") is not large enough to write a rectangle of "
                        + width
                        + "x"
                        + height
                        + " at "
                        + destX
                        + "x"
                        + destY
                );
            } else if (destination.isClosed()) {
                throw new IllegalStateException("Destination texture is closed");
            } else if ((destination.usage() & 1) == 0) {
                throw new IllegalStateException("Color texture must have USAGE_COPY_DST to be a destination for a write");
            } else if (depthOrLayer >= destination.getDepthOrLayers()) {
                throw new UnsupportedOperationException("Depth or layer is out of range, must be >= 0 and < " + destination.getDepthOrLayers());
            } else {
                this.backend.writeToTexture(destination, source, format, mipLevel, depthOrLayer, destX, destY, width, height);
            }
        } else {
            throw new IllegalArgumentException("Invalid mipLevel, must be >= 0 and < " + destination.getMipLevels());
        }
    }
 
    public void copyTextureToBuffer(GpuTexture source, GpuBuffer destination, long offset, Runnable callback, int mipLevel) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else {
            this.backend.copyTextureToBuffer(source, destination, offset, callback, mipLevel);
        }
    }
 
    public void copyTextureToBuffer(GpuTexture source, GpuBuffer destination, long offset, Runnable callback, int mipLevel, int x, int y, int width, int height) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else if (mipLevel >= 0 && mipLevel < source.getMipLevels()) {
            if ((long)width * height * source.getFormat().pixelSize() + offset > destination.size()) {
                throw new IllegalArgumentException(
                    "Buffer of size "
                        + destination.size()
                        + " is not large enough to hold "
                        + width
                        + "x"
                        + height
                        + " pixels ("
                        + source.getFormat().pixelSize()
                        + " bytes each) starting from offset "
                        + offset
                );
            } else if ((source.usage() & 2) == 0) {
                throw new IllegalArgumentException("Texture needs USAGE_COPY_SRC to be a source for a copy");
            } else if ((destination.usage() & 8) == 0) {
                throw new IllegalArgumentException("Buffer needs USAGE_COPY_DST to be a destination for a copy");
            } else if (x + width > source.getWidth(mipLevel) || y + height > source.getHeight(mipLevel)) {
                throw new IllegalArgumentException(
                    "Copy source texture ("
                        + source.getWidth(mipLevel)
                        + "x"
                        + source.getHeight(mipLevel)
                        + ") is not large enough to read a rectangle of "
                        + width
                        + "x"
                        + height
                        + " from "
                        + x
                        + ","
                        + y
                );
            } else if (source.isClosed()) {
                throw new IllegalStateException("Source texture is closed");
            } else if (destination.isClosed()) {
                throw new IllegalStateException("Destination buffer is closed");
            } else if (source.getDepthOrLayers() > 1) {
                throw new UnsupportedOperationException("Textures with multiple depths or layers are not yet supported for copying");
            } else {
                this.backend.copyTextureToBuffer(source, destination, offset, callback, mipLevel, x, y, width, height);
            }
        } else {
            throw new IllegalArgumentException("Invalid mipLevel " + mipLevel + ", must be >= 0 and < " + source.getMipLevels());
        }
    }
 
    public void copyTextureToTexture(
        GpuTexture source, GpuTexture destination, int mipLevel, int destX, int destY, int sourceX, int sourceY, int width, int height
    ) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else if (mipLevel >= 0 && mipLevel < source.getMipLevels() && mipLevel < destination.getMipLevels()) {
            if (destX + width > destination.getWidth(mipLevel) || destY + height > destination.getHeight(mipLevel)) {
                throw new IllegalArgumentException(
                    "Dest texture ("
                        + destination.getWidth(mipLevel)
                        + "x"
                        + destination.getHeight(mipLevel)
                        + ") is not large enough to write a rectangle of "
                        + width
                        + "x"
                        + height
                        + " at "
                        + destX
                        + "x"
                        + destY
                );
            } else if (sourceX + width > source.getWidth(mipLevel) || sourceY + height > source.getHeight(mipLevel)) {
                throw new IllegalArgumentException(
                    "Source texture ("
                        + source.getWidth(mipLevel)
                        + "x"
                        + source.getHeight(mipLevel)
                        + ") is not large enough to read a rectangle of "
                        + width
                        + "x"
                        + height
                        + " at "
                        + sourceX
                        + "x"
                        + sourceY
                );
            } else if (source.isClosed()) {
                throw new IllegalStateException("Source texture is closed");
            } else if (destination.isClosed()) {
                throw new IllegalStateException("Destination texture is closed");
            } else if ((source.usage() & 2) == 0) {
                throw new IllegalArgumentException("Texture needs USAGE_COPY_SRC to be a source for a copy");
            } else if ((destination.usage() & 1) == 0) {
                throw new IllegalArgumentException("Texture needs USAGE_COPY_DST to be a destination for a copy");
            } else if (source.getDepthOrLayers() > 1) {
                throw new UnsupportedOperationException("Textures with multiple depths or layers are not yet supported for copying");
            } else if (destination.getDepthOrLayers() > 1) {
                throw new UnsupportedOperationException("Textures with multiple depths or layers are not yet supported for copying");
            } else {
                this.backend.copyTextureToTexture(source, destination, mipLevel, destX, destY, sourceX, sourceY, width, height);
            }
        } else {
            throw new IllegalArgumentException(
                "Invalid mipLevel " + mipLevel + ", must be >= 0 and < " + source.getMipLevels() + " and < " + destination.getMipLevels()
            );
        }
    }
 
    public void presentTexture(GpuTextureView textureView) {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else if (!textureView.texture().getFormat().hasColorAspect()) {
            throw new IllegalStateException("Cannot present a non-color texture!");
        } else if ((textureView.texture().usage() & 8) == 0) {
            throw new IllegalStateException("Color texture must have USAGE_RENDER_ATTACHMENT to presented to the screen");
        } else if (textureView.texture().getDepthOrLayers() > 1) {
            throw new UnsupportedOperationException("Textures with multiple depths or layers are not yet supported for presentation");
        } else {
            this.backend.presentTexture(textureView);
        }
    }
 
    public GpuFence createFence() {
        if (this.backend.isInRenderPass()) {
            throw new IllegalStateException("Close the existing render pass before performing additional commands");
        } else {
            return this.backend.createFence();
        }
    }
 
    public GpuQuery timerQueryBegin() {
        return this.backend.timerQueryBegin();
    }
 
    public void timerQueryEnd(GpuQuery query) {
        this.backend.timerQueryEnd(query);
    }
 
    private void verifyColorTexture(GpuTexture colorTexture) {
        if (!colorTexture.getFormat().hasColorAspect()) {
            throw new IllegalStateException("Trying to clear a non-color texture as color");
        } else if (colorTexture.isClosed()) {
            throw new IllegalStateException("Color texture is closed");
        } else if ((colorTexture.usage() & 8) == 0) {
            throw new IllegalStateException("Color texture must have USAGE_RENDER_ATTACHMENT");
        } else if ((colorTexture.usage() & 1) == 0) {
            throw new IllegalStateException("Color texture must have USAGE_COPY_DST");
        } else if (colorTexture.getDepthOrLayers() > 1) {
            throw new UnsupportedOperationException("Clearing a texture with multiple layers or depths is not yet supported");
        }
    }
 
    private void verifyDepthTexture(GpuTexture depthTexture) {
        if (!depthTexture.getFormat().hasDepthAspect()) {
            throw new IllegalStateException("Trying to clear a non-depth texture as depth");
        } else if (depthTexture.isClosed()) {
            throw new IllegalStateException("Depth texture is closed");
        } else if ((depthTexture.usage() & 8) == 0) {
            throw new IllegalStateException("Depth texture must have USAGE_RENDER_ATTACHMENT");
        } else if ((depthTexture.usage() & 1) == 0) {
            throw new IllegalStateException("Depth texture must have USAGE_COPY_DST");
        } else if (depthTexture.getDepthOrLayers() > 1) {
            throw new UnsupportedOperationException("Clearing a texture with multiple layers or depths is not yet supported");
        }
    }
 
    private void verifyRegion(GpuTexture colorTexture, int regionX, int regionY, int regionWidth, int regionHeight) {
        if (regionX < 0 || regionX >= colorTexture.getWidth(0)) {
            throw new IllegalArgumentException("regionX should not be outside of the texture");
        } else if (regionY < 0 || regionY >= colorTexture.getHeight(0)) {
            throw new IllegalArgumentException("regionY should not be outside of the texture");
        } else if (regionWidth <= 0) {
            throw new IllegalArgumentException("regionWidth should be greater than 0");
        } else if (regionX + regionWidth > colorTexture.getWidth(0)) {
            throw new IllegalArgumentException("regionWidth + regionX should be less than the texture width");
        } else if (regionHeight <= 0) {
            throw new IllegalArgumentException("regionHeight should be greater than 0");
        } else if (regionY + regionHeight > colorTexture.getHeight(0)) {
            throw new IllegalArgumentException("regionWidth + regionX should be less than the texture height");
        }
    }
}

引用的其他类