Я создаю графическое приложение, которое использует Metal для рендеринга всего. Когда я выполнял отладку фрейма под конвейерной статистикой для всех моих вызовов отрисовки, есть !! приоритетное предупреждение под названием «Запрещенная загрузка режима адреса устройства» с подробной информацией:
Indexing using unsigned int for offset prevents addressing calculation in device. To prevent this extra ALU operation use int for offset.
Так что для моего простейшего колл-колла, который включает это, вот что происходит. Существует большое количество данных вершин, за которыми следует индексный буфер. Индексный буфер создается и заполняется в начале, а затем становится постоянным. Данные вершин постоянно меняются.
У меня есть следующие типы:
struct Vertex {
float3 data;
};
typedef int32_t indexType;
Затем следующий розыгрыш
[encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle indexCount:/*int here*/ indexType:MTLIndexTypeUInt32 indexBuffer:indexBuffer indexBufferOffset:0];
Который идет к следующей функции вершины
vertex VertexOutTC vertex_fun(constant Vertex * vertexBuffer [[ buffer(0) ]],
indexType vid [[ vertex_id ]],
constant matrix_float3x3* matrix [[buffer(1)]]) {
const float2 coords[] = {float2(-1, -1), float2(-1, 1), float2(1, -1), float2(1, 1)};
CircleVertex vert = vertexBuffer[vid];
VertexOutTC out;
out.position = float4((*matrix * float3(vert.data.x, vert.data.y, 1.0)).xy, ((float)((int)vid/4))/10000.0, 1.0);
out.color = HSVtoRGB(vert.data.z, 1.0, 1.0);
out.tc = coords[vid % 4];
return out;
}
Меня очень смущает, что именно я здесь делаю неправильно. Казалось бы, ошибка предполагает, что я не должен использовать беззнаковый тип для смещения, которое, как я предполагаю, является индексным буфером.
Дело в том, что в конечном итоге для индексного буфера есть только MTLIndexTypeUInt32
а также MTLIndexTypeUInt16
оба из которых без знака. Кроме того, если я пытаюсь использовать сырье int
как тип, шейдер не будет компилироваться. Что здесь происходит?
Задача ещё не решена.
Других решений пока нет …