Suppose that there is a 200 x 200 color drawable. I want to clear the region(0,0, 100, 100) of the screen to color red. The code is as follows:
- (void)drawInMTKView:(nonnull MTKView *)view
{
// Create a new command buffer for each render pass to the current drawable.
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
commandBuffer.label = @"MyCommand";
// Obtain a renderPassDescriptor generated from the view's drawable textures.
MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 0.0, 0.0, 1.0);
if(renderPassDescriptor != nil)
{
// Create a render command encoder.
id<MTLRenderCommandEncoder> renderEncoder =
[commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
renderEncoder.label = @"MyRenderEncoder";
// Set the region of the drawable to half.
NSUInteger renderAreaWidth = _drawableSize.x/2;
NSUInteger renderAreaHeight = _drawableSize.y/2;
[renderEncoder setViewport:(MTLViewport){0, 0, renderAreaWidth, renderAreaHeight}];
[renderEncoder setScissorRect:(MTLScissorRect){0, 0, renderAreaWidth, renderAreaHeight}];
[renderEncoder endEncoding];
// Schedule a present once the framebuffer is complete using the current drawable.
[commandBuffer presentDrawable:view.currentDrawable];
}
// Finalize rendering here & push the command buffer to the GPU.
[commandBuffer commit];
}
The expected result should be that the top-left part of the drawable was clear to red and the rest is black.
However I found that the entire drawable was clear to red.
How can that be? How do I fix it?
As you've determined, Metal doesn't apply the viewports and scissors to renderpass load-action clearing.
You'll have to clear the sub-region manually: