2017-12-12 1 views
1

메탈 2를 사용하여 인스턴스 렌더링 시스템을 설정하려고합니다. 모든 것이 제대로 작동하지만 여전히 문제가있는 것 같습니다. ~ 1,000 인스턴스를 렌더링 할 때마다 모든 인스턴스에 균일 한 데이터가 필요합니다. 유니폼은 CPU 측면에서 다음과 같이 보입니다.올바른 버퍼 크기

struct InstanceUniform { 
    var position: float2 
    var layer: Int 
} 

이 인스턴스마다 하나씩 필요합니다. 내 예를 유니폼에 대한 버퍼를 만들 때, 나는이 작업을 수행 : 내 인스턴스에 대한 충분한 메모리를 할당해야처럼 보인다

buffer = device.makeBuffer(length: MemoryLayout<InstanceUniform>.stride * instanceCount, options: []) 

. 그러나 한 번의 드로 콜에서 내 다음 드로 호출까지 항상 데이터의 "유출"이 있습니다. 두 가지 draw 호출이 있습니다. 첫 번째는 인스턴스를 렌더링하기위한 것이고 두 번째는 정상적인 호출이며 instancing은 아닙니다. 내 첫 무승부에 두 개의 버퍼가 있고 두 번째 버퍼에는 두 개의 버퍼가 있습니다. 그러나 Metal을 디버깅 할 때 두 번째 draw 호출은 첫 번째 호출의 두 번째 버퍼와 크기가 같고 임의 메모리 값으로 채워진 두 번째 버퍼 첨부 파일이 있음을 보여줍니다.

또한 인스턴스 버퍼에 지정된 길이를 원래 값으로 4로 나눈 값을 수정해도 문제가 발생하지 않으므로이 문제가 버퍼 크기와 관련이 있다고 추측해야합니다. .

도움이 될 것입니다.

답변

2

나는 첫 번째 드로잉을위한 버퍼 두 개와 나의 초 당 하나의 버퍼 두 개를 가지고있다.

버퍼는 그리기 호출과 관련이 없습니다. 렌더 명령 엔코더에서 설정됩니다. 버퍼를 렌더 명령 엔코더의 테이블에 설정하면 버퍼를 지우거나 다른 버퍼로 바꿀 때까지 버퍼가 남아 있습니다. 두 번째 그리기 호출에 대해 활성 인 셰이더가이를 사용하지 않아도 이후의 모든 그리기 호출에 대해 할당됩니다. (물론 하나의 인코더로 끝내고 새 버퍼를 만들면 빈 버퍼 테이블로 시작합니다.)

버퍼의 크기에 관해서는 구조체의 layer 속성은 Int입니다. 이는 64 비트 정수 유형입니다. Metal은 64 비트 정수 유형을 처리하지 않습니다. 따라서 앱 코드의 버퍼 레이아웃과 쉐이더 사이에는 필연적으로 불일치가 있습니다. Swift 쪽에서 Int32을 사용하여 int과 일치해야합니다.

+0

와우, 정말 고마워요! 나는 이것을 답으로 표시 할 것이지만 또 다른 빠른 질문이있다. 이것이 성능에 영향을 미칩니 까? 큰 버퍼가 문제가되는 많은 그리기 호출이 있다고 상상할 수 있습니다. 또한 Swift와 Metal의 Int의 불일치에 대한 팁을 보내 주셔서 감사합니다! –

+1

성능에 많은 영향을 미치지 않을 것이라고 생각합니다. 각 끌기마다 버퍼가 복사되지 않습니다. 그들은 필요할 때 처음 복사됩니다. 그 후, 그들은 이미 GPU에 있습니다. –