mojira.dev
MC-308281

OpenGL MultiDraw crash due to missing element buffer bind

The new multi draw functionality is missing the element buffer bind on the OpenGL backend (GlCommandEncoder) resulting in a crash.

Comments 2

Hi!
Thank you for your report! 

Could you please provide more details or/and media files. As we have no repro of this issue. 

Also, just a reminder, to make your bug report as effective as possible, please try and include the following steps to reproduce the problem: 

Steps to Reproduce: 

  1.  

  2.  

  3.  

Observed Results: 

(Briefly describe what happens) 

Expected Results: 

(Briefly describe what should happen) 

Quick Links: 
📓 Issue Guidelines – 💬 Mojang Support – 📧 Suggestions – 📖 Minecraft Wiki

Since this functionality was introduced exclusively for mod devs (not used in vanilla minecraft) there is no way to reproduce this crash without a mod.

Basically this function in GlCommandEncoder misses the index buffer binding

	public void executeDraws(
		final GlRenderPass renderPass,
		@Nullable final IndexType indexType,
		@Nullable final PointerBuffer firstIndexOffsets,
		final IntBuffer indexCounts,
		final IntBuffer vertexOffsets,
		final int drawCount
	) {
		if (this.trySetup(renderPass, Collections.emptyList())) {
			this.validateDraw(renderPass, indexType);
			this.lastVertexArray = this.device
				.vertexArrayCache()
				.bindVertexArray(renderPass.pipeline.info().getVertexFormatBindings(), renderPass.vertexBuffers, renderPass.vertexBufferDirty ? null : this.lastVertexArray);
			renderPass.vertexBufferDirty = false;
			if (indexType == null) {
				GL33C.nglMultiDrawArrays(
					GlConst.toGl(renderPass.pipeline.info().getPrimitiveTopology()), MemoryUtil.memAddress(vertexOffsets), MemoryUtil.memAddress(indexCounts), drawCount
				);
			} else {
				assert firstIndexOffsets != null;


				GL33C.nglMultiDrawElementsBaseVertex(
					GlConst.toGl(renderPass.pipeline.info().getPrimitiveTopology()),
					MemoryUtil.memAddress(indexCounts),
					GlConst.toGl(indexType),
					MemoryUtil.memAddress(firstIndexOffsets),
					drawCount,
					MemoryUtil.memAddress(vertexOffsets)
				);
			}
		}
	}

Here is the other function in GlCommandEncoder which actually properly binds the index buffer

	private void drawFromBuffers(
		final GlRenderPass renderPass,
		final int baseVertex,
		final int firstIndex,
		final int drawCount,
		@Nullable final IndexType indexType,
		final GlRenderPipeline pipeline,
		final int instanceCount,
		final int firstInstance
	) {
		if (indexType != null) {
--->		GlStateManager._glBindBuffer(34963, ((GlBuffer)renderPass.indexBuffer).handle());
			if (firstInstance > 0) {
				ARBBaseInstance.glDrawElementsInstancedBaseVertexBaseInstance(
					GlConst.toGl(pipeline.info().getPrimitiveTopology()),
					drawCount,
					GlConst.toGl(indexType),
					(long)firstIndex * indexType.bytes,
					instanceCount,
					baseVertex,
					firstInstance
				);
			} else {
				GL33C.glDrawElementsInstancedBaseVertex(
					GlConst.toGl(pipeline.info().getPrimitiveTopology()), drawCount, GlConst.toGl(indexType), (long)firstIndex * indexType.bytes, instanceCount, baseVertex
				);
			}
		} else if (firstInstance > 0) {
			ARBBaseInstance.glDrawArraysInstancedBaseInstance(GlConst.toGl(pipeline.info().getPrimitiveTopology()), baseVertex, drawCount, instanceCount, firstInstance);
		} else {
			GL33C.glDrawArraysInstanced(GlConst.toGl(pipeline.info().getPrimitiveTopology()), baseVertex, drawCount, instanceCount);
		}
	}

haubner

RogueLogix

Plausible

Platform G

Normal

Rendering

26.2 Snapshot 8

26.2 Pre-Release 2

Retrieved