Fix resolve logic

This commit is contained in:
tanmaysachan 2024-11-10 23:46:10 +05:30
parent 3faeacb5ce
commit df439e60f7
2 changed files with 83 additions and 19 deletions

View File

@ -164,6 +164,26 @@ namespace RT64 {
id<MTLBuffer> computePushConstantsBuffer = nil;
std::map<id<MTLTexture>, id<MTLTexture>> 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<MTLBuffer> indexBuffer = nil;
int32_t baseVertexLocation = 0;
uint32_t startIndexLocation = 0;
};
std::vector<DrawCall> 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;

View File

@ -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) {