偶尔会发生段故障。我不知道它是否是由[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 ]
命令后报告。有什么不对吗?