Archived
1
Fork 0

Add framework for compute shaders

This commit is contained in:
redstrate 2020-09-22 15:39:20 -04:00
parent bcac561a1e
commit 41ef1c33f5
10 changed files with 65 additions and 4 deletions

View file

@ -42,7 +42,8 @@ public:
// pipeline operations // pipeline operations
GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override; GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override;
GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override;
GFXCommandBuffer* acquire_command_buffer() override; GFXCommandBuffer* acquire_command_buffer() override;
void submit(GFXCommandBuffer* command_buffer, const int window = -1) override; void submit(GFXCommandBuffer* command_buffer, const int window = -1) override;

View file

@ -641,6 +641,43 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
return pipeline; return pipeline;
} }
GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) {
GFXMetalPipeline* pipeline = new GFXMetalPipeline();
NSError* error = nil;
// vertex
id<MTLLibrary> computeLibrary;
{
std::string compute_src;
if(info.shaders.compute_path.empty()) {
compute_src = info.shaders.compute_src.as_string();
} else {
const auto compute_path = utility::format("{}.msl", info.shaders.compute_path);
auto file = file::open(file::internal_domain / compute_path);
if(file != std::nullopt) {
compute_src = file->read_as_string();
} else {
console::error(System::GFX, "Failed to load compute shader from {}!", compute_path);
}
}
computeLibrary = [device newLibraryWithSource:[NSString stringWithFormat:@"%s", compute_src.c_str()] options:nil error:&error];
if(!computeLibrary)
NSLog(@"%@", error.debugDescription);
}
id<MTLFunction> computeFunc = [computeLibrary newFunctionWithName:@"main0"];
MTLComputePipelineDescriptor* pipelineDescriptor = [MTLComputePipelineDescriptor new];
pipelineDescriptor.computeFunction = computeFunc;
[computeLibrary release];
return pipeline;
}
GFXCommandBuffer* GFXMetal::acquire_command_buffer() { GFXCommandBuffer* GFXMetal::acquire_command_buffer() {
GFXCommandBuffer* cmdbuf = nullptr; GFXCommandBuffer* cmdbuf = nullptr;
while(cmdbuf == nullptr) { while(cmdbuf == nullptr) {

View file

@ -199,6 +199,7 @@ struct GFXComputePipelineCreateInfo {
struct Shaders { struct Shaders {
std::string_view compute_path; std::string_view compute_path;
ShaderSource compute_src;
} shaders; } shaders;
}; };

View file

@ -78,4 +78,5 @@ add_shader(TARGET Renderer
shaders/rendering.nocompile.glsl shaders/rendering.nocompile.glsl
shaders/common.nocompile.glsl shaders/common.nocompile.glsl
shaders/dof.vert.glsl shaders/dof.vert.glsl
shaders/dof.frag.glsl) shaders/dof.frag.glsl
shaders/histogram.comp.glsl)

View file

@ -139,6 +139,7 @@ private:
void createUIPipeline(); void createUIPipeline();
void createGaussianResources(); void createGaussianResources();
void createBRDF(); void createBRDF();
void create_histogram_resources();
GFX* gfx = nullptr; GFX* gfx = nullptr;
prism::Extent extent; prism::Extent extent;
@ -176,6 +177,9 @@ private:
// general ui // general ui
GFXPipeline* generalPipeline, *worldGeneralPipeline = nullptr; GFXPipeline* generalPipeline, *worldGeneralPipeline = nullptr;
// histogram compute
GFXPipeline* histogram_pipeline = nullptr;
std::unique_ptr<SMAAPass> smaaPass; std::unique_ptr<SMAAPass> smaaPass;
std::unique_ptr<GaussianHelper> gHelper; std::unique_ptr<GaussianHelper> gHelper;

View file

@ -87,6 +87,7 @@ Renderer::Renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) {
shader_compiler.set_include_path(file::get_domain_path(file::Domain::Internal).string()); shader_compiler.set_include_path(file::get_domain_path(file::Domain::Internal).string());
createDummyTexture(); createDummyTexture();
create_histogram_resources();
shadow_pass = std::make_unique<ShadowPass>(gfx); shadow_pass = std::make_unique<ShadowPass>(gfx);
scene_capture = std::make_unique<SceneCapture>(gfx); scene_capture = std::make_unique<SceneCapture>(gfx);
@ -994,3 +995,10 @@ void Renderer::createBRDF() {
gfx->submit(command_buffer); gfx->submit(command_buffer);
} }
void Renderer::create_histogram_resources() {
GFXComputePipelineCreateInfo create_info = {};
create_info.shaders.compute_path = "histogram.comp";
histogram_pipeline = gfx->create_compute_pipeline(create_info);
}

View file

@ -9,7 +9,8 @@
/// The shader stage that the shader is written in. /// The shader stage that the shader is written in.
enum class ShaderStage { enum class ShaderStage {
Vertex, Vertex,
Fragment Fragment,
Compute
}; };
/// The shader language that the shader is written in. /// The shader language that the shader is written in.

View file

@ -89,6 +89,9 @@ std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_la
case ShaderStage::Fragment: case ShaderStage::Fragment:
lang = EShLangFragment; lang = EShLangFragment;
break; break;
case ShaderStage::Compute:
lang = EShLangCompute;
break;
} }
auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options); auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options);

3
shaders/histogram.comp.glsl Executable file
View file

@ -0,0 +1,3 @@
void main() {
}

View file

@ -41,8 +41,10 @@ int main(int argc, char* argv[]) {
ShaderStage stage; ShaderStage stage;
if(has_extension(source_path, ".vert")) if(has_extension(source_path, ".vert"))
stage = ShaderStage::Vertex; stage = ShaderStage::Vertex;
else else if(has_extension(source_path, ".frag"))
stage = ShaderStage::Fragment; stage = ShaderStage::Fragment;
else if(has_extension(source_path, ".comp"))
stage = ShaderStage::Compute;
ShaderLanguage language; ShaderLanguage language;
CompileOptions options; CompileOptions options;