Я работаю над движком рисования, используя Металл. Я перерабатываю предыдущую версию, поэтому, начиная с нуля
Я получаю ошибку Выполнение буфера команд было прервано из-за ошибки во время выполнения. Вызванная ошибка зависания графического процессора (код IOAF 3)
После некоторой отладки я возложил вину на свою процедуру drawPrimitives, я нашел случай весьма интересным
У меня будут различные кисти, все они будут работать с указанием c информации о вершине
Итак, я сказал, почему бы и нет? Пусть все кисти отвечают на протокол
Протокол для вершин будет следующим:
protocol MetalVertice {}
И информация о вершине, используемая этим параметром c bru sh, будет:
struct PointVertex:MetalVertice{
var pointId:UInt32
let relativePosition:UInt32
}
bru sh может быть вызван либо путем предоставления ранее созданных вершин, либо путем вызова функции для создания этих вершин. В любом случае, реальное рисование происходит в функции вершины
var vertices:[PointVertex] = [PointVertex].init(repeating: PointVertex(pointId: 0,
relativePosition: 0),
count: totalVertices)
for (verticeIdx, pointIndex) in pointsIndices.enumerated(){
vertices[verticeIdx].pointId = UInt32(pointIndex)
}
for vertice in vertices{
print("size: \(MemoryLayout.size(ofValue: vertice))")
}
self.renderVertices(vertices: vertices,
forStroke: stroke,
inDrawing: drawing,
commandEncoder: commandEncoder)
return vertices
}
func renderVertices(vertices: [MetalVertice], forStroke stroke: LFStroke, inDrawing drawing:LFDrawing, commandEncoder: MTLRenderCommandEncoder) {
if vertices.count > 1{
print("vertices a escribir: \(vertices.count)")
print("stride: \(MemoryLayout<PointVertex>.stride)")
print("size of array \(MemoryLayout.size(ofValue: vertices))")
for vertice in vertices{
print("ispointvertex: \(vertice is PointVertex)")
print("size: \(MemoryLayout.size(ofValue: vertice))")
}
}
let vertexBuffer = LFDrawing.device.makeBuffer(bytes: vertices,
length: MemoryLayout<PointVertex>.stride * vertices.count,
options: [])
. Это была проблема, вызов этого специфического c кода приводит к следующим результатам в консоли:
size: 8
size: 8
vertices a escribir: 2
stride: 8
size of array 8
ispointvertex: true
size: 40
ispointvertex: true
size: 40
В предыдущем функция, размер вершин составляет 8 байт, но по какой-то причине, когда они входят в следующую функцию, они превращаются в 40 байт, поэтому буфер неправильно создается
, если я изменяю сигнатуру функции на:
func renderVertices(vertices: [PointVertex], forStroke stroke: LFStroke, inDrawing drawing:LFDrawing, commandEncoder: MTLRenderCommandEncoder) {
Вершины правильно указаны как 8-байтовые, и процедура рисования работает как задумано
Что-то я пропустил? если протокол MetalVertice вносит некоторый шум?