Skip to content

Instantly share code, notes, and snippets.

@ZJUGuoShuai
Created July 31, 2023 09:46
Show Gist options
  • Select an option

  • Save ZJUGuoShuai/2dc56e9be636e1926896bc5d7b43254d to your computer and use it in GitHub Desktop.

Select an option

Save ZJUGuoShuai/2dc56e9be636e1926896bc5d7b43254d to your computer and use it in GitHub Desktop.

ComputeShader class 增加以下三个方法:

// 从 OpenCV Mat 创建(只读的) Metal Texture
- (id<MTLTexture>) textureFromCVMat:(const void*)cv_data Width:(int) w Height:(int)h {
  // Create a Metal texture descriptor
  MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Unorm
                                                                                               width:w
                                                                                              height:h
                                                                                           mipmapped:NO];
  textureDescriptor.storageMode = MTLStorageModeShared;
  
  // Create a Metal texture from the descriptor
  id<MTLTexture> texture = [_device newTextureWithDescriptor:textureDescriptor];

  // Copy the data from the cv::Mat to the Metal texture
  [texture replaceRegion:MTLRegionMake2D(0, 0, w, h) mipmapLevel:0 withBytes:cv_data bytesPerRow:w];

  return texture;
}

// 从宽高创建空的(可写的)Metal Texture
- (id<MTLTexture>) writableTextureWithWidth:(int) w Height:(int)h {
  // Create a Metal texture descriptor
  MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Unorm
                                                                                               width:w
                                                                                              height:h
                                                                                           mipmapped:NO];
  textureDescriptor.storageMode = MTLStorageModeShared;
  textureDescriptor.usage = MTLTextureUsageShaderWrite;
  
  // Create a Metal texture from the descriptor
  id<MTLTexture> texture = [_device newTextureWithDescriptor:textureDescriptor];

  return texture;
}

// 以 src Texture 为输入,进行 Sobel 计算,输出到 dst Texture
-(void) sobel:(id<MTLTexture>)src To:(id<MTLTexture>)dst
{
    id<MTLCommandBuffer> commandBuffer_sobel = [_commandQueue commandBuffer];
    assert(commandBuffer_sobel != nil);
    self.sobelKernel=[[MPSImageSobel alloc] initWithDevice:_device];
    [_sobelKernel encodeToCommandBuffer:commandBuffer_sobel sourceTexture:src  destinationTexture:dst];
   
    [commandBuffer_sobel commit];
    [commandBuffer_sobel waitUntilCompleted];
}

使用方法(在 NLE::pca_smooth_detection() 中):

id<MTLTexture> src_texture = [shader textureFromCVMat:img.data Width:col Height:row];
id<MTLTexture> dst_texture = [shader writableTextureWithWidth:col Height:row];
[shader sobel:src_texture To:dst_texture];

运行效果:

image

@ZJUGuoShuai

Copy link
Copy Markdown
Author

关于 Metal Texture 数据读写,可以参考 Resource Objects: Buffers and Textures

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment