我已经坚持了一段时间了;这不是一个特别昂贵的着色器(至少,基于我对 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()