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
// any, to VAR.
#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
// overloading with different number of variables.

View File

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