diff --git a/src/metal/rt64_metal.h b/src/metal/rt64_metal.h index 458c7ba..7b06d7e 100755 --- a/src/metal/rt64_metal.h +++ b/src/metal/rt64_metal.h @@ -61,7 +61,6 @@ namespace RT64 { uint32_t entryCount = 0; uint32_t descriptorTypeMaxIndex = 0; std::vector descriptorTypes; - std::vector descriptorToRangeIndex; std::vector samplerIndices; MetalDescriptorSet(MetalDevice *device, const RenderDescriptorSetDesc &desc); @@ -83,10 +82,13 @@ namespace RT64 { MetalDevice *device = nullptr; std::vector descriptorTypes; std::vector descriptorToRangeIndex; + std::vector descriptorIndexBases; + std::vector descriptorRangeBinding; std::vector samplerIndices; uint32_t bufferOffset = 0; uint32_t entryCount = 0; uint32_t descriptorTypeMaxIndex = 0; + uint32_t initialIndexOffset = 0; MetalDescriptorSetLayout(MetalDevice *device, const RenderDescriptorSetDesc &desc); ~MetalDescriptorSetLayout(); @@ -141,6 +143,7 @@ namespace RT64 { id renderEncoder = nil; id computeEncoder = nil; id blitEncoder = nil; + MTLCaptureManager *captureManager = nil; MTLRenderPassDescriptor *renderDescriptor = nil; @@ -183,7 +186,6 @@ namespace RT64 { void guaranteeRenderEncoder(); void guaranteeComputeEncoder(); void guaranteeBlitEncoder(); - void rebindRenderState(MetalRenderState *renderState); 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 05b748a..f559c6a 100755 --- a/src/metal/rt64_metal.mm +++ b/src/metal/rt64_metal.mm @@ -612,7 +612,7 @@ namespace RT64 { } if (totalPushConstantSize > 0) { - uint32_t alignedSize = calculateAlignedSize(totalPushConstantSize); + size_t alignedSize = calculateAlignedSize(totalPushConstantSize); pushConstantsBuffer = [device->device newBufferWithLength: alignedSize options: MTLResourceStorageModeShared]; } @@ -633,6 +633,16 @@ namespace RT64 { entryCount = 0; argumentDescriptors = [NSMutableArray array]; + for (uint32_t i = 0; i < desc.descriptorRangesCount; i++) { + const RenderDescriptorRange &range = desc.descriptorRanges[i]; + + uint32_t indexBase = uint32_t(descriptorIndexBases.size()); + for (uint32_t j = 0; j < range.count; j++) { + descriptorIndexBases.emplace_back(indexBase); + descriptorRangeBinding.emplace_back(range.binding); + } + } + // Figure out the total amount of entries that will be required. uint32_t rangeCount = desc.descriptorRangesCount; if (desc.lastRangeIsBoundless) { @@ -650,21 +660,18 @@ namespace RT64 { const RenderDescriptorRange &range = sortedRanges[i]; for (uint32_t j = 0; j < range.count; j++) { descriptorTypes.emplace_back(range.type); - descriptorToRangeIndex.emplace_back(i); entryCount++; if (range.immutableSampler != nullptr) { const auto *sampler = static_cast(range.immutableSampler[j]); staticSamplers.emplace_back(sampler->samplerState); - samplerIndices.emplace_back(range.binding - 1 + j); + samplerIndices.emplace_back(range.binding + j); } } MTLArgumentDescriptor *argumentDesc = [MTLArgumentDescriptor new]; argumentDesc.dataType = toMTL(range.type); - - // TODO: Figure out the binding mess - argumentDesc.index = range.binding - 1; + argumentDesc.index = range.binding; argumentDesc.arrayLength = range.count > 1 ? range.count : 0; if (range.type == RenderDescriptorRangeType::TEXTURE) { argumentDesc.textureType = MTLTextureType2D; @@ -682,7 +689,7 @@ namespace RT64 { MTLArgumentDescriptor *argumentDesc = [MTLArgumentDescriptor new]; argumentDesc.dataType = toMTL(lastDescriptorRange.type); - argumentDesc.index = lastDescriptorRange.binding - 1; + argumentDesc.index = lastDescriptorRange.binding; argumentDesc.arrayLength = lastDescriptorRange.count > 1 ? lastDescriptorRange.count : 0; // TODO: Fix the upper bound length, metal wants fixed argumentDesc.arrayLength = 8192; @@ -701,7 +708,7 @@ namespace RT64 { } argumentEncoder = [device->device newArgumentEncoderWithArguments: argumentDescriptors]; - uint64_t bufferLength = [argumentEncoder encodedLength]; + size_t bufferLength = [argumentEncoder encodedLength]; descriptorBuffer = [device->device newBufferWithLength: bufferLength options: MTLResourceStorageModeShared]; [argumentEncoder setArgumentBuffer: descriptorBuffer offset: 0]; @@ -1250,7 +1257,9 @@ namespace RT64 { auto *texture = pair.second; if (texture != nil) { [renderEncoder useResource:texture usage:MTLResourceUsageRead stages:MTLRenderStageFragment]; - [setLayout->argumentEncoder setTexture:texture atIndex: index]; + + uint32_t adjustedIndex = index - setLayout->descriptorIndexBases[index] + setLayout->descriptorRangeBinding[index]; + [setLayout->argumentEncoder setTexture:texture atIndex: adjustedIndex]; } } @@ -1287,10 +1296,6 @@ namespace RT64 { } } - void MetalCommandList::rebindRenderState(MetalRenderState *renderState) { - activeRenderState = renderState; - } - void MetalCommandList::barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) { // TODO: Ignore for now, Metal should handle most of this itself. } @@ -1346,7 +1351,7 @@ namespace RT64 { } case MetalPipeline::Type::Graphics: { const auto *graphicsPipeline = static_cast(interfacePipeline); - rebindRenderState(graphicsPipeline->renderState); + activeRenderState = graphicsPipeline->renderState; break; } default: @@ -1387,6 +1392,7 @@ namespace RT64 { assert(activeGraphicsPipelineLayout != nullptr); assert(rangeIndex < activeGraphicsPipelineLayout->pushConstantRanges.size()); + // TODO: make sure there's parity with Vulkan const RenderPushConstantRange &range = activeGraphicsPipelineLayout->pushConstantRanges[rangeIndex]; uint32_t startOffset = 0; for (uint32_t i = 0; i < rangeIndex; i++) {