Skip to content

Commit eabe670

Browse files
authored
Add generator support for Compat extensions in core header (#583)
This is currently unused, but will get used in #580. Not easy to add specific tests for this so I'm leaving it untested until that lands. I've tested it locally with the changes I pushed there: afba5c5
1 parent 74472a7 commit eabe670

8 files changed

Lines changed: 135 additions & 104 deletions

File tree

gen/cheader.tmpl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,15 @@ struct {{CType .Base ""}}CallbackInfo;
198198
{{- range $entryIndex, $_ := .Entries}}
199199
{{- if .}}
200200
{{- MCommentEnumValue .Doc 0 $enum $entryIndex }}
201-
_wgpu_EXTEND_ENUM({{CType $enum.Base ""}}, {{CEnumName $enum.Base .Base}}, {{EnumValue32 $enum $entryIndex | printf "0x%.8X"}});
201+
_wgpu_EXTEND_ENUM({{CType $enum.Base ""}}, {{CEnumValueName $enum.Base .Base}}, {{EnumValue32 $enum $entryIndex | printf "0x%.8X"}});
202202
{{- end}}
203203
{{- end}}
204204
{{- else}}
205205
typedef enum {{CType .Base ""}} {
206206
{{- range $entryIndex, $_ := .Entries}}
207207
{{- if .}}
208208
{{- MCommentEnumValue .Doc 4 $enum $entryIndex }}
209-
{{CEnumName $enum.Base .Base}} = {{EnumValue32 $enum $entryIndex | printf "0x%.8X"}},
209+
{{CEnumValueName $enum.Base .Base}} = {{EnumValue32 $enum $entryIndex | printf "0x%.8X"}},
210210
{{- end}}
211211
{{- end}}
212212
{{CType $enum.Base ""}}_Force32 = 0x7FFFFFFF
@@ -230,7 +230,7 @@ typedef WGPUFlags {{CType .Base ""}};
230230
{{- end}}
231231
{{- range $entryIndex, $_ := .Entries}}
232232
{{- MCommentBitflagValue .Doc 0 $bitflag $entryIndex }}
233-
static const {{CType $bitflag.Base ""}} {{CEnumName $bitflag.Base .Base}} = {{BitflagValue $bitflag $entryIndex}};
233+
static const {{CType $bitflag.Base ""}} {{CEnumValueName $bitflag.Base .Base}} = {{BitflagValue $bitflag $entryIndex}};
234234
{{- end}}
235235
{{- end}}
236236

gen/gen.go

Lines changed: 89 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212
)
1313

1414
type Generator struct {
15-
ExtPrefix string
16-
HeaderName string
15+
UseExtPrefix bool
16+
HeaderName string
1717
*Yml
1818
}
1919

@@ -194,7 +194,7 @@ func (g *Generator) Gen(dst io.Writer) error {
194194
"CamelCase": CamelCase,
195195
"ConstantCaseName": g.ConstantCaseName,
196196
"PascalCaseName": g.PascalCaseName,
197-
"CEnumName": g.CEnumName,
197+
"CEnumValueName": g.CEnumValueName,
198198
"CMethodName": g.CMethodName,
199199
"CType": g.CType,
200200
"CValue": g.CValue,
@@ -243,92 +243,110 @@ func (g *Generator) FindBaseType(typ string) Base {
243243
case "constant":
244244
idx := slices.IndexFunc(g.Constants, func(c Constant) bool { return c.Name == name })
245245
if idx == -1 {
246-
return Base{Name: name, Namespace: g.PrefixForNamespace("")}
246+
return Base{Name: name, Namespace: "webgpu"}
247247
}
248248
return g.Constants[idx].Base
249249
case "typedef":
250250
idx := slices.IndexFunc(g.Typedefs, func(t Typedef) bool { return t.Name == name })
251251
if idx == -1 {
252-
return Base{Name: name, Namespace: g.PrefixForNamespace("")}
252+
return Base{Name: name, Namespace: "webgpu"}
253253
}
254254
return g.Typedefs[idx].Base
255255
case "enum":
256256
idx := slices.IndexFunc(g.Enums, func(e Enum) bool { return e.Name == name })
257257
if idx == -1 {
258-
return Base{Name: name, Namespace: g.PrefixForNamespace("")}
258+
return Base{Name: name, Namespace: "webgpu"}
259259
}
260260
return g.Enums[idx].Base
261261
case "bitflag":
262262
idx := slices.IndexFunc(g.Bitflags, func(b Bitflag) bool { return b.Name == name })
263263
if idx == -1 {
264-
return Base{Name: name, Namespace: g.PrefixForNamespace("")}
264+
return Base{Name: name, Namespace: "webgpu"}
265265
}
266266
return g.Bitflags[idx].Base
267267
case "struct":
268268
idx := slices.IndexFunc(g.Structs, func(s Struct) bool { return s.Name == name })
269269
if idx == -1 {
270-
return Base{Name: name, Namespace: g.PrefixForNamespace("")}
270+
return Base{Name: name, Namespace: "webgpu"}
271271
}
272272
return g.Structs[idx].Base
273273
case "callback":
274274
idx := slices.IndexFunc(g.Callbacks, func(c Callback) bool { return c.Name == name })
275275
if idx == -1 {
276-
return Base{Name: name, Namespace: g.PrefixForNamespace("")}
276+
return Base{Name: name, Namespace: "webgpu"}
277277
}
278278
return g.Callbacks[idx].Base
279279
case "object":
280280
idx := slices.IndexFunc(g.Objects, func(o Object) bool { return o.Name == name })
281281
if idx == -1 {
282-
return Base{Name: name, Namespace: g.PrefixForNamespace("")}
282+
return Base{Name: name, Namespace: "webgpu"}
283283
}
284284
return g.Objects[idx].Base
285285
default:
286286
panic("Unable to find unknown category type: " + category + " for identifier: " + typ)
287287
}
288288
}
289289

290-
func (g *Generator) ConstantCaseName(b Base) string {
291-
if b.Extended {
292-
return ConstantCase(b.Name)
293-
}
294-
295-
prefix := g.PrefixForNamespace(b.Namespace)
296-
switch prefix {
297-
case "":
298-
return ConstantCase(b.Name)
299-
default:
300-
return ConstantCase(prefix + "_" + b.Name)
290+
// Top-level items: constants, typedefs, and types (objects/enums/bitflags/structs/callbacks)
291+
func (g *Generator) ResolveNamespaceForTopLevelItem(b Base) string {
292+
if b.Namespace != "" {
293+
return b.Namespace
294+
} else if b.Extended {
295+
// If we're extending an enum, assume it's in the core namespace if not otherwise specified
296+
return "webgpu"
297+
} else {
298+
return g.Name
301299
}
302300
}
303301

304-
func (g *Generator) PascalCaseName(b Base) string {
305-
if b.Extended {
306-
return PascalCase(b.Name)
302+
// Items nested inside other items: methods, enum values, and bitflag values
303+
func (g *Generator) ResolveNamespaceForNestedItem(topLevelItem Base, nestedItem Base) string {
304+
if nestedItem.Namespace != "" {
305+
return nestedItem.Namespace
306+
} else if topLevelItem.Namespace != "" {
307+
return topLevelItem.Namespace
308+
} else {
309+
return g.Name
307310
}
311+
}
308312

309-
prefix := g.PrefixForNamespace(b.Namespace)
313+
func (g *Generator) CanonicalCaseName(prefix string, b Base) string {
310314
switch prefix {
311315
case "":
312-
return PascalCase(b.Name)
316+
return b.Name
313317
default:
314-
return PascalCase(prefix + "_" + b.Name)
318+
return prefix + "_" + b.Name
315319
}
316320
}
317321

318-
func (g *Generator) CEnumName(typ Base, entry Base) string {
319-
if !typ.Extended {
320-
return g.CType(typ, "") + "_" + PascalCase(entry.Name)
322+
func (g *Generator) ConstantCaseName(b Base) string {
323+
prefix := g.GetNamespacePrefix(g.ResolveNamespaceForTopLevelItem(b))
324+
return ConstantCase(g.CanonicalCaseName(prefix, b))
325+
}
326+
327+
func (g *Generator) PascalCaseName(b Base) string {
328+
prefix := g.GetNamespacePrefix(g.ResolveNamespaceForTopLevelItem(b))
329+
return PascalCase(g.CanonicalCaseName(prefix, b))
330+
}
331+
332+
func (g *Generator) GetNamespacePrefixForNestedItem(topLevelItem Base, nestedItem Base) string {
333+
outerNamespace := g.ResolveNamespaceForTopLevelItem(topLevelItem)
334+
innerNamespace := g.ResolveNamespaceForNestedItem(topLevelItem, nestedItem)
335+
if outerNamespace == innerNamespace {
336+
return ""
321337
} else {
322-
return g.CType(typ, "") + "_" + g.PascalCaseName(entry)
338+
return g.GetNamespacePrefix(innerNamespace)
323339
}
324340
}
325341

342+
func (g *Generator) CEnumValueName(typ Base, entry Base) string {
343+
entryPrefix := g.GetNamespacePrefixForNestedItem(typ, entry)
344+
return g.CType(typ, "") + "_" + PascalCase(g.CanonicalCaseName(entryPrefix, entry))
345+
}
346+
326347
func (g *Generator) CMethodName(o Object, m Function) string {
327-
if !o.Extended {
328-
return g.PascalCaseName(o.Base) + PascalCase(m.Name)
329-
} else {
330-
return PascalCase(o.Name) + g.PascalCaseName(m.Base)
331-
}
348+
entryPrefix := g.GetNamespacePrefixForNestedItem(o.Base, m.Base)
349+
return g.PascalCaseName(o.Base) + PascalCase(g.CanonicalCaseName(entryPrefix, m.Base))
332350
}
333351

334352
func (g *Generator) CValue(s string) (string, error) {
@@ -488,34 +506,38 @@ func (g *Generator) CallbackArgs(f Callback) string {
488506
return sb.String()
489507
}
490508

491-
func (g *Generator) EnumValue16(e Enum, entryIndex int) (uint16, error) {
509+
func (g *Generator) EnumValue32(e Enum, entryIndex int) (uint32, error) {
492510
entry := e.Entries[entryIndex]
493-
if entry.Value == "" {
494-
return uint16(entryIndex), nil
495-
} else {
496-
var num string
497-
var base int
498-
if strings.HasPrefix(entry.Value, "0x") {
499-
base = 16
500-
num = strings.TrimPrefix(entry.Value, "0x")
501-
} else {
502-
base = 10
503-
num = entry.Value
511+
512+
var enum_prefix uint16
513+
if entry.Namespace != "" {
514+
if g.EnumPrefix != 0 {
515+
return 0, fmt.Errorf("EnumValue32: entry %s with overridden namespace %s can only be used in core webgpu.h (with global enum_prefix 0)", entry.Name, entry.Namespace)
504516
}
505-
value, err := strconv.ParseUint(num, base, 16)
506-
if err != nil {
507-
return 0, err
517+
if entry.Value == nil {
518+
return 0, fmt.Errorf("EnumValue32: entry %s with overridden namespace %s must have an explicit value", entry.Name, entry.Namespace)
508519
}
509-
return uint16(value), nil
520+
switch entry.Namespace {
521+
case "compatibility_mode":
522+
enum_prefix = 0x2000
523+
default:
524+
return 0, fmt.Errorf("EnumValue32: unknown namespace %s", entry.Namespace)
525+
}
526+
} else {
527+
enum_prefix = g.EnumPrefix
510528
}
511-
}
512529

513-
func (g *Generator) EnumValue32(e Enum, entryIndex int) (uint32, error) {
514-
value16, err := g.EnumValue16(e, entryIndex)
515-
if err != nil {
516-
return 0, err
530+
var value16 uint16
531+
if entry.Value == nil {
532+
value16 = uint16(entryIndex)
533+
if int(value16) != entryIndex {
534+
return 0, fmt.Errorf("EnumValue32: entry %s default value (entry index %d) is too large", entry.Name, entryIndex)
535+
}
536+
} else {
537+
value16 = *entry.Value
517538
}
518-
return uint32(g.EnumPrefix)<<16 | uint32(value16), nil
539+
540+
return uint32(enum_prefix)<<16 | uint32(value16), nil
519541
}
520542

521543
func bitflagEntryValue(entry BitflagEntry, entryIndex int) (uint64, error) {
@@ -587,14 +609,20 @@ func (g *Generator) BitflagValue(b Bitflag, entryIndex int, isDocString bool) (s
587609
}
588610
}
589611

590-
func (g *Generator) PrefixForNamespace(namespace string) string {
612+
func (g *Generator) GetNamespacePrefix(namespace string) string {
591613
switch namespace {
592614
case "":
593-
return g.ExtPrefix
615+
panic("Missing namespace")
594616
case "webgpu":
595617
return ""
618+
case "compatibility_mode":
619+
return ""
596620
default:
597-
return namespace
621+
if g.UseExtPrefix {
622+
return namespace
623+
} else {
624+
return ""
625+
}
598626
}
599627
}
600628

gen/main.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,10 @@ func main() {
7676

7777
SortAndTransform(&yml)
7878

79-
prefix := ""
80-
if yml.Name != "webgpu" && extPrefix {
81-
prefix = yml.Name
82-
}
8379
g := &Generator{
84-
Yml: &yml,
85-
HeaderName: outHeaderFileNameSplit[0],
86-
ExtPrefix: prefix,
80+
Yml: &yml,
81+
HeaderName: outHeaderFileNameSplit[0],
82+
UseExtPrefix: extPrefix,
8783
}
8884
if err := g.Gen(dst); err != nil {
8985
panic(err)

gen/yml.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type Enum struct {
4646
}
4747
type EnumEntry struct {
4848
Base `yaml:",inline"`
49-
Value string `yaml:"value"`
49+
Value *uint16 `yaml:"value"`
5050
}
5151

5252
type Bitflag struct {

0 commit comments

Comments
 (0)