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 <kainino@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
676e8f39df
commit
28efed139f
|
@ -104,6 +104,10 @@ namespace dawn_native {
|
||||||
return mStages[stage];
|
return mStages[stage];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PerStage<ProgrammableStage>& PipelineBase::GetAllStages() const {
|
||||||
|
return mStages;
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError PipelineBase::ValidateGetBindGroupLayout(uint32_t groupIndex) {
|
MaybeError PipelineBase::ValidateGetBindGroupLayout(uint32_t groupIndex) {
|
||||||
DAWN_TRY(GetDevice()->ValidateIsAlive());
|
DAWN_TRY(GetDevice()->ValidateIsAlive());
|
||||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace dawn_native {
|
||||||
const PipelineLayoutBase* GetLayout() const;
|
const PipelineLayoutBase* GetLayout() const;
|
||||||
const RequiredBufferSizes& GetMinBufferSizes() const;
|
const RequiredBufferSizes& GetMinBufferSizes() const;
|
||||||
const ProgrammableStage& GetStage(SingleShaderStage stage) const;
|
const ProgrammableStage& GetStage(SingleShaderStage stage) const;
|
||||||
|
const PerStage<ProgrammableStage>& GetAllStages() const;
|
||||||
|
|
||||||
BindGroupLayoutBase* GetBindGroupLayout(uint32_t groupIndex);
|
BindGroupLayoutBase* GetBindGroupLayout(uint32_t groupIndex);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace dawn_native { namespace opengl {
|
||||||
PerStage<const ShaderModule*> modules(nullptr);
|
PerStage<const ShaderModule*> modules(nullptr);
|
||||||
modules[SingleShaderStage::Compute] = ToBackend(descriptor->computeStage.module);
|
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() {
|
void ComputePipeline::ApplyNow() {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "common/BitSetIterator.h"
|
#include "common/BitSetIterator.h"
|
||||||
#include "common/Log.h"
|
#include "common/Log.h"
|
||||||
#include "dawn_native/BindGroupLayout.h"
|
#include "dawn_native/BindGroupLayout.h"
|
||||||
|
#include "dawn_native/Pipeline.h"
|
||||||
#include "dawn_native/opengl/Forward.h"
|
#include "dawn_native/opengl/Forward.h"
|
||||||
#include "dawn_native/opengl/OpenGLFunctions.h"
|
#include "dawn_native/opengl/OpenGLFunctions.h"
|
||||||
#include "dawn_native/opengl/PipelineLayoutGL.h"
|
#include "dawn_native/opengl/PipelineLayoutGL.h"
|
||||||
|
@ -48,7 +49,7 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
void PipelineGL::Initialize(const OpenGLFunctions& gl,
|
void PipelineGL::Initialize(const OpenGLFunctions& gl,
|
||||||
const PipelineLayout* layout,
|
const PipelineLayout* layout,
|
||||||
const PerStage<const ShaderModule*>& modules) {
|
const PerStage<ProgrammableStage>& stages) {
|
||||||
auto CreateShader = [](const OpenGLFunctions& gl, GLenum type,
|
auto CreateShader = [](const OpenGLFunctions& gl, GLenum type,
|
||||||
const char* source) -> GLuint {
|
const char* source) -> GLuint {
|
||||||
GLuint shader = gl.CreateShader(type);
|
GLuint shader = gl.CreateShader(type);
|
||||||
|
@ -73,18 +74,25 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
mProgram = gl.CreateProgram();
|
mProgram = gl.CreateProgram();
|
||||||
|
|
||||||
|
// Compute the set of active stages.
|
||||||
wgpu::ShaderStage activeStages = wgpu::ShaderStage::None;
|
wgpu::ShaderStage activeStages = wgpu::ShaderStage::None;
|
||||||
for (SingleShaderStage stage : IterateStages(kAllStages)) {
|
for (SingleShaderStage stage : IterateStages(kAllStages)) {
|
||||||
if (modules[stage] != nullptr) {
|
if (stages[stage].module != nullptr) {
|
||||||
activeStages |= StageBit(stage);
|
activeStages |= StageBit(stage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an OpenGL shader for each stage and gather the list of combined samplers.
|
||||||
|
PerStage<CombinedSamplerInfo> combinedSamplers;
|
||||||
for (SingleShaderStage stage : IterateStages(activeStages)) {
|
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);
|
gl.AttachShader(mProgram, shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Link all the shaders together.
|
||||||
gl.LinkProgram(mProgram);
|
gl.LinkProgram(mProgram);
|
||||||
|
|
||||||
GLint linkStatus = GL_FALSE;
|
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
|
// The uniforms are part of the program state so we can pre-bind buffer units, texture units
|
||||||
// etc.
|
// etc.
|
||||||
|
gl.UseProgram(mProgram);
|
||||||
const auto& indices = layout->GetBindingIndexInfo();
|
const auto& indices = layout->GetBindingIndexInfo();
|
||||||
|
|
||||||
for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
|
for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
|
||||||
|
@ -154,8 +161,6 @@ namespace dawn_native { namespace opengl {
|
||||||
case wgpu::BindingType::StorageTexture:
|
case wgpu::BindingType::StorageTexture:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +169,7 @@ namespace dawn_native { namespace opengl {
|
||||||
{
|
{
|
||||||
std::set<CombinedSampler> combinedSamplersSet;
|
std::set<CombinedSampler> combinedSamplersSet;
|
||||||
for (SingleShaderStage stage : IterateStages(activeStages)) {
|
for (SingleShaderStage stage : IterateStages(activeStages)) {
|
||||||
for (const auto& combined : modules[stage]->GetCombinedSamplerInfo()) {
|
for (const CombinedSampler& combined : combinedSamplers[stage]) {
|
||||||
combinedSamplersSet.insert(combined);
|
combinedSamplersSet.insert(combined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,20 @@
|
||||||
|
|
||||||
#include "dawn_native/Pipeline.h"
|
#include "dawn_native/Pipeline.h"
|
||||||
|
|
||||||
|
#include "dawn_native/PerStage.h"
|
||||||
#include "dawn_native/opengl/opengl_platform.h"
|
#include "dawn_native/opengl/opengl_platform.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace dawn_native {
|
||||||
|
struct ProgrammableStage;
|
||||||
|
} // namespace dawn_native
|
||||||
|
|
||||||
namespace dawn_native { namespace opengl {
|
namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
struct OpenGLFunctions;
|
struct OpenGLFunctions;
|
||||||
class PersistentPipelineState;
|
class PersistentPipelineState;
|
||||||
class PipelineLayout;
|
class PipelineLayout;
|
||||||
class ShaderModule;
|
|
||||||
|
|
||||||
class PipelineGL {
|
class PipelineGL {
|
||||||
public:
|
public:
|
||||||
|
@ -34,7 +38,7 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
void Initialize(const OpenGLFunctions& gl,
|
void Initialize(const OpenGLFunctions& gl,
|
||||||
const PipelineLayout* layout,
|
const PipelineLayout* layout,
|
||||||
const PerStage<const ShaderModule*>& modules);
|
const PerStage<ProgrammableStage>& stages);
|
||||||
|
|
||||||
// For each unit a sampler is bound to we need to know if we should use filtering or not
|
// 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.
|
// because int and uint texture are only complete without filtering.
|
||||||
|
|
|
@ -204,7 +204,7 @@ namespace dawn_native { namespace opengl {
|
||||||
modules[SingleShaderStage::Vertex] = ToBackend(descriptor->vertexStage.module);
|
modules[SingleShaderStage::Vertex] = ToBackend(descriptor->vertexStage.module);
|
||||||
modules[SingleShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->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);
|
CreateVAOForVertexState(descriptor->vertexState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
|
#include "dawn_native/SpirvUtils.h"
|
||||||
#include "dawn_native/opengl/DeviceGL.h"
|
#include "dawn_native/opengl/DeviceGL.h"
|
||||||
|
|
||||||
#include <spirv_glsl.hpp>
|
#include <spirv_glsl.hpp>
|
||||||
|
@ -54,26 +55,17 @@ namespace dawn_native { namespace opengl {
|
||||||
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
|
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
|
||||||
const ShaderModuleDescriptor* descriptor) {
|
const ShaderModuleDescriptor* descriptor) {
|
||||||
Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor));
|
Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor));
|
||||||
DAWN_TRY(module->Initialize());
|
DAWN_TRY(module->InitializeBase());
|
||||||
return module.Detach();
|
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)
|
ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor)
|
||||||
: ShaderModuleBase(device, descriptor) {
|
: ShaderModuleBase(device, descriptor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ShaderModule::Initialize() {
|
std::string ShaderModule::TranslateToGLSL(const char* entryPointName,
|
||||||
DAWN_TRY(InitializeBase());
|
SingleShaderStage stage,
|
||||||
const std::vector<uint32_t>& spirv = GetSpirv();
|
CombinedSamplerInfo* combinedSamplers) const {
|
||||||
|
|
||||||
// If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
|
// If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
|
||||||
// be updated.
|
// be updated.
|
||||||
spirv_cross::CompilerGLSL::Options options;
|
spirv_cross::CompilerGLSL::Options options;
|
||||||
|
@ -92,31 +84,32 @@ namespace dawn_native { namespace opengl {
|
||||||
options.version = 440;
|
options.version = 440;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spirv_cross::CompilerGLSL compiler(spirv);
|
spirv_cross::CompilerGLSL compiler(GetSpirv());
|
||||||
compiler.set_common_options(options);
|
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.
|
// 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.
|
// Now translate the separate sampler / textures into combined ones and store their info. We
|
||||||
// We need to do this before removing the set and binding decorations.
|
// need to do this before removing the set and binding decorations.
|
||||||
compiler.build_combined_image_samplers();
|
compiler.build_combined_image_samplers();
|
||||||
|
|
||||||
for (const auto& combined : compiler.get_combined_image_samplers()) {
|
for (const auto& combined : compiler.get_combined_image_samplers()) {
|
||||||
mCombinedInfo.emplace_back();
|
combinedSamplers->emplace_back();
|
||||||
|
|
||||||
auto& info = mCombinedInfo.back();
|
CombinedSampler* info = &combinedSamplers->back();
|
||||||
info.samplerLocation.group = BindGroupIndex(
|
info->samplerLocation.group = BindGroupIndex(
|
||||||
compiler.get_decoration(combined.sampler_id, spv::DecorationDescriptorSet));
|
compiler.get_decoration(combined.sampler_id, spv::DecorationDescriptorSet));
|
||||||
info.samplerLocation.binding =
|
info->samplerLocation.binding =
|
||||||
BindingNumber(compiler.get_decoration(combined.sampler_id, spv::DecorationBinding));
|
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));
|
compiler.get_decoration(combined.image_id, spv::DecorationDescriptorSet));
|
||||||
info.textureLocation.binding =
|
info->textureLocation.binding =
|
||||||
BindingNumber(compiler.get_decoration(combined.image_id, spv::DecorationBinding));
|
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 =
|
const EntryPointMetadata::BindingInfo& bindingInfo =
|
||||||
GetEntryPoint("main", GetMainEntryPointStageForTransition()).bindings;
|
GetEntryPoint(entryPointName, stage).bindings;
|
||||||
|
|
||||||
// Change binding names to be "dawn_binding_<group>_<binding>".
|
// Change binding names to be "dawn_binding_<group>_<binding>".
|
||||||
// Also unsets the SPIRV "Binding" decoration as it outputs "layout(binding=)" which
|
// 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 compiler.compile();
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace dawn_native::opengl
|
}} // namespace dawn_native::opengl
|
||||||
|
|
|
@ -38,23 +38,20 @@ namespace dawn_native { namespace opengl {
|
||||||
};
|
};
|
||||||
bool operator<(const CombinedSampler& a, const CombinedSampler& b);
|
bool operator<(const CombinedSampler& a, const CombinedSampler& b);
|
||||||
|
|
||||||
|
using CombinedSamplerInfo = std::vector<CombinedSampler>;
|
||||||
|
|
||||||
class ShaderModule final : public ShaderModuleBase {
|
class ShaderModule final : public ShaderModuleBase {
|
||||||
public:
|
public:
|
||||||
static ResultOrError<ShaderModule*> Create(Device* device,
|
static ResultOrError<ShaderModule*> Create(Device* device,
|
||||||
const ShaderModuleDescriptor* descriptor);
|
const ShaderModuleDescriptor* descriptor);
|
||||||
|
|
||||||
using CombinedSamplerInfo = std::vector<CombinedSampler>;
|
std::string TranslateToGLSL(const char* entryPointName,
|
||||||
|
SingleShaderStage stage,
|
||||||
const char* GetSource() const;
|
CombinedSamplerInfo* combinedSamplers) const;
|
||||||
const CombinedSamplerInfo& GetCombinedSamplerInfo() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
|
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
|
||||||
~ShaderModule() override = default;
|
~ShaderModule() override = default;
|
||||||
MaybeError Initialize();
|
|
||||||
|
|
||||||
CombinedSamplerInfo mCombinedInfo;
|
|
||||||
std::string mGlslSource;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::opengl
|
}} // namespace dawn_native::opengl
|
||||||
|
|
Loading…
Reference in New Issue