From 28efed139f1df95484a0400e49c949b8e7ee4c56 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Wed, 9 Sep 2020 22:51:37 +0000 Subject: [PATCH] OpenGL: Make GLSL generation per-entrypoint. Bug: dawn:216 Change-Id: I7b4c0e9c210af59711318a744d8055cfb9b82092 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28242 Commit-Queue: Kai Ninomiya Reviewed-by: Kai Ninomiya --- src/dawn_native/Pipeline.cpp | 4 ++ src/dawn_native/Pipeline.h | 1 + src/dawn_native/opengl/ComputePipelineGL.cpp | 2 +- src/dawn_native/opengl/PipelineGL.cpp | 21 +++++---- src/dawn_native/opengl/PipelineGL.h | 8 +++- src/dawn_native/opengl/RenderPipelineGL.cpp | 2 +- src/dawn_native/opengl/ShaderModuleGL.cpp | 45 ++++++++------------ src/dawn_native/opengl/ShaderModuleGL.h | 13 +++--- 8 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/dawn_native/Pipeline.cpp b/src/dawn_native/Pipeline.cpp index 691e3a976a..d7ebbe2aef 100644 --- a/src/dawn_native/Pipeline.cpp +++ b/src/dawn_native/Pipeline.cpp @@ -104,6 +104,10 @@ namespace dawn_native { return mStages[stage]; } + const PerStage& PipelineBase::GetAllStages() const { + return mStages; + } + MaybeError PipelineBase::ValidateGetBindGroupLayout(uint32_t groupIndex) { DAWN_TRY(GetDevice()->ValidateIsAlive()); DAWN_TRY(GetDevice()->ValidateObject(this)); diff --git a/src/dawn_native/Pipeline.h b/src/dawn_native/Pipeline.h index 44e3f981d2..9bc249c4b6 100644 --- a/src/dawn_native/Pipeline.h +++ b/src/dawn_native/Pipeline.h @@ -47,6 +47,7 @@ namespace dawn_native { const PipelineLayoutBase* GetLayout() const; const RequiredBufferSizes& GetMinBufferSizes() const; const ProgrammableStage& GetStage(SingleShaderStage stage) const; + const PerStage& GetAllStages() const; BindGroupLayoutBase* GetBindGroupLayout(uint32_t groupIndex); diff --git a/src/dawn_native/opengl/ComputePipelineGL.cpp b/src/dawn_native/opengl/ComputePipelineGL.cpp index ab25bb1e23..dcb88bec7c 100644 --- a/src/dawn_native/opengl/ComputePipelineGL.cpp +++ b/src/dawn_native/opengl/ComputePipelineGL.cpp @@ -23,7 +23,7 @@ namespace dawn_native { namespace opengl { PerStage modules(nullptr); modules[SingleShaderStage::Compute] = ToBackend(descriptor->computeStage.module); - PipelineGL::Initialize(device->gl, ToBackend(descriptor->layout), modules); + PipelineGL::Initialize(device->gl, ToBackend(descriptor->layout), GetAllStages()); } void ComputePipeline::ApplyNow() { diff --git a/src/dawn_native/opengl/PipelineGL.cpp b/src/dawn_native/opengl/PipelineGL.cpp index 76c24b6b40..219a19db88 100644 --- a/src/dawn_native/opengl/PipelineGL.cpp +++ b/src/dawn_native/opengl/PipelineGL.cpp @@ -17,6 +17,7 @@ #include "common/BitSetIterator.h" #include "common/Log.h" #include "dawn_native/BindGroupLayout.h" +#include "dawn_native/Pipeline.h" #include "dawn_native/opengl/Forward.h" #include "dawn_native/opengl/OpenGLFunctions.h" #include "dawn_native/opengl/PipelineLayoutGL.h" @@ -48,7 +49,7 @@ namespace dawn_native { namespace opengl { void PipelineGL::Initialize(const OpenGLFunctions& gl, const PipelineLayout* layout, - const PerStage& modules) { + const PerStage& stages) { auto CreateShader = [](const OpenGLFunctions& gl, GLenum type, const char* source) -> GLuint { GLuint shader = gl.CreateShader(type); @@ -73,18 +74,25 @@ namespace dawn_native { namespace opengl { mProgram = gl.CreateProgram(); + // Compute the set of active stages. wgpu::ShaderStage activeStages = wgpu::ShaderStage::None; for (SingleShaderStage stage : IterateStages(kAllStages)) { - if (modules[stage] != nullptr) { + if (stages[stage].module != nullptr) { activeStages |= StageBit(stage); } } + // Create an OpenGL shader for each stage and gather the list of combined samplers. + PerStage combinedSamplers; for (SingleShaderStage stage : IterateStages(activeStages)) { - GLuint shader = CreateShader(gl, GLShaderType(stage), modules[stage]->GetSource()); + const ShaderModule* module = ToBackend(stages[stage].module.Get()); + std::string glsl = module->TranslateToGLSL(stages[stage].entryPoint.c_str(), stage, + &combinedSamplers[stage]); + GLuint shader = CreateShader(gl, GLShaderType(stage), glsl.c_str()); gl.AttachShader(mProgram, shader); } + // Link all the shaders together. gl.LinkProgram(mProgram); GLint linkStatus = GL_FALSE; @@ -100,10 +108,9 @@ namespace dawn_native { namespace opengl { } } - gl.UseProgram(mProgram); - // The uniforms are part of the program state so we can pre-bind buffer units, texture units // etc. + gl.UseProgram(mProgram); const auto& indices = layout->GetBindingIndexInfo(); for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) { @@ -154,8 +161,6 @@ namespace dawn_native { namespace opengl { case wgpu::BindingType::StorageTexture: UNREACHABLE(); break; - - // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. } } } @@ -164,7 +169,7 @@ namespace dawn_native { namespace opengl { { std::set combinedSamplersSet; for (SingleShaderStage stage : IterateStages(activeStages)) { - for (const auto& combined : modules[stage]->GetCombinedSamplerInfo()) { + for (const CombinedSampler& combined : combinedSamplers[stage]) { combinedSamplersSet.insert(combined); } } diff --git a/src/dawn_native/opengl/PipelineGL.h b/src/dawn_native/opengl/PipelineGL.h index a79909ab55..ffef4d2e95 100644 --- a/src/dawn_native/opengl/PipelineGL.h +++ b/src/dawn_native/opengl/PipelineGL.h @@ -17,16 +17,20 @@ #include "dawn_native/Pipeline.h" +#include "dawn_native/PerStage.h" #include "dawn_native/opengl/opengl_platform.h" #include +namespace dawn_native { + struct ProgrammableStage; +} // namespace dawn_native + namespace dawn_native { namespace opengl { struct OpenGLFunctions; class PersistentPipelineState; class PipelineLayout; - class ShaderModule; class PipelineGL { public: @@ -34,7 +38,7 @@ namespace dawn_native { namespace opengl { void Initialize(const OpenGLFunctions& gl, const PipelineLayout* layout, - const PerStage& modules); + const PerStage& stages); // For each unit a sampler is bound to we need to know if we should use filtering or not // because int and uint texture are only complete without filtering. diff --git a/src/dawn_native/opengl/RenderPipelineGL.cpp b/src/dawn_native/opengl/RenderPipelineGL.cpp index 10add8c93d..5130e5911d 100644 --- a/src/dawn_native/opengl/RenderPipelineGL.cpp +++ b/src/dawn_native/opengl/RenderPipelineGL.cpp @@ -204,7 +204,7 @@ namespace dawn_native { namespace opengl { modules[SingleShaderStage::Vertex] = ToBackend(descriptor->vertexStage.module); modules[SingleShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module); - PipelineGL::Initialize(device->gl, ToBackend(GetLayout()), modules); + PipelineGL::Initialize(device->gl, ToBackend(GetLayout()), GetAllStages()); CreateVAOForVertexState(descriptor->vertexState); } diff --git a/src/dawn_native/opengl/ShaderModuleGL.cpp b/src/dawn_native/opengl/ShaderModuleGL.cpp index c2606f04fd..81c8c80054 100644 --- a/src/dawn_native/opengl/ShaderModuleGL.cpp +++ b/src/dawn_native/opengl/ShaderModuleGL.cpp @@ -16,6 +16,7 @@ #include "common/Assert.h" #include "common/Platform.h" +#include "dawn_native/SpirvUtils.h" #include "dawn_native/opengl/DeviceGL.h" #include @@ -54,26 +55,17 @@ namespace dawn_native { namespace opengl { ResultOrError ShaderModule::Create(Device* device, const ShaderModuleDescriptor* descriptor) { Ref module = AcquireRef(new ShaderModule(device, descriptor)); - DAWN_TRY(module->Initialize()); + DAWN_TRY(module->InitializeBase()); return module.Detach(); } - const char* ShaderModule::GetSource() const { - return mGlslSource.c_str(); - } - - const ShaderModule::CombinedSamplerInfo& ShaderModule::GetCombinedSamplerInfo() const { - return mCombinedInfo; - } - ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor) : ShaderModuleBase(device, descriptor) { } - MaybeError ShaderModule::Initialize() { - DAWN_TRY(InitializeBase()); - const std::vector& spirv = GetSpirv(); - + std::string ShaderModule::TranslateToGLSL(const char* entryPointName, + SingleShaderStage stage, + CombinedSamplerInfo* combinedSamplers) const { // If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to // be updated. spirv_cross::CompilerGLSL::Options options; @@ -92,31 +84,32 @@ namespace dawn_native { namespace opengl { options.version = 440; #endif - spirv_cross::CompilerGLSL compiler(spirv); + spirv_cross::CompilerGLSL compiler(GetSpirv()); compiler.set_common_options(options); + compiler.set_entry_point(entryPointName, ShaderStageToExecutionModel(stage)); // Extract bindings names so that it can be used to get its location in program. - // Now translate the separate sampler / textures into combined ones and store their info. - // We need to do this before removing the set and binding decorations. + // Now translate the separate sampler / textures into combined ones and store their info. We + // need to do this before removing the set and binding decorations. compiler.build_combined_image_samplers(); for (const auto& combined : compiler.get_combined_image_samplers()) { - mCombinedInfo.emplace_back(); + combinedSamplers->emplace_back(); - auto& info = mCombinedInfo.back(); - info.samplerLocation.group = BindGroupIndex( + CombinedSampler* info = &combinedSamplers->back(); + info->samplerLocation.group = BindGroupIndex( compiler.get_decoration(combined.sampler_id, spv::DecorationDescriptorSet)); - info.samplerLocation.binding = + info->samplerLocation.binding = BindingNumber(compiler.get_decoration(combined.sampler_id, spv::DecorationBinding)); - info.textureLocation.group = BindGroupIndex( + info->textureLocation.group = BindGroupIndex( compiler.get_decoration(combined.image_id, spv::DecorationDescriptorSet)); - info.textureLocation.binding = + info->textureLocation.binding = BindingNumber(compiler.get_decoration(combined.image_id, spv::DecorationBinding)); - compiler.set_name(combined.combined_id, info.GetName()); + compiler.set_name(combined.combined_id, info->GetName()); } const EntryPointMetadata::BindingInfo& bindingInfo = - GetEntryPoint("main", GetMainEntryPointStageForTransition()).bindings; + GetEntryPoint(entryPointName, stage).bindings; // Change binding names to be "dawn_binding__". // Also unsets the SPIRV "Binding" decoration as it outputs "layout(binding=)" which @@ -146,9 +139,7 @@ namespace dawn_native { namespace opengl { } } - mGlslSource = compiler.compile(); - - return {}; + return compiler.compile(); } }} // namespace dawn_native::opengl diff --git a/src/dawn_native/opengl/ShaderModuleGL.h b/src/dawn_native/opengl/ShaderModuleGL.h index 3ddd19a7f1..0f9474f8f1 100644 --- a/src/dawn_native/opengl/ShaderModuleGL.h +++ b/src/dawn_native/opengl/ShaderModuleGL.h @@ -38,23 +38,20 @@ namespace dawn_native { namespace opengl { }; bool operator<(const CombinedSampler& a, const CombinedSampler& b); + using CombinedSamplerInfo = std::vector; + class ShaderModule final : public ShaderModuleBase { public: static ResultOrError Create(Device* device, const ShaderModuleDescriptor* descriptor); - using CombinedSamplerInfo = std::vector; - - const char* GetSource() const; - const CombinedSamplerInfo& GetCombinedSamplerInfo() const; + std::string TranslateToGLSL(const char* entryPointName, + SingleShaderStage stage, + CombinedSamplerInfo* combinedSamplers) const; private: ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor); ~ShaderModule() override = default; - MaybeError Initialize(); - - CombinedSamplerInfo mCombinedInfo; - std::string mGlslSource; }; }} // namespace dawn_native::opengl