diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py index 46691aee2a..29c1be93db 100644 --- a/generator/dawn_json_generator.py +++ b/generator/dawn_json_generator.py @@ -684,6 +684,15 @@ def as_wireType(metadata, typ): 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): return typ.methods + [ x for x in [ @@ -753,7 +762,8 @@ def make_base_render_params(metadata): 'as_jsEnumValue': as_jsEnumValue, 'convert_cType_to_cppType': convert_cType_to_cppType, 'as_varName': as_varName, - 'decorate': decorate + 'decorate': decorate, + 'as_formatType': as_formatType } diff --git a/generator/generator_lib.py b/generator/generator_lib.py index e3d46bd194..11b3ed2594 100644 --- a/generator/generator_lib.py +++ b/generator/generator_lib.py @@ -156,7 +156,8 @@ _FileOutput = namedtuple('FileOutput', ['name', 'content']) def _do_renders(renders, template_dir): loader = _PreprocessingLoader(template_dir) - env = jinja2.Environment(loader=loader, + env = jinja2.Environment(extensions=['jinja2.ext.do'], + loader=loader, lstrip_blocks=True, trim_blocks=True, line_comment_prefix='//*') diff --git a/generator/templates/dawn/native/api_absl_format.cpp b/generator/templates/dawn/native/api_absl_format.cpp index 6a9477c774..a3b7ea22cd 100644 --- a/generator/templates/dawn/native/api_absl_format.cpp +++ b/generator/templates/dawn/native/api_absl_format.cpp @@ -49,6 +49,42 @@ namespace {{native_namespace}} { {% 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 + 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}} {% set namespace = metadata.namespace %} @@ -59,22 +95,24 @@ namespace {{namespace}} { // {% for type in by_category["enum"] %} - absl::FormatConvertResult - AbslFormatConvert({{as_cppType(type.name)}} value, - const absl::FormatConversionSpec& spec, - absl::FormatSink* s) { + absl::FormatConvertResult + AbslFormatConvert({{as_cppType(type.name)}} value, + const absl::FormatConversionSpec& spec, + absl::FormatSink* s) { + if (spec.conversion_char() == absl::FormatConversionChar::s) { s->Append("{{as_cppType(type.name)}}::"); switch (value) { {% for value in type.values %} case {{as_cppType(type.name)}}::{{as_cppEnum(value.name)}}: - s->Append("{{as_cppEnum(value.name)}}"); - break; + s->Append("{{as_cppEnum(value.name)}}"); + break; {% endfor %} - default: - s->Append(absl::StrFormat("%x", static_cast::type>(value))); } - return {true}; + } else { + s->Append(absl::StrFormat("%u", static_cast::type>(value))); } + return {true}; + } {% endfor %} // @@ -82,10 +120,11 @@ namespace {{namespace}} { // {% for type in by_category["bitmask"] %} - absl::FormatConvertResult - AbslFormatConvert({{as_cppType(type.name)}} value, - const absl::FormatConversionSpec& spec, - absl::FormatSink* s) { + absl::FormatConvertResult + AbslFormatConvert({{as_cppType(type.name)}} value, + const absl::FormatConversionSpec& spec, + absl::FormatSink* s) { + if (spec.conversion_char() == absl::FormatConversionChar::s) { s->Append("{{as_cppType(type.name)}}::"); if (!static_cast(value)) { {% for value in type.values if value.value == 0 %} @@ -124,9 +163,11 @@ namespace {{namespace}} { if (moreThanOneBit) { s->Append(")"); } - - return {true}; + } else { + s->Append(absl::StrFormat("%u", static_cast::type>(value))); } + return {true}; + } {% endfor %} } // namespace {{namespace}} diff --git a/generator/templates/dawn/native/api_absl_format.h b/generator/templates/dawn/native/api_absl_format.h index 5fa583f236..ab06098218 100644 --- a/generator/templates/dawn/native/api_absl_format.h +++ b/generator/templates/dawn/native/api_absl_format.h @@ -36,12 +36,33 @@ namespace {{native_namespace}} { {% for member in type.members %} {% if member.name.canonical_case() == "label" %} absl::FormatConvertResult - AbslFormatConvert(const {{as_cppType(type.name)}}* value, - const absl::FormatConversionSpec& spec, - absl::FormatSink* s); + AbslFormatConvert(const {{as_cppType(type.name)}}* value, + const absl::FormatConversionSpec& spec, + absl::FormatSink* s); {% endif %} {% 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 + AbslFormatConvert(const {{as_cppType(type.name)}}& value, + const absl::FormatConversionSpec& spec, + absl::FormatSink* s); + {% endif %} + {% endfor %} + } // namespace {{native_namespace}} {% set namespace = metadata.namespace %} @@ -52,7 +73,7 @@ namespace {{namespace}} { // {% for type in by_category["enum"] %} - absl::FormatConvertResult + absl::FormatConvertResult AbslFormatConvert({{as_cppType(type.name)}} value, const absl::FormatConversionSpec& spec, absl::FormatSink* s); @@ -63,7 +84,7 @@ namespace {{namespace}} { // {% for type in by_category["bitmask"] %} - absl::FormatConvertResult + absl::FormatConvertResult AbslFormatConvert({{as_cppType(type.name)}} value, const absl::FormatConversionSpec& spec, absl::FormatSink* s); diff --git a/src/dawn/native/BindGroupLayout.cpp b/src/dawn/native/BindGroupLayout.cpp index f535545466..201aecc118 100644 --- a/src/dawn/native/BindGroupLayout.cpp +++ b/src/dawn/native/BindGroupLayout.cpp @@ -661,11 +661,13 @@ namespace dawn::native { } std::string BindGroupLayoutBase::EntriesToString() const { - std::string entries = " ["; + std::string entries = "["; + std::string sep = ""; const BindGroupLayoutBase::BindingMap& bindingMap = GetBindingMap(); for (const auto [bindingNumber, bindingIndex] : bindingMap) { const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex); - entries += absl::StrFormat("%s, ", bindingInfo); + entries += absl::StrFormat("%s%s", sep, bindingInfo); + sep = ", "; } entries += "]"; return entries; diff --git a/src/dawn/native/BindingInfo.cpp b/src/dawn/native/BindingInfo.cpp index af4905a18f..d19017d05d 100644 --- a/src/dawn/native/BindingInfo.cpp +++ b/src/dawn/native/BindingInfo.cpp @@ -24,19 +24,19 @@ namespace dawn::native { absl::FormatSink* s) { switch (value) { case BindingInfoType::Buffer: - s->Append("Buffer"); + s->Append("buffer"); break; case BindingInfoType::Sampler: - s->Append("Sampler"); + s->Append("sampler"); break; case BindingInfoType::Texture: - s->Append("Texture"); + s->Append("texture"); break; case BindingInfoType::StorageTexture: - s->Append("StorageTexture"); + s->Append("storageTexture"); break; case BindingInfoType::ExternalTexture: - s->Append("ExternalTexture"); + s->Append("externalTexture"); break; default: UNREACHABLE(); @@ -48,44 +48,29 @@ namespace dawn::native { const BindingInfo& value, const absl::FormatConversionSpec& spec, absl::FormatSink* s) { - s->Append(absl::StrFormat("{\n binding: %u\n visibility: %s\n %s: {\n", - static_cast(value.binding), value.visibility, - value.bindingType)); - + static const auto* const fmt = + new absl::ParsedFormat<'u', 's', 's', 's'>("{ binding: %u, visibility: %s, %s: %s }"); switch (value.bindingType) { case BindingInfoType::Buffer: - s->Append(absl::StrFormat(" type: %s\n", value.buffer.type)); - if (value.buffer.hasDynamicOffset) { - s->Append(" hasDynamicOffset: true\n"); - } - if (value.buffer.minBindingSize != 0) { - s->Append( - absl::StrFormat(" minBindingSize: %u\n", value.buffer.minBindingSize)); - } + s->Append(absl::StrFormat(*fmt, static_cast(value.binding), + value.visibility, value.bindingType, value.buffer)); break; case BindingInfoType::Sampler: - s->Append(absl::StrFormat(" type: %s\n", value.sampler.type)); + s->Append(absl::StrFormat(*fmt, static_cast(value.binding), + value.visibility, value.bindingType, value.sampler)); break; case BindingInfoType::Texture: - s->Append(absl::StrFormat(" sampleType: %s\n", value.texture.sampleType)); - s->Append(absl::StrFormat(" viewDimension: %s\n", value.texture.viewDimension)); - if (value.texture.multisampled) { - s->Append(" multisampled: true\n"); - } else { - s->Append(" multisampled: false\n"); - } + s->Append(absl::StrFormat(*fmt, static_cast(value.binding), + value.visibility, value.bindingType, value.texture)); break; case BindingInfoType::StorageTexture: - s->Append(absl::StrFormat(" access: %s\n", value.storageTexture.access)); - s->Append(absl::StrFormat(" format: %s\n", value.storageTexture.format)); - s->Append( - absl::StrFormat(" viewDimension: %s\n", value.storageTexture.viewDimension)); + s->Append(absl::StrFormat(*fmt, static_cast(value.binding), + value.visibility, value.bindingType, + value.storageTexture)); break; case BindingInfoType::ExternalTexture: break; } - - s->Append(" }\n}"); return {true}; }