金属导致段故障:11

时间:2016-08-05 07:39:30

标签: ios macos metal

偶尔会发生段故障。我不知道它是否是由[MTLComputeComandEncoder setCcomptePipelinestate]方法引起的。相关代码列于以下

void metal_func( void *metal_context,  int16_t *dst, uint8_t *_src, int  _srcstride, int height, int mx, int my, int width)
{
    int x, y;
    pixel        *src       = (pixel*)_src;
    int     srcstride = _srcstride / sizeof(pixel);
    int16_t dst_buf[4900];
    int16_t out_buf[4900];
    int16_t *pdst = dst_buf;
    int16_t *pout = out_buf;
    uint8_t local_src[4900];
    MetalContext *mc = metal_context;
    memset( out_buf, 0, sizeof(int16_t)*4900 );

    int dst_size = sizeof(int16_t)*4900;
    int src_size = sizeof(uint8_t)*4900;

    id<MTLDevice> device = mc->metal_device;
    id<MTLCommandQueue> commandQueue = mc->metal_commandqueue;
    id<MTLComputePipelineState> cpipeline = mc->metal_cps_v;

    // Buffer for storing encoded commands that are sent to GPU
    id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
    id<MTLBuffer> dst_buffer;
    id<MTLBuffer> src_buffer;
    id<MTLBuffer> stride_buffer;
    id<MTLBuffer> mx_buffer;
    id<MTLBuffer> my_buffer;
    id<MTLBuffer> depth_buffer;
    id <MTLComputeCommandEncoder> computeCommandEncoder;

    MTLSize ts= {1, 1, 1};
    MTLSize numThreadgroups = {70*height, 1, 1};
    int m_x = mx;
    int m_y = my;
    int s = _srcstride / sizeof(pixel);
    int i_size = sizeof(int);
    int dpt = BIT_DEPTH;
    memset( pdst, 0, 4900*sizeof(int16_t));

    //copy data to the local_src_buffer
    uint8_t *pcsrc = _src - 3*s;
    uint8_t *pcdst = local_src;
    memset( local_src, 0, sizeof(uint8_t)*4900 );
    for( int i = 0; i < height+7; i++ )
    {
        memcpy( pcdst, pcsrc, sizeof(uint8_t)*width);
        pcsrc += s;
        pcdst += 70;
    }

    int local_src_stride = 70;
    computeCommandEncoder = [commandBuffer computeCommandEncoder];
    //set kernel function parammeters
    dst_buffer  = [device newBufferWithBytes: pdst length: dst_size options: MTLResourceOptionCPUCacheModeDefault ];
    [computeCommandEncoder setBuffer: dst_buffer offset: 0 atIndex: 0 ];
    src_buffer = [device newBufferWithBytes: local_src length: src_size options: MTLResourceOptionCPUCacheModeDefault ];
    [computeCommandEncoder setBuffer: src_buffer offset: 0 atIndex: 1 ];
    stride_buffer = [device newBufferWithBytes: &local_src_stride length: i_size options: MTLResourceOptionCPUCacheModeDefault ];
    [computeCommandEncoder setBuffer: stride_buffer offset: 0 atIndex: 2 ];

    mx_buffer = [device newBufferWithBytes: &m_x length: i_size options: MTLResourceOptionCPUCacheModeDefault ];
    [computeCommandEncoder setBuffer: mx_buffer offset: 0 atIndex: 3 ];
    my_buffer = [device newBufferWithBytes: &m_y length: i_size options: MTLResourceOptionCPUCacheModeDefault ];
    [computeCommandEncoder setBuffer: my_buffer offset: 0 atIndex: 4 ];

    depth_buffer = [device newBufferWithBytes: &dpt length: i_size options: MTLResourceOptionCPUCacheModeDefault ];
    [computeCommandEncoder setBuffer: depth_buffer offset: 0 atIndex: 5 ];

    [computeCommandEncoder setComputePipelineState:cpipeline ];
    **//occasionally, segment fault was reported just after the above commands**   

    [computeCommandEncoder dispatchThreadgroups:numThreadgroups threadsPerThreadgroup:ts];
    [computeCommandEncoder endEncoding ];

    [ commandBuffer commit];
    [ commandBuffer waitUntilCompleted];

    //get the data computed by GPU
    NSData* outdata = [NSData dataWithBytesNoCopy:[dst_buffer contents] length: dst_size freeWhenDone:false   ];
    [outdata getBytes:pout length:dst_size];

    [dst_buffer release];
    [src_buffer release];
    [stride_buffer release];
    [mx_buffer release];
    [my_buffer release];
    [depth_buffer release];

    pout = out_buf;
    pdst = dst;
    for( int j = 0; j < height; j++ )
    {
        memcpy( pdst, pout, sizeof(int16_t)*width );
        pdst += MAX_PB_SIZE;
        pout += 70;
    }
}

MetalContext定义如下。当程序开始时,MetalContext的3个成员在外部初始化,并且它们被初始化一次。

typedef struct {
void * metal_device;
void * metal_commandqueue;
void * metal_cps_v;        
}MetalContext;

代码无法一直成功运行。有时,&#34;段故障:11&#34;在[computeCommandEncoder setComputePipelineState:cpipeline ]命令后报告。有什么不对吗?

0 个答案:

没有答案