Skip to content

Commit 5a2ef3e

Browse files
committed
Fix iOS Metal shader function lookup
1 parent 91f295c commit 5a2ef3e

1 file changed

Lines changed: 84 additions & 21 deletions

File tree

tools/patches/plume-ios-metal.patch

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ index 64e4dc9..1d14600 100644
242242
}
243243
}
244244
diff --git a/plume_metal.cpp b/plume_metal.cpp
245-
index ebbbaa3..0155004 100644
245+
index ebbbaa3..c72adf6 100644
246246
--- a/plume_metal.cpp
247247
+++ b/plume_metal.cpp
248248
@@ -14,8 +14,12 @@
@@ -258,7 +258,7 @@ index ebbbaa3..0155004 100644
258258

259259
#include "plume_metal.h"
260260

261-
@@ -38,6 +42,264 @@ namespace plume {
261+
@@ -38,6 +42,304 @@ namespace plume {
262262
return (n + alignment - 1) & ~(alignment - 1);
263263
}
264264

@@ -351,6 +351,45 @@ index ebbbaa3..0155004 100644
351351
+ };
352352
+
353353
+#if PLUME_IOS
354+
+ bool isMetalIdentifierChar(const char c) {
355+
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
356+
+ }
357+
+
358+
+ std::string findMetalEntryPointName(const std::string& source, const std::string& fallbackName) {
359+
+ for (const char* stagePrefix : { "vertex ", "fragment ", "kernel " }) {
360+
+ size_t searchOffset = 0;
361+
+ while (true) {
362+
+ const size_t stageOffset = source.find(stagePrefix, searchOffset);
363+
+ if (stageOffset == std::string::npos) {
364+
+ break;
365+
+ }
366+
+
367+
+ const size_t openParenOffset = source.find('(', stageOffset);
368+
+ if (openParenOffset == std::string::npos) {
369+
+ break;
370+
+ }
371+
+
372+
+ size_t nameEnd = openParenOffset;
373+
+ while (nameEnd > stageOffset && (source[nameEnd - 1] == ' ' || source[nameEnd - 1] == '\t' || source[nameEnd - 1] == '\r' || source[nameEnd - 1] == '\n')) {
374+
+ nameEnd--;
375+
+ }
376+
+
377+
+ size_t nameStart = nameEnd;
378+
+ while (nameStart > stageOffset && isMetalIdentifierChar(source[nameStart - 1])) {
379+
+ nameStart--;
380+
+ }
381+
+
382+
+ if (nameStart < nameEnd) {
383+
+ return source.substr(nameStart, nameEnd - nameStart);
384+
+ }
385+
+
386+
+ searchOffset = openParenOffset + 1;
387+
+ }
388+
+ }
389+
+
390+
+ return fallbackName;
391+
+ }
392+
+
354393
+ size_t findMetalEntryPointOpenParen(const std::string& source, const std::string& entryPointName, const char* builtinName) {
355394
+ if (!entryPointName.empty()) {
356395
+ const std::string functionNeedle = entryPointName + "(";
@@ -514,6 +553,7 @@ index ebbbaa3..0155004 100644
514553
+ translatedSource.entryPointName = compiler.get_cleansed_entry_point_name(spirvEntryPointName, executionModel);
515554
+ translatedSource.source = compiler.compile();
516555
+#if PLUME_IOS
556+
+ translatedSource.entryPointName = findMetalEntryPointName(translatedSource.source, translatedSource.entryPointName);
517557
+ patchImplicitBaseBuiltinArguments(translatedSource.source, translatedSource.entryPointName);
518558
+#endif
519559
+
@@ -523,7 +563,7 @@ index ebbbaa3..0155004 100644
523563
uint64_t createClearPipelineKey(MTL::RenderPipelineDescriptor *pipelineDesc, bool depthWriteEnabled, bool stencilWriteEnabled) {
524564
auto colorFormat = [&](uint32_t index) {
525565
if (auto colorAttachment = pipelineDesc->colorAttachments()->object(index)) {
526-
@@ -1133,7 +1395,7 @@ namespace plume {
566+
@@ -1133,7 +1435,7 @@ namespace plume {
527567
}
528568

529569
uint64_t MetalBuffer::getDeviceAddress() const {
@@ -532,7 +572,7 @@ index ebbbaa3..0155004 100644
532572
return mtl->gpuAddress();
533573
}
534574

535-
@@ -1278,24 +1540,46 @@ namespace plume {
575+
@@ -1278,24 +1580,46 @@ namespace plume {
536576
assert(device != nullptr);
537577
assert(data != nullptr);
538578
assert(size > 0);
@@ -585,7 +625,7 @@ index ebbbaa3..0155004 100644
585625
if (debugName) {
586626
debugName->release();
587627
}
588-
@@ -1306,10 +1590,16 @@ namespace plume {
628+
@@ -1306,10 +1630,16 @@ namespace plume {
589629
debugName->release();
590630
}
591631
debugName = NS::String::string(name.c_str(), NS::UTF8StringEncoding);
@@ -603,7 +643,30 @@ index ebbbaa3..0155004 100644
603643
MTL::FunctionConstantValues *values = MTL::FunctionConstantValues::alloc()->init();
604644
if (specConstants != nullptr) {
605645
for (uint32_t i = 0; i < specConstantsCount; i++) {
606-
@@ -1437,6 +1727,13 @@ namespace plume {
646+
@@ -1325,6 +1655,10 @@ namespace plume {
647+
fprintf(stderr, "MTLLibrary newFunction: failed with error: %s.\n", error->localizedDescription()->utf8String());
648+
return nullptr;
649+
}
650+
+ if (function == nullptr) {
651+
+ fprintf(stderr, "MTLLibrary newFunction: failed without an error object.\n");
652+
+ return nullptr;
653+
+ }
654+
655+
if (debugName) {
656+
function->setLabel(debugName);
657+
@@ -1384,6 +1718,11 @@ namespace plume {
658+
659+
MTL::ComputePipelineDescriptor *descriptor = MTL::ComputePipelineDescriptor::alloc()->init();
660+
MTL::Function *function = computeShader->createFunction(desc.specConstants, desc.specConstantsCount);
661+
+ if (function == nullptr) {
662+
+ fprintf(stderr, "Metal compute pipeline creation failed: shader function is null.\n");
663+
+ descriptor->release();
664+
+ return;
665+
+ }
666+
descriptor->setComputeFunction(function);
667+
descriptor->setLabel(computeShader->functionName);
668+
669+
@@ -1437,6 +1776,13 @@ namespace plume {
607670
const MetalShader *metalShader = static_cast<const MetalShader *>(desc.vertexShader);
608671

609672
MTL::Function *vertexFunction = metalShader->createFunction(desc.specConstants, desc.specConstantsCount);
@@ -617,7 +680,7 @@ index ebbbaa3..0155004 100644
617680
descriptor->setVertexFunction(vertexFunction);
618681

619682
MTL::VertexDescriptor *vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
620-
@@ -1479,6 +1776,15 @@ namespace plume {
683+
@@ -1479,6 +1825,15 @@ namespace plume {
621684
if (desc.pixelShader != nullptr) {
622685
const MetalShader *pixelShader = static_cast<const MetalShader *>(desc.pixelShader);
623686
MTL::Function *fragmentFunction = pixelShader->createFunction(desc.specConstants, desc.specConstantsCount);
@@ -633,7 +696,7 @@ index ebbbaa3..0155004 100644
633696
descriptor->setFragmentFunction(fragmentFunction);
634697
fragmentFunction->release();
635698
}
636-
@@ -1547,8 +1853,24 @@ namespace plume {
699+
@@ -1547,8 +1902,24 @@ namespace plume {
637700
state.depthBiasSlopeFactor = desc.slopeScaledDepthBias;
638701
}
639702

@@ -660,7 +723,7 @@ index ebbbaa3..0155004 100644
660723
return;
661724
}
662725

663-
@@ -1793,6 +2115,11 @@ namespace plume {
726+
@@ -1793,6 +2164,11 @@ namespace plume {
664727

665728
MetalSwapChain::MetalSwapChain(MetalCommandQueue *commandQueue, const RenderWindow renderWindow, uint32_t textureCount, const RenderFormat format) {
666729
this->layer = static_cast<CA::MetalLayer*>(renderWindow.view);
@@ -672,7 +735,7 @@ index ebbbaa3..0155004 100644
672735
layer->setDevice(commandQueue->device->mtl);
673736
layer->setPixelFormat(mapPixelFormat(format));
674737

675-
@@ -1819,7 +2146,10 @@ namespace plume {
738+
@@ -1819,7 +2195,10 @@ namespace plume {
676739
}
677740

678741
bool MetalSwapChain::present(const uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, const uint32_t waitSemaphoreCount) {
@@ -684,7 +747,7 @@ index ebbbaa3..0155004 100644
684747
NS::AutoreleasePool *releasePool = NS::AutoreleasePool::alloc()->init();
685748

686749
const MetalDrawable &drawable = drawables[textureIndex];
687-
@@ -1861,7 +2191,7 @@ namespace plume {
750+
@@ -1861,7 +2240,7 @@ namespace plume {
688751
bool MetalSwapChain::resize() {
689752
getWindowSize(width, height);
690753

@@ -693,7 +756,7 @@ index ebbbaa3..0155004 100644
693756
return false;
694757
}
695758

696-
@@ -1886,11 +2216,29 @@ namespace plume {
759+
@@ -1886,11 +2265,29 @@ namespace plume {
697760
}
698761

699762
void MetalSwapChain::setVsyncEnabled(const bool vsyncEnabled) {
@@ -723,7 +786,7 @@ index ebbbaa3..0155004 100644
723786
}
724787

725788
uint32_t MetalSwapChain::getWidth() const {
726-
@@ -1910,6 +2258,10 @@ namespace plume {
789+
@@ -1910,6 +2307,10 @@ namespace plume {
727790
assert(textureIndex != nullptr);
728791
assert(*textureIndex < MAX_DRAWABLES);
729792

@@ -734,15 +797,15 @@ index ebbbaa3..0155004 100644
734797
NS::AutoreleasePool *releasePool = NS::AutoreleasePool::alloc()->init();
735798

736799
// Create a command buffer just to encode the signal
737-
@@ -1923,6 +2275,7 @@ namespace plume {
800+
@@ -1923,6 +2324,7 @@ namespace plume {
738801
CA::MetalDrawable *nextDrawable = layer->nextDrawable();
739802
if (nextDrawable == nullptr) {
740803
fprintf(stderr, "No more drawables available for rendering.\n");
741804
+ releasePool->release();
742805
return false;
743806
}
744807

745-
@@ -1954,10 +2307,20 @@ namespace plume {
808+
@@ -1954,10 +2356,20 @@ namespace plume {
746809
}
747810

748811
uint32_t MetalSwapChain::getRefreshRate() const {
@@ -763,7 +826,7 @@ index ebbbaa3..0155004 100644
763826
CocoaWindowAttributes attributes;
764827
windowWrapper->getWindowAttributes(&attributes);
765828
dstWidth = attributes.width;
766-
@@ -3308,6 +3671,9 @@ namespace plume {
829+
@@ -3308,6 +3720,9 @@ namespace plume {
767830
this->renderInterface = renderInterface;
768831

769832
// Device Selection
@@ -773,7 +836,7 @@ index ebbbaa3..0155004 100644
773836
const NS::Array* devices = MTL::CopyAllDevices();
774837
MTL::Device *preferredDevice = nullptr;
775838
for (NS::UInteger i = 0; i < devices->count(); i++) {
776-
@@ -3320,12 +3686,31 @@ namespace plume {
839+
@@ -3320,12 +3735,31 @@ namespace plume {
777840
}
778841

779842
mtl = preferredDevice ? preferredDevice : MTL::CreateSystemDefaultDevice();;
@@ -806,7 +869,7 @@ index ebbbaa3..0155004 100644
806869

807870
// Setup blit, clear and resolve shaders / pipelines
808871
createClearShaderLibrary();
809-
@@ -3337,7 +3722,7 @@ namespace plume {
872+
@@ -3337,7 +3771,7 @@ namespace plume {
810873
// TODO: Support Raytracing.
811874
// capabilities.raytracing = mtl->supportsRaytracing();
812875
capabilities.maxTextureSize = mtl->supportsFamily(MTL::GPUFamilyApple3) ? 16384 : 8192;
@@ -815,7 +878,7 @@ index ebbbaa3..0155004 100644
815878
capabilities.resolveModes = false;
816879
#if PLUME_IOS
817880
capabilities.descriptorIndexing = mtl->supportsFamily(MTL::GPUFamilyApple3);
818-
@@ -3345,11 +3730,11 @@ namespace plume {
881+
@@ -3345,11 +3779,11 @@ namespace plume {
819882
capabilities.descriptorIndexing = true;
820883
#endif
821884
capabilities.scalarBlockLayout = true;
@@ -830,7 +893,7 @@ index ebbbaa3..0155004 100644
830893
capabilities.gpuUploadHeap = capabilities.uma;
831894
capabilities.queryPools = false;
832895

833-
@@ -3357,17 +3742,19 @@ namespace plume {
896+
@@ -3357,17 +3791,19 @@ namespace plume {
834897
}
835898

836899
MetalDevice::~MetalDevice() {
@@ -856,7 +919,7 @@ index ebbbaa3..0155004 100644
856919
}
857920

858921
std::unique_ptr<RenderDescriptorSet> MetalDevice::createDescriptorSet(const RenderDescriptorSetDesc &desc) {
859-
@@ -3635,16 +4022,24 @@ namespace plume {
922+
@@ -3635,16 +4071,24 @@ namespace plume {
860923

861924
MetalInterface::MetalInterface() {
862925
NS::AutoreleasePool *releasePool = NS::AutoreleasePool::alloc()->init();

0 commit comments

Comments
 (0)