Use Tint SingleEntryPoint transform in Vulkan/GL backends
Some Vulkan drivers don't handle multiple entrypoints well. In addition, SPIRV-Cross translation can be wrong for shader modules with multiple entrypoints. Always emit a single SPIR-V entrypoint to workaround these issues. This allows updating CopyTextureForBrowser to use a single shader module, and it fixes some tests with multiple entrypoints. Fixed: dawn:948, dawn:959, dawn:1013 Change-Id: Ie129a32a54845316d11917331937ca44fba3d347 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/60640 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
c5989a9042
commit
8e957160b1
|
@ -33,17 +33,14 @@
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
namespace {
|
namespace {
|
||||||
// TODO(crbug.com/1221110): Remove this header macro by merging vertex and
|
|
||||||
// fragment shaders into one shader source. Now it blocks by
|
|
||||||
// crbug.com/dawn/947 and crbug.com/tint/915
|
|
||||||
#define HEADER \
|
|
||||||
" [[block]] struct Uniforms {\n" \
|
|
||||||
" u_scale: vec2<f32>;\n" \
|
|
||||||
" u_offset: vec2<f32>;\n" \
|
|
||||||
" u_alphaOp: u32;\n" \
|
|
||||||
" };\n"
|
|
||||||
|
|
||||||
static const char sCopyTextureForBrowserVertex[] = HEADER R"(
|
static const char sCopyTextureForBrowserShader[] = R"(
|
||||||
|
[[block]] struct Uniforms {
|
||||||
|
u_scale: vec2<f32>;
|
||||||
|
u_offset: vec2<f32>;
|
||||||
|
u_alphaOp: u32;
|
||||||
|
};
|
||||||
|
|
||||||
[[binding(0), group(0)]] var<uniform> uniforms : Uniforms;
|
[[binding(0), group(0)]] var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
struct VertexOutputs {
|
struct VertexOutputs {
|
||||||
|
@ -51,7 +48,7 @@ namespace dawn_native {
|
||||||
[[builtin(position)]] position : vec4<f32>;
|
[[builtin(position)]] position : vec4<f32>;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[stage(vertex)]] fn main(
|
[[stage(vertex)]] fn vs_main(
|
||||||
[[builtin(vertex_index)]] VertexIndex : u32
|
[[builtin(vertex_index)]] VertexIndex : u32
|
||||||
) -> VertexOutputs {
|
) -> VertexOutputs {
|
||||||
var texcoord = array<vec2<f32>, 3>(
|
var texcoord = array<vec2<f32>, 3>(
|
||||||
|
@ -84,14 +81,11 @@ namespace dawn_native {
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
)";
|
|
||||||
|
|
||||||
static const char sCopyTextureForBrowserFragment[] = HEADER R"(
|
|
||||||
[[binding(0), group(0)]] var<uniform> uniforms : Uniforms;
|
|
||||||
[[binding(1), group(0)]] var mySampler: sampler;
|
[[binding(1), group(0)]] var mySampler: sampler;
|
||||||
[[binding(2), group(0)]] var myTexture: texture_2d<f32>;
|
[[binding(2), group(0)]] var myTexture: texture_2d<f32>;
|
||||||
|
|
||||||
[[stage(fragment)]] fn main(
|
[[stage(fragment)]] fn fs_main(
|
||||||
[[location(0)]] texcoord : vec2<f32>
|
[[location(0)]] texcoord : vec2<f32>
|
||||||
) -> [[location(0)]] vec4<f32> {
|
) -> [[location(0)]] vec4<f32> {
|
||||||
// Clamp the texcoord and discard the out-of-bound pixels.
|
// Clamp the texcoord and discard the out-of-bound pixels.
|
||||||
|
@ -226,39 +220,27 @@ namespace dawn_native {
|
||||||
|
|
||||||
if (GetCachedPipeline(store, dstFormat) == nullptr) {
|
if (GetCachedPipeline(store, dstFormat) == nullptr) {
|
||||||
// Create vertex shader module if not cached before.
|
// Create vertex shader module if not cached before.
|
||||||
if (store->copyTextureForBrowserVS == nullptr) {
|
if (store->copyTextureForBrowser == nullptr) {
|
||||||
ShaderModuleDescriptor descriptor;
|
ShaderModuleDescriptor descriptor;
|
||||||
ShaderModuleWGSLDescriptor wgslDesc;
|
ShaderModuleWGSLDescriptor wgslDesc;
|
||||||
wgslDesc.source = sCopyTextureForBrowserVertex;
|
wgslDesc.source = sCopyTextureForBrowserShader;
|
||||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
||||||
|
|
||||||
DAWN_TRY_ASSIGN(store->copyTextureForBrowserVS,
|
DAWN_TRY_ASSIGN(store->copyTextureForBrowser,
|
||||||
device->CreateShaderModule(&descriptor));
|
device->CreateShaderModule(&descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderModuleBase* vertexModule = store->copyTextureForBrowserVS.Get();
|
ShaderModuleBase* shaderModule = store->copyTextureForBrowser.Get();
|
||||||
|
|
||||||
// Create fragment shader module if not cached before.
|
|
||||||
if (store->copyTextureForBrowserFS == nullptr) {
|
|
||||||
ShaderModuleDescriptor descriptor;
|
|
||||||
ShaderModuleWGSLDescriptor wgslDesc;
|
|
||||||
wgslDesc.source = sCopyTextureForBrowserFragment;
|
|
||||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
|
||||||
DAWN_TRY_ASSIGN(store->copyTextureForBrowserFS,
|
|
||||||
device->CreateShaderModule(&descriptor));
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderModuleBase* fragmentModule = store->copyTextureForBrowserFS.Get();
|
|
||||||
|
|
||||||
// Prepare vertex stage.
|
// Prepare vertex stage.
|
||||||
VertexState vertex = {};
|
VertexState vertex = {};
|
||||||
vertex.module = vertexModule;
|
vertex.module = shaderModule;
|
||||||
vertex.entryPoint = "main";
|
vertex.entryPoint = "vs_main";
|
||||||
|
|
||||||
// Prepare frgament stage.
|
// Prepare frgament stage.
|
||||||
FragmentState fragment = {};
|
FragmentState fragment = {};
|
||||||
fragment.module = fragmentModule;
|
fragment.module = shaderModule;
|
||||||
fragment.entryPoint = "main";
|
fragment.entryPoint = "fs_main";
|
||||||
|
|
||||||
// Prepare color state.
|
// Prepare color state.
|
||||||
ColorTargetState target = {};
|
ColorTargetState target = {};
|
||||||
|
|
|
@ -28,8 +28,7 @@ namespace dawn_native {
|
||||||
std::unordered_map<wgpu::TextureFormat, Ref<RenderPipelineBase>>
|
std::unordered_map<wgpu::TextureFormat, Ref<RenderPipelineBase>>
|
||||||
copyTextureForBrowserPipelines;
|
copyTextureForBrowserPipelines;
|
||||||
|
|
||||||
Ref<ShaderModuleBase> copyTextureForBrowserVS;
|
Ref<ShaderModuleBase> copyTextureForBrowser;
|
||||||
Ref<ShaderModuleBase> copyTextureForBrowserFS;
|
|
||||||
|
|
||||||
Ref<ComputePipelineBase> timestampComputePipeline;
|
Ref<ComputePipelineBase> timestampComputePipeline;
|
||||||
Ref<ShaderModuleBase> timestampCS;
|
Ref<ShaderModuleBase> timestampCS;
|
||||||
|
|
|
@ -18,12 +18,19 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace opengl {
|
namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
ComputePipeline::ComputePipeline(Device* device, const ComputePipelineDescriptor* descriptor)
|
// static
|
||||||
: ComputePipelineBase(device, descriptor) {
|
ResultOrError<Ref<ComputePipeline>> ComputePipeline::Create(
|
||||||
PerStage<const ShaderModule*> modules(nullptr);
|
Device* device,
|
||||||
modules[SingleShaderStage::Compute] = ToBackend(descriptor->compute.module);
|
const ComputePipelineDescriptor* descriptor) {
|
||||||
|
Ref<ComputePipeline> pipeline = AcquireRef(new ComputePipeline(device, descriptor));
|
||||||
|
DAWN_TRY(pipeline->Initialize(descriptor));
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
PipelineGL::Initialize(device->gl, ToBackend(descriptor->layout), GetAllStages());
|
MaybeError ComputePipeline::Initialize(const ComputePipelineDescriptor*) {
|
||||||
|
DAWN_TRY(
|
||||||
|
InitializeBase(ToBackend(GetDevice())->gl, ToBackend(GetLayout()), GetAllStages()));
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputePipeline::ApplyNow() {
|
void ComputePipeline::ApplyNow() {
|
||||||
|
|
|
@ -27,12 +27,16 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
class ComputePipeline final : public ComputePipelineBase, public PipelineGL {
|
class ComputePipeline final : public ComputePipelineBase, public PipelineGL {
|
||||||
public:
|
public:
|
||||||
ComputePipeline(Device* device, const ComputePipelineDescriptor* descriptor);
|
static ResultOrError<Ref<ComputePipeline>> Create(
|
||||||
|
Device* device,
|
||||||
|
const ComputePipelineDescriptor* descriptor);
|
||||||
|
|
||||||
void ApplyNow();
|
void ApplyNow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using ComputePipelineBase::ComputePipelineBase;
|
||||||
~ComputePipeline() override = default;
|
~ComputePipeline() override = default;
|
||||||
|
MaybeError Initialize(const ComputePipelineDescriptor* descriptor) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::opengl
|
}} // namespace dawn_native::opengl
|
||||||
|
|
|
@ -129,7 +129,7 @@ namespace dawn_native { namespace opengl {
|
||||||
}
|
}
|
||||||
ResultOrError<Ref<ComputePipelineBase>> Device::CreateComputePipelineImpl(
|
ResultOrError<Ref<ComputePipelineBase>> Device::CreateComputePipelineImpl(
|
||||||
const ComputePipelineDescriptor* descriptor) {
|
const ComputePipelineDescriptor* descriptor) {
|
||||||
return AcquireRef(new ComputePipeline(this, descriptor));
|
return ComputePipeline::Create(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<Ref<PipelineLayoutBase>> Device::CreatePipelineLayoutImpl(
|
ResultOrError<Ref<PipelineLayoutBase>> Device::CreatePipelineLayoutImpl(
|
||||||
const PipelineLayoutDescriptor* descriptor) {
|
const PipelineLayoutDescriptor* descriptor) {
|
||||||
|
@ -141,7 +141,7 @@ namespace dawn_native { namespace opengl {
|
||||||
}
|
}
|
||||||
ResultOrError<Ref<RenderPipelineBase>> Device::CreateRenderPipelineImpl(
|
ResultOrError<Ref<RenderPipelineBase>> Device::CreateRenderPipelineImpl(
|
||||||
const RenderPipelineDescriptor* descriptor) {
|
const RenderPipelineDescriptor* descriptor) {
|
||||||
return AcquireRef(new RenderPipeline(this, descriptor));
|
return RenderPipeline::Create(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<Ref<SamplerBase>> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
ResultOrError<Ref<SamplerBase>> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
||||||
return AcquireRef(new Sampler(this, descriptor));
|
return AcquireRef(new Sampler(this, descriptor));
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "dawn_native/opengl/PipelineGL.h"
|
#include "dawn_native/opengl/PipelineGL.h"
|
||||||
|
|
||||||
#include "common/BitSetIterator.h"
|
#include "common/BitSetIterator.h"
|
||||||
#include "common/Log.h"
|
|
||||||
#include "dawn_native/BindGroupLayout.h"
|
#include "dawn_native/BindGroupLayout.h"
|
||||||
#include "dawn_native/Device.h"
|
#include "dawn_native/Device.h"
|
||||||
#include "dawn_native/Pipeline.h"
|
#include "dawn_native/Pipeline.h"
|
||||||
|
@ -26,6 +25,7 @@
|
||||||
#include "dawn_native/opengl/ShaderModuleGL.h"
|
#include "dawn_native/opengl/ShaderModuleGL.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace dawn_native { namespace opengl {
|
namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
|
@ -47,11 +47,11 @@ namespace dawn_native { namespace opengl {
|
||||||
PipelineGL::PipelineGL() = default;
|
PipelineGL::PipelineGL() = default;
|
||||||
PipelineGL::~PipelineGL() = default;
|
PipelineGL::~PipelineGL() = default;
|
||||||
|
|
||||||
void PipelineGL::Initialize(const OpenGLFunctions& gl,
|
MaybeError PipelineGL::InitializeBase(const OpenGLFunctions& gl,
|
||||||
const PipelineLayout* layout,
|
const PipelineLayout* layout,
|
||||||
const PerStage<ProgrammableStage>& stages) {
|
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) -> ResultOrError<GLuint> {
|
||||||
GLuint shader = gl.CreateShader(type);
|
GLuint shader = gl.CreateShader(type);
|
||||||
gl.ShaderSource(shader, 1, &source, nullptr);
|
gl.ShaderSource(shader, 1, &source, nullptr);
|
||||||
gl.CompileShader(shader);
|
gl.CompileShader(shader);
|
||||||
|
@ -65,8 +65,9 @@ namespace dawn_native { namespace opengl {
|
||||||
if (infoLogLength > 1) {
|
if (infoLogLength > 1) {
|
||||||
std::vector<char> buffer(infoLogLength);
|
std::vector<char> buffer(infoLogLength);
|
||||||
gl.GetShaderInfoLog(shader, infoLogLength, nullptr, &buffer[0]);
|
gl.GetShaderInfoLog(shader, infoLogLength, nullptr, &buffer[0]);
|
||||||
dawn::ErrorLog() << source << "\nProgram compilation failed:\n"
|
std::stringstream ss;
|
||||||
<< buffer.data();
|
ss << source << "\nProgram compilation failed:\n" << buffer.data();
|
||||||
|
return DAWN_VALIDATION_ERROR(ss.str().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return shader;
|
return shader;
|
||||||
|
@ -87,10 +88,12 @@ namespace dawn_native { namespace opengl {
|
||||||
bool needsDummySampler = false;
|
bool needsDummySampler = false;
|
||||||
for (SingleShaderStage stage : IterateStages(activeStages)) {
|
for (SingleShaderStage stage : IterateStages(activeStages)) {
|
||||||
const ShaderModule* module = ToBackend(stages[stage].module.Get());
|
const ShaderModule* module = ToBackend(stages[stage].module.Get());
|
||||||
std::string glsl =
|
std::string glsl;
|
||||||
module->TranslateToGLSL(stages[stage].entryPoint.c_str(), stage,
|
DAWN_TRY_ASSIGN(glsl, module->TranslateToGLSL(stages[stage].entryPoint.c_str(), stage,
|
||||||
&combinedSamplers[stage], layout, &needsDummySampler);
|
&combinedSamplers[stage], layout,
|
||||||
GLuint shader = CreateShader(gl, GLShaderType(stage), glsl.c_str());
|
&needsDummySampler));
|
||||||
|
GLuint shader;
|
||||||
|
DAWN_TRY_ASSIGN(shader, CreateShader(gl, GLShaderType(stage), glsl.c_str()));
|
||||||
gl.AttachShader(mProgram, shader);
|
gl.AttachShader(mProgram, shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +118,9 @@ namespace dawn_native { namespace opengl {
|
||||||
if (infoLogLength > 1) {
|
if (infoLogLength > 1) {
|
||||||
std::vector<char> buffer(infoLogLength);
|
std::vector<char> buffer(infoLogLength);
|
||||||
gl.GetProgramInfoLog(mProgram, infoLogLength, nullptr, &buffer[0]);
|
gl.GetProgramInfoLog(mProgram, infoLogLength, nullptr, &buffer[0]);
|
||||||
dawn::ErrorLog() << "Program link failed:\n" << buffer.data();
|
std::stringstream ss;
|
||||||
|
ss << "Program link failed:\n" << buffer.data();
|
||||||
|
return DAWN_VALIDATION_ERROR(ss.str().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +177,7 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
textureUnit++;
|
textureUnit++;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<PipelineGL::SamplerUnit>& PipelineGL::GetTextureUnitsForSampler(
|
const std::vector<PipelineGL::SamplerUnit>& PipelineGL::GetTextureUnitsForSampler(
|
||||||
|
|
|
@ -37,10 +37,6 @@ namespace dawn_native { namespace opengl {
|
||||||
PipelineGL();
|
PipelineGL();
|
||||||
~PipelineGL();
|
~PipelineGL();
|
||||||
|
|
||||||
void Initialize(const OpenGLFunctions& gl,
|
|
||||||
const PipelineLayout* layout,
|
|
||||||
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.
|
||||||
struct SamplerUnit {
|
struct SamplerUnit {
|
||||||
|
@ -53,6 +49,11 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
void ApplyNow(const OpenGLFunctions& gl);
|
void ApplyNow(const OpenGLFunctions& gl);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MaybeError InitializeBase(const OpenGLFunctions& gl,
|
||||||
|
const PipelineLayout* layout,
|
||||||
|
const PerStage<ProgrammableStage>& stages);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint mProgram;
|
GLuint mProgram;
|
||||||
std::vector<std::vector<SamplerUnit>> mUnitsForSamplers;
|
std::vector<std::vector<SamplerUnit>> mUnitsForSamplers;
|
||||||
|
|
|
@ -219,16 +219,26 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
// static
|
||||||
|
ResultOrError<Ref<RenderPipeline>> RenderPipeline::Create(
|
||||||
|
Device* device,
|
||||||
|
const RenderPipelineDescriptor* descriptor) {
|
||||||
|
Ref<RenderPipeline> pipeline = AcquireRef(new RenderPipeline(device, descriptor));
|
||||||
|
DAWN_TRY(pipeline->Initialize());
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||||
: RenderPipelineBase(device, descriptor),
|
: RenderPipelineBase(device, descriptor),
|
||||||
mVertexArrayObject(0),
|
mVertexArrayObject(0),
|
||||||
mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
|
mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
|
||||||
PerStage<const ShaderModule*> modules(nullptr);
|
}
|
||||||
modules[SingleShaderStage::Vertex] = ToBackend(descriptor->vertex.module);
|
|
||||||
modules[SingleShaderStage::Fragment] = ToBackend(descriptor->fragment->module);
|
|
||||||
|
|
||||||
PipelineGL::Initialize(device->gl, ToBackend(GetLayout()), GetAllStages());
|
MaybeError RenderPipeline::Initialize() {
|
||||||
|
DAWN_TRY(
|
||||||
|
InitializeBase(ToBackend(GetDevice())->gl, ToBackend(GetLayout()), GetAllStages()));
|
||||||
CreateVAOForVertexState();
|
CreateVAOForVertexState();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPipeline::~RenderPipeline() {
|
RenderPipeline::~RenderPipeline() {
|
||||||
|
|
|
@ -29,7 +29,9 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
class RenderPipeline final : public RenderPipelineBase, public PipelineGL {
|
class RenderPipeline final : public RenderPipelineBase, public PipelineGL {
|
||||||
public:
|
public:
|
||||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
static ResultOrError<Ref<RenderPipeline>> Create(
|
||||||
|
Device* device,
|
||||||
|
const RenderPipelineDescriptor* descriptor);
|
||||||
|
|
||||||
GLenum GetGLPrimitiveTopology() const;
|
GLenum GetGLPrimitiveTopology() const;
|
||||||
ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes> GetAttributesUsingVertexBuffer(
|
ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes> GetAttributesUsingVertexBuffer(
|
||||||
|
@ -38,7 +40,10 @@ namespace dawn_native { namespace opengl {
|
||||||
void ApplyNow(PersistentPipelineState& persistentPipelineState);
|
void ApplyNow(PersistentPipelineState& persistentPipelineState);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||||
~RenderPipeline() override;
|
~RenderPipeline() override;
|
||||||
|
MaybeError Initialize();
|
||||||
|
|
||||||
void CreateVAOForVertexState();
|
void CreateVAOForVertexState();
|
||||||
|
|
||||||
// TODO(yunchao.he@intel.com): vao need to be deduplicated between pipelines.
|
// TODO(yunchao.he@intel.com): vao need to be deduplicated between pipelines.
|
||||||
|
|
|
@ -94,14 +94,14 @@ namespace dawn_native { namespace opengl {
|
||||||
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
|
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
mGLSpirv = std::move(result.spirv);
|
DAWN_TRY_ASSIGN(mGLEntryPoints,
|
||||||
DAWN_TRY_ASSIGN(mGLEntryPoints, ReflectShaderUsingSPIRVCross(GetDevice(), mGLSpirv));
|
ReflectShaderUsingSPIRVCross(GetDevice(), result.spirv));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ShaderModule::TranslateToGLSL(const char* entryPointName,
|
ResultOrError<std::string> ShaderModule::TranslateToGLSL(const char* entryPointName,
|
||||||
SingleShaderStage stage,
|
SingleShaderStage stage,
|
||||||
CombinedSamplerInfo* combinedSamplers,
|
CombinedSamplerInfo* combinedSamplers,
|
||||||
const PipelineLayout* layout,
|
const PipelineLayout* layout,
|
||||||
|
@ -125,8 +125,32 @@ namespace dawn_native { namespace opengl {
|
||||||
options.es = version.IsES();
|
options.es = version.IsES();
|
||||||
options.version = version.GetMajor() * 100 + version.GetMinor() * 10;
|
options.version = version.GetMajor() * 100 + version.GetMinor() * 10;
|
||||||
|
|
||||||
spirv_cross::CompilerGLSL compiler(
|
std::vector<uint32_t> spirv;
|
||||||
GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator) ? mGLSpirv : GetSpirv());
|
if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) {
|
||||||
|
tint::transform::SingleEntryPoint singleEntryPointTransform;
|
||||||
|
|
||||||
|
tint::transform::DataMap transformInputs;
|
||||||
|
transformInputs.Add<tint::transform::SingleEntryPoint::Config>(entryPointName);
|
||||||
|
|
||||||
|
tint::Program program;
|
||||||
|
DAWN_TRY_ASSIGN(program, RunTransforms(&singleEntryPointTransform, GetTintProgram(),
|
||||||
|
transformInputs, nullptr, nullptr));
|
||||||
|
|
||||||
|
tint::writer::spirv::Options options;
|
||||||
|
options.disable_workgroup_init =
|
||||||
|
GetDevice()->IsToggleEnabled(Toggle::DisableWorkgroupInit);
|
||||||
|
auto result = tint::writer::spirv::Generate(&program, options);
|
||||||
|
if (!result.success) {
|
||||||
|
std::ostringstream errorStream;
|
||||||
|
errorStream << "Generator: " << result.error << std::endl;
|
||||||
|
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
spirv = std::move(result.spirv);
|
||||||
|
} else {
|
||||||
|
spirv = GetSpirv();
|
||||||
|
}
|
||||||
|
spirv_cross::CompilerGLSL compiler(std::move(spirv));
|
||||||
compiler.set_common_options(options);
|
compiler.set_common_options(options);
|
||||||
compiler.set_entry_point(entryPointName, ShaderStageToExecutionModel(stage));
|
compiler.set_entry_point(entryPointName, ShaderStageToExecutionModel(stage));
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace dawn_native { namespace opengl {
|
||||||
const ShaderModuleDescriptor* descriptor,
|
const ShaderModuleDescriptor* descriptor,
|
||||||
ShaderModuleParseResult* parseResult);
|
ShaderModuleParseResult* parseResult);
|
||||||
|
|
||||||
std::string TranslateToGLSL(const char* entryPointName,
|
ResultOrError<std::string> TranslateToGLSL(const char* entryPointName,
|
||||||
SingleShaderStage stage,
|
SingleShaderStage stage,
|
||||||
CombinedSamplerInfo* combinedSamplers,
|
CombinedSamplerInfo* combinedSamplers,
|
||||||
const PipelineLayout* layout,
|
const PipelineLayout* layout,
|
||||||
|
@ -61,7 +61,6 @@ namespace dawn_native { namespace opengl {
|
||||||
~ShaderModule() override = default;
|
~ShaderModule() override = default;
|
||||||
MaybeError Initialize(ShaderModuleParseResult* parseResult);
|
MaybeError Initialize(ShaderModuleParseResult* parseResult);
|
||||||
|
|
||||||
std::vector<uint32_t> mGLSpirv;
|
|
||||||
EntryPointMetadataTable mGLEntryPoints;
|
EntryPointMetadataTable mGLEntryPoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
DAWN_TRY_ASSIGN(program,
|
DAWN_TRY_ASSIGN(program,
|
||||||
RunTransforms(&transformManager, parseResult->tintProgram.get(),
|
RunTransforms(&transformManager, parseResult->tintProgram.get(),
|
||||||
transformInputs, nullptr, nullptr));
|
transformInputs, nullptr, nullptr));
|
||||||
// We will miss the messages generated in this RunTransforms.
|
|
||||||
|
|
||||||
tint::writer::spirv::Options options;
|
tint::writer::spirv::Options options;
|
||||||
options.emit_vertex_point_size = true;
|
options.emit_vertex_point_size = true;
|
||||||
|
@ -203,11 +202,14 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
tint::transform::Manager transformManager;
|
tint::transform::Manager transformManager;
|
||||||
transformManager.append(std::make_unique<tint::transform::BindingRemapper>());
|
transformManager.append(std::make_unique<tint::transform::BindingRemapper>());
|
||||||
|
// Many Vulkan drivers can't handle multi-entrypoint shader modules.
|
||||||
|
transformManager.append(std::make_unique<tint::transform::SingleEntryPoint>());
|
||||||
|
|
||||||
tint::transform::DataMap transformInputs;
|
tint::transform::DataMap transformInputs;
|
||||||
transformInputs.Add<BindingRemapper::Remappings>(std::move(bindingPoints),
|
transformInputs.Add<BindingRemapper::Remappings>(std::move(bindingPoints),
|
||||||
std::move(accessControls),
|
std::move(accessControls),
|
||||||
/* mayCollide */ false);
|
/* mayCollide */ false);
|
||||||
|
transformInputs.Add<tint::transform::SingleEntryPoint::Config>(entryPointName);
|
||||||
|
|
||||||
tint::Program program;
|
tint::Program program;
|
||||||
DAWN_TRY_ASSIGN(program, RunTransforms(&transformManager, GetTintProgram(), transformInputs,
|
DAWN_TRY_ASSIGN(program, RunTransforms(&transformManager, GetTintProgram(), transformInputs,
|
||||||
|
|
|
@ -140,6 +140,10 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
DawnTest::SetUp();
|
DawnTest::SetUp();
|
||||||
|
// crbug.com/dawn/948: Tint required for multiple entrypoints in a module.
|
||||||
|
// CopyTextureForBrowser uses and internal pipeline with a multi-entrypoint
|
||||||
|
// shader module.
|
||||||
|
DAWN_TEST_UNSUPPORTED_IF(!HasToggleEnabled("use_tint_generator"));
|
||||||
|
|
||||||
testPipeline = MakeTestPipeline();
|
testPipeline = MakeTestPipeline();
|
||||||
|
|
||||||
|
|
|
@ -262,8 +262,8 @@ fn main(input : FragmentIn) -> [[location(0)]] vec4<f32> {
|
||||||
|
|
||||||
// Tests that shaders I/O structs can be shared between vertex and fragment shaders.
|
// Tests that shaders I/O structs can be shared between vertex and fragment shaders.
|
||||||
TEST_P(ShaderTests, WGSLSharedStructIO) {
|
TEST_P(ShaderTests, WGSLSharedStructIO) {
|
||||||
// TODO(tint:714): Not yet implemeneted in tint yet, but intended to work.
|
// crbug.com/dawn/948: Tint required for multiple entrypoints in a module.
|
||||||
DAWN_SUPPRESS_TEST_IF(IsD3D12() || IsVulkan() || IsMetal() || IsOpenGL() || IsOpenGLES());
|
DAWN_TEST_UNSUPPORTED_IF(!HasToggleEnabled("use_tint_generator"));
|
||||||
|
|
||||||
std::string shader = R"(
|
std::string shader = R"(
|
||||||
struct VertexIn {
|
struct VertexIn {
|
||||||
|
|
Loading…
Reference in New Issue