Return errors in ExtractSpirvInfo instead of sending to the device
BUG=dawn:274 Change-Id: Ieeaffdd356a6f2174a39a8098b306c36d10ef9e7 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15100 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Ryan Harrison <rharrison@chromium.org>
This commit is contained in:
parent
3a1746e71c
commit
9af58bbe14
|
@ -119,20 +119,19 @@ namespace dawn_native {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(rharrison): Convert this to ResultOrError once ExtractSPIRVInfo turns an error
|
ResultOrError<SingleShaderStage> ToSingleShaderStage(
|
||||||
SingleShaderStage ToSingleShaderStage(shaderc_spvc_execution_model execution_model) {
|
shaderc_spvc_execution_model execution_model) {
|
||||||
switch (execution_model) {
|
switch (execution_model) {
|
||||||
case shaderc_spvc_execution_model_vertex:
|
case shaderc_spvc_execution_model_vertex:
|
||||||
return SingleShaderStage::Vertex;
|
return {SingleShaderStage::Vertex};
|
||||||
case shaderc_spvc_execution_model_fragment:
|
case shaderc_spvc_execution_model_fragment:
|
||||||
return SingleShaderStage::Fragment;
|
return {SingleShaderStage::Fragment};
|
||||||
case shaderc_spvc_execution_model_glcompute:
|
case shaderc_spvc_execution_model_glcompute:
|
||||||
return SingleShaderStage::Compute;
|
return {SingleShaderStage::Compute};
|
||||||
default:
|
default:
|
||||||
// This will be converted to an error return when the whole
|
|
||||||
// calling stack is changed to passing errors.
|
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return SingleShaderStage::Vertex;
|
return DAWN_VALIDATION_ERROR(
|
||||||
|
"Attempted to convert invalid spvc execution model to SingleShaderStage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -198,45 +197,40 @@ namespace dawn_native {
|
||||||
return new ShaderModuleBase(device, ObjectBase::kError);
|
return new ShaderModuleBase(device, ObjectBase::kError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderModuleBase::ExtractSpirvInfo(const spirv_cross::Compiler& compiler) {
|
MaybeError ShaderModuleBase::ExtractSpirvInfo(const spirv_cross::Compiler& compiler) {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
|
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
|
||||||
ExtractSpirvInfoWithSpvc(compiler);
|
DAWN_TRY(ExtractSpirvInfoWithSpvc());
|
||||||
} else {
|
} else {
|
||||||
ExtractSpirvInfoWithSpirvCross(compiler);
|
DAWN_TRY(ExtractSpirvInfoWithSpirvCross(compiler));
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderModuleBase::ExtractSpirvInfoWithSpvc(const spirv_cross::Compiler& compiler) {
|
MaybeError ShaderModuleBase::ExtractSpirvInfoWithSpvc() {
|
||||||
shaderc_spvc_execution_model execution_model;
|
shaderc_spvc_execution_model execution_model;
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetExecutionModel(&execution_model),
|
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetExecutionModel(&execution_model),
|
||||||
"Unable to get execution model for shader.")) {
|
"Unable to get execution model for shader."));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mExecutionModel = ToSingleShaderStage(execution_model);
|
DAWN_TRY_ASSIGN(mExecutionModel, ToSingleShaderStage(execution_model));
|
||||||
|
|
||||||
size_t push_constant_buffers_count;
|
size_t push_constant_buffers_count;
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetPushConstantBufferCount(&push_constant_buffers_count),
|
DAWN_TRY(
|
||||||
"Unable to get push constant buffer count for shader.")) {
|
CheckSpvcSuccess(mSpvcContext.GetPushConstantBufferCount(&push_constant_buffers_count),
|
||||||
return;
|
"Unable to get push constant buffer count for shader."));
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(rharrison): This should be handled by spirv-val pass in spvc,
|
// TODO(rharrison): This should be handled by spirv-val pass in spvc,
|
||||||
// but need to confirm.
|
// but need to confirm.
|
||||||
if (push_constant_buffers_count > 0) {
|
if (push_constant_buffers_count > 0) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Push constants aren't supported.");
|
||||||
"Push constants aren't supported.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in bindingInfo with the SPIRV bindings
|
// Fill in bindingInfo with the SPIRV bindings
|
||||||
auto ExtractResourcesBinding = [this](std::vector<shaderc_spvc_binding_info> bindings) {
|
auto ExtractResourcesBinding =
|
||||||
|
[this](std::vector<shaderc_spvc_binding_info> bindings) -> MaybeError {
|
||||||
for (const auto& binding : bindings) {
|
for (const auto& binding : bindings) {
|
||||||
if (binding.binding >= kMaxBindingsPerGroup || binding.set >= kMaxBindGroups) {
|
if (binding.binding >= kMaxBindingsPerGroup || binding.set >= kMaxBindGroups) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Binding over limits in the SPIRV");
|
||||||
"Binding over limits in the SPIRV");
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BindingInfo* info = &mBindingInfo[binding.set][binding.binding];
|
BindingInfo* info = &mBindingInfo[binding.set][binding.binding];
|
||||||
|
@ -251,108 +245,90 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
info->type = ToWGPUBindingType(binding.binding_type);
|
info->type = ToWGPUBindingType(binding.binding_type);
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<shaderc_spvc_binding_info> resource_bindings;
|
std::vector<shaderc_spvc_binding_info> resource_bindings;
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetBindingInfo(
|
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetBindingInfo(
|
||||||
shaderc_spvc_shader_resource_uniform_buffers,
|
shaderc_spvc_shader_resource_uniform_buffers,
|
||||||
shaderc_spvc_binding_type_uniform_buffer, &resource_bindings),
|
shaderc_spvc_binding_type_uniform_buffer, &resource_bindings),
|
||||||
"Unable to get binding info for uniform buffers from shader")) {
|
"Unable to get binding info for uniform buffers from shader"));
|
||||||
return;
|
DAWN_TRY(ExtractResourcesBinding(resource_bindings));
|
||||||
}
|
|
||||||
ExtractResourcesBinding(resource_bindings);
|
|
||||||
|
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetBindingInfo(
|
DAWN_TRY(CheckSpvcSuccess(
|
||||||
shaderc_spvc_shader_resource_separate_images,
|
mSpvcContext.GetBindingInfo(shaderc_spvc_shader_resource_separate_images,
|
||||||
shaderc_spvc_binding_type_sampled_texture, &resource_bindings),
|
shaderc_spvc_binding_type_sampled_texture,
|
||||||
"Unable to get binding info for sampled textures from shader")) {
|
&resource_bindings),
|
||||||
return;
|
"Unable to get binding info for sampled textures from shader"));
|
||||||
}
|
DAWN_TRY(ExtractResourcesBinding(resource_bindings));
|
||||||
ExtractResourcesBinding(resource_bindings);
|
|
||||||
|
|
||||||
if (!CheckSpvcSuccess(
|
DAWN_TRY(CheckSpvcSuccess(
|
||||||
mSpvcContext.GetBindingInfo(shaderc_spvc_shader_resource_separate_samplers,
|
mSpvcContext.GetBindingInfo(shaderc_spvc_shader_resource_separate_samplers,
|
||||||
shaderc_spvc_binding_type_sampler, &resource_bindings),
|
shaderc_spvc_binding_type_sampler, &resource_bindings),
|
||||||
"Unable to get binding info for samples from shader")) {
|
"Unable to get binding info for samples from shader"));
|
||||||
return;
|
DAWN_TRY(ExtractResourcesBinding(resource_bindings));
|
||||||
}
|
|
||||||
ExtractResourcesBinding(resource_bindings);
|
|
||||||
|
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetBindingInfo(
|
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetBindingInfo(
|
||||||
shaderc_spvc_shader_resource_storage_buffers,
|
shaderc_spvc_shader_resource_storage_buffers,
|
||||||
shaderc_spvc_binding_type_storage_buffer, &resource_bindings),
|
shaderc_spvc_binding_type_storage_buffer, &resource_bindings),
|
||||||
"Unable to get binding info for storage buffers from shader")) {
|
"Unable to get binding info for storage buffers from shader"));
|
||||||
return;
|
DAWN_TRY(ExtractResourcesBinding(resource_bindings));
|
||||||
}
|
|
||||||
ExtractResourcesBinding(resource_bindings);
|
|
||||||
|
|
||||||
std::vector<shaderc_spvc_resource_location_info> input_stage_locations;
|
std::vector<shaderc_spvc_resource_location_info> input_stage_locations;
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetInputStageLocationInfo(&input_stage_locations),
|
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetInputStageLocationInfo(&input_stage_locations),
|
||||||
"Unable to get input stage location information from shader")) {
|
"Unable to get input stage location information from shader"));
|
||||||
input_stage_locations.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& input : input_stage_locations) {
|
for (const auto& input : input_stage_locations) {
|
||||||
if (mExecutionModel == SingleShaderStage::Vertex) {
|
if (mExecutionModel == SingleShaderStage::Vertex) {
|
||||||
if (input.location >= kMaxVertexAttributes) {
|
if (input.location >= kMaxVertexAttributes) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Attribute location over limits in the SPIRV");
|
||||||
"Attribute location over limits in the SPIRV");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
mUsedVertexAttributes.set(input.location);
|
mUsedVertexAttributes.set(input.location);
|
||||||
} else if (mExecutionModel == SingleShaderStage::Fragment) {
|
} else if (mExecutionModel == SingleShaderStage::Fragment) {
|
||||||
// Without a location qualifier on vertex inputs, spirv_cross::CompilerMSL gives
|
// Without a location qualifier on vertex inputs, spirv_cross::CompilerMSL gives
|
||||||
// them all the location 0, causing a compile error.
|
// them all the location 0, causing a compile error.
|
||||||
if (!input.has_location) {
|
if (!input.has_location) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Need location qualifier on fragment input");
|
||||||
"Need location qualifier on fragment input");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<shaderc_spvc_resource_location_info> output_stage_locations;
|
std::vector<shaderc_spvc_resource_location_info> output_stage_locations;
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetOutputStageLocationInfo(&output_stage_locations),
|
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetOutputStageLocationInfo(&output_stage_locations),
|
||||||
"Unable to get output stage location information from shader")) {
|
"Unable to get output stage location information from shader"));
|
||||||
output_stage_locations.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& output : output_stage_locations) {
|
for (const auto& output : output_stage_locations) {
|
||||||
if (mExecutionModel == SingleShaderStage::Vertex) {
|
if (mExecutionModel == SingleShaderStage::Vertex) {
|
||||||
// Without a location qualifier on vertex outputs, spirv_cross::CompilerMSL
|
// Without a location qualifier on vertex outputs, spirv_cross::CompilerMSL
|
||||||
// gives them all the location 0, causing a compile error.
|
// gives them all the location 0, causing a compile error.
|
||||||
if (!output.has_location) {
|
if (!output.has_location) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Need location qualifier on vertex output");
|
||||||
"Need location qualifier on vertex output");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else if (mExecutionModel == SingleShaderStage::Fragment) {
|
} else if (mExecutionModel == SingleShaderStage::Fragment) {
|
||||||
if (output.location >= kMaxColorAttachments) {
|
if (output.location >= kMaxColorAttachments) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR(
|
||||||
"Fragment output location over limits in the SPIRV");
|
"Fragment output location over limits in the SPIRV");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mExecutionModel == SingleShaderStage::Fragment) {
|
if (mExecutionModel == SingleShaderStage::Fragment) {
|
||||||
std::vector<shaderc_spvc_resource_type_info> output_types;
|
std::vector<shaderc_spvc_resource_type_info> output_types;
|
||||||
if (!CheckSpvcSuccess(mSpvcContext.GetOutputStageTypeInfo(&output_types),
|
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetOutputStageTypeInfo(&output_types),
|
||||||
"Unable to get output stage type information from shader")) {
|
"Unable to get output stage type information from shader"));
|
||||||
output_stage_locations.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& output : output_types) {
|
for (const auto& output : output_types) {
|
||||||
ASSERT(output.type != shaderc_spvc_texture_format_type_other);
|
if (output.type == shaderc_spvc_texture_format_type_other) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Unexpected Fragment output type");
|
||||||
|
}
|
||||||
mFragmentOutputFormatBaseTypes[output.location] = ToDawnFormatType(output.type);
|
mFragmentOutputFormatBaseTypes[output.location] = ToDawnFormatType(output.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderModuleBase::ExtractSpirvInfoWithSpirvCross(const spirv_cross::Compiler& compiler) {
|
MaybeError ShaderModuleBase::ExtractSpirvInfoWithSpirvCross(
|
||||||
|
const spirv_cross::Compiler& compiler) {
|
||||||
// TODO(cwallez@chromium.org): make errors here creation errors
|
// TODO(cwallez@chromium.org): make errors here creation errors
|
||||||
// currently errors here do not prevent the shadermodule from being used
|
// currently errors here do not prevent the shadermodule from being used
|
||||||
const auto& resources = compiler.get_shader_resources();
|
const auto& resources = compiler.get_shader_resources();
|
||||||
|
@ -369,30 +345,33 @@ namespace dawn_native {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
return DAWN_VALIDATION_ERROR("Unexpected shader execution model");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resources.push_constant_buffers.size() > 0) {
|
if (resources.push_constant_buffers.size() > 0) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Push constants aren't supported.");
|
||||||
"Push constants aren't supported.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in bindingInfo with the SPIRV bindings
|
// Fill in bindingInfo with the SPIRV bindings
|
||||||
auto ExtractResourcesBinding =
|
auto ExtractResourcesBinding =
|
||||||
[this](const spirv_cross::SmallVector<spirv_cross::Resource>& resources,
|
[this](const spirv_cross::SmallVector<spirv_cross::Resource>& resources,
|
||||||
const spirv_cross::Compiler& compiler, wgpu::BindingType bindingType) {
|
const spirv_cross::Compiler& compiler,
|
||||||
|
wgpu::BindingType bindingType) -> MaybeError {
|
||||||
for (const auto& resource : resources) {
|
for (const auto& resource : resources) {
|
||||||
ASSERT(compiler.get_decoration_bitset(resource.id).get(spv::DecorationBinding));
|
if (!compiler.get_decoration_bitset(resource.id).get(spv::DecorationBinding)) {
|
||||||
ASSERT(compiler.get_decoration_bitset(resource.id)
|
return DAWN_VALIDATION_ERROR("No Binding decoration set for resource");
|
||||||
.get(spv::DecorationDescriptorSet));
|
}
|
||||||
|
|
||||||
|
if (!compiler.get_decoration_bitset(resource.id)
|
||||||
|
.get(spv::DecorationDescriptorSet)) {
|
||||||
|
return DAWN_VALIDATION_ERROR("No Descriptor Decoration set for resource");
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t binding = compiler.get_decoration(resource.id, spv::DecorationBinding);
|
uint32_t binding = compiler.get_decoration(resource.id, spv::DecorationBinding);
|
||||||
uint32_t set =
|
uint32_t set = compiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||||
compiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
|
||||||
|
|
||||||
if (binding >= kMaxBindingsPerGroup || set >= kMaxBindGroups) {
|
if (binding >= kMaxBindingsPerGroup || set >= kMaxBindGroups) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Binding over limits in the SPIRV");
|
||||||
"Binding over limits in the SPIRV");
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BindingInfo* info = &mBindingInfo[set][binding];
|
BindingInfo* info = &mBindingInfo[set][binding];
|
||||||
|
@ -417,8 +396,7 @@ namespace dawn_native {
|
||||||
case wgpu::BindingType::StorageBuffer: {
|
case wgpu::BindingType::StorageBuffer: {
|
||||||
// Differentiate between readonly storage bindings and writable ones
|
// Differentiate between readonly storage bindings and writable ones
|
||||||
// based on the NonWritable decoration
|
// based on the NonWritable decoration
|
||||||
spirv_cross::Bitset flags =
|
spirv_cross::Bitset flags = compiler.get_buffer_block_flags(resource.id);
|
||||||
compiler.get_buffer_block_flags(resource.id);
|
|
||||||
if (flags.get(spv::DecorationNonWritable)) {
|
if (flags.get(spv::DecorationNonWritable)) {
|
||||||
info->type = wgpu::BindingType::ReadonlyStorageBuffer;
|
info->type = wgpu::BindingType::ReadonlyStorageBuffer;
|
||||||
} else {
|
} else {
|
||||||
|
@ -429,26 +407,29 @@ namespace dawn_native {
|
||||||
info->type = bindingType;
|
info->type = bindingType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
ExtractResourcesBinding(resources.uniform_buffers, compiler,
|
DAWN_TRY(ExtractResourcesBinding(resources.uniform_buffers, compiler,
|
||||||
wgpu::BindingType::UniformBuffer);
|
wgpu::BindingType::UniformBuffer));
|
||||||
ExtractResourcesBinding(resources.separate_images, compiler,
|
DAWN_TRY(ExtractResourcesBinding(resources.separate_images, compiler,
|
||||||
wgpu::BindingType::SampledTexture);
|
wgpu::BindingType::SampledTexture));
|
||||||
ExtractResourcesBinding(resources.separate_samplers, compiler, wgpu::BindingType::Sampler);
|
DAWN_TRY(ExtractResourcesBinding(resources.separate_samplers, compiler,
|
||||||
ExtractResourcesBinding(resources.storage_buffers, compiler,
|
wgpu::BindingType::Sampler));
|
||||||
wgpu::BindingType::StorageBuffer);
|
DAWN_TRY(ExtractResourcesBinding(resources.storage_buffers, compiler,
|
||||||
|
wgpu::BindingType::StorageBuffer));
|
||||||
|
|
||||||
// Extract the vertex attributes
|
// Extract the vertex attributes
|
||||||
if (mExecutionModel == SingleShaderStage::Vertex) {
|
if (mExecutionModel == SingleShaderStage::Vertex) {
|
||||||
for (const auto& attrib : resources.stage_inputs) {
|
for (const auto& attrib : resources.stage_inputs) {
|
||||||
ASSERT(compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation));
|
if (!(compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation))) {
|
||||||
|
return DAWN_VALIDATION_ERROR(
|
||||||
|
"Unable to find Location decoration for Vertex input");
|
||||||
|
}
|
||||||
uint32_t location = compiler.get_decoration(attrib.id, spv::DecorationLocation);
|
uint32_t location = compiler.get_decoration(attrib.id, spv::DecorationLocation);
|
||||||
|
|
||||||
if (location >= kMaxVertexAttributes) {
|
if (location >= kMaxVertexAttributes) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Attribute location over limits in the SPIRV");
|
||||||
"Attribute location over limits in the SPIRV");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mUsedVertexAttributes.set(location);
|
mUsedVertexAttributes.set(location);
|
||||||
|
@ -458,9 +439,7 @@ namespace dawn_native {
|
||||||
// them all the location 0, causing a compile error.
|
// them all the location 0, causing a compile error.
|
||||||
for (const auto& attrib : resources.stage_outputs) {
|
for (const auto& attrib : resources.stage_outputs) {
|
||||||
if (!compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation)) {
|
if (!compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation)) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Need location qualifier on vertex output");
|
||||||
"Need location qualifier on vertex output");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,31 +449,34 @@ namespace dawn_native {
|
||||||
// them all the location 0, causing a compile error.
|
// them all the location 0, causing a compile error.
|
||||||
for (const auto& attrib : resources.stage_inputs) {
|
for (const auto& attrib : resources.stage_inputs) {
|
||||||
if (!compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation)) {
|
if (!compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation)) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR("Need location qualifier on fragment input");
|
||||||
"Need location qualifier on fragment input");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& fragmentOutput : resources.stage_outputs) {
|
for (const auto& fragmentOutput : resources.stage_outputs) {
|
||||||
ASSERT(
|
if (!compiler.get_decoration_bitset(fragmentOutput.id)
|
||||||
compiler.get_decoration_bitset(fragmentOutput.id).get(spv::DecorationLocation));
|
.get(spv::DecorationLocation)) {
|
||||||
|
return DAWN_VALIDATION_ERROR(
|
||||||
|
"Unable to find Location decoration for Fragment output");
|
||||||
|
}
|
||||||
uint32_t location =
|
uint32_t location =
|
||||||
compiler.get_decoration(fragmentOutput.id, spv::DecorationLocation);
|
compiler.get_decoration(fragmentOutput.id, spv::DecorationLocation);
|
||||||
if (location >= kMaxColorAttachments) {
|
if (location >= kMaxColorAttachments) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation,
|
return DAWN_VALIDATION_ERROR(
|
||||||
"Fragment output location over limits in the SPIRV");
|
"Fragment output location over limits in the SPIRV");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spirv_cross::SPIRType::BaseType shaderFragmentOutputBaseType =
|
spirv_cross::SPIRType::BaseType shaderFragmentOutputBaseType =
|
||||||
compiler.get_type(fragmentOutput.base_type_id).basetype;
|
compiler.get_type(fragmentOutput.base_type_id).basetype;
|
||||||
Format::Type formatType =
|
Format::Type formatType =
|
||||||
SpirvCrossBaseTypeToFormatType(shaderFragmentOutputBaseType);
|
SpirvCrossBaseTypeToFormatType(shaderFragmentOutputBaseType);
|
||||||
ASSERT(formatType != Format::Type::Other);
|
if (formatType == Format::Type::Other) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Unexpected Fragment output type");
|
||||||
|
};
|
||||||
mFragmentOutputFormatBaseTypes[location] = formatType;
|
mFragmentOutputFormatBaseTypes[location] = formatType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShaderModuleBase::ModuleBindingInfo& ShaderModuleBase::GetBindingInfo() const {
|
const ShaderModuleBase::ModuleBindingInfo& ShaderModuleBase::GetBindingInfo() const {
|
||||||
|
@ -600,12 +582,12 @@ namespace dawn_native {
|
||||||
return a->mCode == b->mCode;
|
return a->mCode == b->mCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderModuleBase::CheckSpvcSuccess(shaderc_spvc_status status, const char* error_msg) {
|
MaybeError ShaderModuleBase::CheckSpvcSuccess(shaderc_spvc_status status,
|
||||||
|
const char* error_msg) {
|
||||||
if (status != shaderc_spvc_status_success) {
|
if (status != shaderc_spvc_status_success) {
|
||||||
GetDevice()->HandleError(wgpu::ErrorType::Validation, error_msg);
|
DAWN_VALIDATION_ERROR(error_msg);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace dawn_native {
|
||||||
|
|
||||||
static ShaderModuleBase* MakeError(DeviceBase* device);
|
static ShaderModuleBase* MakeError(DeviceBase* device);
|
||||||
|
|
||||||
void ExtractSpirvInfo(const spirv_cross::Compiler& compiler);
|
MaybeError ExtractSpirvInfo(const spirv_cross::Compiler& compiler);
|
||||||
|
|
||||||
struct BindingInfo {
|
struct BindingInfo {
|
||||||
// The SPIRV ID of the resource.
|
// The SPIRV ID of the resource.
|
||||||
|
@ -91,10 +91,10 @@ namespace dawn_native {
|
||||||
|
|
||||||
// Different implementations reflection into the shader depending on
|
// Different implementations reflection into the shader depending on
|
||||||
// whether using spvc, or directly accessing spirv-cross.
|
// whether using spvc, or directly accessing spirv-cross.
|
||||||
void ExtractSpirvInfoWithSpvc(const spirv_cross::Compiler& compiler);
|
MaybeError ExtractSpirvInfoWithSpvc();
|
||||||
void ExtractSpirvInfoWithSpirvCross(const spirv_cross::Compiler& compiler);
|
MaybeError ExtractSpirvInfoWithSpirvCross(const spirv_cross::Compiler& compiler);
|
||||||
|
|
||||||
bool CheckSpvcSuccess(shaderc_spvc_status status, const char* error_msg);
|
MaybeError CheckSpvcSuccess(shaderc_spvc_status status, const char* error_msg);
|
||||||
|
|
||||||
// TODO(cwallez@chromium.org): The code is only stored for deduplication. We could maybe
|
// TODO(cwallez@chromium.org): The code is only stored for deduplication. We could maybe
|
||||||
// store a cryptographic hash of the code instead?
|
// store a cryptographic hash of the code instead?
|
||||||
|
|
|
@ -60,10 +60,10 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
spirv_cross::Compiler* compiler =
|
spirv_cross::Compiler* compiler =
|
||||||
reinterpret_cast<spirv_cross::Compiler*>(mSpvcContext.GetCompiler());
|
reinterpret_cast<spirv_cross::Compiler*>(mSpvcContext.GetCompiler());
|
||||||
ExtractSpirvInfo(*compiler);
|
DAWN_TRY(ExtractSpirvInfo(*compiler));
|
||||||
} else {
|
} else {
|
||||||
spirv_cross::CompilerHLSL compiler(descriptor->code, descriptor->codeSize);
|
spirv_cross::CompilerHLSL compiler(descriptor->code, descriptor->codeSize);
|
||||||
ExtractSpirvInfo(compiler);
|
DAWN_TRY(ExtractSpirvInfo(compiler));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,10 +84,10 @@ namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
spirv_cross::CompilerMSL* compiler =
|
spirv_cross::CompilerMSL* compiler =
|
||||||
reinterpret_cast<spirv_cross::CompilerMSL*>(mSpvcContext.GetCompiler());
|
reinterpret_cast<spirv_cross::CompilerMSL*>(mSpvcContext.GetCompiler());
|
||||||
ExtractSpirvInfo(*compiler);
|
DAWN_TRY(ExtractSpirvInfo(*compiler));
|
||||||
} else {
|
} else {
|
||||||
spirv_cross::CompilerMSL compiler(mSpirv);
|
spirv_cross::CompilerMSL compiler(mSpirv);
|
||||||
ExtractSpirvInfo(compiler);
|
DAWN_TRY(ExtractSpirvInfo(compiler));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,10 +138,10 @@ namespace dawn_native { namespace null {
|
||||||
|
|
||||||
spirv_cross::Compiler* compiler =
|
spirv_cross::Compiler* compiler =
|
||||||
reinterpret_cast<spirv_cross::Compiler*>(context.GetCompiler());
|
reinterpret_cast<spirv_cross::Compiler*>(context.GetCompiler());
|
||||||
module->ExtractSpirvInfo(*compiler);
|
DAWN_TRY(module->ExtractSpirvInfo(*compiler));
|
||||||
} else {
|
} else {
|
||||||
spirv_cross::Compiler compiler(descriptor->code, descriptor->codeSize);
|
spirv_cross::Compiler compiler(descriptor->code, descriptor->codeSize);
|
||||||
module->ExtractSpirvInfo(compiler);
|
DAWN_TRY(module->ExtractSpirvInfo(compiler));
|
||||||
}
|
}
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace dawn_native { namespace opengl {
|
||||||
compiler->set_common_options(options);
|
compiler->set_common_options(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtractSpirvInfo(*compiler);
|
DAWN_TRY(ExtractSpirvInfo(*compiler));
|
||||||
|
|
||||||
const auto& bindingInfo = GetBindingInfo();
|
const auto& bindingInfo = GetBindingInfo();
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,10 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
spirv_cross::Compiler* compiler =
|
spirv_cross::Compiler* compiler =
|
||||||
reinterpret_cast<spirv_cross::Compiler*>(mSpvcContext.GetCompiler());
|
reinterpret_cast<spirv_cross::Compiler*>(mSpvcContext.GetCompiler());
|
||||||
ExtractSpirvInfo(*compiler);
|
DAWN_TRY(ExtractSpirvInfo(*compiler));
|
||||||
} else {
|
} else {
|
||||||
spirv_cross::Compiler compiler(descriptor->code, descriptor->codeSize);
|
spirv_cross::Compiler compiler(descriptor->code, descriptor->codeSize);
|
||||||
ExtractSpirvInfo(compiler);
|
DAWN_TRY(ExtractSpirvInfo(compiler));
|
||||||
}
|
}
|
||||||
|
|
||||||
VkShaderModuleCreateInfo createInfo;
|
VkShaderModuleCreateInfo createInfo;
|
||||||
|
|
Loading…
Reference in New Issue