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];
|
||||
}
|
||||
|
||||
const PerStage<ProgrammableStage>& PipelineBase::GetAllStages() const {
|
||||
return mStages;
|
||||
}
|
||||
|
||||
MaybeError PipelineBase::ValidateGetBindGroupLayout(uint32_t groupIndex) {
|
||||
DAWN_TRY(GetDevice()->ValidateIsAlive());
|
||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace dawn_native {
|
|||
const PipelineLayoutBase* GetLayout() const;
|
||||
const RequiredBufferSizes& GetMinBufferSizes() const;
|
||||
const ProgrammableStage& GetStage(SingleShaderStage stage) const;
|
||||
const PerStage<ProgrammableStage>& GetAllStages() const;
|
||||
|
||||
BindGroupLayoutBase* GetBindGroupLayout(uint32_t groupIndex);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace dawn_native { namespace opengl {
|
|||
PerStage<const ShaderModule*> 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() {
|
||||
|
|
|
@ -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<const ShaderModule*>& modules) {
|
||||
const PerStage<ProgrammableStage>& 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<CombinedSamplerInfo> 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<CombinedSampler> combinedSamplersSet;
|
||||
for (SingleShaderStage stage : IterateStages(activeStages)) {
|
||||
for (const auto& combined : modules[stage]->GetCombinedSamplerInfo()) {
|
||||
for (const CombinedSampler& combined : combinedSamplers[stage]) {
|
||||
combinedSamplersSet.insert(combined);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,16 +17,20 @@
|
|||
|
||||
#include "dawn_native/Pipeline.h"
|
||||
|
||||
#include "dawn_native/PerStage.h"
|
||||
#include "dawn_native/opengl/opengl_platform.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
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<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
|
||||
// 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::Fragment] = ToBackend(descriptor->fragmentStage->module);
|
||||
|
||||
PipelineGL::Initialize(device->gl, ToBackend(GetLayout()), modules);
|
||||
PipelineGL::Initialize(device->gl, ToBackend(GetLayout()), GetAllStages());
|
||||
CreateVAOForVertexState(descriptor->vertexState);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "common/Assert.h"
|
||||
#include "common/Platform.h"
|
||||
#include "dawn_native/SpirvUtils.h"
|
||||
#include "dawn_native/opengl/DeviceGL.h"
|
||||
|
||||
#include <spirv_glsl.hpp>
|
||||
|
@ -54,26 +55,17 @@ namespace dawn_native { namespace opengl {
|
|||
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
|
||||
const ShaderModuleDescriptor* descriptor) {
|
||||
Ref<ShaderModule> 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<uint32_t>& 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_<group>_<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
|
||||
|
|
|
@ -38,23 +38,20 @@ namespace dawn_native { namespace opengl {
|
|||
};
|
||||
bool operator<(const CombinedSampler& a, const CombinedSampler& b);
|
||||
|
||||
using CombinedSamplerInfo = std::vector<CombinedSampler>;
|
||||
|
||||
class ShaderModule final : public ShaderModuleBase {
|
||||
public:
|
||||
static ResultOrError<ShaderModule*> Create(Device* device,
|
||||
const ShaderModuleDescriptor* descriptor);
|
||||
|
||||
using CombinedSamplerInfo = std::vector<CombinedSampler>;
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue