[iOS, GPU] Metal의 그리기 파이프라인을 도해해 본다

6179 단어 C++iOSSwift금속GPU
Apple에서 제작 한 GPU 셰이더 언어 Metal에서 초등학교는 잡기 어려운 드로잉 메커니즘을 보여 주면서 설명하고 싶습니다.

소개



거꾸로 Metal에서는 다음과 같은 순서로 묘화가 행해집니다.
  • 그리기 정보 설정 (정점 및 색상 설정 등)
  • 그리기 명령 생성 및 전송
  • Shader (.Metal 확장자에 쓰여진 그리기 함수)와 같이 그리기를 수행합니다.



  • 이하, 이들 각각의 개략을 그림과 함께보고 싶습니다.

    그리기 정보 설정



    우선 그림에 기재된
    - MTLRenderPipelineDescriptor
    - MTLRenderPassDescriptor
    두 객체에 그리기 정보를 설정하고 그리기 명령으로 전달합니다.


    let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
    let depthStencilDescriptor = MTLDepthStencilDescriptor()
    

    MTLRenderPipelineDescriptor



    주로,
    ・정점 묘화용의 함수 (VertexFunction)
    · 정점 그리기 설정 (VertexDescriptor)
    ・정점의 색정보 결정하기 위한 함수 (FragmentFunction)
    등을 MTTLRenderPipelineDescriptor 객체의 속성으로 설정합니다.

    그런 다음 MTLPipelineState 개체가 MTTLRenderPipelineDescriptor에서 생성됩니다.
    따라서 MTLPipelineState (그리기 설정을 유지하고 정보를 GPU에 명령을 전달하는 데 사용)를 만듭니다.

    또한 Depth 정보는 MTLDepthStencilDescriptor 객체로 설정합니다.

    자세한 내용은 여기 공식에서 소개 된 소스 코드를 참조하십시오.

    MTLRenderPathDescriptor



    주로 출력 대상 설정이 수행됩니다. 출력으로 MTLTexture를 설정하여 GPU 계산을 수행하고 CPU에 결과 MTLTexure를 반환 할 수도 있습니다.

    다음과 같이 기본 mtkView에서 매 프레임을 가져 와서 설정을 수행합니다. MTLRenderPathDescriptor는 매 프레임에서 초기화되므로 그림과 프레임을 설정해야합니다.
    let renderPassDescriptor = mtkView.currentRenderPassDescriptor
    

    그리기 명령 생성 및 전송



    기본 흐름



    방금 그리기 설정은 아래 그림과 같이 MTLCommandBuffer에 전달되며이를 사용하여 MTLRenderCommandEncoder 클래스 객체를 생성합니다.
    이 ... CommandEncoder는 GPU가 해석 가능한 데이터로 간주됩니다.


    commandQueue = device.makeCommandQueue()
    let commandBuffer = commandQueue.makeCommandBuffer()
    

    이 commandBuffer에 필요한 이미지와 같은 데이터를 설정하여 GPU 그리기를 수행합니다.

    다른 흐름



    그리기를 사용자 정의하고 실행하려면 위의 MTLCommandBuffer 설정이 필요하지만 사용자 지정 그리기가 아닌 경우 MTLCommandBuffer를 건너 뛸 수 있습니다 (위 그림의 보라색 화살표).
    예를 들어 내장 이미지 필터 카운티는 기본이 사양입니다.
    let filter = MPSImageGaussianBlur(device: device!, sigma: 5)
    
                filter.encode(commandBuffer: commandBuffer,
                              sourceTexture: secTex, destinationTexture: dstTex)
    

    Shader



    마지막은 Shader입니다.

    Shader 함수는 앞에서 설명한 MTLRenderPipelineDescriptor 시점에서 문자열로 설정된 함수를 사용합니다.


    let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
    
    // (MTLTextureを順にセットする等、必要な処理を実行)
    
    renderEncoder.endEncoding()
    commandBuffer.present(currentDrawable) // 描画
    commandBuffer.commit() // 描画完了
    

    먼저 MTLComanndBuffeer에서 MTLRenderEncoder가 생성됩니다.
    이 MTLRenderEncoder는 앞에서 설명한 MTLRenderPipelineState 객체도 입력합니다.

    (Shader의 구조는 본고에 추기하거나 혹은 다른 기사에서 형태로 후일 설명합니다)

    참고



    Metal의 각종 Tips에 대해서, 여기의 기사에 정리하고 있으므로 아울러 참고에 주실 수 있으면 다행입니다.

    끝에



    개선점이나 의견 등 있으면, 꼭 댓글주세요!

    좋은 웹페이지 즐겨찾기