Archived
1
Fork 0

Handle pipelines with no fragment shaders on Metal

This commit is contained in:
redstrate 2021-02-05 19:50:19 -05:00
parent fcf6277032
commit d97e88741b

View file

@ -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;
} }