3

我已经坚持了一段时间了;这不是一个特别昂贵的着色器(至少,基于我对 Metal 的非常有限的经验),但我仍然在前几帧收到此消息:

Execution of the command buffer was aborted due to an error during execution. Caused GPU Hang Error (IOAF code 3)

然后我得到这个所有后续帧:

Execution of the command buffer was aborted due to an error during execution. Ignored (for causing prior/excessive GPU errors) (IOAF code 4)

这是顶点着色器,它实际上并没有做任何事情:

vertex VertexOut viewportProgram(uint vertexID [[ vertex_id ]],
                                 constant float2 *positions [[ buffer(0) ]],
                                 constant float2 *texcoords [[ buffer(1) ]]) {
    VertexOut out;

    out.position.xy = positions[vertexID];
    out.position.z = 0.0; // Only 2D; no depth
    out.position.w = 1.0; // Only 2D; no perspective divide

    out.texcoord = texcoords[vertexID];

    return out;
}

这是我的片段着色器,它将颜色从 YUV 转换为 RGB:

fragment float4 colorConvertProgram(VertexOut in [[stage_in]],
                                texture2d<float, access::sample> yTexture [[ texture(0) ]],
                                texture2d<float, access::sample> uvTexture [[ texture(1) ]],
                                sampler textureSampler [[ sampler(0) ]]) {


    float3 colorOffset = float3(-(16.0/255.0), -0.5, -0.5);
    float3x3 colorMatrix = float3x3(float3(1.164,  0.000,  1.596),
                                    float3(1.164, -0.392, -0.813),
                                    float3(1.164,  2.017,  0.000));

    float3 yuv = float3(yTexture.sample(textureSampler, in.texcoord).r,
                    uvTexture.sample(textureSampler, in.texcoord).rg);
    float3 rgb = (yuv + colorOffset) * colorMatrix;

    return float4(rgb, 1.0);
}

这是我的 Swift 代码,将它们组合在一起:

    let samplerDescriptor = MTLSamplerDescriptor()
    samplerDescriptor.minFilter = .linear
    samplerDescriptor.mipFilter = .linear
    samplerDescriptor.sAddressMode = .clampToZero
    samplerDescriptor.tAddressMode = .clampToZero
    let sampler = device.makeSamplerState(descriptor: samplerDescriptor)

    renderEncoder.setViewport(MTLViewport(originX: 0.0, originY: 0.0,
                                          width: Double(bounds.width),
                                          height: Double(bounds.height),
                                          znear: -1.0, zfar: 1.0))
    renderEncoder.setRenderPipelineState(renderPipelineState)
    renderEncoder.setVertexBuffer(vertexPositionBuffer, offset: 0, index: 0)
    renderEncoder.setVertexBuffer(vertexTexcoordBuffer, offset: 0, index: 1)
    renderEncoder.setFragmentTexture(yTexture, index: 0)
    renderEncoder.setFragmentTexture(uvTexture, index: 1)
    renderEncoder.setFragmentSamplerState(sampler, index: 0)
    renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4)
    renderEncoder.endEncoding()

    commandBuffer.present(drawable)
    commandBuffer.commit()
4

0 回答 0