diff --git a/Sources/Alloy/Core/MTLIndexBuffer.swift b/Sources/Alloy/Core/MTLIndexBuffer.swift index c57e9cf..d03fab3 100644 --- a/Sources/Alloy/Core/MTLIndexBuffer.swift +++ b/Sources/Alloy/Core/MTLIndexBuffer.swift @@ -6,6 +6,25 @@ public class MTLIndexBuffer { public let count: Int public let type: MTLIndexType + public init(device: MTLDevice, + count: Int, + type: MTLIndexType, + options: MTLResourceOptions = .cpuCacheModeWriteCombined) throws { + let indexStride: Int + switch type { + case .uint16: indexStride = MemoryLayout.stride + case .uint32: indexStride = MemoryLayout.stride + @unknown default: throw MetalError.MTLBufferError.incompatibleData + } + + guard let allocatedBuffer = device.makeBuffer(length: count * indexStride, options: options) + else { throw MetalError.MTLDeviceError.bufferCreationFailed } + + self.buffer = allocatedBuffer + self.count = count + self.type = type + } + public init(device: MTLDevice, indexArray: [UInt16], options: MTLResourceOptions = []) throws { @@ -31,4 +50,74 @@ public class MTLIndexBuffer { self.count = indexArray.count self.type = .uint32 } + + func pointer(of type: T.Type) -> UnsafeMutablePointer? { + return self.buffer.pointer(of: T.self) + } + + func bufferPointer(of type: T.Type, + count: Int) -> UnsafeBufferPointer? { + return self.buffer.bufferPointer(of: T.self, count: count) + } + + func array(of type: T.Type, + count: Int) -> [T]? { + return self.buffer.array(of: T.self, count: count) + } + + /// Put a value in `MTLIndexBuffer` at desired offset. + /// - Parameters: + /// - value: value to put in the buffer. + /// - offset: offset in bytes. + func put(_ value: UInt16, + at offset: Int = 0) throws { + #if DEBUG + if self.type != .uint16 { + assertionFailure("WARNING: Trying to insert UInt16 index into different type index buffer") + } + #endif + try self.buffer.put(value, at: offset) + } + + /// Put values in `MTLIndexBuffer` at desired offset. + /// - Parameters: + /// - values: values to put in the buffer. + /// - offset: offset in bytes. + func put(_ values: [UInt16], + at offset: Int = 0) throws { + #if DEBUG + if self.type != .uint16 { + assertionFailure("WARNING: Trying to insert UInt16 index into different type index buffer") + } + #endif + try self.buffer.put(values, at: offset) + } + + /// Put a value in `MTLIndexBuffer` at desired offset. + /// - Parameters: + /// - value: value to put in the buffer. + /// - offset: offset in bytes. + func put(_ value: UInt32, + at offset: Int = 0) throws { + #if DEBUG + if self.type != .uint32 { + assertionFailure("WARNING: Trying to insert UInt16 index into different type index buffer") + } + #endif + try self.buffer.put(value, at: offset) + } + + /// Put values in `MTLIndexBuffer` at desired offset. + /// - Parameters: + /// - values: values to put in the buffer. + /// - offset: offset in bytes. + func put(_ values: [UInt32], + at offset: Int = 0) throws { + #if DEBUG + if self.type != .uint32 { + assertionFailure("WARNING: Trying to insert UInt16 index into different type index buffer") + } + #endif + try self.buffer.put(values, at: offset) + } }