Skip to content

Commit 778fc11

Browse files
chinmaygardednfield
authored andcommitted
Allow shader libraries to look at multiple shader dylibs.
1 parent 97455db commit 778fc11

File tree

6 files changed

+77
-35
lines changed

6 files changed

+77
-35
lines changed

impeller/playground/playground.mm

+12-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,19 @@
3535
return fml::paths::JoinPaths({path_result.second, "shaders"});
3636
}
3737

38+
static std::vector<std::string> ShaderLibraryPathsForPlayground() {
39+
std::vector<std::string> paths;
40+
paths.emplace_back(fml::paths::JoinPaths(
41+
{ShaderLibraryDirectory(), "shader_fixtures.metallib"}));
42+
paths.emplace_back(
43+
fml::paths::JoinPaths({fml::paths::GetExecutableDirectoryPath().second,
44+
"shaders", "entity.metallib"}));
45+
return paths;
46+
}
47+
3848
Playground::Playground()
39-
: renderer_(std::make_shared<ContextMTL>(ShaderLibraryDirectory(),
40-
"shader_fixtures.metallib")) {}
49+
: renderer_(
50+
std::make_shared<ContextMTL>(ShaderLibraryPathsForPlayground())) {}
4151

4252
Playground::~Playground() = default;
4353

impeller/renderer/backend/metal/context_mtl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace impeller {
2222
class ContextMTL final : public Context,
2323
public BackendCast<ContextMTL, Context> {
2424
public:
25-
ContextMTL(std::string shaders_directory, std::string main_library_file_name);
25+
ContextMTL(const std::vector<std::string>& shader_libraries);
2626

2727
// |Context|
2828
~ContextMTL() override;

impeller/renderer/backend/metal/context_mtl.mm

+32-25
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "impeller/renderer/backend/metal/context_mtl.h"
66

7+
#include <Foundation/Foundation.h>
8+
79
#include "flutter/fml/file.h"
810
#include "flutter/fml/logging.h"
911
#include "flutter/fml/paths.h"
@@ -12,8 +14,30 @@
1214

1315
namespace impeller {
1416

15-
ContextMTL::ContextMTL(std::string shaders_directory,
16-
std::string main_library_file_name)
17+
static NSArray<id<MTLLibrary>>* ShaderLibrariesFromFiles(
18+
id<MTLDevice> device,
19+
const std::vector<std::string>& libraries_paths) {
20+
NSMutableArray<id<MTLLibrary>>* found_libraries = [NSMutableArray array];
21+
for (const auto& library_path : libraries_paths) {
22+
if (!fml::IsFile(library_path)) {
23+
FML_LOG(ERROR) << "Shader library does not exist at path '"
24+
<< library_path << "'";
25+
continue;
26+
}
27+
NSError* shader_library_error = nil;
28+
auto library = [device newLibraryWithFile:@(library_path.c_str())
29+
error:&shader_library_error];
30+
if (!library) {
31+
FML_LOG(ERROR) << "Could not create shader library: "
32+
<< shader_library_error.localizedDescription.UTF8String;
33+
continue;
34+
}
35+
[found_libraries addObject:library];
36+
}
37+
return found_libraries;
38+
}
39+
40+
ContextMTL::ContextMTL(const std::vector<std::string>& libraries_paths)
1741
: device_(::MTLCreateSystemDefaultDevice()) {
1842
// Setup device.
1943
if (!device_) {
@@ -33,31 +57,14 @@
3357

3458
// Setup the shader library.
3559
{
36-
NSError* shader_library_error = nil;
37-
auto shader_library_path =
38-
fml::paths::JoinPaths({shaders_directory, main_library_file_name});
39-
40-
auto library_exists = fml::IsFile(shader_library_path);
41-
42-
if (!library_exists) {
43-
FML_LOG(ERROR) << "Shader library does not exist at path '"
44-
<< shader_library_path
45-
<< "'. No piplines can be created in this context.";
46-
}
47-
auto library =
48-
library_exists
49-
? [device_ newLibraryWithFile:@(shader_library_path.c_str())
50-
error:&shader_library_error]
51-
: [device_ newDefaultLibrary];
52-
if (!library && shader_library_error) {
53-
FML_LOG(ERROR) << "Could not create shader library: "
54-
<< shader_library_error.localizedDescription.UTF8String;
60+
// std::make_shared disallowed because of private friend ctor.
61+
auto library = std::shared_ptr<ShaderLibraryMTL>(new ShaderLibraryMTL(
62+
ShaderLibrariesFromFiles(device_, libraries_paths)));
63+
if (!library->IsValid()) {
64+
FML_DLOG(ERROR) << "Could not create valid Metal shader library.";
5565
return;
5666
}
57-
58-
// std::make_shared disallowed because of private friend ctor.
59-
shader_library_ =
60-
std::shared_ptr<ShaderLibraryMTL>(new ShaderLibraryMTL(library));
67+
shader_library_ = std::move(library);
6168
}
6269

6370
// Setup the pipeline library.

impeller/renderer/backend/metal/shader_library_mtl.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#pragma once
66

7+
#include <Foundation/Foundation.h>
78
#include <Metal/Metal.h>
89

910
#include <memory>
@@ -23,6 +24,9 @@ class ShaderLibraryMTL final : public ShaderLibrary {
2324
// |ShaderLibrary|
2425
~ShaderLibraryMTL() override;
2526

27+
// |ShaderLibrary|
28+
bool IsValid() const override;
29+
2630
private:
2731
friend class ContextMTL;
2832

@@ -53,10 +57,11 @@ class ShaderLibraryMTL final : public ShaderLibrary {
5357
ShaderKey::Equal>;
5458

5559
UniqueID library_id_;
56-
id<MTLLibrary> library_ = nullptr;
60+
NSArray<id<MTLLibrary>>* libraries_ = nullptr;
5761
Functions functions_;
62+
bool is_valid_ = false;
5863

59-
ShaderLibraryMTL(id<MTLLibrary> library);
64+
ShaderLibraryMTL(NSArray<id<MTLLibrary>>* libraries);
6065

6166
// |ShaderLibrary|
6267
std::shared_ptr<const ShaderFunction> GetFunction(

impeller/renderer/backend/metal/shader_library_mtl.mm

+23-5
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,25 @@
88

99
namespace impeller {
1010

11-
ShaderLibraryMTL::ShaderLibraryMTL(id<MTLLibrary> library)
12-
: library_(library) {}
11+
ShaderLibraryMTL::ShaderLibraryMTL(NSArray<id<MTLLibrary>>* libraries)
12+
: libraries_(libraries) {
13+
if (libraries_ == nil || libraries_.count == 0) {
14+
return;
15+
}
16+
17+
is_valid_ = true;
18+
}
1319

1420
ShaderLibraryMTL::~ShaderLibraryMTL() = default;
1521

22+
bool ShaderLibraryMTL::IsValid() const {
23+
return is_valid_;
24+
}
25+
1626
std::shared_ptr<const ShaderFunction> ShaderLibraryMTL::GetFunction(
1727
const std::string_view& name,
1828
ShaderStage stage) {
19-
if (!library_) {
29+
if (!IsValid()) {
2030
return nullptr;
2131
}
2232

@@ -26,8 +36,16 @@
2636
return found->second;
2737
}
2838

29-
auto function = [library_ newFunctionWithName:@(name.data())];
30-
if (!function) {
39+
id<MTLFunction> function = nil;
40+
41+
for (size_t i = 0, count = [libraries_ count]; i < count; i++) {
42+
function = [libraries_[i] newFunctionWithName:@(name.data())];
43+
if (function) {
44+
break;
45+
}
46+
}
47+
48+
if (function == nil) {
3149
return nullptr;
3250
}
3351

impeller/renderer/shader_library.h

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class ShaderLibrary {
1919
public:
2020
virtual ~ShaderLibrary();
2121

22+
virtual bool IsValid() const = 0;
23+
2224
virtual std::shared_ptr<const ShaderFunction> GetFunction(
2325
const std::string_view& name,
2426
ShaderStage stage) = 0;

0 commit comments

Comments
 (0)