Adds strformat code-gen for helping auto-generate readable strings for structs.
- Adds generator infra for absl::StrFormat for bind group structs and types. - Uses absl::ParsedFormat to avoid multiple parsing for format strings. Bug: dawn:549 Change-Id: Ida4ca65eb85c4474c492161c8ae34f53bd692a3c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/81944 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Loko Kung <lokokung@google.com>
This commit is contained in:
parent
39c2029063
commit
4d8352542a
|
@ -684,6 +684,15 @@ def as_wireType(metadata, typ):
|
||||||
return as_cppType(typ.name)
|
return as_cppType(typ.name)
|
||||||
|
|
||||||
|
|
||||||
|
def as_formatType(typ):
|
||||||
|
# Unsigned integral types
|
||||||
|
if typ.json_data['type'] in ['bool', 'uint32_t', 'uint64_t']:
|
||||||
|
return 'u'
|
||||||
|
|
||||||
|
# Defaults everything else to strings.
|
||||||
|
return 's'
|
||||||
|
|
||||||
|
|
||||||
def c_methods(params, typ):
|
def c_methods(params, typ):
|
||||||
return typ.methods + [
|
return typ.methods + [
|
||||||
x for x in [
|
x for x in [
|
||||||
|
@ -753,7 +762,8 @@ def make_base_render_params(metadata):
|
||||||
'as_jsEnumValue': as_jsEnumValue,
|
'as_jsEnumValue': as_jsEnumValue,
|
||||||
'convert_cType_to_cppType': convert_cType_to_cppType,
|
'convert_cType_to_cppType': convert_cType_to_cppType,
|
||||||
'as_varName': as_varName,
|
'as_varName': as_varName,
|
||||||
'decorate': decorate
|
'decorate': decorate,
|
||||||
|
'as_formatType': as_formatType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,8 @@ _FileOutput = namedtuple('FileOutput', ['name', 'content'])
|
||||||
|
|
||||||
def _do_renders(renders, template_dir):
|
def _do_renders(renders, template_dir):
|
||||||
loader = _PreprocessingLoader(template_dir)
|
loader = _PreprocessingLoader(template_dir)
|
||||||
env = jinja2.Environment(loader=loader,
|
env = jinja2.Environment(extensions=['jinja2.ext.do'],
|
||||||
|
loader=loader,
|
||||||
lstrip_blocks=True,
|
lstrip_blocks=True,
|
||||||
trim_blocks=True,
|
trim_blocks=True,
|
||||||
line_comment_prefix='//*')
|
line_comment_prefix='//*')
|
||||||
|
|
|
@ -49,6 +49,42 @@ namespace {{native_namespace}} {
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compatible with absl::StrFormat (Needs to be disjoint from having a 'label' for now.)
|
||||||
|
// Currently uses a hard-coded list to determine which structures are actually supported. If
|
||||||
|
// additional structures are added, be sure to update the header file's list as well.
|
||||||
|
//
|
||||||
|
using absl::ParsedFormat;
|
||||||
|
|
||||||
|
{% for type in by_category["structure"] %}
|
||||||
|
{% if type.name.get() in [
|
||||||
|
"buffer binding layout",
|
||||||
|
"sampler binding layout",
|
||||||
|
"texture binding layout",
|
||||||
|
"storage texture binding layout"
|
||||||
|
]
|
||||||
|
%}
|
||||||
|
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
||||||
|
AbslFormatConvert(const {{as_cppType(type.name)}}& value,
|
||||||
|
const absl::FormatConversionSpec& spec,
|
||||||
|
absl::FormatSink* s) {
|
||||||
|
{% set members = [] %}
|
||||||
|
{% set format = [] %}
|
||||||
|
{% set template = [] %}
|
||||||
|
{% for member in type.members %}
|
||||||
|
{% set memberName = member.name.camelCase() %}
|
||||||
|
{% do members.append("value." + memberName) %}
|
||||||
|
{% do format.append(memberName + ": %" + as_formatType(member)) %}
|
||||||
|
{% do template.append("'" + as_formatType(member) + "'") %}
|
||||||
|
{% endfor %}
|
||||||
|
static const auto* const fmt =
|
||||||
|
new ParsedFormat<{{template|join(",")}}>("{ {{format|join(", ")}} }");
|
||||||
|
s->Append(absl::StrFormat(*fmt, {{members|join(", ")}}));
|
||||||
|
return {true};
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
} // namespace {{native_namespace}}
|
} // namespace {{native_namespace}}
|
||||||
|
|
||||||
{% set namespace = metadata.namespace %}
|
{% set namespace = metadata.namespace %}
|
||||||
|
@ -59,22 +95,24 @@ namespace {{namespace}} {
|
||||||
//
|
//
|
||||||
|
|
||||||
{% for type in by_category["enum"] %}
|
{% for type in by_category["enum"] %}
|
||||||
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
absl::FormatConvertResult<absl::FormatConversionCharSet::kString|absl::FormatConversionCharSet::kIntegral>
|
||||||
AbslFormatConvert({{as_cppType(type.name)}} value,
|
AbslFormatConvert({{as_cppType(type.name)}} value,
|
||||||
const absl::FormatConversionSpec& spec,
|
const absl::FormatConversionSpec& spec,
|
||||||
absl::FormatSink* s) {
|
absl::FormatSink* s) {
|
||||||
|
if (spec.conversion_char() == absl::FormatConversionChar::s) {
|
||||||
s->Append("{{as_cppType(type.name)}}::");
|
s->Append("{{as_cppType(type.name)}}::");
|
||||||
switch (value) {
|
switch (value) {
|
||||||
{% for value in type.values %}
|
{% for value in type.values %}
|
||||||
case {{as_cppType(type.name)}}::{{as_cppEnum(value.name)}}:
|
case {{as_cppType(type.name)}}::{{as_cppEnum(value.name)}}:
|
||||||
s->Append("{{as_cppEnum(value.name)}}");
|
s->Append("{{as_cppEnum(value.name)}}");
|
||||||
break;
|
break;
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
default:
|
|
||||||
s->Append(absl::StrFormat("%x", static_cast<typename std::underlying_type<{{as_cppType(type.name)}}>::type>(value)));
|
|
||||||
}
|
}
|
||||||
return {true};
|
} else {
|
||||||
|
s->Append(absl::StrFormat("%u", static_cast<typename std::underlying_type<{{as_cppType(type.name)}}>::type>(value)));
|
||||||
}
|
}
|
||||||
|
return {true};
|
||||||
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -82,10 +120,11 @@ namespace {{namespace}} {
|
||||||
//
|
//
|
||||||
|
|
||||||
{% for type in by_category["bitmask"] %}
|
{% for type in by_category["bitmask"] %}
|
||||||
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
absl::FormatConvertResult<absl::FormatConversionCharSet::kString|absl::FormatConversionCharSet::kIntegral>
|
||||||
AbslFormatConvert({{as_cppType(type.name)}} value,
|
AbslFormatConvert({{as_cppType(type.name)}} value,
|
||||||
const absl::FormatConversionSpec& spec,
|
const absl::FormatConversionSpec& spec,
|
||||||
absl::FormatSink* s) {
|
absl::FormatSink* s) {
|
||||||
|
if (spec.conversion_char() == absl::FormatConversionChar::s) {
|
||||||
s->Append("{{as_cppType(type.name)}}::");
|
s->Append("{{as_cppType(type.name)}}::");
|
||||||
if (!static_cast<bool>(value)) {
|
if (!static_cast<bool>(value)) {
|
||||||
{% for value in type.values if value.value == 0 %}
|
{% for value in type.values if value.value == 0 %}
|
||||||
|
@ -124,9 +163,11 @@ namespace {{namespace}} {
|
||||||
if (moreThanOneBit) {
|
if (moreThanOneBit) {
|
||||||
s->Append(")");
|
s->Append(")");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
return {true};
|
s->Append(absl::StrFormat("%u", static_cast<typename std::underlying_type<{{as_cppType(type.name)}}>::type>(value)));
|
||||||
}
|
}
|
||||||
|
return {true};
|
||||||
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
} // namespace {{namespace}}
|
} // namespace {{namespace}}
|
||||||
|
|
|
@ -36,12 +36,33 @@ namespace {{native_namespace}} {
|
||||||
{% for member in type.members %}
|
{% for member in type.members %}
|
||||||
{% if member.name.canonical_case() == "label" %}
|
{% if member.name.canonical_case() == "label" %}
|
||||||
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
||||||
AbslFormatConvert(const {{as_cppType(type.name)}}* value,
|
AbslFormatConvert(const {{as_cppType(type.name)}}* value,
|
||||||
const absl::FormatConversionSpec& spec,
|
const absl::FormatConversionSpec& spec,
|
||||||
absl::FormatSink* s);
|
absl::FormatSink* s);
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compatible with absl::StrFormat (Needs to be disjoint from having a 'label' for now.)
|
||||||
|
// Currently uses a hard-coded list to determine which structures are actually supported. If
|
||||||
|
// additional structures are added, be sure to update the cpp file's list as well.
|
||||||
|
//
|
||||||
|
{% for type in by_category["structure"] %}
|
||||||
|
{% if type.name.get() in [
|
||||||
|
"buffer binding layout",
|
||||||
|
"sampler binding layout",
|
||||||
|
"texture binding layout",
|
||||||
|
"storage texture binding layout"
|
||||||
|
]
|
||||||
|
%}
|
||||||
|
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
||||||
|
AbslFormatConvert(const {{as_cppType(type.name)}}& value,
|
||||||
|
const absl::FormatConversionSpec& spec,
|
||||||
|
absl::FormatSink* s);
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
} // namespace {{native_namespace}}
|
} // namespace {{native_namespace}}
|
||||||
|
|
||||||
{% set namespace = metadata.namespace %}
|
{% set namespace = metadata.namespace %}
|
||||||
|
@ -52,7 +73,7 @@ namespace {{namespace}} {
|
||||||
//
|
//
|
||||||
|
|
||||||
{% for type in by_category["enum"] %}
|
{% for type in by_category["enum"] %}
|
||||||
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
absl::FormatConvertResult<absl::FormatConversionCharSet::kString|absl::FormatConversionCharSet::kIntegral>
|
||||||
AbslFormatConvert({{as_cppType(type.name)}} value,
|
AbslFormatConvert({{as_cppType(type.name)}} value,
|
||||||
const absl::FormatConversionSpec& spec,
|
const absl::FormatConversionSpec& spec,
|
||||||
absl::FormatSink* s);
|
absl::FormatSink* s);
|
||||||
|
@ -63,7 +84,7 @@ namespace {{namespace}} {
|
||||||
//
|
//
|
||||||
|
|
||||||
{% for type in by_category["bitmask"] %}
|
{% for type in by_category["bitmask"] %}
|
||||||
absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
|
absl::FormatConvertResult<absl::FormatConversionCharSet::kString|absl::FormatConversionCharSet::kIntegral>
|
||||||
AbslFormatConvert({{as_cppType(type.name)}} value,
|
AbslFormatConvert({{as_cppType(type.name)}} value,
|
||||||
const absl::FormatConversionSpec& spec,
|
const absl::FormatConversionSpec& spec,
|
||||||
absl::FormatSink* s);
|
absl::FormatSink* s);
|
||||||
|
|
|
@ -661,11 +661,13 @@ namespace dawn::native {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BindGroupLayoutBase::EntriesToString() const {
|
std::string BindGroupLayoutBase::EntriesToString() const {
|
||||||
std::string entries = " [";
|
std::string entries = "[";
|
||||||
|
std::string sep = "";
|
||||||
const BindGroupLayoutBase::BindingMap& bindingMap = GetBindingMap();
|
const BindGroupLayoutBase::BindingMap& bindingMap = GetBindingMap();
|
||||||
for (const auto [bindingNumber, bindingIndex] : bindingMap) {
|
for (const auto [bindingNumber, bindingIndex] : bindingMap) {
|
||||||
const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
|
const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
|
||||||
entries += absl::StrFormat("%s, ", bindingInfo);
|
entries += absl::StrFormat("%s%s", sep, bindingInfo);
|
||||||
|
sep = ", ";
|
||||||
}
|
}
|
||||||
entries += "]";
|
entries += "]";
|
||||||
return entries;
|
return entries;
|
||||||
|
|
|
@ -24,19 +24,19 @@ namespace dawn::native {
|
||||||
absl::FormatSink* s) {
|
absl::FormatSink* s) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case BindingInfoType::Buffer:
|
case BindingInfoType::Buffer:
|
||||||
s->Append("Buffer");
|
s->Append("buffer");
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::Sampler:
|
case BindingInfoType::Sampler:
|
||||||
s->Append("Sampler");
|
s->Append("sampler");
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::Texture:
|
case BindingInfoType::Texture:
|
||||||
s->Append("Texture");
|
s->Append("texture");
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::StorageTexture:
|
case BindingInfoType::StorageTexture:
|
||||||
s->Append("StorageTexture");
|
s->Append("storageTexture");
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::ExternalTexture:
|
case BindingInfoType::ExternalTexture:
|
||||||
s->Append("ExternalTexture");
|
s->Append("externalTexture");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -48,44 +48,29 @@ namespace dawn::native {
|
||||||
const BindingInfo& value,
|
const BindingInfo& value,
|
||||||
const absl::FormatConversionSpec& spec,
|
const absl::FormatConversionSpec& spec,
|
||||||
absl::FormatSink* s) {
|
absl::FormatSink* s) {
|
||||||
s->Append(absl::StrFormat("{\n binding: %u\n visibility: %s\n %s: {\n",
|
static const auto* const fmt =
|
||||||
static_cast<uint32_t>(value.binding), value.visibility,
|
new absl::ParsedFormat<'u', 's', 's', 's'>("{ binding: %u, visibility: %s, %s: %s }");
|
||||||
value.bindingType));
|
|
||||||
|
|
||||||
switch (value.bindingType) {
|
switch (value.bindingType) {
|
||||||
case BindingInfoType::Buffer:
|
case BindingInfoType::Buffer:
|
||||||
s->Append(absl::StrFormat(" type: %s\n", value.buffer.type));
|
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
|
||||||
if (value.buffer.hasDynamicOffset) {
|
value.visibility, value.bindingType, value.buffer));
|
||||||
s->Append(" hasDynamicOffset: true\n");
|
|
||||||
}
|
|
||||||
if (value.buffer.minBindingSize != 0) {
|
|
||||||
s->Append(
|
|
||||||
absl::StrFormat(" minBindingSize: %u\n", value.buffer.minBindingSize));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::Sampler:
|
case BindingInfoType::Sampler:
|
||||||
s->Append(absl::StrFormat(" type: %s\n", value.sampler.type));
|
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
|
||||||
|
value.visibility, value.bindingType, value.sampler));
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::Texture:
|
case BindingInfoType::Texture:
|
||||||
s->Append(absl::StrFormat(" sampleType: %s\n", value.texture.sampleType));
|
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
|
||||||
s->Append(absl::StrFormat(" viewDimension: %s\n", value.texture.viewDimension));
|
value.visibility, value.bindingType, value.texture));
|
||||||
if (value.texture.multisampled) {
|
|
||||||
s->Append(" multisampled: true\n");
|
|
||||||
} else {
|
|
||||||
s->Append(" multisampled: false\n");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::StorageTexture:
|
case BindingInfoType::StorageTexture:
|
||||||
s->Append(absl::StrFormat(" access: %s\n", value.storageTexture.access));
|
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
|
||||||
s->Append(absl::StrFormat(" format: %s\n", value.storageTexture.format));
|
value.visibility, value.bindingType,
|
||||||
s->Append(
|
value.storageTexture));
|
||||||
absl::StrFormat(" viewDimension: %s\n", value.storageTexture.viewDimension));
|
|
||||||
break;
|
break;
|
||||||
case BindingInfoType::ExternalTexture:
|
case BindingInfoType::ExternalTexture:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->Append(" }\n}");
|
|
||||||
return {true};
|
return {true};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue