我正在使用以下代码向显示器展示 MTLTexture。这是一个大的(~12k)纹理,需要大约 10 毫秒来绘制。由于我需要渲染至少30FPS(33 毫秒/帧),因此仅显示纹理就需要将近三分之一的计算时间。
是否有任何技巧可以提高性能并更快地绘制纹理?在 GPU 帧捕获中,它显示了大量的剔除时间。我尝试启用/禁用剔除,但我仍然看到用于剔除的时间相同。
vertex TextureMappingVertex mapTexture(unsigned int vertex_id [[ vertex_id ]], constant Uniforms& uniforms [[ buffer(0) ]]) {
float4x4 renderedCoordinates = float4x4(float4( -1.f, -1.f, 0.f, 1.f ),
float4( 1.f, -1.f, 0.f, 1.f ),
float4( -1.f, 1.f, 0.f, 1.f ),
float4( 1.f, 1.f, 0.f, 1.f ));
float4x2 textureCoordinates = float4x2(float2( 0.f, 1.f ),
float2( 1.f, 1.f ),
float2( 0.f, 0.f ),
float2( 1.f, 0.f ));
TextureMappingVertex outVertex;
outVertex.renderedCoordinate = uniforms.mvp_matrix * renderedCoordinates[vertex_id];
outVertex.textureCoordinate = textureCoordinates[vertex_id];
return outVertex;
}
fragment half4 displayTexture(TextureMappingVertex mappingVertex [[ stage_in ]],
texture2d<half, access::sample> texture [[ texture(0) ]]) {
constexpr sampler s(address::clamp_to_edge, filter::nearest);
return half4(texture.sample(s, mappingVertex.textureCoordinate));
}
func draw(in view: MTKView) {
guard let commandBuffer = commandQueue.makeCommandBuffer() else { return }
guard let descriptor = view.currentRenderPassDescriptor else {return}
let render = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor)
render?.pushDebugGroup("Render to Screen")
render?.setRenderPipelineState(renderCanvasPipelineState)
render?.setFragmentTexture(canvasTexture, index: 0)
render?.setVertexBuffer(uniformBuffer, offset: 0, index: 0)
render?.setCullMode(.none)
render?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1)
render?.popDebugGroup()
render?.endEncoding()
guard let drawable = view.currentDrawable else { return }
commandBuffer.present(drawable)
commandBuffer.commit()
}
func initializeCanvasRenderPipelineState() {
let library = Renderer.device.makeDefaultLibrary()
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.sampleCount = 1
pipelineDescriptor.rasterSampleCount = 1
pipelineDescriptor.colorAttachments[0].pixelFormat = .rgba8Unorm
pipelineDescriptor.depthAttachmentPixelFormat = .invalid
pipelineDescriptor.vertexFunction = library?.makeFunction(name: "mapTexture")
pipelineDescriptor.fragmentFunction = library?.makeFunction(name: "displayTexture")
pipelineDescriptor.colorAttachments[0].isBlendingEnabled = false
do {
try renderCanvasPipelineState = Renderer.device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
catch {
assertionFailure("Failed creating a render state pipeline. Can't render the texture without one.")
return
}
}