Handle pipelines with no fragment shaders on Metal
This commit is contained in:
parent
fcf6277032
commit
d97e88741b
1 changed files with 61 additions and 62 deletions
|
@ -441,61 +441,73 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
||||||
|
|
||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
|
|
||||||
// vertex
|
MTLRenderPipelineDescriptor *pipelineDescriptor = [MTLRenderPipelineDescriptor new];
|
||||||
id<MTLLibrary> vertexLibrary;
|
|
||||||
{
|
const bool has_vertex_stage = !info.shaders.vertex_path.empty() || !info.shaders.vertex_src.empty();
|
||||||
std::string vertex_src;
|
const bool has_fragment_stage = !info.shaders.fragment_path.empty() || !info.shaders.fragment_src.empty();
|
||||||
if(info.shaders.vertex_path.empty()) {
|
|
||||||
vertex_src = info.shaders.vertex_src.as_string();
|
if(has_vertex_stage) {
|
||||||
} else {
|
id<MTLLibrary> vertexLibrary;
|
||||||
const auto vertex_path = utility::format("{}.msl", info.shaders.vertex_path);
|
{
|
||||||
|
std::string vertex_src;
|
||||||
auto file = file::open(file::internal_domain / vertex_path);
|
if(info.shaders.vertex_path.empty()) {
|
||||||
if(file != std::nullopt) {
|
vertex_src = info.shaders.vertex_src.as_string();
|
||||||
vertex_src = file->read_as_string();
|
|
||||||
} else {
|
} else {
|
||||||
console::error(System::GFX, "Failed to load vertex shader from {}!", vertex_path);
|
const auto vertex_path = utility::format("{}.msl", info.shaders.vertex_path);
|
||||||
|
|
||||||
|
auto file = file::open(file::internal_domain / vertex_path);
|
||||||
|
if(file != std::nullopt) {
|
||||||
|
vertex_src = file->read_as_string();
|
||||||
|
} else {
|
||||||
|
console::error(System::GFX, "Failed to load vertex shader from {}!", vertex_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
vertexLibrary = [device newLibraryWithSource:[NSString stringWithFormat:@"%s", vertex_src.c_str()] options:nil error:&error];
|
|
||||||
if(!vertexLibrary)
|
|
||||||
NSLog(@"%@", error.debugDescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fragment
|
|
||||||
id<MTLLibrary> fragmentLibrary;
|
|
||||||
{
|
|
||||||
std::string fragment_src;
|
|
||||||
if(info.shaders.fragment_path.empty()) {
|
|
||||||
fragment_src = info.shaders.fragment_src.as_string();
|
|
||||||
} else {
|
|
||||||
const auto fragment_path = utility::format("{}.msl", info.shaders.fragment_path);
|
|
||||||
|
|
||||||
auto file = file::open(file::internal_domain / fragment_path);
|
vertexLibrary = [device newLibraryWithSource:[NSString stringWithFormat:@"%s", vertex_src.c_str()] options:nil error:&error];
|
||||||
if(file != std::nullopt) {
|
if(!vertexLibrary)
|
||||||
fragment_src = file->read_as_string();
|
NSLog(@"%@", error.debugDescription);
|
||||||
} else {
|
|
||||||
console::error(System::GFX, "Failed to load fragment shader from {}!", fragment_path);
|
auto vertex_constants = get_constant_values(info.shaders.vertex_constants);
|
||||||
}
|
|
||||||
|
id<MTLFunction> vertexFunc = [vertexLibrary newFunctionWithName:@"main0" constantValues:vertex_constants error:nil];
|
||||||
|
|
||||||
|
if(debug_enabled)
|
||||||
|
vertexFunc.label = [NSString stringWithFormat:@"%s", info.shaders.vertex_path.data()];
|
||||||
|
|
||||||
|
pipelineDescriptor.vertexFunction = vertexFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
fragmentLibrary = [device newLibraryWithSource:[NSString stringWithFormat:@"%s", fragment_src.c_str()] options:nil error:&error];
|
|
||||||
if(!fragmentLibrary)
|
|
||||||
NSLog(@"%@", error.debugDescription);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto vertex_constants = get_constant_values(info.shaders.vertex_constants);
|
if(has_fragment_stage) {
|
||||||
|
id<MTLLibrary> fragmentLibrary;
|
||||||
id<MTLFunction> vertexFunc = [vertexLibrary newFunctionWithName:@"main0" constantValues:vertex_constants error:nil];
|
{
|
||||||
|
std::string fragment_src;
|
||||||
auto fragment_constants = get_constant_values(info.shaders.fragment_constants);
|
if(info.shaders.fragment_path.empty()) {
|
||||||
|
fragment_src = info.shaders.fragment_src.as_string();
|
||||||
id<MTLFunction> fragmentFunc = [fragmentLibrary newFunctionWithName:@"main0" constantValues:fragment_constants error:nil];
|
} else {
|
||||||
|
const auto fragment_path = utility::format("{}.msl", info.shaders.fragment_path);
|
||||||
if(debug_enabled) {
|
|
||||||
vertexFunc.label = [NSString stringWithFormat:@"%s", info.shaders.vertex_path.data()];
|
auto file = file::open(file::internal_domain / fragment_path);
|
||||||
fragmentFunc.label = [NSString stringWithFormat:@"%s", info.shaders.fragment_path.data()];
|
if(file != std::nullopt) {
|
||||||
|
fragment_src = file->read_as_string();
|
||||||
|
} else {
|
||||||
|
console::error(System::GFX, "Failed to load fragment shader from {}!", fragment_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragmentLibrary = [device newLibraryWithSource:[NSString stringWithFormat:@"%s", fragment_src.c_str()] options:nil error:&error];
|
||||||
|
if(!fragmentLibrary)
|
||||||
|
NSLog(@"%@", error.debugDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fragment_constants = get_constant_values(info.shaders.fragment_constants);
|
||||||
|
|
||||||
|
id<MTLFunction> fragmentFunc = [fragmentLibrary newFunctionWithName:@"main0" constantValues:fragment_constants error:nil];
|
||||||
|
|
||||||
|
if(debug_enabled)
|
||||||
|
fragmentFunc.label = [NSString stringWithFormat:@"%s", info.shaders.fragment_path.data()];
|
||||||
|
|
||||||
|
pipelineDescriptor.fragmentFunction = fragmentFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLVertexDescriptor* descriptor = [MTLVertexDescriptor new];
|
MTLVertexDescriptor* descriptor = [MTLVertexDescriptor new];
|
||||||
|
@ -539,10 +551,6 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
||||||
descriptor.attributes[attribute.location].offset = (NSUInteger)attribute.offset;
|
descriptor.attributes[attribute.location].offset = (NSUInteger)attribute.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLRenderPipelineDescriptor *pipelineDescriptor = [MTLRenderPipelineDescriptor new];
|
|
||||||
pipelineDescriptor.vertexFunction = vertexFunc;
|
|
||||||
pipelineDescriptor.fragmentFunction = fragmentFunc;
|
|
||||||
|
|
||||||
if(info.render_pass != nullptr) {
|
if(info.render_pass != nullptr) {
|
||||||
GFXMetalRenderPass* metalRenderPass = (GFXMetalRenderPass*)info.render_pass;
|
GFXMetalRenderPass* metalRenderPass = (GFXMetalRenderPass*)info.render_pass;
|
||||||
|
|
||||||
|
@ -635,15 +643,6 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
||||||
if(info.rasterization.polygon_type == GFXPolygonType::Line)
|
if(info.rasterization.polygon_type == GFXPolygonType::Line)
|
||||||
pipeline->renderWire = true;
|
pipeline->renderWire = true;
|
||||||
|
|
||||||
[vertexFunc release];
|
|
||||||
[fragmentFunc release];
|
|
||||||
|
|
||||||
[vertexLibrary release];
|
|
||||||
[fragmentLibrary release];
|
|
||||||
|
|
||||||
[vertex_constants release];
|
|
||||||
[fragment_constants release];
|
|
||||||
|
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue