2016-06-28 11 views
0

나는 커널 함수 (컴퓨 트 쉐이더)가에 쓰는 동안 이전 값을 읽기는 현재 픽셀의 값 (를 업데이트 간단한 회선이 아닙니다).아이폰 OS 금속 - 텍스처에서 픽셀의 주변 픽셀을 읽고 이전 근처의 픽셀 값에 따라 질감

내가 BlitCommandEncoder를 사용하여 질감의 사본을 만들고 2 개 텍스처 커널 함수를 먹이 시도했습니다 - 하나 개의 읽기 전용 및 다른 쓰기 전용. 불행하게도,이 방법은 GPU에 많은 시간을 소비합니다.

컨텐츠를 업데이트하는 동안 텍스처에서 이전 값을 읽는 가장 효율적인 (위해 GPU와 메모리 현명한) 방법은 무엇입니까?

+0

당신은 (악기의) 시간 프로파일과 (엑스 코드에서) GPU 프레임 캡처하여 응용 프로그램을 프로파일 적이 있습니까? 리소스를 할당하고, 복사하고, 실행하는 데 소비하는 시간을 결정하면 먼저 최적화 할 항목을 파악하는 데 도움이됩니다. – warrenm

+0

@warrenm 응답 해 주셔서 감사합니다. 'BlitCommandEncoder'를 사용하는 루틴이 지연을 야기한 다른 시간 소모적 인 함수를 호출하고 있음을 알 수 있습니다. Blit 연산은 지연의 주요 원인이 아니 었습니다. 그것은 제 잘못이었습니다. 그러나 GPU 프레임 캡처를 살펴보면 Blit 연산의 지속 시간은 Compute 연산과 반대되는 것으로 나타났습니다. 이러한 연산을 측정 할 방법이 없습니까? – sarasvati

+0

현재 GPU 프레임 캡처에서 계산 인코더 지속 시간을 캡처하는 방법이 없다고 생각합니다. 미안합니다. – warrenm

답변

2

(비트 늦었지만 잘 오) 당신이 하나 개의 텍스처와 함께 작동 할 수있는 방법이 없다

GPU는 고도의 병렬 프로세서이기 때문에 : 당신이 호출되는 하나의 픽셀에 대해 쓴 커널 모든 픽셀에 대해 평행선을 사용하면 어떤 픽셀이 먼저 표시되는지 알 수 없습니다.

그래서 당신은 확실히 2 개 텍스처가 필요합니다. 당신이해야 할 일은 하나는 "오래된"것이고 다른 하나는 "새로운 것"인 2 개의 텍스처를 사용하는 것입니다. 패스 간에는 텍스처의 역할을 바꿉니다. 이제는 새 것이고 새로운 것은 오래된 것입니다. 여기에 몇 가지 의사 슬라이드가 있습니다 :

var currentText = MTLTexture() 
var nextText = MTLTexture() 

let semaphore = dispatch_semaphore_create(1) 

func update() { 
    dispatch_semaphore_wait(semaphore) // Wait for updating done signal 

    let commands = commandQueue.commandBuffer() 
    let encoder = commands.computeCommandEncoder() 

    encoder.setTexture(currentText, atIndex: 0) 
    encoder.setTexture(nextText, atIndex: 1) 

    encoder.dispatchThreadgroups(...) 
    encoder.endEncoding() 

    // When updating done, swap the textures and signal that it's done updating 
    commands.addCompletionHandler { 
     swap(&currentText, &nextText) 
     dispatch_semaphore_signal(semaphore) 
    } 
    commands.commit() 
} 
0

나는 렌더링되는 동일한 텍스처를 샘플링 (또는 읽음)하는 많은 iOS Metal 코드를 작성했습니다. 렌더링 파이프 라인을 사용하고 렌더링 텍스처 첨부 파일로 텍스처를 설정하고 소스 텍스처로로드합니다. 그것은 잘 작동합니다.

분명히하기 위해,보다 효율적인 접근 방법은 당신의 조각 쉐이더에 color() 속성을 사용하는 것입니다,하지만 당신이 필요로하는 모든이 현재 조각의 값이 아닌 다른 가까운 위치 인 경우 그에만 적합합니다. 당신이 렌더 타겟의 다른 위치에서 읽을 필요가 있다면, 난 그냥 프레 그먼트 쉐이더로 소스 텍스처로 렌더링 타겟을로드 할 것입니다.