Skip to content

Commit

Permalink
[Metal] Fixed crash in Metal PSO creation when invalid shaders are pr…
Browse files Browse the repository at this point in the history
…ovided.

LLGL should no longer throw an exception on PSO creation failure.
This replaces the old behavior in the Metal backend with the error report like in the other baackends.
  • Loading branch information
LukasBanana committed May 22, 2024
1 parent 6a3e698 commit 8a78d24
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
10 changes: 8 additions & 2 deletions sources/Renderer/Metal/RenderState/MTComputePSO.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@
/* Get native shader functions */
computeShader_ = LLGL_CAST(const MTShader*, desc.computeShader);
if (!computeShader_)
throw std::invalid_argument("cannot create Metal compute pipeline without compute shader");
{
GetMutableReport().Errorf("cannot create Metal compute pipeline without compute shader");
return;
}

id<MTLFunction> kernelFunc = computeShader_->GetNative();
if (!kernelFunc)
throw std::invalid_argument("cannot create Metal compute pipeline without valid compute kernel function");
{
GetMutableReport().Errorf("cannot create Metal compute pipeline without valid compute kernel function");
return;
}

/* Create native compute pipeline state */
NSError* error = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion sources/Renderer/Metal/RenderState/MTGraphicsPSO.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class MTGraphicsPSO final : public MTPipelineState

private:

void CreateRenderPipelineState(
bool CreateRenderPipelineState(
id<MTLDevice> device,
const GraphicsPipelineDescriptor& desc,
const MTRenderPass* defaultRenderPass
Expand Down
21 changes: 17 additions & 4 deletions sources/Renderer/Metal/RenderState/MTGraphicsPSO.mm
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ static void FillDefaultMTStencilDesc(MTLStencilDescriptor* dst)
blendColor_[3] = desc.blend.blendFactor[3];

/* Create render pipeline and depth-stencil states */
CreateRenderPipelineState(device, desc, defaultRenderPass);
CreateDepthStencilState(device, desc);
BuildStaticStateBuffer(desc);
if (CreateRenderPipelineState(device, desc, defaultRenderPass))
{
CreateDepthStencilState(device, desc);
BuildStaticStateBuffer(desc);
}
}

void MTGraphicsPSO::Bind(id<MTLRenderCommandEncoder> renderEncoder)
Expand Down Expand Up @@ -202,7 +204,7 @@ static void FillColorAttachmentDesc(
return vertexShaderMT;
}

void MTGraphicsPSO::CreateRenderPipelineState(
bool MTGraphicsPSO::CreateRenderPipelineState(
id<MTLDevice> device,
const GraphicsPipelineDescriptor& desc,
const MTRenderPass* defaultRenderPass)
Expand All @@ -214,7 +216,16 @@ static void FillColorAttachmentDesc(
numPatchControlPoints_ = vertexShaderMT->GetNumPatchControlPoints();

if (id<MTLFunction> vertexFunc = vertexShaderMT->GetNative())
{
/* Cache patch type of vertex function */
patchType_ = [vertexFunc patchType];
}
else
{
/* Error: Every graphics PSO needs a valid vertex function */
GetMutableReport().Errorf("cannot create Metal graphics PSO without valid vertex function");
return false;
}

/* Get render pass object */
const MTRenderPass* renderPassMT = nullptr;
Expand Down Expand Up @@ -288,6 +299,8 @@ static void FillColorAttachmentDesc(
else
throw std::invalid_argument("cannot create Metal tessellation pipeline without tessellation compute shader");
}

return true;
}

id<MTLRenderPipelineState> MTGraphicsPSO::CreateNativeRenderPipelineState(
Expand Down

0 comments on commit 8a78d24

Please sign in to comment.