tint/sem: Make BindingPoint optional
Reduces hops from sem -> ast, just to know whether the variable has a binding point. Change-Id: I5620198e6f08b73d5a0171d95874f1a2dae5d93e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/127060 Reviewed-by: James Price <jrprice@google.com> Auto-Submit: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: James Price <jrprice@google.com>
This commit is contained in:
parent
d1aa1cb29a
commit
5f4847c23e
|
@ -36,12 +36,13 @@ writer::ExternalTextureOptions::BindingsMap GenerateExternalTextureBindings(
|
||||||
std::vector<sem::BindingPoint> ext_tex_bps;
|
std::vector<sem::BindingPoint> ext_tex_bps;
|
||||||
for (auto* var : program->AST().GlobalVariables()) {
|
for (auto* var : program->AST().GlobalVariables()) {
|
||||||
if (auto* sem_var = program->Sem().Get(var)->As<sem::GlobalVariable>()) {
|
if (auto* sem_var = program->Sem().Get(var)->As<sem::GlobalVariable>()) {
|
||||||
auto bp = sem_var->BindingPoint();
|
if (auto bp = sem_var->BindingPoint()) {
|
||||||
auto& n = group_to_next_binding_number[bp.group];
|
auto& n = group_to_next_binding_number[bp->group];
|
||||||
n = std::max(n, bp.binding + 1);
|
n = std::max(n, bp->binding + 1);
|
||||||
|
|
||||||
if (sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) {
|
if (sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) {
|
||||||
ext_tex_bps.emplace_back(bp);
|
ext_tex_bps.emplace_back(*bp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,12 +271,13 @@ int CommonFuzzer::Run(const uint8_t* data, size_t size) {
|
||||||
std::vector<sem::BindingPoint> ext_tex_bps;
|
std::vector<sem::BindingPoint> ext_tex_bps;
|
||||||
for (auto* var : program.AST().GlobalVariables()) {
|
for (auto* var : program.AST().GlobalVariables()) {
|
||||||
if (auto* sem_var = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
|
if (auto* sem_var = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
|
||||||
auto bp = sem_var->BindingPoint();
|
if (auto bp = sem_var->BindingPoint()) {
|
||||||
auto& n = group_to_next_binding_number[bp.group];
|
auto& n = group_to_next_binding_number[bp->group];
|
||||||
n = std::max(n, bp.binding + 1);
|
n = std::max(n, bp->binding + 1);
|
||||||
|
|
||||||
if (sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) {
|
if (sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) {
|
||||||
ext_tex_bps.emplace_back(bp);
|
ext_tex_bps.emplace_back(*bp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -531,8 +531,8 @@ std::vector<SamplerTexturePair> Inspector::GetSamplerTextureUses(
|
||||||
auto* texture = pair.first->As<sem::GlobalVariable>();
|
auto* texture = pair.first->As<sem::GlobalVariable>();
|
||||||
auto* sampler = pair.second ? pair.second->As<sem::GlobalVariable>() : nullptr;
|
auto* sampler = pair.second ? pair.second->As<sem::GlobalVariable>() : nullptr;
|
||||||
SamplerTexturePair new_pair;
|
SamplerTexturePair new_pair;
|
||||||
new_pair.sampler_binding_point = sampler ? sampler->BindingPoint() : placeholder;
|
new_pair.sampler_binding_point = sampler ? *sampler->BindingPoint() : placeholder;
|
||||||
new_pair.texture_binding_point = texture->BindingPoint();
|
new_pair.texture_binding_point = *texture->BindingPoint();
|
||||||
new_pairs.push_back(new_pair);
|
new_pairs.push_back(new_pair);
|
||||||
}
|
}
|
||||||
return new_pairs;
|
return new_pairs;
|
||||||
|
@ -834,8 +834,8 @@ void Inspector::GenerateSamplerTargets() {
|
||||||
|
|
||||||
GetOriginatingResources(std::array<const ast::Expression*, 2>{t, s},
|
GetOriginatingResources(std::array<const ast::Expression*, 2>{t, s},
|
||||||
[&](std::array<const sem::GlobalVariable*, 2> globals) {
|
[&](std::array<const sem::GlobalVariable*, 2> globals) {
|
||||||
auto texture_binding_point = globals[0]->BindingPoint();
|
auto texture_binding_point = *globals[0]->BindingPoint();
|
||||||
auto sampler_binding_point = globals[1]->BindingPoint();
|
auto sampler_binding_point = *globals[1]->BindingPoint();
|
||||||
|
|
||||||
for (auto* entry_point : entry_points) {
|
for (auto* entry_point : entry_points) {
|
||||||
const auto& ep_name =
|
const auto& ep_name =
|
||||||
|
|
|
@ -276,7 +276,7 @@ sem::Variable* Resolver::Let(const ast::Let* v, bool is_global) {
|
||||||
sem = builder_->create<sem::GlobalVariable>(
|
sem = builder_->create<sem::GlobalVariable>(
|
||||||
v, ty, sem::EvaluationStage::kRuntime, builtin::AddressSpace::kUndefined,
|
v, ty, sem::EvaluationStage::kRuntime, builtin::AddressSpace::kUndefined,
|
||||||
builtin::Access::kUndefined,
|
builtin::Access::kUndefined,
|
||||||
/* constant_value */ nullptr, sem::BindingPoint{}, std::nullopt);
|
/* constant_value */ nullptr, std::nullopt, std::nullopt);
|
||||||
} else {
|
} else {
|
||||||
sem = builder_->create<sem::LocalVariable>(v, ty, sem::EvaluationStage::kRuntime,
|
sem = builder_->create<sem::LocalVariable>(v, ty, sem::EvaluationStage::kRuntime,
|
||||||
builtin::AddressSpace::kUndefined,
|
builtin::AddressSpace::kUndefined,
|
||||||
|
@ -336,7 +336,7 @@ sem::Variable* Resolver::Override(const ast::Override* v) {
|
||||||
auto* sem = builder_->create<sem::GlobalVariable>(
|
auto* sem = builder_->create<sem::GlobalVariable>(
|
||||||
v, ty, sem::EvaluationStage::kOverride, builtin::AddressSpace::kUndefined,
|
v, ty, sem::EvaluationStage::kOverride, builtin::AddressSpace::kUndefined,
|
||||||
builtin::Access::kUndefined,
|
builtin::Access::kUndefined,
|
||||||
/* constant_value */ nullptr, sem::BindingPoint{}, std::nullopt);
|
/* constant_value */ nullptr, std::nullopt, std::nullopt);
|
||||||
sem->SetInitializer(rhs);
|
sem->SetInitializer(rhs);
|
||||||
|
|
||||||
if (auto* id_attr = ast::GetAttribute<ast::IdAttribute>(v->attributes)) {
|
if (auto* id_attr = ast::GetAttribute<ast::IdAttribute>(v->attributes)) {
|
||||||
|
@ -430,7 +430,7 @@ sem::Variable* Resolver::Const(const ast::Const* c, bool is_global) {
|
||||||
auto* sem = is_global
|
auto* sem = is_global
|
||||||
? static_cast<sem::Variable*>(builder_->create<sem::GlobalVariable>(
|
? static_cast<sem::Variable*>(builder_->create<sem::GlobalVariable>(
|
||||||
c, ty, sem::EvaluationStage::kConstant, builtin::AddressSpace::kUndefined,
|
c, ty, sem::EvaluationStage::kConstant, builtin::AddressSpace::kUndefined,
|
||||||
builtin::Access::kUndefined, value, sem::BindingPoint{}, std::nullopt))
|
builtin::Access::kUndefined, value, std::nullopt, std::nullopt))
|
||||||
: static_cast<sem::Variable*>(builder_->create<sem::LocalVariable>(
|
: static_cast<sem::Variable*>(builder_->create<sem::LocalVariable>(
|
||||||
c, ty, sem::EvaluationStage::kConstant, builtin::AddressSpace::kUndefined,
|
c, ty, sem::EvaluationStage::kConstant, builtin::AddressSpace::kUndefined,
|
||||||
builtin::Access::kUndefined, current_statement_, value));
|
builtin::Access::kUndefined, current_statement_, value));
|
||||||
|
@ -528,7 +528,7 @@ sem::Variable* Resolver::Var(const ast::Var* var, bool is_global) {
|
||||||
|
|
||||||
sem::Variable* sem = nullptr;
|
sem::Variable* sem = nullptr;
|
||||||
if (is_global) {
|
if (is_global) {
|
||||||
sem::BindingPoint binding_point;
|
std::optional<sem::BindingPoint> binding_point;
|
||||||
if (var->HasBindingPoint()) {
|
if (var->HasBindingPoint()) {
|
||||||
uint32_t binding = 0;
|
uint32_t binding = 0;
|
||||||
{
|
{
|
||||||
|
@ -640,8 +640,9 @@ sem::Parameter* Resolver::Parameter(const ast::Parameter* param, uint32_t index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::BindingPoint binding_point;
|
std::optional<sem::BindingPoint> binding_point;
|
||||||
if (param->HasBindingPoint()) {
|
if (param->HasBindingPoint()) {
|
||||||
|
binding_point = sem::BindingPoint{};
|
||||||
{
|
{
|
||||||
ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "@binding value"};
|
ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "@binding value"};
|
||||||
TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
|
TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
|
||||||
|
@ -651,7 +652,7 @@ sem::Parameter* Resolver::Parameter(const ast::Parameter* param, uint32_t index)
|
||||||
if (!materialized) {
|
if (!materialized) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
binding_point.binding = materialized->ConstantValue()->ValueAs<u32>();
|
binding_point->binding = materialized->ConstantValue()->ValueAs<u32>();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "@group value"};
|
ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "@group value"};
|
||||||
|
@ -662,7 +663,7 @@ sem::Parameter* Resolver::Parameter(const ast::Parameter* param, uint32_t index)
|
||||||
if (!materialized) {
|
if (!materialized) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
binding_point.group = materialized->ConstantValue()->ValueAs<u32>();
|
binding_point->group = materialized->ConstantValue()->ValueAs<u32>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1346,11 +1346,14 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage)
|
||||||
utils::Hashmap<sem::BindingPoint, const ast::Variable*, 8> binding_points;
|
utils::Hashmap<sem::BindingPoint, const ast::Variable*, 8> binding_points;
|
||||||
for (auto* global : func->TransitivelyReferencedGlobals()) {
|
for (auto* global : func->TransitivelyReferencedGlobals()) {
|
||||||
auto* var_decl = global->Declaration()->As<ast::Var>();
|
auto* var_decl = global->Declaration()->As<ast::Var>();
|
||||||
if (!var_decl || !var_decl->HasBindingPoint()) {
|
if (!var_decl) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto bp = global->BindingPoint();
|
auto bp = global->BindingPoint();
|
||||||
if (auto added = binding_points.Add(bp, var_decl);
|
if (!bp) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (auto added = binding_points.Add(*bp, var_decl);
|
||||||
!added &&
|
!added &&
|
||||||
IsValidationEnabled(decl->attributes,
|
IsValidationEnabled(decl->attributes,
|
||||||
ast::DisabledValidation::kBindingPointCollision) &&
|
ast::DisabledValidation::kBindingPointCollision) &&
|
||||||
|
@ -1364,7 +1367,7 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage)
|
||||||
AddError(
|
AddError(
|
||||||
"entry point '" + func_name +
|
"entry point '" + func_name +
|
||||||
"' references multiple variables that use the same resource binding @group(" +
|
"' references multiple variables that use the same resource binding @group(" +
|
||||||
std::to_string(bp.group) + "), @binding(" + std::to_string(bp.binding) + ")",
|
std::to_string(bp->group) + "), @binding(" + std::to_string(bp->binding) + ")",
|
||||||
var_decl->source);
|
var_decl->source);
|
||||||
AddNote("first resource binding usage declared here", (*added.value)->source);
|
AddNote("first resource binding usage declared here", (*added.value)->source);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -60,8 +60,8 @@ Function::VariableBindings Function::TransitivelyReferencedUniformVariables() co
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global->Declaration()->HasBindingPoint()) {
|
if (auto bp = global->BindingPoint()) {
|
||||||
ret.push_back({global, global->BindingPoint()});
|
ret.push_back({global, *bp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -75,8 +75,8 @@ Function::VariableBindings Function::TransitivelyReferencedStorageBufferVariable
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global->Declaration()->HasBindingPoint()) {
|
if (auto bp = global->BindingPoint()) {
|
||||||
ret.push_back({global, global->BindingPoint()});
|
ret.push_back({global, *bp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -119,8 +119,8 @@ Function::VariableBindings Function::TransitivelyReferencedVariablesOfType(
|
||||||
for (auto* global : TransitivelyReferencedGlobals()) {
|
for (auto* global : TransitivelyReferencedGlobals()) {
|
||||||
auto* unwrapped_type = global->Type()->UnwrapRef();
|
auto* unwrapped_type = global->Type()->UnwrapRef();
|
||||||
if (unwrapped_type->TypeInfo().Is(type)) {
|
if (unwrapped_type->TypeInfo().Is(type)) {
|
||||||
if (global->Declaration()->HasBindingPoint()) {
|
if (auto bp = global->BindingPoint()) {
|
||||||
ret.push_back({global, global->BindingPoint()});
|
ret.push_back({global, *bp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,8 +147,8 @@ Function::VariableBindings Function::TransitivelyReferencedSamplerVariablesImpl(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global->Declaration()->HasBindingPoint()) {
|
if (auto bp = global->BindingPoint()) {
|
||||||
ret.push_back({global, global->BindingPoint()});
|
ret.push_back({global, *bp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -172,8 +172,8 @@ Function::VariableBindings Function::TransitivelyReferencedSampledTextureVariabl
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global->Declaration()->HasBindingPoint()) {
|
if (auto bp = global->BindingPoint()) {
|
||||||
ret.push_back({global, global->BindingPoint()});
|
ret.push_back({global, *bp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ GlobalVariable::GlobalVariable(const ast::Variable* declaration,
|
||||||
builtin::AddressSpace address_space,
|
builtin::AddressSpace address_space,
|
||||||
builtin::Access access,
|
builtin::Access access,
|
||||||
const constant::Value* constant_value,
|
const constant::Value* constant_value,
|
||||||
sem::BindingPoint binding_point,
|
std::optional<sem::BindingPoint> binding_point,
|
||||||
std::optional<uint32_t> location)
|
std::optional<uint32_t> location)
|
||||||
: Base(declaration, type, stage, address_space, access, constant_value),
|
: Base(declaration, type, stage, address_space, access, constant_value),
|
||||||
binding_point_(binding_point),
|
binding_point_(binding_point),
|
||||||
|
@ -75,7 +75,7 @@ Parameter::Parameter(const ast::Parameter* declaration,
|
||||||
builtin::AddressSpace address_space,
|
builtin::AddressSpace address_space,
|
||||||
builtin::Access access,
|
builtin::Access access,
|
||||||
const ParameterUsage usage /* = ParameterUsage::kNone */,
|
const ParameterUsage usage /* = ParameterUsage::kNone */,
|
||||||
sem::BindingPoint binding_point /* = {} */,
|
std::optional<sem::BindingPoint> binding_point /* = {} */,
|
||||||
std::optional<uint32_t> location /* = std::nullopt */)
|
std::optional<uint32_t> location /* = std::nullopt */)
|
||||||
: Base(declaration, type, EvaluationStage::kRuntime, address_space, access, nullptr),
|
: Base(declaration, type, EvaluationStage::kRuntime, address_space, access, nullptr),
|
||||||
index_(index),
|
index_(index),
|
||||||
|
|
|
@ -165,14 +165,14 @@ class GlobalVariable final : public Castable<GlobalVariable, Variable> {
|
||||||
builtin::AddressSpace address_space,
|
builtin::AddressSpace address_space,
|
||||||
builtin::Access access,
|
builtin::Access access,
|
||||||
const constant::Value* constant_value,
|
const constant::Value* constant_value,
|
||||||
sem::BindingPoint binding_point = {},
|
std::optional<sem::BindingPoint> binding_point = std::nullopt,
|
||||||
std::optional<uint32_t> location = std::nullopt);
|
std::optional<uint32_t> location = std::nullopt);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~GlobalVariable() override;
|
~GlobalVariable() override;
|
||||||
|
|
||||||
/// @returns the resource binding point for the variable
|
/// @returns the resource binding point for the variable
|
||||||
sem::BindingPoint BindingPoint() const { return binding_point_; }
|
std::optional<sem::BindingPoint> BindingPoint() const { return binding_point_; }
|
||||||
|
|
||||||
/// @param id the constant identifier to assign to this variable
|
/// @param id the constant identifier to assign to this variable
|
||||||
void SetOverrideId(OverrideId id) { override_id_ = id; }
|
void SetOverrideId(OverrideId id) { override_id_ = id; }
|
||||||
|
@ -184,7 +184,7 @@ class GlobalVariable final : public Castable<GlobalVariable, Variable> {
|
||||||
std::optional<uint32_t> Location() const { return location_; }
|
std::optional<uint32_t> Location() const { return location_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const sem::BindingPoint binding_point_;
|
const std::optional<sem::BindingPoint> binding_point_;
|
||||||
|
|
||||||
tint::OverrideId override_id_;
|
tint::OverrideId override_id_;
|
||||||
std::optional<uint32_t> location_;
|
std::optional<uint32_t> location_;
|
||||||
|
@ -208,7 +208,7 @@ class Parameter final : public Castable<Parameter, Variable> {
|
||||||
builtin::AddressSpace address_space,
|
builtin::AddressSpace address_space,
|
||||||
builtin::Access access,
|
builtin::Access access,
|
||||||
const ParameterUsage usage = ParameterUsage::kNone,
|
const ParameterUsage usage = ParameterUsage::kNone,
|
||||||
sem::BindingPoint binding_point = {},
|
std::optional<sem::BindingPoint> binding_point = {},
|
||||||
std::optional<uint32_t> location = std::nullopt);
|
std::optional<uint32_t> location = std::nullopt);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
|
@ -239,7 +239,7 @@ class Parameter final : public Castable<Parameter, Variable> {
|
||||||
void SetShadows(const CastableBase* shadows) { shadows_ = shadows; }
|
void SetShadows(const CastableBase* shadows) { shadows_ = shadows; }
|
||||||
|
|
||||||
/// @returns the resource binding point for the parameter
|
/// @returns the resource binding point for the parameter
|
||||||
sem::BindingPoint BindingPoint() const { return binding_point_; }
|
std::optional<sem::BindingPoint> BindingPoint() const { return binding_point_; }
|
||||||
|
|
||||||
/// @returns the location value for the parameter, if set
|
/// @returns the location value for the parameter, if set
|
||||||
std::optional<uint32_t> Location() const { return location_; }
|
std::optional<uint32_t> Location() const { return location_; }
|
||||||
|
@ -249,7 +249,7 @@ class Parameter final : public Castable<Parameter, Variable> {
|
||||||
const ParameterUsage usage_;
|
const ParameterUsage usage_;
|
||||||
CallTarget const* owner_ = nullptr;
|
CallTarget const* owner_ = nullptr;
|
||||||
const CastableBase* shadows_ = nullptr;
|
const CastableBase* shadows_ = nullptr;
|
||||||
const sem::BindingPoint binding_point_;
|
const std::optional<sem::BindingPoint> binding_point_;
|
||||||
const std::optional<uint32_t> location_;
|
const std::optional<uint32_t> location_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -82,13 +82,14 @@ struct ArrayLengthFromUniform::State {
|
||||||
|
|
||||||
IterateArrayLengthOnStorageVar([&](const ast::CallExpression*, const sem::VariableUser*,
|
IterateArrayLengthOnStorageVar([&](const ast::CallExpression*, const sem::VariableUser*,
|
||||||
const sem::GlobalVariable* var) {
|
const sem::GlobalVariable* var) {
|
||||||
auto binding = var->BindingPoint();
|
if (auto binding = var->BindingPoint()) {
|
||||||
auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
|
auto idx_itr = cfg->bindpoint_to_size_index.find(*binding);
|
||||||
if (idx_itr == cfg->bindpoint_to_size_index.end()) {
|
if (idx_itr == cfg->bindpoint_to_size_index.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (idx_itr->second > max_buffer_size_index) {
|
if (idx_itr->second > max_buffer_size_index) {
|
||||||
max_buffer_size_index = idx_itr->second;
|
max_buffer_size_index = idx_itr->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -120,7 +121,10 @@ struct ArrayLengthFromUniform::State {
|
||||||
const sem::VariableUser* storage_buffer_sem,
|
const sem::VariableUser* storage_buffer_sem,
|
||||||
const sem::GlobalVariable* var) {
|
const sem::GlobalVariable* var) {
|
||||||
auto binding = var->BindingPoint();
|
auto binding = var->BindingPoint();
|
||||||
auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
|
if (!binding) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto idx_itr = cfg->bindpoint_to_size_index.find(*binding);
|
||||||
if (idx_itr == cfg->bindpoint_to_size_index.end()) {
|
if (idx_itr == cfg->bindpoint_to_size_index.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,8 @@ Transform::ApplyResult BindingRemapper::Apply(const Program* src,
|
||||||
auto* func = src->Sem().Get(func_ast);
|
auto* func = src->Sem().Get(func_ast);
|
||||||
std::unordered_map<sem::BindingPoint, int> binding_point_counts;
|
std::unordered_map<sem::BindingPoint, int> binding_point_counts;
|
||||||
for (auto* global : func->TransitivelyReferencedGlobals()) {
|
for (auto* global : func->TransitivelyReferencedGlobals()) {
|
||||||
if (global->Declaration()->HasBindingPoint()) {
|
if (auto from = global->BindingPoint()) {
|
||||||
BindingPoint from = global->BindingPoint();
|
auto bp_it = remappings->binding_points.find(*from);
|
||||||
|
|
||||||
auto bp_it = remappings->binding_points.find(from);
|
|
||||||
if (bp_it != remappings->binding_points.end()) {
|
if (bp_it != remappings->binding_points.end()) {
|
||||||
// Remapped
|
// Remapped
|
||||||
BindingPoint to = bp_it->second;
|
BindingPoint to = bp_it->second;
|
||||||
|
@ -83,8 +81,8 @@ Transform::ApplyResult BindingRemapper::Apply(const Program* src,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No remapping
|
// No remapping
|
||||||
if (binding_point_counts[from]++) {
|
if (binding_point_counts[*from]++) {
|
||||||
add_collision_attr.emplace(from);
|
add_collision_attr.emplace(*from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +95,7 @@ Transform::ApplyResult BindingRemapper::Apply(const Program* src,
|
||||||
auto* global_sem = src->Sem().Get<sem::GlobalVariable>(var);
|
auto* global_sem = src->Sem().Get<sem::GlobalVariable>(var);
|
||||||
|
|
||||||
// The original binding point
|
// The original binding point
|
||||||
BindingPoint from = global_sem->BindingPoint();
|
BindingPoint from = *global_sem->BindingPoint();
|
||||||
|
|
||||||
// The binding point after remapping
|
// The binding point after remapping
|
||||||
BindingPoint bp = from;
|
BindingPoint bp = from;
|
||||||
|
|
|
@ -107,10 +107,10 @@ struct CombineSamplers::State {
|
||||||
const sem::Variable* sampler_var,
|
const sem::Variable* sampler_var,
|
||||||
std::string name) {
|
std::string name) {
|
||||||
SamplerTexturePair bp_pair;
|
SamplerTexturePair bp_pair;
|
||||||
bp_pair.texture_binding_point = texture_var->As<sem::GlobalVariable>()->BindingPoint();
|
bp_pair.texture_binding_point = *texture_var->As<sem::GlobalVariable>()->BindingPoint();
|
||||||
bp_pair.sampler_binding_point = sampler_var
|
bp_pair.sampler_binding_point =
|
||||||
? sampler_var->As<sem::GlobalVariable>()->BindingPoint()
|
sampler_var ? *sampler_var->As<sem::GlobalVariable>()->BindingPoint()
|
||||||
: binding_info->placeholder_binding_point;
|
: binding_info->placeholder_binding_point;
|
||||||
auto it = binding_info->binding_map.find(bp_pair);
|
auto it = binding_info->binding_map.find(bp_pair);
|
||||||
if (it != binding_info->binding_map.end()) {
|
if (it != binding_info->binding_map.end()) {
|
||||||
name = it->second;
|
name = it->second;
|
||||||
|
@ -161,9 +161,8 @@ struct CombineSamplers::State {
|
||||||
if (tint::IsAnyOf<type::Texture, type::Sampler>(type) &&
|
if (tint::IsAnyOf<type::Texture, type::Sampler>(type) &&
|
||||||
!type->Is<type::StorageTexture>()) {
|
!type->Is<type::StorageTexture>()) {
|
||||||
ctx.Remove(ctx.src->AST().GlobalDeclarations(), global);
|
ctx.Remove(ctx.src->AST().GlobalDeclarations(), global);
|
||||||
} else if (global->HasBindingPoint()) {
|
} else if (auto binding_point = global_sem->BindingPoint()) {
|
||||||
auto binding_point = global_sem->BindingPoint();
|
if (binding_point->group == 0 && binding_point->binding == 0) {
|
||||||
if (binding_point.group == 0 && binding_point.binding == 0) {
|
|
||||||
auto* attribute =
|
auto* attribute =
|
||||||
ctx.dst->Disable(ast::DisabledValidation::kBindingPointCollision);
|
ctx.dst->Disable(ast::DisabledValidation::kBindingPointCollision);
|
||||||
ctx.InsertFront(global->attributes, attribute);
|
ctx.InsertFront(global->attributes, attribute);
|
||||||
|
|
|
@ -115,7 +115,7 @@ struct MultiplanarExternalTexture::State {
|
||||||
// The binding points for the newly introduced bindings must have been provided to this
|
// The binding points for the newly introduced bindings must have been provided to this
|
||||||
// transform. We fetch the new binding points by providing the original texture_external
|
// transform. We fetch the new binding points by providing the original texture_external
|
||||||
// binding points into the passed map.
|
// binding points into the passed map.
|
||||||
sem::BindingPoint bp = sem_var->BindingPoint();
|
sem::BindingPoint bp = *sem_var->BindingPoint();
|
||||||
|
|
||||||
BindingsMap::const_iterator it = new_binding_points->bindings_map.find(bp);
|
BindingsMap::const_iterator it = new_binding_points->bindings_map.find(bp);
|
||||||
if (it == new_binding_points->bindings_map.end()) {
|
if (it == new_binding_points->bindings_map.end()) {
|
||||||
|
|
|
@ -148,11 +148,10 @@ Transform::ApplyResult NumWorkgroupsFromUniform::Apply(const Program* src,
|
||||||
group = 0;
|
group = 0;
|
||||||
|
|
||||||
for (auto* global : src->AST().GlobalVariables()) {
|
for (auto* global : src->AST().GlobalVariables()) {
|
||||||
if (global->HasBindingPoint()) {
|
auto* global_sem = src->Sem().Get<sem::GlobalVariable>(global);
|
||||||
auto* global_sem = src->Sem().Get<sem::GlobalVariable>(global);
|
if (auto bp = global_sem->BindingPoint()) {
|
||||||
auto binding_point = global_sem->BindingPoint();
|
if (bp->group >= group) {
|
||||||
if (binding_point.group >= group) {
|
group = bp->group + 1;
|
||||||
group = binding_point.group + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,18 +67,18 @@ TEST_F(FlattenBindingsTest, NotFlat_SingleNamespace) {
|
||||||
|
|
||||||
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[0]);
|
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[0]);
|
||||||
ASSERT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_EQ(sem->BindingPoint().group, 0u);
|
EXPECT_EQ(sem->BindingPoint()->group, 0u);
|
||||||
EXPECT_EQ(sem->BindingPoint().binding, 0u);
|
EXPECT_EQ(sem->BindingPoint()->binding, 0u);
|
||||||
|
|
||||||
sem = flattened->Sem().Get<sem::GlobalVariable>(vars[1]);
|
sem = flattened->Sem().Get<sem::GlobalVariable>(vars[1]);
|
||||||
ASSERT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_EQ(sem->BindingPoint().group, 0u);
|
EXPECT_EQ(sem->BindingPoint()->group, 0u);
|
||||||
EXPECT_EQ(sem->BindingPoint().binding, 1u);
|
EXPECT_EQ(sem->BindingPoint()->binding, 1u);
|
||||||
|
|
||||||
sem = flattened->Sem().Get<sem::GlobalVariable>(vars[2]);
|
sem = flattened->Sem().Get<sem::GlobalVariable>(vars[2]);
|
||||||
ASSERT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_EQ(sem->BindingPoint().group, 0u);
|
EXPECT_EQ(sem->BindingPoint()->group, 0u);
|
||||||
EXPECT_EQ(sem->BindingPoint().binding, 2u);
|
EXPECT_EQ(sem->BindingPoint()->binding, 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(FlattenBindingsTest, NotFlat_MultipleNamespaces) {
|
TEST_F(FlattenBindingsTest, NotFlat_MultipleNamespaces) {
|
||||||
|
@ -131,20 +131,20 @@ TEST_F(FlattenBindingsTest, NotFlat_MultipleNamespaces) {
|
||||||
for (size_t i = 0; i < num_buffers; ++i) {
|
for (size_t i = 0; i < num_buffers; ++i) {
|
||||||
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i]);
|
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i]);
|
||||||
ASSERT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_EQ(sem->BindingPoint().group, 0u);
|
EXPECT_EQ(sem->BindingPoint()->group, 0u);
|
||||||
EXPECT_EQ(sem->BindingPoint().binding, i);
|
EXPECT_EQ(sem->BindingPoint()->binding, i);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < num_samplers; ++i) {
|
for (size_t i = 0; i < num_samplers; ++i) {
|
||||||
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i + num_buffers]);
|
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i + num_buffers]);
|
||||||
ASSERT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_EQ(sem->BindingPoint().group, 0u);
|
EXPECT_EQ(sem->BindingPoint()->group, 0u);
|
||||||
EXPECT_EQ(sem->BindingPoint().binding, i);
|
EXPECT_EQ(sem->BindingPoint()->binding, i);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < num_textures; ++i) {
|
for (size_t i = 0; i < num_textures; ++i) {
|
||||||
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i + num_buffers + num_samplers]);
|
auto* sem = flattened->Sem().Get<sem::GlobalVariable>(vars[i + num_buffers + num_samplers]);
|
||||||
ASSERT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_EQ(sem->BindingPoint().group, 0u);
|
EXPECT_EQ(sem->BindingPoint()->group, 0u);
|
||||||
EXPECT_EQ(sem->BindingPoint().binding, i);
|
EXPECT_EQ(sem->BindingPoint()->binding, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2031,7 +2031,7 @@ bool GeneratorImpl::EmitUniformVariable(const ast::Var* var, const sem::Variable
|
||||||
TINT_ICE(Writer, builder_.Diagnostics()) << "storage variable must be of struct type";
|
TINT_ICE(Writer, builder_.Diagnostics()) << "storage variable must be of struct type";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto bp = sem->As<sem::GlobalVariable>()->BindingPoint();
|
auto bp = *sem->As<sem::GlobalVariable>()->BindingPoint();
|
||||||
{
|
{
|
||||||
auto out = line();
|
auto out = line();
|
||||||
out << "layout(binding = " << bp.binding << ", std140";
|
out << "layout(binding = " << bp.binding << ", std140";
|
||||||
|
@ -2052,7 +2052,7 @@ bool GeneratorImpl::EmitStorageVariable(const ast::Var* var, const sem::Variable
|
||||||
TINT_ICE(Writer, builder_.Diagnostics()) << "storage variable must be of struct type";
|
TINT_ICE(Writer, builder_.Diagnostics()) << "storage variable must be of struct type";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto bp = sem->As<sem::GlobalVariable>()->BindingPoint();
|
auto bp = *sem->As<sem::GlobalVariable>()->BindingPoint();
|
||||||
line() << "layout(binding = " << bp.binding << ", std430) buffer "
|
line() << "layout(binding = " << bp.binding << ", std430) buffer "
|
||||||
<< UniqueIdentifier(StructName(str) + "_ssbo") << " {";
|
<< UniqueIdentifier(StructName(str) + "_ssbo") << " {";
|
||||||
EmitStructMembers(current_buffer_, str);
|
EmitStructMembers(current_buffer_, str);
|
||||||
|
|
|
@ -3066,7 +3066,7 @@ bool GeneratorImpl::EmitGlobalVariable(const ast::Variable* global) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitUniformVariable(const ast::Var* var, const sem::Variable* sem) {
|
bool GeneratorImpl::EmitUniformVariable(const ast::Var* var, const sem::Variable* sem) {
|
||||||
auto binding_point = sem->As<sem::GlobalVariable>()->BindingPoint();
|
auto binding_point = *sem->As<sem::GlobalVariable>()->BindingPoint();
|
||||||
auto* type = sem->Type()->UnwrapRef();
|
auto* type = sem->Type()->UnwrapRef();
|
||||||
auto name = var->name->symbol.Name();
|
auto name = var->name->symbol.Name();
|
||||||
line() << "cbuffer cbuffer_" << name << RegisterAndSpace('b', binding_point) << " {";
|
line() << "cbuffer cbuffer_" << name << RegisterAndSpace('b', binding_point) << " {";
|
||||||
|
@ -3095,7 +3095,7 @@ bool GeneratorImpl::EmitStorageVariable(const ast::Var* var, const sem::Variable
|
||||||
|
|
||||||
auto* global_sem = sem->As<sem::GlobalVariable>();
|
auto* global_sem = sem->As<sem::GlobalVariable>();
|
||||||
out << RegisterAndSpace(sem->Access() == builtin::Access::kRead ? 't' : 'u',
|
out << RegisterAndSpace(sem->Access() == builtin::Access::kRead ? 't' : 'u',
|
||||||
global_sem->BindingPoint())
|
*global_sem->BindingPoint())
|
||||||
<< ";";
|
<< ";";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -3124,14 +3124,14 @@ bool GeneratorImpl::EmitHandleVariable(const ast::Var* var, const sem::Variable*
|
||||||
|
|
||||||
if (register_space) {
|
if (register_space) {
|
||||||
auto bp = sem->As<sem::GlobalVariable>()->BindingPoint();
|
auto bp = sem->As<sem::GlobalVariable>()->BindingPoint();
|
||||||
out << " : register(" << register_space << bp.binding;
|
out << " : register(" << register_space << bp->binding;
|
||||||
// Omit the space if it's 0, as it's the default.
|
// Omit the space if it's 0, as it's the default.
|
||||||
// SM 5.0 doesn't support spaces, so we don't emit them if group is 0 for better
|
// SM 5.0 doesn't support spaces, so we don't emit them if group is 0 for better
|
||||||
// compatibility.
|
// compatibility.
|
||||||
if (bp.group == 0) {
|
if (bp->group == 0) {
|
||||||
out << ")";
|
out << ")";
|
||||||
} else {
|
} else {
|
||||||
out << ", space" << bp.group << ")";
|
out << ", space" << bp->group << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1996,12 +1996,12 @@ bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) {
|
||||||
}
|
}
|
||||||
auto* param_sem = program_->Sem().Get<sem::Parameter>(param);
|
auto* param_sem = program_->Sem().Get<sem::Parameter>(param);
|
||||||
auto bp = param_sem->BindingPoint();
|
auto bp = param_sem->BindingPoint();
|
||||||
if (TINT_UNLIKELY(bp.group != 0)) {
|
if (TINT_UNLIKELY(bp->group != 0)) {
|
||||||
TINT_ICE(Writer, diagnostics_) << "encountered non-zero resource group index (use "
|
TINT_ICE(Writer, diagnostics_) << "encountered non-zero resource group index (use "
|
||||||
"BindingRemapper to fix)";
|
"BindingRemapper to fix)";
|
||||||
return kInvalidBindingIndex;
|
return kInvalidBindingIndex;
|
||||||
}
|
}
|
||||||
return bp.binding;
|
return bp->binding;
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -867,14 +867,14 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* v) {
|
||||||
[&](const ast::BindingAttribute*) {
|
[&](const ast::BindingAttribute*) {
|
||||||
auto bp = sem->BindingPoint();
|
auto bp = sem->BindingPoint();
|
||||||
push_annot(spv::Op::OpDecorate, {Operand(var_id), U32Operand(SpvDecorationBinding),
|
push_annot(spv::Op::OpDecorate, {Operand(var_id), U32Operand(SpvDecorationBinding),
|
||||||
Operand(bp.binding)});
|
Operand(bp->binding)});
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const ast::GroupAttribute*) {
|
[&](const ast::GroupAttribute*) {
|
||||||
auto bp = sem->BindingPoint();
|
auto bp = sem->BindingPoint();
|
||||||
push_annot(
|
push_annot(
|
||||||
spv::Op::OpDecorate,
|
spv::Op::OpDecorate,
|
||||||
{Operand(var_id), U32Operand(SpvDecorationDescriptorSet), Operand(bp.group)});
|
{Operand(var_id), U32Operand(SpvDecorationDescriptorSet), Operand(bp->group)});
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const ast::IdAttribute*) {
|
[&](const ast::IdAttribute*) {
|
||||||
|
|
Loading…
Reference in New Issue