开发者社区> 问答> 正文

写入MTLTexture会导致致命错误

给出MTLTexture,定义如下。

// Create device.
id<MTLDevice> dev = MTLCreateDefaultSystemDevice();

// Size of texture.
const unsigned int W = 640;
const unsigned int H = 480;

// Define texture.
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
desc.pixelFormat = MTLPixelFormatBGRA8Unorm;
desc.width = W;
desc.height = H;

// Create texture.
id<MTLTexture> tex = [device newTextureWithDescriptor:desc];

据我所知,在这一点上应中定义的纹理desc在设备上分配dev并可通过tex.

现在,给出另一种纹理tex2(已知分配和访问)和金属计算内核定义如下。

kernel void foo(texture2d<float, access::read> in [[texture(0)]],
                texture2d<float, access::write> out [[texture(1)]],
                uint2 pix [[thread_position_in_grid]]) {
    // Out of bounds check.
    if (pix.x >= out.get_width() || pix.y >= out.get_height()) {
        return;
    }

    // Do some processing on the input texture.
    // ... All fine up to here.

    // Write out a pixel to the output buffer.
    const float4 p = abc; // abc is computed above.
    out.write(p, pix);
}

据我所知,当像素p写成out的价值p将转换为符合tex,在这种情况下MTLPixelFormatBGRA8Unorm.

但是,在按如下方式启动内核时,p写成out(以上定义为tex)触发一个关键错误(SIGABRT).

// Create a Metal library.
id<MTLLibrary> lib = [dev newDefaultLibrary];

// Load the kernel.
id<MTLFunction> kernel = [lib newFunctionWithName:@"foo"];

// Create a pipeline state.
id<MTLComputePipelineState> pipelineState = [dev newComputePipelineStateWithFunction:kernel error:NULL];

// Create a command queue.
id<MTLCommandQueue> cmdQueue = [dev newCommandQueue];

// Create command buffer.
id<MTLCommandBuffer> cmdBuff = [cmdQueue commandBuffer];

// Create compute encoder.
id<MTLComputeCommandEncoder> enc = [cmdBuff computeCommandEncoder];

// Set the pipeline state.
[enc setComputePipelineState:pipelineState];

// Set the input textures (tex2 is read only in the kernel, as above).
[enc setTexture:tex2 atIndex:0];
[enc setTexture:tex atIndex:1];

// 2D launch configuration.
const MTLSize groupDim = MTLSizeMake(16, 16, 1);
const MTLSize gridDim = MTLSizeMake((int)ceil((float)(W / (float)groupDim.width)),
                                    (int)ceil((float)(H / (float)groupDim.height)),
                                    1);

// Launch kernel.
[enc dispatchThreadgroups:gridDim threadsPerThreadgroup:groupDim];
[enc endEncoding];
[enc commit];
[cmdBuff waitUntilCompleted];

我的问题是,在上述情况下,我是否理解如何分配MTLTexture对,是这样?或者,上面的示例仅仅定义了包装器围绕一些纹理,我需要分开分配?

展开
收起
游客5akardh5cojhg 2019-12-19 21:10:31 1010 0
0 条回答
写回答
取消 提交回答
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载