From 251ad9451457211a862e8e6742b80e7b8754204a Mon Sep 17 00:00:00 2001 From: Dmitry Sergeev Date: Sun, 13 Sep 2026 17:22:02 +0300 Subject: [PATCH] cleanup + pattern selector --- cmd/wgpu-gen/main.go | 80 ++++++++++++++++--- .../dvdLogo.wgsl} | 0 .../smpteBars.wgsl} | 0 .../{v210_y_ramp.wgsl => dynamic/yRamp.wgsl} | 0 .../{v210_bars.wgsl => static/smpteBars.wgsl} | 0 5 files changed, 68 insertions(+), 12 deletions(-) rename kernels/{v210_dvd_logo.wgsl => dynamic/dvdLogo.wgsl} (100%) rename kernels/{v210_bars_move.wgsl => dynamic/smpteBars.wgsl} (100%) rename kernels/{v210_y_ramp.wgsl => dynamic/yRamp.wgsl} (100%) rename kernels/{v210_bars.wgsl => static/smpteBars.wgsl} (100%) diff --git a/cmd/wgpu-gen/main.go b/cmd/wgpu-gen/main.go index 9d617cb..4d5765e 100644 --- a/cmd/wgpu-gen/main.go +++ b/cmd/wgpu-gen/main.go @@ -29,7 +29,7 @@ type appArgs struct { domain string videoFlowDefFile string audioFlowDefFile string - pattern uint8 + pattern string listPatterns bool textOverlay string @@ -117,7 +117,6 @@ func checkArgs(args appArgs) { audioFlowDefProvided = true } - // TODO: check selected pattern if !videoFlowDefProvided { if args.videoWidth == 0 || args.videoWidth%6 != 0 { // width%6 == 0 - because of v210 (6 pixels per 16-byte block) @@ -145,6 +144,13 @@ func checkArgs(args appArgs) { } else { args.videoUUID = uuid.NewString() } + if args.pattern != "" { + if _, exists := patterns[args.pattern]; !exists { + fmt.Fprintf(os.Stderr, "Pattern %s is not in available list.\n", args.pattern) + listPatterns(os.Stderr) + os.Exit(2) + } + } } if !audioFlowDefProvided { @@ -172,6 +178,60 @@ func checkArgs(args appArgs) { } } +type pattern struct { + name string + description string + kernelPath string + motion bool +} + +var patterns = map[string]pattern{ + "bars": { + name: "bars", + description: "SMPTE 75% color bars", + kernelPath: "kernels/static/smpteBars.wgsl", + motion: false, + }, + "bars-move": { + name: "bars-move", + description: "SMPTE 75% color bars with moving square", + kernelPath: "kernels/dynamic/smpteBars.wgsl", + motion: true, + }, + "gray-ramp": { + name: "gray-ramp", + description: "Y gradient", + kernelPath: "kernels/static/yRamp.wgsl", + motion: false, + }, + "gray-ramp-move": { + name: "gray-ramp-move", + description: "Y gradient with moving square", + kernelPath: "kernels/dynamic/yRamp.wgsl", + motion: false, + }, + "dvd": { + name: "dvd", + description: "DVD logo pattern, but with MXL logo", + kernelPath: "kernels/dynamic/dvdLogo.wgsl", + motion: true, + }, +} + +func listPatterns(f *os.File) { + fmt.Fprintln(f, "List of available video patterns:") + var maxNameWidth int = 0 + for name, _ := range patterns { + l := len(name) + if l > maxNameWidth { + maxNameWidth = l + } + } + for name, p := range patterns { + fmt.Fprintf(f, " %-*s - %s\n", maxNameWidth, name, p.description) + } +} + func flagSetAddFlags(fs *pflag.FlagSet, args *appArgs) { // common flags fs.BoolVarP(&args.showHelp, "help", "h", false, "Show help message and exit") @@ -180,8 +240,8 @@ func flagSetAddFlags(fs *pflag.FlagSet, args *appArgs) { fs.StringVarP(&args.videoFlowDefFile, "video", "v", "", "Video flow definition JSON file path") fs.StringVarP(&args.audioFlowDefFile, "audio", "a", "", "Audio flow definition JSON file path [TODO]") // Video pattern flags - fs.Uint8VarP(&args.pattern, "pattern", "p", 0, "Video pattern type [TODO]") - fs.BoolVar(&args.listPatterns, "list-patterns", false, "List video available video patterns and exit [TODO]") + fs.StringVarP(&args.pattern, "pattern", "p", "bars", "Video pattern type") + fs.BoolVar(&args.listPatterns, "list-patterns", false, "List video available video patterns and exit") fs.StringVarP(&args.textOverlay, "text", "t", "", "Text overlay above video pattern") fs.UintVar(&args.videoWidth, "width", 1920, "Video pattern width") fs.UintVar(&args.videoHeight, "height", 1080, "Video pattern height") @@ -210,8 +270,7 @@ func main() { return } if args.listPatterns { - // TODO - printUsage() + listPatterns(os.Stderr) return } checkArgs(args) @@ -259,19 +318,16 @@ func main() { log.Printf("Video UUID: %s", vi.uuid) // TODO: if init failed -> CPU generator - // But before i should create same patterns for both generators - // and text overlays - kernel := "kernels/v210_bars_move.wgsl" - // kernel = "kernels/v210_dvd_logo.wgsl" + videoPattern := patterns[args.pattern] var genOpts []generator.WGPUOption - if kernel == "kernels/v210_dvd_logo.wgsl" { + if videoPattern.name == "dvd" { plane, err := generator.LoadLogoPNG("assets/mxl.png") if err != nil { log.Fatalf("logo load failed: %v", err) } genOpts = append(genOpts, generator.WithLogo(plane)) } - gen, err := generator.NewWGPUGenerator(vi.width, vi.height, kernel, genOpts...) + gen, err := generator.NewWGPUGenerator(vi.width, vi.height, videoPattern.kernelPath, genOpts...) if err != nil { log.Fatalf("wgpu init failed: %v", err) } diff --git a/kernels/v210_dvd_logo.wgsl b/kernels/dynamic/dvdLogo.wgsl similarity index 100% rename from kernels/v210_dvd_logo.wgsl rename to kernels/dynamic/dvdLogo.wgsl diff --git a/kernels/v210_bars_move.wgsl b/kernels/dynamic/smpteBars.wgsl similarity index 100% rename from kernels/v210_bars_move.wgsl rename to kernels/dynamic/smpteBars.wgsl diff --git a/kernels/v210_y_ramp.wgsl b/kernels/dynamic/yRamp.wgsl similarity index 100% rename from kernels/v210_y_ramp.wgsl rename to kernels/dynamic/yRamp.wgsl diff --git a/kernels/v210_bars.wgsl b/kernels/static/smpteBars.wgsl similarity index 100% rename from kernels/v210_bars.wgsl rename to kernels/static/smpteBars.wgsl