GlCommandEncoder.java
com.mojang.blaze3d.opengl.GlCommandEncoder
信息
- 全限定名:com.mojang.blaze3d.opengl.GlCommandEncoder
- 类型:package-private class
- 包:com.mojang.blaze3d.opengl
- 源码路径:src/main/java/com/mojang/blaze3d/opengl/GlCommandEncoder.java
- 起始行号:L44
- 实现:CommandEncoderBackend
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
device- 类型:
GlDevice - 修饰符:
private final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
readFbo- 类型:
int - 修饰符:
private final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
drawFbo- 类型:
int - 修饰符:
private final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
lastPipeline- 类型:
RenderPipeline - 修饰符:
private - 源码定位:
L49 - 说明:
TODO
- 类型:
-
inRenderPass- 类型:
boolean - 修饰符:
private - 源码定位:
L50 - 说明:
TODO
- 类型:
-
lastProgram- 类型:
GlProgram - 修饰符:
private - 源码定位:
L51 - 说明:
TODO
- 类型:
-
activeTimerQuery- 类型:
GlTimerQuery - 修饰符:
private - 源码定位:
L52 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
protected GlCommandEncoder(GlDevice device) @ L54
- 构造器名:GlCommandEncoder
- 源码定位:L54
- 修饰符:protected
参数:
- device: GlDevice
说明:
TODO
方法
下面的方法块按源码顺序生成。
public RenderPassBackend createRenderPass(Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor) @ L60
- 方法名:createRenderPass
- 源码定位:L60
- 返回类型:RenderPassBackend
- 修饰符:public
参数:
- label: Supplier
- colorTexture: GpuTextureView
- clearColor: OptionalInt
说明:
TODO
public RenderPassBackend createRenderPass(Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor, GpuTextureView depthTexture, OptionalDouble clearDepth) @ L65
- 方法名:createRenderPass
- 源码定位:L65
- 返回类型:RenderPassBackend
- 修饰符:public
参数:
- label: Supplier
- colorTexture: GpuTextureView
- clearColor: OptionalInt
- depthTexture: GpuTextureView
- clearDepth: OptionalDouble
说明:
TODO
public boolean isInRenderPass() @ L97
- 方法名:isInRenderPass
- 源码定位:L97
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void clearColorTexture(GpuTexture colorTexture, int clearColor) @ L102
- 方法名:clearColorTexture
- 源码定位:L102
- 返回类型:void
- 修饰符:public
参数:
- colorTexture: GpuTexture
- clearColor: int
说明:
TODO
public void clearColorAndDepthTextures(GpuTexture colorTexture, int clearColor, GpuTexture depthTexture, double clearDepth) @ L113
- 方法名:clearColorAndDepthTextures
- 源码定位:L113
- 返回类型: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) @ L126
- 方法名:clearColorAndDepthTextures
- 源码定位:L126
- 返回类型: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) @ L142
- 方法名:clearDepthTexture
- 源码定位:L142
- 返回类型:void
- 修饰符:public
参数:
- depthTexture: GpuTexture
- clearDepth: double
说明:
TODO
public void writeToBuffer(GpuBufferSlice slice, ByteBuffer data) @ L155
- 方法名:writeToBuffer
- 源码定位:L155
- 返回类型:void
- 修饰符:public
参数:
- slice: GpuBufferSlice
- data: ByteBuffer
说明:
TODO
public GpuBuffer.MappedView mapBuffer(GpuBufferSlice slice, boolean read, boolean write) @ L184
- 方法名:mapBuffer
- 源码定位:L184
- 返回类型:GpuBuffer.MappedView
- 修饰符:public
参数:
- slice: GpuBufferSlice
- read: boolean
- write: boolean
说明:
TODO
public void copyToBuffer(GpuBufferSlice source, GpuBufferSlice target) @ L199
- 方法名:copyToBuffer
- 源码定位:L199
- 返回类型:void
- 修饰符:public
参数:
- source: GpuBufferSlice
- target: GpuBufferSlice
说明:
TODO
public void writeToTexture(GpuTexture destination, NativeImage source, int mipLevel, int depthOrLayer, int destX, int destY, int width, int height, int sourceX, int sourceY) @ L206
- 方法名:writeToTexture
- 源码定位:L206
- 返回类型: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) @ L226
- 方法名:writeToTexture
- 源码定位:L226
- 返回类型: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) @ L246
- 方法名:copyTextureToBuffer
- 源码定位:L246
- 返回类型: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) @ L251
- 方法名:copyTextureToBuffer
- 源码定位:L251
- 返回类型: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) @ L268
- 方法名:copyTextureToTexture
- 源码定位:L268
- 返回类型: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) @ L290
- 方法名:presentTexture
- 源码定位:L290
- 返回类型:void
- 修饰符:public
参数:
- textureView: GpuTextureView
说明:
TODO
public GpuFence createFence() @ L304
- 方法名:createFence
- 源码定位:L304
- 返回类型:GpuFence
- 修饰符:public
参数:
- 无
说明:
TODO
protected <T> void executeDrawMultiple(GlRenderPass renderPass, Collection<RenderPass.Draw<T>> draws, GpuBuffer defaultIndexBuffer, VertexFormat.IndexType defaultIndexType, Collection<String> dynamicUniforms, T uniformArgument) @ L309
- 方法名:executeDrawMultiple
- 源码定位:L309
- 返回类型:
void - 修饰符:protected
参数:
- renderPass: GlRenderPass
- draws: Collection<RenderPass.Draw
> - defaultIndexBuffer: GpuBuffer
- defaultIndexType: VertexFormat.IndexType
- dynamicUniforms: Collection
- uniformArgument: T
说明:
TODO
protected void executeDraw(GlRenderPass renderPass, int baseVertex, int firstIndex, int drawCount, VertexFormat.IndexType indexType, int instanceCount) @ L361
- 方法名:executeDraw
- 源码定位:L361
- 返回类型:void
- 修饰符:protected
参数:
- renderPass: GlRenderPass
- baseVertex: int
- firstIndex: int
- drawCount: int
- indexType: VertexFormat.IndexType
- instanceCount: int
说明:
TODO
private void drawFromBuffers(GlRenderPass renderPass, int baseVertex, int firstIndex, int drawCount, VertexFormat.IndexType indexType, GlRenderPipeline pipeline, int instanceCount) @ L398
- 方法名:drawFromBuffers
- 源码定位:L398
- 返回类型:void
- 修饰符:private
参数:
- renderPass: GlRenderPass
- baseVertex: int
- firstIndex: int
- drawCount: int
- indexType: VertexFormat.IndexType
- pipeline: GlRenderPipeline
- instanceCount: int
说明:
TODO
private boolean trySetup(GlRenderPass renderPass, Collection<String> dynamicUniforms) @ L445
- 方法名:trySetup
- 源码定位:L445
- 返回类型:boolean
- 修饰符:private
参数:
- renderPass: GlRenderPass
- dynamicUniforms: Collection
说明:
TODO
private void applyPipelineState(RenderPipeline pipeline) @ L610
- 方法名:applyPipelineState
- 源码定位:L610
- 返回类型:void
- 修饰符:private
参数:
- pipeline: RenderPipeline
说明:
TODO
public void finishRenderPass() @ L654
- 方法名:finishRenderPass
- 源码定位:L654
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public GpuQuery timerQueryBegin() @ L660
- 方法名:timerQueryBegin
- 源码定位:L660
- 返回类型:GpuQuery
- 修饰符:public
参数:
- 无
说明:
TODO
public void timerQueryEnd(GpuQuery query) @ L673
- 方法名:timerQueryEnd
- 源码定位:L673
- 返回类型:void
- 修饰符:public
参数:
- query: GpuQuery
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
class GlCommandEncoder implements CommandEncoderBackend {
private static final Logger LOGGER = LogUtils.getLogger();
private final GlDevice device;
private final int readFbo;
private final int drawFbo;
private @Nullable RenderPipeline lastPipeline;
private boolean inRenderPass;
private @Nullable GlProgram lastProgram;
private @Nullable GlTimerQuery activeTimerQuery;
protected GlCommandEncoder(GlDevice device) {
this.device = device;
this.readFbo = device.directStateAccess().createFrameBufferObject();
this.drawFbo = device.directStateAccess().createFrameBufferObject();
}
@Override
public RenderPassBackend createRenderPass(Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor) {
return this.createRenderPass(label, colorTexture, clearColor, null, OptionalDouble.empty());
}
@Override
public RenderPassBackend createRenderPass(
Supplier<String> label, GpuTextureView colorTexture, OptionalInt clearColor, @Nullable GpuTextureView depthTexture, OptionalDouble clearDepth
) {
this.inRenderPass = true;
this.device.debugLabels().pushDebugGroup(label);
int fbo = ((GlTextureView)colorTexture).getFbo(this.device.directStateAccess(), depthTexture == null ? null : depthTexture.texture());
GlStateManager._glBindFramebuffer(36160, fbo);
int clearMask = 0;
if (clearColor.isPresent()) {
int argb = clearColor.getAsInt();
GL11.glClearColor(ARGB.redFloat(argb), ARGB.greenFloat(argb), ARGB.blueFloat(argb), ARGB.alphaFloat(argb));
clearMask |= 16384;
}
if (depthTexture != null && clearDepth.isPresent()) {
GL11.glClearDepth(clearDepth.getAsDouble());
clearMask |= 256;
}
if (clearMask != 0) {
GlStateManager._disableScissorTest();
GlStateManager._depthMask(true);
GlStateManager._colorMask(15);
GlStateManager._clear(clearMask);
}
GlStateManager._viewport(0, 0, colorTexture.getWidth(0), colorTexture.getHeight(0));
this.lastPipeline = null;
return new GlRenderPass(this, this.device, depthTexture != null);
}
@Override
public boolean isInRenderPass() {
return this.inRenderPass;
}
@Override
public void clearColorTexture(GpuTexture colorTexture, int clearColor) {
this.device.directStateAccess().bindFrameBufferTextures(this.drawFbo, ((GlTexture)colorTexture).id, 0, 0, 36160);
GL11.glClearColor(ARGB.redFloat(clearColor), ARGB.greenFloat(clearColor), ARGB.blueFloat(clearColor), ARGB.alphaFloat(clearColor));
GlStateManager._disableScissorTest();
GlStateManager._colorMask(15);
GlStateManager._clear(16384);
GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, 0, 0);
GlStateManager._glBindFramebuffer(36160, 0);
}
@Override
public void clearColorAndDepthTextures(GpuTexture colorTexture, int clearColor, GpuTexture depthTexture, double clearDepth) {
int fbo = ((GlTexture)colorTexture).getFbo(this.device.directStateAccess(), depthTexture);
GlStateManager._glBindFramebuffer(36160, fbo);
GlStateManager._disableScissorTest();
GL11.glClearDepth(clearDepth);
GL11.glClearColor(ARGB.redFloat(clearColor), ARGB.greenFloat(clearColor), ARGB.blueFloat(clearColor), ARGB.alphaFloat(clearColor));
GlStateManager._depthMask(true);
GlStateManager._colorMask(15);
GlStateManager._clear(16640);
GlStateManager._glBindFramebuffer(36160, 0);
}
@Override
public void clearColorAndDepthTextures(
GpuTexture colorTexture, int clearColor, GpuTexture depthTexture, double clearDepth, int regionX, int regionY, int regionWidth, int regionHeight
) {
int fbo = ((GlTexture)colorTexture).getFbo(this.device.directStateAccess(), depthTexture);
GlStateManager._glBindFramebuffer(36160, fbo);
GlStateManager._scissorBox(regionX, regionY, regionWidth, regionHeight);
GlStateManager._enableScissorTest();
GL11.glClearDepth(clearDepth);
GL11.glClearColor(ARGB.redFloat(clearColor), ARGB.greenFloat(clearColor), ARGB.blueFloat(clearColor), ARGB.alphaFloat(clearColor));
GlStateManager._depthMask(true);
GlStateManager._colorMask(15);
GlStateManager._clear(16640);
GlStateManager._glBindFramebuffer(36160, 0);
}
@Override
public void clearDepthTexture(GpuTexture depthTexture, double clearDepth) {
this.device.directStateAccess().bindFrameBufferTextures(this.drawFbo, 0, ((GlTexture)depthTexture).id, 0, 36160);
GL11.glDrawBuffer(0);
GL11.glClearDepth(clearDepth);
GlStateManager._depthMask(true);
GlStateManager._disableScissorTest();
GlStateManager._clear(256);
GL11.glDrawBuffer(36064);
GlStateManager._glFramebufferTexture2D(36160, 36096, 3553, 0, 0);
GlStateManager._glBindFramebuffer(36160, 0);
}
@Override
public void writeToBuffer(GpuBufferSlice slice, ByteBuffer data) {
GlBuffer buffer = (GlBuffer)slice.buffer();
if (buffer.closed) {
throw new IllegalStateException("Buffer already closed");
} else if ((buffer.usage() & 8) == 0) {
throw new IllegalStateException("Buffer needs USAGE_COPY_DST to be a destination for a copy");
} else {
int length = data.remaining();
if (length > slice.length()) {
throw new IllegalArgumentException(
"Cannot write more data than the slice allows (attempting to write " + length + " bytes into a slice of length " + slice.length() + ")"
);
} else if (slice.length() + slice.offset() > buffer.size()) {
throw new IllegalArgumentException(
"Cannot write more data than this buffer can hold (attempting to write "
+ length
+ " bytes at offset "
+ slice.offset()
+ " to "
+ buffer.size()
+ " size buffer)"
);
} else {
this.device.directStateAccess().bufferSubData(buffer.handle, slice.offset(), data, buffer.usage());
}
}
}
@Override
public GpuBuffer.MappedView mapBuffer(GpuBufferSlice slice, boolean read, boolean write) {
GlBuffer buffer = (GlBuffer)slice.buffer();
int flags = 0;
if (read) {
flags |= 1;
}
if (write) {
flags |= 34;
}
return this.device.getBufferStorage().mapBuffer(this.device.directStateAccess(), buffer, slice.offset(), slice.length(), flags);
}
@Override
public void copyToBuffer(GpuBufferSlice source, GpuBufferSlice target) {
GlBuffer sourceBuffer = (GlBuffer)source.buffer();
GlBuffer targetBuffer = (GlBuffer)target.buffer();
this.device.directStateAccess().copyBufferSubData(sourceBuffer.handle, targetBuffer.handle, source.offset(), target.offset(), source.length());
}
@Override
public void writeToTexture(
GpuTexture destination, NativeImage source, int mipLevel, int depthOrLayer, int destX, int destY, int width, int height, int sourceX, int sourceY
) {
int target;
if ((destination.usage() & 16) != 0) {
target = GlConst.CUBEMAP_TARGETS[depthOrLayer % 6];
GL11.glBindTexture(34067, ((GlTexture)destination).id);
} else {
target = 3553;
GlStateManager._bindTexture(((GlTexture)destination).id);
}
GlStateManager._pixelStore(3314, source.getWidth());
GlStateManager._pixelStore(3316, sourceX);
GlStateManager._pixelStore(3315, sourceY);
GlStateManager._pixelStore(3317, source.format().components());
GlStateManager._texSubImage2D(target, mipLevel, destX, destY, width, height, GlConst.toGl(source.format()), 5121, source.getPointer());
}
@Override
public void writeToTexture(
GpuTexture destination, ByteBuffer source, NativeImage.Format format, int mipLevel, int depthOrLayer, int destX, int destY, int width, int height
) {
int target;
if ((destination.usage() & 16) != 0) {
target = GlConst.CUBEMAP_TARGETS[depthOrLayer % 6];
GL11.glBindTexture(34067, ((GlTexture)destination).id);
} else {
target = 3553;
GlStateManager._bindTexture(((GlTexture)destination).id);
}
GlStateManager._pixelStore(3314, width);
GlStateManager._pixelStore(3316, 0);
GlStateManager._pixelStore(3315, 0);
GlStateManager._pixelStore(3317, format.components());
GlStateManager._texSubImage2D(target, mipLevel, destX, destY, width, height, GlConst.toGl(format), 5121, source);
}
@Override
public void copyTextureToBuffer(GpuTexture source, GpuBuffer destination, long offset, Runnable callback, int mipLevel) {
this.copyTextureToBuffer(source, destination, offset, callback, mipLevel, 0, 0, source.getWidth(mipLevel), source.getHeight(mipLevel));
}
@Override
public void copyTextureToBuffer(GpuTexture source, GpuBuffer destination, long offset, Runnable callback, int mipLevel, int x, int y, int width, int height) {
GlStateManager.clearGlErrors();
this.device.directStateAccess().bindFrameBufferTextures(this.readFbo, ((GlTexture)source).glId(), 0, mipLevel, 36008);
GlStateManager._glBindBuffer(35051, ((GlBuffer)destination).handle);
GlStateManager._pixelStore(3330, width);
GlStateManager._readPixels(x, y, width, height, GlConst.toGlExternalId(source.getFormat()), GlConst.toGlType(source.getFormat()), offset);
RenderSystem.queueFencedTask(callback);
GlStateManager._glFramebufferTexture2D(36008, 36064, 3553, 0, mipLevel);
GlStateManager._glBindFramebuffer(36008, 0);
GlStateManager._glBindBuffer(35051, 0);
int error = GlStateManager._getError();
if (error != 0) {
throw new IllegalStateException("Couldn't perform copyTobuffer for texture " + source.getLabel() + ": GL error " + error);
}
}
@Override
public void copyTextureToTexture(
GpuTexture source, GpuTexture destination, int mipLevel, int destX, int destY, int sourceX, int sourceY, int width, int height
) {
GlStateManager.clearGlErrors();
GlStateManager._disableScissorTest();
boolean isDepth = source.getFormat().hasDepthAspect();
int sourceId = ((GlTexture)source).glId();
int destId = ((GlTexture)destination).glId();
this.device.directStateAccess().bindFrameBufferTextures(this.readFbo, isDepth ? 0 : sourceId, isDepth ? sourceId : 0, 0, 0);
this.device.directStateAccess().bindFrameBufferTextures(this.drawFbo, isDepth ? 0 : destId, isDepth ? destId : 0, 0, 0);
this.device
.directStateAccess()
.blitFrameBuffers(this.readFbo, this.drawFbo, sourceX, sourceY, width, height, destX, destY, width, height, isDepth ? 256 : 16384, 9728);
int error = GlStateManager._getError();
if (error != 0) {
throw new IllegalStateException(
"Couldn't perform copyToTexture for texture " + source.getLabel() + " to " + destination.getLabel() + ": GL error " + error
);
}
}
@Override
public void presentTexture(GpuTextureView textureView) {
GlStateManager._disableScissorTest();
GlStateManager._viewport(0, 0, textureView.getWidth(0), textureView.getHeight(0));
GlStateManager._depthMask(true);
GlStateManager._colorMask(15);
this.device.directStateAccess().bindFrameBufferTextures(this.drawFbo, ((GlTexture)textureView.texture()).glId(), 0, 0, 0);
this.device
.directStateAccess()
.blitFrameBuffers(
this.drawFbo, 0, 0, 0, textureView.getWidth(0), textureView.getHeight(0), 0, 0, textureView.getWidth(0), textureView.getHeight(0), 16384, 9728
);
}
@Override
public GpuFence createFence() {
return new GlFence();
}
protected <T> void executeDrawMultiple(
GlRenderPass renderPass,
Collection<RenderPass.Draw<T>> draws,
@Nullable GpuBuffer defaultIndexBuffer,
VertexFormat.@Nullable IndexType defaultIndexType,
Collection<String> dynamicUniforms,
T uniformArgument
) {
if (this.trySetup(renderPass, dynamicUniforms)) {
if (defaultIndexType == null) {
defaultIndexType = VertexFormat.IndexType.SHORT;
}
for (RenderPass.Draw<T> draw : draws) {
VertexFormat.IndexType indexType = draw.indexType() == null ? defaultIndexType : draw.indexType();
renderPass.setIndexBuffer(draw.indexBuffer() == null ? defaultIndexBuffer : draw.indexBuffer(), indexType);
renderPass.setVertexBuffer(draw.slot(), draw.vertexBuffer());
if (GlRenderPass.VALIDATION) {
if (renderPass.indexBuffer == null) {
throw new IllegalStateException("Missing index buffer");
}
if (renderPass.indexBuffer.isClosed()) {
throw new IllegalStateException("Index buffer has been closed!");
}
if (renderPass.vertexBuffers[0] == null) {
throw new IllegalStateException("Missing vertex buffer at slot 0");
}
if (renderPass.vertexBuffers[0].isClosed()) {
throw new IllegalStateException("Vertex buffer at slot 0 has been closed!");
}
}
BiConsumer<T, RenderPass.UniformUploader> uniformUploaderConsumer = draw.uniformUploaderConsumer();
if (uniformUploaderConsumer != null) {
uniformUploaderConsumer.accept(uniformArgument, (name, buffer) -> {
if (renderPass.pipeline.program().getUniform(name) instanceof Uniform.Ubo(int var9x)) {
int patt2$temp = var9x;
if (true) {
GL32.glBindBufferRange(35345, patt2$temp, ((GlBuffer)buffer.buffer()).handle, buffer.offset(), buffer.length());
}
}
});
}
this.drawFromBuffers(renderPass, draw.baseVertex(), draw.firstIndex(), draw.indexCount(), indexType, renderPass.pipeline, 1);
}
}
}
protected void executeDraw(
GlRenderPass renderPass, int baseVertex, int firstIndex, int drawCount, VertexFormat.@Nullable IndexType indexType, int instanceCount
) {
if (this.trySetup(renderPass, Collections.emptyList())) {
if (GlRenderPass.VALIDATION) {
if (indexType != null) {
if (renderPass.indexBuffer == null) {
throw new IllegalStateException("Missing index buffer");
}
if (renderPass.indexBuffer.isClosed()) {
throw new IllegalStateException("Index buffer has been closed!");
}
if ((renderPass.indexBuffer.usage() & 64) == 0) {
throw new IllegalStateException("Index buffer must have GpuBuffer.USAGE_INDEX!");
}
}
GlRenderPipeline pipeline = renderPass.pipeline;
if (renderPass.vertexBuffers[0] == null && pipeline != null && !pipeline.info().getVertexFormat().getElements().isEmpty()) {
throw new IllegalStateException("Vertex format contains elements but vertex buffer at slot 0 is null");
}
if (renderPass.vertexBuffers[0] != null && renderPass.vertexBuffers[0].isClosed()) {
throw new IllegalStateException("Vertex buffer at slot 0 has been closed!");
}
if (renderPass.vertexBuffers[0] != null && (renderPass.vertexBuffers[0].usage() & 32) == 0) {
throw new IllegalStateException("Vertex buffer must have GpuBuffer.USAGE_VERTEX!");
}
}
this.drawFromBuffers(renderPass, baseVertex, firstIndex, drawCount, indexType, renderPass.pipeline, instanceCount);
}
}
private void drawFromBuffers(
GlRenderPass renderPass,
int baseVertex,
int firstIndex,
int drawCount,
VertexFormat.@Nullable IndexType indexType,
GlRenderPipeline pipeline,
int instanceCount
) {
this.device.vertexArrayCache().bindVertexArray(pipeline.info().getVertexFormat(), (GlBuffer)renderPass.vertexBuffers[0]);
if (indexType != null) {
GlStateManager._glBindBuffer(34963, ((GlBuffer)renderPass.indexBuffer).handle);
if (instanceCount > 1) {
if (baseVertex > 0) {
GL32.glDrawElementsInstancedBaseVertex(
GlConst.toGl(pipeline.info().getVertexFormatMode()),
drawCount,
GlConst.toGl(indexType),
(long)firstIndex * indexType.bytes,
instanceCount,
baseVertex
);
} else {
GL31.glDrawElementsInstanced(
GlConst.toGl(pipeline.info().getVertexFormatMode()),
drawCount,
GlConst.toGl(indexType),
(long)firstIndex * indexType.bytes,
instanceCount
);
}
} else if (baseVertex > 0) {
GL32.glDrawElementsBaseVertex(
GlConst.toGl(pipeline.info().getVertexFormatMode()), drawCount, GlConst.toGl(indexType), (long)firstIndex * indexType.bytes, baseVertex
);
} else {
GlStateManager._drawElements(
GlConst.toGl(pipeline.info().getVertexFormatMode()), drawCount, GlConst.toGl(indexType), (long)firstIndex * indexType.bytes
);
}
} else if (instanceCount > 1) {
GL31.glDrawArraysInstanced(GlConst.toGl(pipeline.info().getVertexFormatMode()), baseVertex, drawCount, instanceCount);
} else {
GlStateManager._drawArrays(GlConst.toGl(pipeline.info().getVertexFormatMode()), baseVertex, drawCount);
}
}
private boolean trySetup(GlRenderPass renderPass, Collection<String> dynamicUniforms) {
if (GlRenderPass.VALIDATION) {
if (renderPass.pipeline == null) {
throw new IllegalStateException("Can't draw without a render pipeline");
}
if (renderPass.pipeline.program() == GlProgram.INVALID_PROGRAM) {
throw new IllegalStateException("Pipeline contains invalid shader program");
}
for (RenderPipeline.UniformDescription uniform : renderPass.pipeline.info().getUniforms()) {
GpuBufferSlice value = renderPass.uniforms.get(uniform.name());
if (!dynamicUniforms.contains(uniform.name())) {
if (value == null) {
throw new IllegalStateException("Missing uniform " + uniform.name() + " (should be " + uniform.type() + ")");
}
if (uniform.type() == UniformType.UNIFORM_BUFFER) {
if (value.buffer().isClosed()) {
throw new IllegalStateException("Uniform buffer " + uniform.name() + " is already closed");
}
if ((value.buffer().usage() & 128) == 0) {
throw new IllegalStateException("Uniform buffer " + uniform.name() + " must have GpuBuffer.USAGE_UNIFORM");
}
}
if (uniform.type() == UniformType.TEXEL_BUFFER) {
if (value.offset() != 0L || value.length() != value.buffer().size()) {
throw new IllegalStateException("Uniform texel buffers do not support a slice of a buffer, must be entire buffer");
}
if (uniform.textureFormat() == null) {
throw new IllegalStateException("Invalid uniform texel buffer " + uniform.name() + " (missing a texture format)");
}
}
}
}
for (Entry<String, Uniform> entry : renderPass.pipeline.program().getUniforms().entrySet()) {
if (entry.getValue() instanceof Uniform.Sampler) {
String name = entry.getKey();
GlRenderPass.TextureViewAndSampler viewAndSampler = renderPass.samplers.get(name);
if (viewAndSampler == null) {
throw new IllegalStateException("Missing sampler " + name);
}
GlTextureView textureView = viewAndSampler.view();
if (textureView.isClosed()) {
throw new IllegalStateException("Texture view " + name + " (" + textureView.texture().getLabel() + ") has been closed!");
}
if ((textureView.texture().usage() & 4) == 0) {
throw new IllegalStateException("Texture view " + name + " (" + textureView.texture().getLabel() + ") must have USAGE_TEXTURE_BINDING!");
}
if (viewAndSampler.sampler().isClosed()) {
throw new IllegalStateException("Sampler for " + name + " (" + textureView.texture().getLabel() + ") has been closed!");
}
}
}
if (renderPass.pipeline.info().wantsDepthTexture() && !renderPass.hasDepthTexture()) {
LOGGER.warn("Render pipeline {} wants a depth texture but none was provided - this is probably a bug", renderPass.pipeline.info().getLocation());
}
} else if (renderPass.pipeline == null || renderPass.pipeline.program() == GlProgram.INVALID_PROGRAM) {
return false;
}
RenderPipeline pipeline = renderPass.pipeline.info();
GlProgram glProgram = renderPass.pipeline.program();
this.applyPipelineState(pipeline);
boolean differentProgram = this.lastProgram != glProgram;
if (differentProgram) {
GlStateManager._glUseProgram(glProgram.getProgramId());
this.lastProgram = glProgram;
}
label200:
for (Entry<String, Uniform> entryx : glProgram.getUniforms().entrySet()) {
String namex = entryx.getKey();
boolean isDirty = renderPass.dirtyUniforms.contains(namex);
Uniform var10000 = entryx.getValue();
Objects.requireNonNull(var10000);
Uniform var10 = var10000;
byte var11 = 0;
{
switch (var10) {
case Uniform.Ubo var12:
int var63;
Uniform.Ubo var62 = var12;
try {
var63 = var62.blockBinding();
} catch (Throwable var32) {
throw new MatchException(var32.toString(), var32);
}
int var41 = var63;
if (true) {
if (isDirty) {
GpuBufferSlice bufferView = renderPass.uniforms.get(namex);
GL32.glBindBufferRange(35345, var41, ((GlBuffer)bufferView.buffer()).handle, bufferView.offset(), bufferView.length());
}
continue label200;
}
var11 = 1;
break;
case Uniform.Utb(int location, int samplerIdx, TextureFormat var45, int var43):
if (differentProgram || isDirty) {
GlStateManager._glUniform1i(location, samplerIdx);
}
GlStateManager._activeTexture(33984 + samplerIdx);
GL11C.glBindTexture(35882, var43);
if (isDirty) {
GpuBufferSlice bufferViewx = renderPass.uniforms.get(namex);
GL31.glTexBuffer(35882, GlConst.toGlInternalId(var45), ((GlBuffer)bufferViewx.buffer()).handle);
}
continue label200;
case Uniform.Sampler(int location, int samplerIndex):
GlRenderPass.TextureViewAndSampler viewAndSamplerxx = renderPass.samplers.get(namex);
if (viewAndSamplerxx == null) {
continue label200;
}
GlTextureView textureViewx = viewAndSamplerxx.view();
if (differentProgram || isDirty) {
GlStateManager._glUniform1i(location, samplerIndex);
}
GlStateManager._activeTexture(33984 + samplerIndex);
GlTexture texture = textureViewx.texture();
int target;
if ((texture.usage() & 16) != 0) {
target = 34067;
GL11.glBindTexture(34067, texture.id);
} else {
target = 3553;
GlStateManager._bindTexture(texture.id);
}
GL33C.glBindSampler(samplerIndex, viewAndSamplerxx.sampler().getId());
GlStateManager._texParameter(target, 33084, textureViewx.baseMipLevel());
GlStateManager._texParameter(target, 33085, textureViewx.baseMipLevel() + textureViewx.mipLevels() - 1);
continue label200;
default:
throw new MatchException(null, null);
}
}
}
renderPass.dirtyUniforms.clear();
if (renderPass.isScissorEnabled()) {
GlStateManager._enableScissorTest();
GlStateManager._scissorBox(renderPass.getScissorX(), renderPass.getScissorY(), renderPass.getScissorWidth(), renderPass.getScissorHeight());
} else {
GlStateManager._disableScissorTest();
}
return true;
}
private void applyPipelineState(RenderPipeline pipeline) {
if (this.lastPipeline != pipeline) {
this.lastPipeline = pipeline;
DepthStencilState depthStencilState = pipeline.getDepthStencilState();
if (depthStencilState != null) {
GlStateManager._enableDepthTest();
GlStateManager._depthFunc(GlConst.toGl(depthStencilState.depthTest()));
GlStateManager._depthMask(depthStencilState.writeDepth());
if (depthStencilState.depthBiasConstant() == 0.0F && depthStencilState.depthBiasScaleFactor() == 0.0F) {
GlStateManager._disablePolygonOffset();
} else {
GlStateManager._polygonOffset(depthStencilState.depthBiasScaleFactor(), depthStencilState.depthBiasConstant());
GlStateManager._enablePolygonOffset();
}
} else {
GlStateManager._disableDepthTest();
GlStateManager._depthMask(false);
GlStateManager._disablePolygonOffset();
}
if (pipeline.isCull()) {
GlStateManager._enableCull();
} else {
GlStateManager._disableCull();
}
if (pipeline.getColorTargetState().blendFunction().isPresent()) {
GlStateManager._enableBlend();
BlendFunction blendFunction = pipeline.getColorTargetState().blendFunction().get();
GlStateManager._blendFuncSeparate(
GlConst.toGl(blendFunction.sourceColor()),
GlConst.toGl(blendFunction.destColor()),
GlConst.toGl(blendFunction.sourceAlpha()),
GlConst.toGl(blendFunction.destAlpha())
);
} else {
GlStateManager._disableBlend();
}
GlStateManager._polygonMode(1032, GlConst.toGl(pipeline.getPolygonMode()));
GlStateManager._colorMask(pipeline.getColorTargetState().writeMask());
}
}
public void finishRenderPass() {
this.inRenderPass = false;
GlStateManager._glBindFramebuffer(36160, 0);
this.device.debugLabels().popDebugGroup();
}
@Override
public GpuQuery timerQueryBegin() {
RenderSystem.assertOnRenderThread();
if (this.activeTimerQuery != null) {
throw new IllegalStateException("A GL_TIME_ELAPSED query is already active");
} else {
int queryId = GL32C.glGenQueries();
GL32C.glBeginQuery(35007, queryId);
this.activeTimerQuery = new GlTimerQuery(queryId);
return this.activeTimerQuery;
}
}
@Override
public void timerQueryEnd(GpuQuery query) {
RenderSystem.assertOnRenderThread();
if (query != this.activeTimerQuery) {
throw new IllegalStateException("Mismatched or duplicate GpuQuery when ending timerQuery");
} else {
GL32C.glEndQuery(35007);
this.activeTimerQuery = null;
}
}
}引用的其他类
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
GlConst.toGl(), GlConst.toGlExternalId(), GlConst.toGlInternalId(), GlConst.toGlType()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GlFence()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
GlRenderPass()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
GlStateManager._activeTexture(), GlStateManager._bindTexture(), GlStateManager._blendFuncSeparate(), GlStateManager._clear(), GlStateManager._colorMask(), GlStateManager._depthFunc(), GlStateManager._depthMask(), GlStateManager._disableBlend(), GlStateManager._disableCull(), GlStateManager._disableDepthTest(), GlStateManager._disablePolygonOffset(), GlStateManager._disableScissorTest(), GlStateManager._drawArrays(), GlStateManager._drawElements(), GlStateManager._enableBlend(), GlStateManager._enableCull(), GlStateManager._enableDepthTest(), GlStateManager._enablePolygonOffset(), GlStateManager._enableScissorTest(), GlStateManager._getError(), GlStateManager._glBindBuffer(), GlStateManager._glBindFramebuffer(), GlStateManager._glFramebufferTexture2D(), GlStateManager._glUniform1i(), GlStateManager._glUseProgram(), GlStateManager._pixelStore(), GlStateManager._polygonMode(), GlStateManager._polygonOffset(), GlStateManager._readPixels(), GlStateManager._scissorBox(), GlStateManager._texParameter(), GlStateManager._texSubImage2D(), GlStateManager._viewport(), GlStateManager.clearGlErrors()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
GlTimerQuery()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Uniform.Sampler(), Uniform.Ubo(), Uniform.Utb()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RenderSystem.assertOnRenderThread(), RenderSystem.queueFencedTask()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ARGB.alphaFloat(), ARGB.blueFloat(), ARGB.greenFloat(), ARGB.redFloat()
- 引用位置: