【问题标题】:How to reinterpret_cast with pointer to MTLBuffer Swift adaptation如何使用指向 MTLBuffer Swift 适配的指针重新解释_cast
【发布时间】:2020-04-03 08:42:17
【问题描述】:

我有一个 Objective-c 函数块,它使用(据我所知)一些额外的东西,我想在 Swift 中完全实现它。这是我开始的原始代码。 (我试图使用 Swiftify 进行转换,但没有运气) 不幸的是,这篇 SO 文章没有帮助:How to reinterpret_cast in Swift?

- (void)updateBuffers
{
    id<MTLBuffer> noiseBuffer = _noise[[self frameIndex]];
    RandomSample* ptr = reinterpret_cast<RandomSample*>([noiseBuffer contents]);
    for (NSUInteger i = 0; i < (NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE); ++i)
    {
        ptr->pixelSample.x = uniformFloatDistribution(randomGenerator);
        ptr->pixelSample.y = uniformFloatDistribution(randomGenerator);
        ptr->barycentricSample.x = uniformFloatDistribution(randomGenerator);
        ptr->barycentricSample.y = uniformFloatDistribution(randomGenerator);
        ptr->emitterBsdfSample.x = uniformFloatDistribution(randomGenerator);
        ptr->emitterBsdfSample.y = uniformFloatDistribution(randomGenerator);
        ptr->bsdfSample.x = uniformFloatDistribution(randomGenerator);
        ptr->bsdfSample.y = uniformFloatDistribution(randomGenerator);
        ptr->componentSample = uniformFloatDistribution(randomGenerator);
        ptr->emitterSample = uniformFloatDistribution(randomGenerator);
        ptr->rrSample = uniformFloatDistribution(randomGenerator);
        ++ptr;
    }
    [_noise[[self frameIndex]] didModifyRange:NSMakeRange(0, [noiseBuffer length])];


}

我假设,objective-c 代码用 Struct (RandomSample) 中的内容填充缓冲区的内容(使用 for 循环)。 NOISE_BLOCK_SIZE 在这种情况下是 64

这就是我目前所拥有的:

    func updateBuffers() {

        let noiseBuffer = noise[Int(frameIndex())] // MTLBuffer

        var randomStruct = RandomSample()
        // Here I should have this ptr (pointer) that like on objective-c

        for i in 0..<(NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE) {

            randomStruct.pixelSample.x          = Float.random(in: 0..<1)
            randomStruct.pixelSample.y          = Float.random(in: 0..<1)
            randomStruct.barycentricSample.x    = Float.random(in: 0..<1)
            randomStruct.barycentricSample.y    = Float.random(in: 0..<1)
            randomStruct.emitterBsdfSample.x    = Float.random(in: 0..<1)
            randomStruct.emitterBsdfSample.y    = Float.random(in: 0..<1)
            randomStruct.bsdfSample.x           = Float.random(in: 0..<1)
            randomStruct.bsdfSample.y           = Float.random(in: 0..<1)
            randomStruct.componentSample        = Float.random(in: 0..<1)
            randomStruct.emitterSample          = Float.random(in: 0..<1)
            randomStruct.rrSample               = Float.random(in: 0..<1)

        }

        // etc... etc...

    }

这是我要引用的 RandomSample 结构,在 .h 文件中定义(这是我的桥接头)

struct RandomSample
{
    simd_float2 pixelSample;
    simd_float2 barycentricSample;
    simd_float2 bsdfSample;
    simd_float2 emitterBsdfSample;
    float componentSample;
    float emitterSample;
    float rrSample;
};

我使用的不是uniformFloatDistribution(在 Swift 代码中) Float.random(in: 0..&lt;1) 这应该产生或多或少相同的结果。

【问题讨论】:

    标签: ios objective-c swift casting metal


    【解决方案1】:

    显然我无法在我的机器上验证这一点,但你应该可以做这样的事情。

    var noiseRaw = noiseBuffer.contents()
    let samples = noiseRaw.bindMemory(
        to: RandomSample.self,
        capacity: NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE
    )
    
    for i in 0..<NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE {
        let sample = samples + i
        sample.pointee.componentSample = Float.random(in: 0..<1)
        sample.pointee.emitterSample = Float.random(in: 0..<1)
        sample.pointee.rrSample = Float.random(in: 0..<1)
    }
    

    【讨论】:

    • 看起来不错。我唯一不确定的是如何在 for 循环中增加指针。在objective-c中它使用++ptr。我怎么能在 Swift 中做到这一点。 (目前我为指针属性执行此操作:=> randomSamplePointer?.pointee.rrSample = Float.random(in: 0..
    • @ZAY 有一个叫做执行类型指针算术的部分。那应该对您有所帮助:developer.apple.com/documentation/swift/unsafemutablepointer。如果您有任何其他问题,请告诉我。
    • 如何用“for”循环运行的次数填充该指针?就像在objective-c中一样。但我还没有找到一种增量器来做到这一点。 (如 ++ptr)。在 Apple 文档中,他们解释了如何访问存储的内存,但我需要用 RandomStruct X-Times 填充该缓冲区。就像它在“for”循环中缺少一些东西一样。
    • @ZAY 我不确定我是否理解你,但我更新了我的答案,希望它能回答我认为你所问的问题。您使用 \\+\\ 运算符增加指针。
    • 这太棒了!你理解我。最后一件事:“let sample = samples + i”应该在 for 循环的顶部(如您的答案)还是在末尾(如在 Objective-c 代码中)?
    猜你喜欢
    • 2020-01-18
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多