Add code path to use spvc in Metal backend
BUG=dawn:291
Change-Id: Idf20496bac733b14db3b7df7eb86ff0a23a9d826
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15161
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/metal/ComputePipelineMTL.mm b/src/dawn_native/metal/ComputePipelineMTL.mm
index 0a66866..5e08cf6 100644
--- a/src/dawn_native/metal/ComputePipelineMTL.mm
+++ b/src/dawn_native/metal/ComputePipelineMTL.mm
@@ -32,7 +32,7 @@
MaybeError ComputePipeline::Initialize(const ComputePipelineDescriptor* descriptor) {
auto mtlDevice = ToBackend(GetDevice())->GetMTLDevice();
- const ShaderModule* computeModule = ToBackend(descriptor->computeStage.module);
+ ShaderModule* computeModule = ToBackend(descriptor->computeStage.module);
const char* computeEntryPoint = descriptor->computeStage.entryPoint;
ShaderModule::MetalFunctionData computeData;
DAWN_TRY(computeModule->GetFunction(computeEntryPoint, SingleShaderStage::Compute,
diff --git a/src/dawn_native/metal/RenderPipelineMTL.mm b/src/dawn_native/metal/RenderPipelineMTL.mm
index c0e7af7..7177fff 100644
--- a/src/dawn_native/metal/RenderPipelineMTL.mm
+++ b/src/dawn_native/metal/RenderPipelineMTL.mm
@@ -330,7 +330,7 @@
MTLRenderPipelineDescriptor* descriptorMTL = [MTLRenderPipelineDescriptor new];
- const ShaderModule* vertexModule = ToBackend(descriptor->vertexStage.module);
+ ShaderModule* vertexModule = ToBackend(descriptor->vertexStage.module);
const char* vertexEntryPoint = descriptor->vertexStage.entryPoint;
ShaderModule::MetalFunctionData vertexData;
DAWN_TRY(vertexModule->GetFunction(vertexEntryPoint, SingleShaderStage::Vertex,
@@ -341,7 +341,7 @@
mStagesRequiringStorageBufferLength |= wgpu::ShaderStage::Vertex;
}
- const ShaderModule* fragmentModule = ToBackend(descriptor->fragmentStage->module);
+ ShaderModule* fragmentModule = ToBackend(descriptor->fragmentStage->module);
const char* fragmentEntryPoint = descriptor->fragmentStage->entryPoint;
ShaderModule::MetalFunctionData fragmentData;
DAWN_TRY(fragmentModule->GetFunction(fragmentEntryPoint, SingleShaderStage::Fragment,
diff --git a/src/dawn_native/metal/ShaderModuleMTL.h b/src/dawn_native/metal/ShaderModuleMTL.h
index 45df04f..ef8dd38 100644
--- a/src/dawn_native/metal/ShaderModuleMTL.h
+++ b/src/dawn_native/metal/ShaderModuleMTL.h
@@ -46,7 +46,7 @@
MaybeError GetFunction(const char* functionName,
SingleShaderStage functionStage,
const PipelineLayout* layout,
- MetalFunctionData* out) const;
+ MetalFunctionData* out);
private:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
diff --git a/src/dawn_native/metal/ShaderModuleMTL.mm b/src/dawn_native/metal/ShaderModuleMTL.mm
index 7543569..d817321 100644
--- a/src/dawn_native/metal/ShaderModuleMTL.mm
+++ b/src/dawn_native/metal/ShaderModuleMTL.mm
@@ -39,6 +39,20 @@
}
}
+ shaderc_spvc_execution_model ToSpvcExecutionModel(SingleShaderStage stage) {
+ switch (stage) {
+ case SingleShaderStage::Vertex:
+ return shaderc_spvc_execution_model_vertex;
+ case SingleShaderStage::Fragment:
+ return shaderc_spvc_execution_model_fragment;
+ case SingleShaderStage::Compute:
+ return shaderc_spvc_execution_model_glcompute;
+ default:
+ UNREACHABLE();
+ return shaderc_spvc_execution_model_invalid;
+ }
+ }
+
shaderc_spvc::CompileOptions GetMSLCompileOptions() {
// If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
// be updated.
@@ -94,7 +108,7 @@
MaybeError ShaderModule::GetFunction(const char* functionName,
SingleShaderStage functionStage,
const PipelineLayout* layout,
- ShaderModule::MetalFunctionData* out) const {
+ ShaderModule::MetalFunctionData* out) {
ASSERT(!IsError());
ASSERT(out);
std::unique_ptr<spirv_cross::CompilerMSL> compiler_impl;
@@ -137,30 +151,58 @@
for (uint32_t binding : IterateBitSet(bgInfo.mask)) {
for (auto stage : IterateStages(bgInfo.visibilities[binding])) {
uint32_t index = layout->GetBindingIndexInfo(stage)[group][binding];
+ if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
+ shaderc_spvc_msl_resource_binding mslBinding;
+ mslBinding.stage = ToSpvcExecutionModel(stage);
+ mslBinding.desc_set = group;
+ mslBinding.binding = binding;
+ mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
+ index;
+ DAWN_TRY(CheckSpvcSuccess(mSpvcContext.AddMSLResourceBinding(mslBinding),
+ "Unable to add MSL Resource Binding"));
+ } else {
+ spirv_cross::MSLResourceBinding mslBinding;
+ mslBinding.stage = SpirvExecutionModelForStage(stage);
+ mslBinding.desc_set = group;
+ mslBinding.binding = binding;
+ mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
+ index;
- spirv_cross::MSLResourceBinding mslBinding;
- mslBinding.stage = SpirvExecutionModelForStage(stage);
- mslBinding.desc_set = group;
- mslBinding.binding = binding;
- mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler = index;
-
- compiler->add_msl_resource_binding(mslBinding);
+ compiler->add_msl_resource_binding(mslBinding);
+ }
}
}
}
{
- spv::ExecutionModel executionModel = SpirvExecutionModelForStage(functionStage);
- auto size = compiler->get_entry_point(functionName, executionModel).workgroup_size;
- out->localWorkgroupSize = MTLSizeMake(size.x, size.y, size.z);
+ if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
+ shaderc_spvc_execution_model executionModel = ToSpvcExecutionModel(functionStage);
+ shaderc_spvc_workgroup_size size;
+ DAWN_TRY(CheckSpvcSuccess(
+ mSpvcContext.GetWorkgroupSize(functionName, executionModel, &size),
+ "Unable to get workgroup size for shader"));
+ out->localWorkgroupSize = MTLSizeMake(size.x, size.y, size.z);
+ } else {
+ spv::ExecutionModel executionModel = SpirvExecutionModelForStage(functionStage);
+ auto size = compiler->get_entry_point(functionName, executionModel).workgroup_size;
+ out->localWorkgroupSize = MTLSizeMake(size.x, size.y, size.z);
+ }
}
{
// SPIRV-Cross also supports re-ordering attributes but it seems to do the correct thing
// by default.
- std::string msl = compiler->compile();
- NSString* mslSource = [NSString stringWithFormat:@"%s", msl.c_str()];
+ NSString* mslSource;
+ if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
+ shaderc_spvc::CompilationResult result;
+ DAWN_TRY(CheckSpvcSuccess(mSpvcContext.CompileShader(&result),
+ "Unable to compile shader"));
+ mslSource = [NSString stringWithFormat:@"%s", result.GetStringOutput().c_str()];
+ } else {
+ std::string msl = compiler->compile();
+ mslSource = [NSString stringWithFormat:@"%s", msl.c_str()];
+ }
auto mtlDevice = ToBackend(GetDevice())->GetMTLDevice();
NSError* error = nil;
id<MTLLibrary> library = [mtlDevice newLibraryWithSource:mslSource
@@ -187,7 +229,13 @@
[library release];
}
- out->needsStorageBufferLength = compiler->needs_buffer_size_buffer();
+ if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
+ DAWN_TRY(
+ CheckSpvcSuccess(mSpvcContext.NeedsBufferSizeBuffer(&out->needsStorageBufferLength),
+ "Unable to determine if shader needs buffer size buffer"));
+ } else {
+ out->needsStorageBufferLength = compiler->needs_buffer_size_buffer();
+ }
return {};
}