Skip to content

Commit

Permalink
cocoaui: better fix for metal API validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksiy-Yakovenko committed Nov 2, 2024
1 parent ac84379 commit d63c1ef
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,7 @@ - (void)displayLayer:(CALayer *)layer {

#pragma mark - ShaderRendererDelegate

- (BOOL)canDraw {
return _draw_data.points != NULL;
}

- (void)applyFragParamsWithViewport:(vector_uint2)viewport device:(id<MTLDevice>)device encoder:(id<MTLRenderCommandEncoder>)encoder viewParams:(ShaderRendererParams)viewParams {
- (BOOL)applyFragParamsWithViewport:(vector_uint2)viewport device:(id<MTLDevice>)device encoder:(id<MTLRenderCommandEncoder>)encoder viewParams:(ShaderRendererParams)viewParams {
float scale = (float)(viewParams.backingScaleFactor / [self scaleFactorForBackingScaleFactor:viewParams.backingScaleFactor]);

struct ScopeFragParams params;
Expand All @@ -416,11 +412,19 @@ - (void)applyFragParamsWithViewport:(vector_uint2)viewport device:(id<MTLDevice>
params.scale = scale;
[encoder setFragmentBytes:&params length:sizeof (params) atIndex:0];

// Metal documentation states that MTLBuffer should be used for buffers larger than 4K in size.
// Alternative is to use setFragmentBytes, which also works, but could have compatibility issues on older hardware.
id<MTLBuffer> buffer = [device newBufferWithBytes:_draw_data.points length:_draw_data.point_count * sizeof (ddb_scope_point_t) * params.channels options:0];
if (_draw_data.points == NULL) {
char bytes[12] = {0};
[encoder setFragmentBytes:bytes length:12 atIndex:1];
}
else {
// Metal documentation states that MTLBuffer should be used for buffers larger than 4K in size.
// Alternative is to use setFragmentBytes, which also works, but could have compatibility issues on older hardware.
id<MTLBuffer> buffer = [device newBufferWithBytes:_draw_data.points length:_draw_data.point_count * sizeof (ddb_scope_point_t) * params.channels options:0];

[encoder setFragmentBuffer:buffer offset:0 atIndex:1];
[encoder setFragmentBuffer:buffer offset:0 atIndex:1];
}

return YES;
}

@end
3 changes: 1 addition & 2 deletions plugins/cocoaui/Visualization/Shared/ShaderRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ typedef struct {
} ShaderRendererParams;

@protocol ShaderRendererDelegate
- (BOOL)canDraw;
- (void)applyFragParamsWithViewport:(vector_uint2)viewport device:(nonnull id <MTLDevice>)device encoder:(nonnull id <MTLRenderCommandEncoder>)encoder viewParams:(ShaderRendererParams)params;
- (BOOL)applyFragParamsWithViewport:(vector_uint2)viewport device:(nonnull id <MTLDevice>)device encoder:(nonnull id <MTLRenderCommandEncoder>)encoder viewParams:(ShaderRendererParams)params;
@end

@interface ShaderRenderer : NSObject
Expand Down
30 changes: 14 additions & 16 deletions plugins/cocoaui/Visualization/Shared/ShaderRenderer.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ - (void)drawableResize:(CGSize)drawableSize
}

- (void)renderToMetalLayer:(nonnull CAMetalLayer*)metalLayer viewParams:(ShaderRendererParams)viewParams {
if (![self.delegate canDraw]) {
return;
}
if (_viewportSize.width == 0 || _viewportSize.height == 0) {
return;
}
Expand Down Expand Up @@ -159,22 +156,23 @@ - (void)renderToMetalLayer:(nonnull CAMetalLayer*)metalLayer viewParams:(ShaderR

[renderEncoder setRenderPipelineState:_pipelineState];

// Pass in the parameter data.
[renderEncoder setVertexBytes:quadVertices
length:sizeof(quadVertices)
atIndex:ShaderRendererVertexInputIndexVertices];

vector_uint2 vp = { (uint)_viewportSize.width, (uint)_viewportSize.height };
[renderEncoder setVertexBytes:&vp
length:sizeof(vp)
atIndex:ShaderRendererVertexInputIndexViewportSize];
if ([self.delegate applyFragParamsWithViewport:vp device:_device encoder:renderEncoder viewParams:viewParams]) {
// Pass in the parameter data.
[renderEncoder setVertexBytes:quadVertices
length:sizeof(quadVertices)
atIndex:ShaderRendererVertexInputIndexVertices];

[self.delegate applyFragParamsWithViewport:vp device:_device encoder:renderEncoder viewParams:viewParams];
[renderEncoder setVertexBytes:&vp
length:sizeof(vp)
atIndex:ShaderRendererVertexInputIndexViewportSize];

// Draw the triangle.
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip
vertexStart:0
vertexCount:4];
// Draw the triangle.
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip
vertexStart:0
vertexCount:4];

}

// end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,11 +437,7 @@ - (void)displayLayer:(CALayer *)layer {

#pragma mark - ShaderRendererDelegate

- (BOOL)canDraw {
return _draw_data.bars != NULL;
}

- (void)applyFragParamsWithViewport:(vector_uint2)viewport device:(id<MTLDevice>)device encoder:(id<MTLRenderCommandEncoder>)encoder viewParams:(ShaderRendererParams)viewParams {
- (BOOL)applyFragParamsWithViewport:(vector_uint2)viewport device:(id<MTLDevice>)device encoder:(id<MTLRenderCommandEncoder>)encoder viewParams:(ShaderRendererParams)viewParams {

struct SpectrumFragParams params;

Expand All @@ -462,8 +458,14 @@ - (void)applyFragParamsWithViewport:(vector_uint2)viewport device:(id<MTLDevice>
assert(sizeof(struct SpectrumFragBar) == sizeof (ddb_analyzer_draw_bar_t));

// bar data
if (_draw_data.bars == NULL) {
char bytes[12] = {0};
[encoder setFragmentBytes:bytes length:12 atIndex:1];

if (_draw_data.mode == DDB_ANALYZER_MODE_FREQUENCIES) {
// This buffer is unused in this scenario, but necessary to shut up API validator
[encoder setFragmentBytes:bytes length:4 atIndex:2];
}
else if (_draw_data.mode == DDB_ANALYZER_MODE_FREQUENCIES) {
// In this scenario, the buffer is too large, need to use MTLBuffer.
id<MTLBuffer> buffer = [device newBufferWithBytes:_draw_data.bars length:_draw_data.bar_count * sizeof (struct SpectrumFragBar) options:0];

Expand All @@ -482,5 +484,7 @@ - (void)applyFragParamsWithViewport:(vector_uint2)viewport device:(id<MTLDevice>
// This buffer is unused in this scenario, but necessary to shut up API validator
[encoder setFragmentBytes:_draw_data.bars length:4 atIndex:2];
}

return YES;
}
@end

0 comments on commit d63c1ef

Please sign in to comment.