From df439e60f725144f7e2ae699cc9cdda0f4b8adaf Mon Sep 17 00:00:00 2001 From: tanmaysachan Date: Sun, 10 Nov 2024 23:46:10 +0530 Subject: [PATCH] Fix resolve logic --- src/metal/rt64_metal.h | 21 +++++++++++ src/metal/rt64_metal.mm | 81 +++++++++++++++++++++++++++++++---------- 2 files changed, 83 insertions(+), 19 deletions(-) diff --git a/src/metal/rt64_metal.h b/src/metal/rt64_metal.h index 3eb0f67..51224f9 100755 --- a/src/metal/rt64_metal.h +++ b/src/metal/rt64_metal.h @@ -164,6 +164,26 @@ namespace RT64 { id computePushConstantsBuffer = nil; std::map, id> resolveTo; + + struct DrawCall { + enum class Type { + Draw, + DrawIndexed + }; + Type type; + MTLPrimitiveType primitiveType = MTLPrimitiveTypeTriangle; + uint32_t startVertexLocation = 0; + uint32_t vertexCountPerInstance = 0; + uint32_t instanceCount = 0; + uint32_t startInstanceLocation = 0; + + uint32_t indexCountPerInstance = 0; + MTLIndexType indexType = MTLIndexTypeUInt32; + id indexBuffer = nil; + int32_t baseVertexLocation = 0; + uint32_t startIndexLocation = 0; + }; + std::vector deferredDrawCalls; #endif MetalDevice *device = nullptr; @@ -192,6 +212,7 @@ namespace RT64 { void guaranteeRenderEncoder(); void guaranteeComputeEncoder(); void guaranteeBlitEncoder(); + void clearDrawCalls(); void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override; void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override; void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override; diff --git a/src/metal/rt64_metal.mm b/src/metal/rt64_metal.mm index 4af507f..f6f28fc 100755 --- a/src/metal/rt64_metal.mm +++ b/src/metal/rt64_metal.mm @@ -1168,6 +1168,7 @@ namespace RT64 { } void MetalCommandList::endEncoder(bool clearDescs) { + clearDrawCalls(); if (renderEncoder != nil) { [renderEncoder endEncoding]; if (clearDescs) { @@ -1188,6 +1189,32 @@ namespace RT64 { blitEncoder = nil; } + void MetalCommandList::clearDrawCalls() { + if (!deferredDrawCalls.empty()) { + guaranteeRenderEncoder(); + } + for (auto &drawCall : deferredDrawCalls) { + if (drawCall.type == DrawCall::Type::Draw) { + [renderEncoder drawPrimitives: drawCall.primitiveType + vertexStart: drawCall.startVertexLocation + vertexCount: drawCall.vertexCountPerInstance + instanceCount: drawCall.instanceCount + baseInstance: drawCall.startInstanceLocation]; + } else if (drawCall.type == DrawCall::Type::DrawIndexed) { + [renderEncoder drawIndexedPrimitives: drawCall.primitiveType + indexCount: drawCall.indexCountPerInstance + indexType: drawCall.indexType + indexBuffer: drawCall.indexBuffer + indexBufferOffset: drawCall.startIndexLocation + instanceCount: drawCall.instanceCount + baseVertex: drawCall.baseVertexLocation + baseInstance: drawCall.startInstanceLocation]; + } + } + + deferredDrawCalls.clear(); + } + void MetalCommandList::guaranteeRenderDescriptor() { if (renderDescriptor == nil) { assert(targetFramebuffer != nullptr && "Cannot encode render commands without a target framebuffer"); @@ -1251,8 +1278,6 @@ namespace RT64 { void MetalCommandList::guaranteeRenderEncoder() { if (renderEncoder == nil) { - endEncoder(false); - guaranteeRenderDescriptor(); renderEncoder = [queue->buffer renderCommandEncoderWithDescriptor: renderDescriptor]; @@ -1339,28 +1364,46 @@ namespace RT64 { } void MetalCommandList::drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) { - guaranteeRenderEncoder(); - assert(renderEncoder != nil && "Cannot encode draw on nil MTLRenderCommandEncoder!"); +// guaranteeRenderEncoder(); +// assert(renderEncoder != nil && "Cannot encode draw on nil MTLRenderCommandEncoder!"); - [renderEncoder drawPrimitives: currentPrimitiveType - vertexStart: startVertexLocation - vertexCount: vertexCountPerInstance - instanceCount: instanceCount - baseInstance: startInstanceLocation]; +// [renderEncoder drawPrimitives: currentPrimitiveType +// vertexStart: startVertexLocation +// vertexCount: vertexCountPerInstance +// instanceCount: instanceCount +// baseInstance: startInstanceLocation]; + + deferredDrawCalls.emplace_back(DrawCall{ + .type = DrawCall::Type::Draw, + .startVertexLocation = startVertexLocation, + .vertexCountPerInstance = vertexCountPerInstance, + .instanceCount = instanceCount, + .startInstanceLocation = startInstanceLocation + }); } void MetalCommandList::drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) { - guaranteeRenderEncoder(); - assert(renderEncoder != nil && "Cannot encode draw on nil MTLRenderCommandEncoder!"); +// guaranteeRenderEncoder(); +// assert(renderEncoder != nil && "Cannot encode draw on nil MTLRenderCommandEncoder!"); - [renderEncoder drawIndexedPrimitives: currentPrimitiveType - indexCount: indexCountPerInstance - indexType: currentIndexType - indexBuffer: indexBuffer - indexBufferOffset: startIndexLocation - instanceCount: instanceCount - baseVertex: baseVertexLocation - baseInstance: startInstanceLocation]; +// [renderEncoder drawIndexedPrimitives: currentPrimitiveType +// indexCount: indexCountPerInstance +// indexType: currentIndexType +// indexBuffer: indexBuffer +// indexBufferOffset: startIndexLocation +// instanceCount: instanceCount +// baseVertex: baseVertexLocation +// baseInstance: startInstanceLocation]; + + deferredDrawCalls.emplace_back(DrawCall{ + .type = DrawCall::Type::DrawIndexed, + .instanceCount = instanceCount, + .startInstanceLocation = startInstanceLocation, + .indexCountPerInstance = indexCountPerInstance, + .indexBuffer = indexBuffer, + .baseVertexLocation = baseVertexLocation, + .startIndexLocation = startIndexLocation, + }); } void MetalCommandList::setPipeline(const RenderPipeline *pipeline) {