Separate entry point reflection in its own function.

This allows adding as an error context the name of the entry point, and
dedents the code a little bit.

Bug: dawn:563
Change-Id: I1ea9760fc1aca506826ca7ef5a65d40f8370136d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/85500
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Brandon Jones <bajones@chromium.org>
Commit-Queue: Brandon Jones <bajones@chromium.org>
This commit is contained in:
Corentin Wallez 2022-04-01 22:04:30 +00:00 committed by Dawn LUCI CQ
parent 705b6e3d08
commit 595e20085d
2 changed files with 334 additions and 337 deletions

View File

@ -130,6 +130,8 @@ namespace dawn::native {
// DAWN_TRY_ASSIGN is the same as DAWN_TRY for ResultOrError and assigns the success value, if // DAWN_TRY_ASSIGN is the same as DAWN_TRY for ResultOrError and assigns the success value, if
// any, to VAR. // any, to VAR.
#define DAWN_TRY_ASSIGN(VAR, EXPR) DAWN_TRY_ASSIGN_WITH_CLEANUP(VAR, EXPR, {}) #define DAWN_TRY_ASSIGN(VAR, EXPR) DAWN_TRY_ASSIGN_WITH_CLEANUP(VAR, EXPR, {})
#define DAWN_TRY_ASSIGN_CONTEXT(VAR, EXPR, ...) \
DAWN_TRY_ASSIGN_WITH_CLEANUP(VAR, EXPR, { error->AppendContext(absl::StrFormat(__VA_ARGS__)); })
// Argument helpers are used to determine which macro implementations should be called when // Argument helpers are used to determine which macro implementations should be called when
// overloading with different number of variables. // overloading with different number of variables.

View File

@ -374,9 +374,8 @@ namespace dawn::native {
return EntryPointMetadata::OverridableConstant::Type::Int32; return EntryPointMetadata::OverridableConstant::Type::Int32;
case tint::inspector::OverridableConstant::Type::kUint32: case tint::inspector::OverridableConstant::Type::kUint32:
return EntryPointMetadata::OverridableConstant::Type::Uint32; return EntryPointMetadata::OverridableConstant::Type::Uint32;
default:
UNREACHABLE();
} }
UNREACHABLE();
} }
ResultOrError<tint::Program> ParseWGSL(const tint::Source::File* file, ResultOrError<tint::Program> ParseWGSL(const tint::Source::File* file,
@ -598,35 +597,22 @@ namespace dawn::native {
return {}; return {};
} }
ResultOrError<EntryPointMetadataTable> ReflectShaderUsingTint( ResultOrError<std::unique_ptr<EntryPointMetadata>> ReflectEntryPointUsingTint(
const DeviceBase* device, const DeviceBase* device,
const tint::Program* program) { tint::inspector::Inspector* inspector,
ASSERT(program->IsValid()); const tint::inspector::EntryPoint& entryPoint) {
const CombinedLimits& limits = device->GetLimits(); const CombinedLimits& limits = device->GetLimits();
EntryPointMetadataTable result;
tint::inspector::Inspector inspector(program);
auto entryPoints = inspector.GetEntryPoints();
DAWN_INVALID_IF(inspector.has_error(), "Tint Reflection failure: Inspector: %s\n",
inspector.error());
// TODO(dawn:563): use DAWN_TRY_CONTEXT to output the name of the entry point we're
// reflecting.
constexpr uint32_t kMaxInterStageShaderLocation = kMaxInterStageShaderVariables - 1; constexpr uint32_t kMaxInterStageShaderLocation = kMaxInterStageShaderVariables - 1;
for (auto& entryPoint : entryPoints) {
ASSERT(result.count(entryPoint.name) == 0);
auto metadata = std::make_unique<EntryPointMetadata>(); std::unique_ptr<EntryPointMetadata> metadata = std::make_unique<EntryPointMetadata>();
if (!entryPoint.overridable_constants.empty()) { if (!entryPoint.overridable_constants.empty()) {
DAWN_INVALID_IF(device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs), DAWN_INVALID_IF(device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs),
"Pipeline overridable constants are disallowed because they " "Pipeline overridable constants are disallowed because they "
"are partially implemented."); "are partially implemented.");
const auto& name2Id = inspector.GetConstantNameToIdMap(); const auto& name2Id = inspector->GetConstantNameToIdMap();
const auto& id2Scalar = inspector.GetConstantIDs(); const auto& id2Scalar = inspector->GetConstantIDs();
for (auto& c : entryPoint.overridable_constants) { for (auto& c : entryPoint.overridable_constants) {
uint32_t id = name2Id.at(c.name); uint32_t id = name2Id.at(c.name);
@ -655,8 +641,7 @@ namespace dawn::native {
metadata->overridableConstants[identifier] = constant; metadata->overridableConstants[identifier] = constant;
if (!c.is_initialized) { if (!c.is_initialized) {
auto [_, inserted] = auto [_, inserted] = metadata->uninitializedOverridableConstants.emplace(
metadata->uninitializedOverridableConstants.emplace(
std::move(identifier)); std::move(identifier));
// The insertion should have taken place // The insertion should have taken place
ASSERT(inserted); ASSERT(inserted);
@ -685,15 +670,14 @@ namespace dawn::native {
// Dimensions have already been validated against their individual limits above. // Dimensions have already been validated against their individual limits above.
// Cast to uint64_t to avoid overflow in this multiplication. // Cast to uint64_t to avoid overflow in this multiplication.
uint64_t numInvocations = static_cast<uint64_t>(entryPoint.workgroup_size_x) * uint64_t numInvocations = static_cast<uint64_t>(entryPoint.workgroup_size_x) *
entryPoint.workgroup_size_y * entryPoint.workgroup_size_y * entryPoint.workgroup_size_z;
entryPoint.workgroup_size_z;
DAWN_INVALID_IF(numInvocations > limits.v1.maxComputeInvocationsPerWorkgroup, DAWN_INVALID_IF(numInvocations > limits.v1.maxComputeInvocationsPerWorkgroup,
"The total number of workgroup invocations (%u) exceeds the " "The total number of workgroup invocations (%u) exceeds the "
"maximum allowed (%u).", "maximum allowed (%u).",
numInvocations, limits.v1.maxComputeInvocationsPerWorkgroup); numInvocations, limits.v1.maxComputeInvocationsPerWorkgroup);
const size_t workgroupStorageSize = const size_t workgroupStorageSize =
inspector.GetWorkgroupStorageSize(entryPoint.name); inspector->GetWorkgroupStorageSize(entryPoint.name);
DAWN_INVALID_IF(workgroupStorageSize > limits.v1.maxComputeWorkgroupStorageSize, DAWN_INVALID_IF(workgroupStorageSize > limits.v1.maxComputeWorkgroupStorageSize,
"The total use of workgroup storage (%u bytes) is larger than " "The total use of workgroup storage (%u bytes) is larger than "
"the maximum allowed (%u bytes).", "the maximum allowed (%u bytes).",
@ -745,14 +729,13 @@ namespace dawn::native {
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(
metadata->interStageVariables[location].baseType, metadata->interStageVariables[location].baseType,
TintComponentTypeToInterStageComponentType(outputVar.component_type)); TintComponentTypeToInterStageComponentType(outputVar.component_type));
DAWN_TRY_ASSIGN(metadata->interStageVariables[location].componentCount, DAWN_TRY_ASSIGN(
TintCompositionTypeToInterStageComponentCount( metadata->interStageVariables[location].componentCount,
outputVar.composition_type)); TintCompositionTypeToInterStageComponentCount(outputVar.composition_type));
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(
metadata->interStageVariables[location].interpolationType, metadata->interStageVariables[location].interpolationType,
TintInterpolationTypeToInterpolationType(outputVar.interpolation_type)); TintInterpolationTypeToInterpolationType(outputVar.interpolation_type));
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(metadata->interStageVariables[location].interpolationSampling,
metadata->interStageVariables[location].interpolationSampling,
TintInterpolationSamplingToInterpolationSamplingType( TintInterpolationSamplingToInterpolationSamplingType(
outputVar.interpolation_sampling)); outputVar.interpolation_sampling));
@ -784,14 +767,13 @@ namespace dawn::native {
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(
metadata->interStageVariables[location].baseType, metadata->interStageVariables[location].baseType,
TintComponentTypeToInterStageComponentType(inputVar.component_type)); TintComponentTypeToInterStageComponentType(inputVar.component_type));
DAWN_TRY_ASSIGN(metadata->interStageVariables[location].componentCount, DAWN_TRY_ASSIGN(
TintCompositionTypeToInterStageComponentCount( metadata->interStageVariables[location].componentCount,
inputVar.composition_type)); TintCompositionTypeToInterStageComponentCount(inputVar.composition_type));
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(
metadata->interStageVariables[location].interpolationType, metadata->interStageVariables[location].interpolationType,
TintInterpolationTypeToInterpolationType(inputVar.interpolation_type)); TintInterpolationTypeToInterpolationType(inputVar.interpolation_type));
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(metadata->interStageVariables[location].interpolationSampling,
metadata->interStageVariables[location].interpolationSampling,
TintInterpolationSamplingToInterpolationSamplingType( TintInterpolationSamplingToInterpolationSamplingType(
inputVar.interpolation_sampling)); inputVar.interpolation_sampling));
@ -827,28 +809,24 @@ namespace dawn::native {
DAWN_INVALID_IF(unsanitizedAttachment >= kMaxColorAttachments, DAWN_INVALID_IF(unsanitizedAttachment >= kMaxColorAttachments,
"Fragment output variable \"%s\" has a location (%u) that " "Fragment output variable \"%s\" has a location (%u) that "
"exceeds the maximum (%u).", "exceeds the maximum (%u).",
outputVar.name, unsanitizedAttachment, outputVar.name, unsanitizedAttachment, kMaxColorAttachments);
kMaxColorAttachments); ColorAttachmentIndex attachment(static_cast<uint8_t>(unsanitizedAttachment));
ColorAttachmentIndex attachment(
static_cast<uint8_t>(unsanitizedAttachment));
DAWN_TRY_ASSIGN( DAWN_TRY_ASSIGN(
metadata->fragmentOutputVariables[attachment].baseType, metadata->fragmentOutputVariables[attachment].baseType,
TintComponentTypeToTextureComponentType(outputVar.component_type)); TintComponentTypeToTextureComponentType(outputVar.component_type));
uint32_t componentCount; uint32_t componentCount;
DAWN_TRY_ASSIGN(componentCount, DAWN_TRY_ASSIGN(componentCount, TintCompositionTypeToInterStageComponentCount(
TintCompositionTypeToInterStageComponentCount(
outputVar.composition_type)); outputVar.composition_type));
// componentCount should be no larger than 4u // componentCount should be no larger than 4u
ASSERT(componentCount <= 4u); ASSERT(componentCount <= 4u);
metadata->fragmentOutputVariables[attachment].componentCount = metadata->fragmentOutputVariables[attachment].componentCount = componentCount;
componentCount;
metadata->fragmentOutputsWritten.set(attachment); metadata->fragmentOutputsWritten.set(attachment);
} }
} }
for (const tint::inspector::ResourceBinding& resource : for (const tint::inspector::ResourceBinding& resource :
inspector.GetResourceBindings(entryPoint.name)) { inspector->GetResourceBindings(entryPoint.name)) {
DAWN_INVALID_IF(resource.bind_group >= kMaxBindGroups, DAWN_INVALID_IF(resource.bind_group >= kMaxBindGroups,
"The entry-point uses a binding with a group decoration (%u) " "The entry-point uses a binding with a group decoration (%u) "
"that exceeds the maximum (%u).", "that exceeds the maximum (%u).",
@ -861,10 +839,9 @@ namespace dawn::native {
"Binding number (%u) exceeds the maximum binding number (%u).", "Binding number (%u) exceeds the maximum binding number (%u).",
uint32_t(bindingNumber), uint32_t(kMaxBindingNumberTyped)); uint32_t(bindingNumber), uint32_t(kMaxBindingNumberTyped));
const auto& [binding, inserted] = metadata->bindings[bindGroupIndex].emplace( const auto& [binding, inserted] =
bindingNumber, ShaderBindingInfo{}); metadata->bindings[bindGroupIndex].emplace(bindingNumber, ShaderBindingInfo{});
DAWN_INVALID_IF( DAWN_INVALID_IF(!inserted,
!inserted,
"Entry-point has a duplicate binding for (group:%u, binding:%u).", "Entry-point has a duplicate binding for (group:%u, binding:%u).",
resource.binding, resource.bind_group); resource.binding, resource.bind_group);
@ -882,8 +859,7 @@ namespace dawn::native {
case tint::inspector::ResourceBinding::ResourceType::kSampler: case tint::inspector::ResourceBinding::ResourceType::kSampler:
info->sampler.isComparison = false; info->sampler.isComparison = false;
break; break;
case tint::inspector::ResourceBinding::ResourceType:: case tint::inspector::ResourceBinding::ResourceType::kComparisonSampler:
kComparisonSampler:
info->sampler.isComparison = true; info->sampler.isComparison = true;
break; break;
default: default:
@ -895,9 +871,8 @@ namespace dawn::native {
TintTextureDimensionToTextureViewDimension(resource.dim); TintTextureDimensionToTextureViewDimension(resource.dim);
if (resource.resource_type == if (resource.resource_type ==
tint::inspector::ResourceBinding::ResourceType::kDepthTexture || tint::inspector::ResourceBinding::ResourceType::kDepthTexture ||
resource.resource_type == resource.resource_type == tint::inspector::ResourceBinding::
tint::inspector::ResourceBinding::ResourceType:: ResourceType::kDepthMultisampledTexture) {
kDepthMultisampledTexture) {
info->texture.compatibleSampleTypes = SampleTypeBit::Depth; info->texture.compatibleSampleTypes = SampleTypeBit::Depth;
} else { } else {
info->texture.compatibleSampleTypes = info->texture.compatibleSampleTypes =
@ -906,9 +881,8 @@ namespace dawn::native {
info->texture.multisampled = info->texture.multisampled =
resource.resource_type == tint::inspector::ResourceBinding:: resource.resource_type == tint::inspector::ResourceBinding::
ResourceType::kMultisampledTexture || ResourceType::kMultisampledTexture ||
resource.resource_type == resource.resource_type == tint::inspector::ResourceBinding::
tint::inspector::ResourceBinding::ResourceType:: ResourceType::kDepthMultisampledTexture;
kDepthMultisampledTexture;
break; break;
case BindingInfoType::StorageTexture: case BindingInfoType::StorageTexture:
@ -929,10 +903,9 @@ namespace dawn::native {
} }
std::vector<tint::inspector::SamplerTexturePair> samplerTextureUses = std::vector<tint::inspector::SamplerTexturePair> samplerTextureUses =
inspector.GetSamplerTextureUses(entryPoint.name); inspector->GetSamplerTextureUses(entryPoint.name);
metadata->samplerTexturePairs.reserve(samplerTextureUses.size()); metadata->samplerTexturePairs.reserve(samplerTextureUses.size());
std::transform( std::transform(samplerTextureUses.begin(), samplerTextureUses.end(),
samplerTextureUses.begin(), samplerTextureUses.end(),
std::back_inserter(metadata->samplerTexturePairs), std::back_inserter(metadata->samplerTexturePairs),
[](const tint::inspector::SamplerTexturePair& pair) { [](const tint::inspector::SamplerTexturePair& pair) {
EntryPointMetadata::SamplerTexturePair result; EntryPointMetadata::SamplerTexturePair result;
@ -943,6 +916,28 @@ namespace dawn::native {
return result; return result;
}); });
return std::move(metadata);
}
ResultOrError<EntryPointMetadataTable> ReflectShaderUsingTint(
const DeviceBase* device,
const tint::Program* program) {
ASSERT(program->IsValid());
tint::inspector::Inspector inspector(program);
std::vector<tint::inspector::EntryPoint> entryPoints = inspector.GetEntryPoints();
DAWN_INVALID_IF(inspector.has_error(), "Tint Reflection failure: Inspector: %s\n",
inspector.error());
EntryPointMetadataTable result;
for (const tint::inspector::EntryPoint& entryPoint : entryPoints) {
std::unique_ptr<EntryPointMetadata> metadata;
DAWN_TRY_ASSIGN_CONTEXT(metadata,
ReflectEntryPointUsingTint(device, &inspector, entryPoint),
"processing entry point \"%s\".", entryPoint.name);
ASSERT(result.count(entryPoint.name) == 0);
result[entryPoint.name] = std::move(metadata); result[entryPoint.name] = std::move(metadata);
} }
return std::move(result); return std::move(result);