Home > Software engineering >  How can I write a using a struct to a MTLBuffer?
How can I write a using a struct to a MTLBuffer?

Time:12-21

I have an array of 3 MTLBuffers. They are created and then reused. They are managed with semaphores to avoid conflicts. I need to write to them using a struct I created. I'm having trouble binding to the MTLBuffer and assign my struct format to it. I'm converting this from OBJ-C to SWIFT. The OBJ-C code works. I'm getting an error in SWIFT "Cast from '(any MTLBuffer)?' to unrelated type 'AAPLUniforms' always fails" How can I do this?

The struct

typedef struct{
matrix_float4x4 mvpMatrix;
float pointSize;} AAPLUniforms;

I create the array of MTLBuffers here

/ Create and allocate the dynamic uniform buffer objects.
for i in 0..<AAPLMaxRenderBuffersInFlight {
  // Indicate shared storage so that both the  CPU can access the buffers
  let storageMode: MTLResourceOptions = .storageModeShared
  
  dynamicUniformBuffers[i] = device.makeBuffer(
    length: MemoryLayout<AAPLUniforms>.size,
    options: storageMode)
  
  dynamicUniformBuffers[i]?.label = String(format: "UniformBuffer%lu", i)
}

I'm getting an error "Cast from '(any MTLBuffer)?' to unrelated type 'AAPLUniforms' always fails" trying at bind the MTLBuffer to the struct type

  func updateState() {

var uniforms = dynamicUniformBuffers[currentBufferIndex] as? AAPLUniforms

uniforms?.pointSize = AAPLBodyPointSize
uniforms?.mvpMatrix = projectionMatrix!
}

The working OBJC code looks like this

- (void)updateState{
AAPLUniforms *uniforms = (AAPLUniforms *)_dynamicUniformBuffers[_currentBufferIndex].contents;
uniforms->pointSize = AAPLBodyPointSize;
uniforms->mvpMatrix = _projectionMatrix;

CodePudding user response:

What you need is the pointer to the actual memory of the MTLBuffer's contents. You get that using its contents() method, which will return an UnsafeMutableRawPointer. You can then call its bindMemory method to bind (cast) it to UnsafeMutablePointer<AAPLUniforms>. After that, you can use its pointee property to access your AAPLUniforms instance.

I think this should do what you want:

let uniformsPtr = dynamicUniformBuffers[currentBufferIndex]!.contents()
    .bindMemory(to: AAPLUniforms.self, capacity: 1)

uniformsPtr.pointee.pointSize = AAPLBodyPointSize
uniformsPtr.pointee.mvpMatrix = projectionMatrix!

  • Related