스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Metal 3를 통해 리소스를 더 신속하게 로드
Metal 3의 빠른 리소스 스트리밍을 사용하여 자산을 신속하게 로드하는 방법을 확인하세요. 앱에서 비동기식 설정 및 저장 작업 흐름을 사용하여 SSD 저장 공간의 속도와 Apple 실리콘의 통합 메모리 아키텍처의 처리량을 활용하는 방법을 보여드리겠습니다. 또한 GPU 렌더링 및 컴퓨팅 작업과 병렬로 실행되면서 동기화되는 별도의 대기열을 만드는 방법을 알아보겠습니다. 마지막으로, 더 낮은 지연 속도로 데이터를 로드할 수 있도록 높은 우선순위 대기열로 오디오와 같은 자산을 지정하는 방법을 공유합니다.
리소스
관련 비디오
WWDC22
-
다운로드
♪ 부드러운 힙합 음악 ♪ ♪ 안녕하세요 전 Jaideep Joshi입니다 애플의 GPU 소프트웨어 엔지니어예요 이번 세션에서는 게임과 앱의 리소스 로딩을 단순화하고 최적화하는 Metal 3의 신기능을 소개해 드리겠습니다 먼저 여러분에게 빠른 리소스 로드 기능이 앱의 자산 로드 파이프라인에 어떻게 적용되는지 보여 드릴게요 또 애플 제품의 새 스토리지 기술을 활용하는 주요 기능을 몇 가지 알려 드리죠 고속 리소스 로딩에는 몇 가지 고급 기능이 있는데 여러분의 앱이 맞닥뜨릴 수 있는 시나리오를 해결할 수 있을 겁니다 또 몇 가지 권장 모범 사례가 있는데요 여러분이 알아 두면 앱에서 기능을 효과적으로 사용하는 데 도움이 될 거예요 앱에 고속 리소스 로딩을 하게 해주는 Metal System Trace나 GPU 디버거 같은 도구도 발생 가능한 문제를 분석하고 해결하는 데 도움이 될 겁니다 마지막으로 고속 리소스 로딩을 실제로 보여 주는 예를 살펴보겠습니다 Metal 3의 고속 리소스 로딩으로 할 수 있는 일들을 알아볼까요?
Metal 3의 고속 리소스 로딩으로 여러분의 게임과 앱은 Apple 플랫폼에 포함된 빠른 SSD 저장소와 Apple 실리콘 통합 메모리 아키텍처를 활용해 대기 시간은 줄이고 처리량은 높여 자산을 로딩할 수 있어요 게임 자산이 제시간에 준비되도록 데이터를 스트리밍하고 로딩 시간을 단축하는 최고의 방법을 배우실 겁니다 로딩 시간 단축의 핵심 요소는 꼭 필요한 것만 최대한 세분화하여 로딩하는 겁니다 Metal 3의 높은 처리량과 짧은 대기 시간으로 앱에서 텍스처, 오디오 및 기하학 데이터를 포함한 고품질 자산을 스트리밍할 수 있습니다 이제 게임에서 자산을 로딩하는 예를 보여 드릴게요 게임은 보통 처음 시작하거나 새로운 레벨을 시작할 때 로딩 화면을 보여 주죠 이때 게임의 자산을 메모리에 로딩할 수 있습니다 플레이어의 레벨이 올라가면 게임의 자산이 더 많이 로딩되죠 이때의 단점은 게임이 미리 저장소 시스템에 자산을 로딩하려고 여러 번 요청하는 동안 플레이어가 오래 기다리게 된다는 겁니다 게다가 이런 자산은 메모리 공간이 클 수 있죠 이런 경험을 개선하는 몇 가지 방법이 있습니다 플레이어가 객체에 가까워질수록 게임이 객체를 동적으로 스트리밍해서 이런 경험을 개선할 수 있어요 이 방식은 게임이 처음에 필요한 것만 로딩하고 플레이어가 레벨을 이동하면서 점차 다른 리소스를 스트리밍합니다 예를 들어 이 게임은 처음에 이 칠판을 낮은 해상도로 로딩하지만 플레이어가 칠판을 향해 가면 더 높은 해상도 버전의 칠판을 로딩하죠 이런 접근 방식은 플레이어가 로딩 화면에서 기다리는 시간을 줄여 줍니다 하지만 고해상도 버전을 로딩하는 게 시간이 너무 오래 걸리는 바람에 플레이어가 가까이 다가가도 여전히 저해상도의 항목을 보게 될 수 있죠 이 문제의 한 가지 해결책은 각 자산의 더 작은 부분을 스트리밍하는 겁니다 예를 들어 보이는 영역만 로딩하는 겁니다 전체 Mip 수준을 스트리밍하는 대신 스파스 텍스처의 타일을 스트리밍하는 거죠 이러면 앱에서 스트리밍해야 하는 데이터 양이 크게 줄어듭니다 이런 접근을 이용하면 로딩 요청이 줄어들죠 이런 방법은 많습니다 하지만 괜찮습니다 최신 저장소 하드웨어는 한번에 여러 로딩 요청을 실행할 수 있으니까요 즉 게임 플레이에 영향을 주지 않고 장면의 해상도를 높이고 규모를 키울 수 있습니다 작은 로딩 요청을 많이 생성할 수도 있고 높은 우선 순위의 요청이 시간 내에 완료될 수 있게 로딩 요청의 우선 순위를 지정할 수도 있습니다 이제 로딩 시간을 줄이면서 게임의 시각적인 충실도를 높이는 방법을 설명했으니 Metal 3의 고속 리소스 로딩이 어떻게 도움이 되는지 보여 드리죠 고속 리소스 로딩은 저장소에서 리소스를 로딩하는 비동기 API입니다 기존 로드 API와 달리 로드를 발행하는 스레드는 로드가 완료될 때까지 기다릴 필요가 없습니다 더 빠른 저장소 처리량을 잘 활용하기 위해서 로드 작업이 동시에 실행됩니다 로드 작업을 일괄 처리 해서 리소스 로딩의 오버헤드를 최소화할 수 있죠 마지막으로 Metal 3를 사용하면 로드 작업의 우선 순위를 지정해 지연 시간을 줄일 수 있습니다 이제 자산 로드 파이프라인을 구축하는 데 도움이 되는 주요 기능을 보여 드릴 거예요 리소스 로드 단계부터 시작해 보죠 리소스 로드에는 세 단계가 있습니다 파일을 열고 필요한 로드 명령을 실행하고 로드 명령을 렌더링 작업과 동기화하는 거죠 이렇게 해 보죠 파일을 여는 것부터 시작해요 메탈 장치 인스턴스로 파일 핸들을 생성하면서 기존 파일을 엽니다 예를 들어 이 코드는 메탈 장치 인스턴스를 사용해 파일 핸들을 만들죠 새 makeIOHandle 메서드를 파일 경로 URL로 호출하면서요 파일 핸들이 생기면 이 핸들을 사용해 로드 명령을 발행할 수 있죠 여기에 로드 작업을 수행하고 GPU 작업을 인코딩하는 앱의 일반적인 시나리오가 있습니다 기존 로드 API를 사용하면 렌더링 작업을 인코딩하기 전에 로드 작업이 완료될 때까지 앱이 기다려야 하죠 Metal 3는 여러분의 앱이 로드 명령을 비동기적으로 실행하게 해 줍니다 먼저 Metal IO 명령 대기열을 만듭니다 이 대기열을 사용해서 IO 명령 버퍼를 만들고 해당 버퍼에 로드 명령을 인코딩합니다 그런데 명령 버퍼가 명령 대기열에서 비동기적으로 실행되기 때문에 로드 작업이 끝날 때까지 기다릴 필요가 없습니다 사실 IO 명령 버퍼 내의 모든 명령이 동시에 실행될 뿐 아니라 IO 명령 버퍼 자체도 동시에 실행되기 때문에 순서 없이 완료됩니다 이런 동시 실행 모델은 처리량을 극대화해 더 빠른 저장소 하드웨어를 더욱 잘 활용하고 있죠 명령 버퍼에 세 가지 유형의 IO 명령을 인코딩할 수 있습니다 loadTexture는 텍스처 스트리밍을 위해 Metal 텍스처로 로드되고 loadBuffer는 장면을 스트리밍하거나 기하학 데이터를 위해 Metal 버퍼로 로드되며 loadBytes는 CPU 액세스 메모리에 로드되죠 IO 명령 대기열에서 IO 명령 버퍼를 생성합니다 대기열을 만들기 위해 먼저 IO 명령 대기열 기술자를 만들고 구성합니다 기본적으로 대기열은 동시에 실행되지만 명령 버퍼의 순서를 정해 연속적으로 실행하게 설정할 수도 있습니다 그다음 대기열 기술자를 Metal 장치 인스턴스의 makeIOCommandQueue 메서드에 전달합니다 IO 명령 버퍼를 생성하는 건 makeCommandBuffer 메서드를 명령 대기열에서 호출하면 됩니다 그러면 이 명령 버퍼를 사용해 텍스처와 버퍼를 로드하는 로드 명령을 인코딩합니다 Metal의 유효성 검사 레이어는 런타임에 인코딩 오류를 포착할 겁니다 로드 명령은 아까 만든 파일 핸들 인스턴스를 사용하는 명령입니다 명령 버퍼에서 로드 명령을 추가한 후에 명령 버퍼의 커밋 메서드를 호출해서 대기열에 제출해 실행합니다 이제 IO 명령 대기열 생성과 명령 버퍼 생성 및 로드 명령 발행 또 대기열로 제출하는 법까지 설명했습니다 이제 로드 작업을 다른 GPU 작업과 동기화하는 법을 보여 드리죠 앱은 일반적으로 렌더링 작업을 시작하기 전에 렌더링에 대한 리소스 로드를 마칩니다 하지만 고속 리소스 로딩을 사용하는 앱은 IO 명령 대기열을 렌더링 명령 대기열에 동기화하는 방법이 필요하죠 이 대기열을 Metal 공유 이벤트와 동기화할 수 있습니다 Metal 공유 이벤트를 통해 IO 대기열의 명령 버퍼와 렌더링 대기열의 명령 버퍼를 동기화할 수 있죠 waitEvent 명령을 인코딩해서 공유 이벤트를 대기하도록 명령 버퍼에 지시할 수 있습니다 마찬가지로 signalEvent 명령을 인코딩해서 공유 이벤트에 신호를 보내도록 명령 버퍼에 지시할 수 있죠 Metal은 공유 이벤트에 신호하기 전에 명령 버퍼의 모든 IO 명령이 완료되게 합니다 명령 버퍼 간에 동기화하려면 먼저 Metal 공유 이벤트가 필요합니다 명령 버퍼에 waitForEvent 메서드를 호출해 공유 이벤트를 대기하게 지정할 수 있죠 마찬가지로 명령 버퍼에 signalEvent 메서드를 호출해 공유 이벤트에 신호를 보내게 할 수 있습니다 그러면 GPU 명령 버퍼에 유사한 논리를 추가해서 IO 명령 버퍼가 동일한 공유 이벤트에 신호를 보낼 때까지 대기하도록 할 수 있죠 여러분의 Metal 앱에 리소스를 로드하는 주요 기능과 API를 요약해 볼게요 Metal 파일 핸들을 만들어 파일을 엽니다 IO 명령 대기열과 IO 명령 버퍼를 생성해서 로드 명령을 발행합니다 그다음 로드 명령을 명령 버퍼로 인코딩해 대기열에서 실행합니다 끝으로 Metal 공유 이벤트를 대기하는 명령과 신호를 보내는 명령으로 로딩과 렌더링을 동기화합니다 이제 여러분에게 도움이 될 만한 고급 기능을 몇 가지 더 소개해 드릴게요 게임의 지도 전체를 메모리에 넣을 수 없는 흔한 시나리오가 있어요 그래서 지도를 영역으로 세분화합니다 플레이어가 지도에서 나아가면 게임은 지도의 영역을 미리 로드하기 시작하죠 플레이어의 방향에 따라 게임은 미리 로드할 만한 영역이 북서부, 서부, 남서부라고 판단합니다 하지만 플레이어가 서부로 이동하고 남쪽으로 향하기 시작하면서 북서부를 미리 로드한 건 더 이상 쓸모가 없습니다 미래 로딩의 지연 시간을 줄이기 위해 Metal 3을 통해 로드 작업을 취소할 수 있습니다 실제로 어떻게 하는지 살펴보겠습니다 플레이어가 중앙에 있을 때 3개 영역에 대해 IO 명령 버퍼를 인코딩하고 커밋합니다 그다음 플레이어가 서쪽 영역으로 이동하고 남쪽으로 향할 때 tryCancel 메서드를 사용해 북서쪽 영역에 대한 로드를 취소합니다 취소는 명령 버퍼 단위에서 이뤄집니다 그래서 명령 버퍼 중간에 실행을 취소할 수 있어요 나중에 영역이 완전히 로드되었는지 확인하려면 명령 버퍼의 상태를 확인할 수 있어요 Metal 3는 IO 작업의 우선 순위를 지정할 수 있습니다 플레이어가 장면에서 새로운 부분으로 순간 이동 하고 게임이 많은 그래픽 자산을 스트리밍하기 시작하는 게임 시나리오를 생각해 보세요 동시에 게임은 순간 이동 효과음을 재생해야 합니다 고속 리소스 로딩을 통해 오디오 데이터를 포함해서 앱의 모든 자산을 로드할 수 있습니다 오디오를 로드하려면 앞의 loadBytes 명령을 사용해 앱에 할당된 메모리에서 로드할 수 있죠 이 예시에서 텍스처와 오디오 IO 명령 버퍼는 단일 IO 명령 대기열에서 동시에 실행됩니다 여기 단순화한 도식이 저장소 레이어의 요청을 보여 줍니다 저장소 시스템은 오디오 및 텍스처 로드 요청 모두를 병렬로 실행할 수 있죠 오디오 지연을 방지하려면 스트리밍 시스템이 텍스처 요청보다 오디오 요청을 우선시하는 게 매우 중요합니다 오디오 요청의 우선 순위를 지정하려면 별도의 IO 명령 대기열을 만들고 높은 우선 순쉬를 지정할 수 있죠 저장소 시스템은 우선 순위가 높은 IO 요청이 대기를 짧게 하고 다른 요청보다 우선시되게 해 줍니다 오디오 자산에 대해 별도의 우선 순위 대기열을 만들고 오디오 요청의 실행 시간은 더 짧아진 반면 병령 텍스처 로드 요청의 실행 시간은 더 길어졌습니다 높은 우선 순위의 대기열을 만드는 법을 알려 드리죠 명렬 대기열 기술자의 우선 순위 속성을 높음으로 설정하면 끝입니다 우선 순위를 보통이나 낮음으로 설정하고 평소처럼 설명자에서 새 IO 명령 대기열을 생성할 수도 있어요 대기열을 만든 후에 대기열 우선 순위 수준을 변경할 수 없다는 것만 기억하세요 앱에 고속 리소스 로딩을 추가할 때 몇 가지 염두에 둘 모범 사례가 있습니다 첫째, 자산 압축을 고려하세요 기본 제공 또는 다른 압축을 사용해 앱의 디스크 사용 공간을 줄일 수 있습니다 압축을 하면 런타임 성능을 더 작은 디스크 사용 공간과 바꿀 수 있죠 또 밀도가 낮은 텍스처를 사용할 때 스파스 페이지 크기를 조정해 저장소 처리량을 향상시킬 수 있죠 하나씩 자세히 살펴볼게요 압축부터 시작합니다 Metal 3의 API를 사용해 자산 파일을 오프라인으로 압축할 수 있어요 먼저 압축 컨텍스트를 생성하고 청크의 크기 및 압축 방법으로 구성합니다 그다음 자산 파일의 일부를 컨텍스트에 전달해서 모든 파일의 단일 압축 버전을 생성합니다 압축 컨텍스트는 모든 데이터의 청크를 사용하고 선택한 코덱으로 압축해서 팩 파일에 저장합니다 이 예시에서 컨텍스트는 데이터를 64K 청크로 압축하지만 압축할 데이터의 크기와 유형에 따라서 적절한 청크 크기를 선택할 수 있습니다 Metal 3의 압축 API를 사용하는 방법입니다 먼저 압축 파일 생성 경로와 압축 방법 및 청크 크기를 제공해 압축 컨텍스트를 생성하세요 그다음 파일 데이터를 가져와 컨텍스트에 추가합니다 여기서 파일 데이터는 NSData 개체에 있어요 데이터를 추가하도록 여러 번 호출해서 서로 다른 파일의 데이터를 추가할 수 있죠 데이터 추가를 마치면 압축 컨텍스트 함수를 플러시 및 삭제하도록 호출해 압축 파일을 완료하고 저장합니다 파일 핸들을 만들면 압축된 파일을 열고 접근할 수 있어요 이 파일 핸들은 로드 명령을 발행할 때 사용됩니다 압축된 파일의 경우 Metal 3는 압축을 풀어야 하는 청크 목록으로 오프셋을 변환하면서 인라인 압축 해제를 수행하고 리소스에 로드합니다 Metal 장치 인스턴스로 파일을 생성하죠 예를 들어 이 코드는 Metal 장치 인스턴스를 사용해 파일 핸들을 만드는 겁니다 앞서 설명한 makeIOHandle 메서드에 압축 파일 경로를 제공하는 방법으로요 압축 파일의 경우 추가 매개 변수는 압축 방법입니다 이건 압축 파일을 만들 때 사용한 압축 방법과 동일합니다 이제 지원되는 여러 가지 압축 방법과 각각의 특징을 설명할 테니까 압축 방법을 선택할 때 참고하시기 바랄게요 압축 해제 속도가 중요할 땐 LZ4를 사용하세요 앱의 디스크 사용 공간을 크게 확보할 수 있습니다 코덱 속도와 압축 비율 간의 균형이 중요한 경우에 ZLib, LZBitmap이나 LZFSE를 사용하세요 안정된 코덱 중에서 ZLib은 비 Apple 기기에서 더 잘 작동합니다 LZBitmap은 인코딩과 디코딩이 빠르고 LZFSE는 압축률이 높습니다 최상의 압축률이 필요하면 LZMA 코덱 사용을 고려해 보세요 앱이 자산을 디코딩할 때 추가 시간을 감당할 수 있다면요 자신만의 압축 방식을 사용할 수도 있어요 사용자 정의 압축 코덱에서 데이터를 유용하게 쓰는 경우도 있죠 이런 경우 압축 컨텍스트를 자체 압축기로 바꾸고 오프셋을 변환해 런타임에 압축을 풀 수 있습니다 이제 압축을 사용해서 디스크 사용 공간을 줄이는 방법을 살펴봤으니 이제 스파스 페이지의 크기 조정 방법을 살펴볼게요 Metal의 이전 버전은 16K 단위로 스파스 텍스처의 타일 로딩을 지원했습니다 Metal 3를 사용하면 스파스 타일 크기를 새롭게 64K와 256K로 지정할 수 있습니다 이 새로운 크기를 통해 텍스처를 더 큰 단위로 스트리밍할 수 있고 저장소 하드웨어를 더 효과적으로 활용하고 포화시킬 수 있죠 더 큰 타일 크기를 스트리밍하는 것과 스트리밍하는 데이터의 양 사이에는 상충하는 부분이 있기 때문에 어떤 크기가 앱과 스파스 텍스처에 가장 적합한지 실험해야 합니다 다음은 Metal 개발자 도구 집합을 사용해서 앱에서 고속 리소스 로딩을 프로파일링하고 디버깅하는 방법을 살펴보죠 Xcode 14는 고속 리소스 로딩을 완벽히 지원합니다 Metal 시스템 트레이스를 사용한 런타임 프로파일링부터 API 검사 및 고급 종속성 분석까지 Metal 디버거를 사용해 가능하죠
런타임 프로파일링부터 시작해 볼게요 Metal 시스템 트레이스의 템플릿을 사용하는 Instruments는 Xcode 14에서 고속 리소스 로딩을 프로파일링할 수 있습니다 Instruments는 Metal 앱에서 최고 성능을 달성하도록 도와주는 강력한 분석 및 프로파일링 도구죠 Metal 시스템 트레이스 템블릿을 사용하면 로드 작업이 인코딩되고 실행되는 시기를 확인할 수 있어요 CPU와 GPU에서 앱이 수행하는 작업과 어떤 상관 관계가 있는지도 이해할 수 있습니다 Instruments로 Metal 앱을 프로파일링하는 법을 알아보려면 이전 세션에서 'GPU 카운터로 Metal 앱 및 게임 최적화'와 'Apple GPU용 고급 게임 최적화'를 확인해 보세요 이제 디버깅으로 초점을 옮겨 봅시다 Xcode 14의 Metal 디버거를 사용해 게임이 사용하는 새로운 고속 리소스 로딩 API를 분석할 수 있습니다 프레임 캡처를 수행하면 고속 리소스 로딩 API 호출을 전부 검사할 수 있죠 생성된 IO 명령 버퍼부터 발행된 로드 작업까지 전부요 이제 새로운 Dependency 뷰어를 사용해 고속 리소스 로딩의 종속성을 시각적으로 검사할 수 있습니다 Dependency 뷰어는 IO 명령 버퍼와 Metal 패스 사이의 리소스 종속성에 대해 자세한 개요를 제공하죠 여기에서 새로운 Dependency 뷰어의 모든 기능을 사용할 수 있어요 새로운 동기화 에지 및 그래프 필터링 같은 기능으로 리소스 로딩 종속성을 심층 분석 하고 최적화하니다 Xcode 14의 새로운 Dependency 뷰어에 대해 자세히 알아보고 싶으면 올해의 'Metal 3와 바인딩에서 벗어나기' 세션을 보세요 이제 고속 리소스 로딩의 실제 사례를 볼게요 새로운 고속 리소스 로딩 API를 사용해 텍스처 데이터를 스트리밍하는 테스트 장면이에요 타일 크기가 16K인 스파스 텍스처를 사용했죠 이 영상은 M1 Pro 칩을 탑재한 MacBook Pro에서 만들었죠 스트리밍 시스템은 GPU 스파스 텍스처 접근 카운터를 쿼리하여 두 가지를 식별해요 샘플링을 했지만 로드되지 않은 타일과 로드되었지만 앱에서 사용하지 않는 타일이죠 앱은 이 정보를 사용해 필요한 타일에 대한 로드 목록과 필요하지 않은 타일에 대한 제거 목록을 인코딩합니다 이 방식으로 작업 세트에는 대부분 앱이 사용할 만한 타일만 포함되죠 플레이어가 장면의 다른 부분으로 이동하면 앱은 고해상도 텍스처 세트를 완전히 새롭게 스트리밍해야 해요 스티리밍 시스템이 충분히 빠르면 플레이어는 이 스트리밍이 발생하는 걸 못 알아차리겠죠 장면을 멈추면 이미지 차이를 더 명확히 관찰할 수 있어요 왼쪽은 프리드 API를 사용해 스파스 타일을 단일 스레드로 로드하고 있죠 오른쪽은 고속 리소스 로딩 API로 스파스 타일을 로드하고 있어요 플레이어가 장면에 들어갈 때는 대부분의 텍스처가 완전히 로딩되지 않았죠 로드가 완료되면 최종 고해상도 텍스처를 눈으로 볼 수 있어요 이 장면의 시작 부분으로 돌아가 속도를 늦추면 고속 리소스 로딩이 제공하는 향상된 기능을 더 쉽게 확인할 수 있습니다 차이를 강조하기 위해서 앱이 아직 로드되지 않은 타일을 빨간색으로 표시할게요 처음 장면에서는 앱이 대부분의 타일을 로드하지 않은 게 나와요 하지만 플레이어가 장면에 들어가면 고속 리소스 로딩으로 고해상도 타일이 빠르게 로딩되고 단일 스레드 프리드 버전과 비교해 지연이 최소화된 것을 볼 수 있죠 Metal 3의 고속 리소스 로딩은 최신 저장소 기술을 활용하여 앱이 강력하고 효율적인 자산 스트리밍 시스템을 구축하도록 도와줍니다 고품질 이미지를 포함한 자산을 제때 스트리밍하여 로딩 시간을 단축할 수 있죠 Metal의 공유 이벤트를 사용해 GPU가 장면을 렌더링하는 동안 자산을 비동기적으로 로드해 보세요 앱이 급하게 필요한 자산은 우선 순위가 높은 명령 대기열을 만들어 대기 시간을 최소화하세요 또 로드 명령을 일찍 전송해 저장소 시스템을 계속 사용하는 것도 명심하시고요 필요 없는 건 언제든 취소할 수 있습니다 Metal 3의 고속 리소스 로딩은 최신 저장소 하드웨어의 성능을 활용하는 새로운 방법을 도입해 처리량이 높은 자산을 로딩합니다 여러분이 이 기능을 어떻게 사용해서 앱의 시각적 품질과 반응성을 향상시킬지 기대되네요 봐 주셔서 감사합니다 ♪
-
-
5:19 - Create a handle to an existing file
// Create an Metal File IO Handle // Create handle to an existing file var fileIOHandle: MTLIOFileHandle! do { try fileHandle = device.makeIOHandle(url: filePath) } catch { print(error) }
-
6:49 - Create a Metal IO command queue
// Create a Metal IO command queue let commandQueueDescriptor = MTLIOCommandQueueDescriptor() commandQueueDescriptor.type = MTLIOCommandQueueType.concurrent // or serial var ioCommandQueue: MTLIOCommandQueue! do { try ioCommandQueue = device.makeIOCommandQueue(descriptor: commandQueueDescriptor) } catch { print(error) }
-
7:17 - Create and submit a Metal IO command buffer
// Create Metal IO Command Buffer let ioCommandBuffer = ioCommandQueue.makeCommandBuffer() // Encode load commands // Encode load texture and load buffer commands ioCommandBuffer.load(texture, slice: 0, level: 0, size: size, sourceBytesPerRow:bytesPerRow, sourceBytesPerImage: bytesPerImage, destinationOrigin: destOrigin, sourceHandle: fileHandle, sourceHandleOffset: 0) ioCommandBuffer.load(buffer, offset: 0, size: size, sourceHandle: fileHandle, sourceHandleOffset: 0) // Commit command buffer for execution ioCommandBuffer.commit()
-
8:51 - Synchronize loading and rendering with Metal shared events
var sharedEvent: MTLSharedEvent! sharedEvent = device.makeSharedEvent() // Create Metal IO command buffer let ioCommandBuffer = ioCommandQueue.makeCommandBuffer() ioCommandBuffer.waitForEvent(sharedEvent, value: waitVal) // Encode load commands ioCommandBuffer.signalEvent(sharedEvent, value: signalVal) ioCommandBuffer.commit() // Graphics work waits for the IO command buffer to signal
-
10:29 - TryCancel Metal IO command buffer
// Player in the center region // Encode loads for the North-West region ioCommandBufferNW.commit() // Encode loads for the West region ioCommandBufferW.commit() // Encode loads for the South-West region ioCommandBufferSW.commit() // Player in the western region and heading south // tryCancel NW command buffer ioCommandBufferNW.tryCancel() // .. // .. func regionNWCancelled() -> Bool { return ioCommandBufferNW.status == MTLIOStatus.cancelled }
-
12:28 - Create a High Priority Metal IO command queue
// Create a Metal IO command queue let commandQueueDescriptor = MTLIOCommandQueueDescriptor() commandQueueDescriptor.type = MTLIOCommandQueueType.concurrent // or serial // Set Metal IO command queue Priority commandQueueDescriptor.priority = MTLIOPriority.high // or normal or low var ioCommandQueue: MTLIOCommandQueue! do { try ioCommandQueue = device.makeIOCommandQueue(descriptor: commandQueueDescriptor) } catch { print(error) }
-
14:04 - Create a compressed file
// Create a compressed file // Create compression context let chunkSize = 64 * 1024 let compressionMethod = MTLIOCompressionMethod.zlib let compressionContext = MTLIOCreateCompressionContext(compressedFilePath, compressionMethod, chunkSize) // Append uncompressed file data to the compression context // Get uncompressed file data MTLIOCompressionContextAppendData(compressionContext, filedata.bytes, filedata.length) // Write the compressed file MTLIOFlushAndDestroyCompressionContext(compressionContext)
-
15:05 - Create a handle to a compressed file
// Create an Metal File IO Handle // Create handle to a compressed file var compressedFileIOHandle : MTLIOFileHandle! do { try compressedFileHandle = device.makeIOHandle(url: compressedFilePath, compressionMethod: MTLIOCompressionMethod.zlib) } catch { print(error) }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.