Ответ 1
Реальная проблема: Это проблема с памятью!
Для всех людей, говорящих, что это проблема памяти, вы были правы! Вот несколько псевдокодов, чтобы проиллюстрировать это. Извините, что он находится в "Swift", но его легче читать. У металлических шейдеров есть забавный способ оживить. Они сначала инициализируются без значений, чтобы получить память. Произошел этот шаг, потому что он полагался на более поздний шаг: установка буфера.
Все зависит от того, какие значения доступны, когда. Мое понимание newComputePipelineStateWithFunction
было неправильным. Это не просто функция шейдера. Это также крошечный шаг в процессе инициализации.
class MetalShader {
// buffers
var aBuffer : [Float]
var aBufferCount : Int
// step One : newComputePipelineStateWithFunction
memory init() {
// assign shader memory
// create memory for one int
let aStaticValue : Int
// create memory for one int
var aNotSoStaticValue : Int // this wil succeed, assigns memory for one int
// create memory for 10 floats
var aStaticArray : [Float] = [Float](count: aStaticValue, repeatedValue: y) // this will succeed
// create memory for x floats
var aDynamicArray : [Float] = [Float](count: aBuffer.count, repeatedValue: y) // this will fail
var aDynamicArray : [Float] = [Float](count: aBufferCount, repeatedValue: y) // this will fail
let tempValue : Float // one float from a loop
}
// step Two : commandEncoder.setBuffer()
assign buffers (buffers) {
aBuffer = cpuMemoryBuffer
}
// step Three : commandEncoder.endEncoding()
actual init() {
// set shader values
let aStaticValue : Int = 0
var aNotSoStaticValue : Int = aBuffer.count
var aDynamicArray : [Float] = [Float](count: aBuffer.count, repeatedValue: 1) // this could work, but the app already crashed before getting to this point.
}
// step Four : commandBuffer.commit()
func shaderFunction() {
// do stuff
for i in 0..<aBuffer.count {
let tempValue = aBuffer[i]
}
}
}
Fix:
Наконец я понял, что буферы представляют собой технически динамические массивы, и вместо создания массивов внутри шейдера я мог бы просто добавить больше буферов. Это очевидно работает.