From 0449126c5bda5a33e13c5d6f0668b00fecd53a4c Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 29 Mar 2023 16:22:20 +0900 Subject: [PATCH] internal/graphicsdriver/directx: integrate EBITENGINE_DIRECTX and EBITENGINE_DIRECTX_FEATURE_LEVEL --- doc.go | 20 +++--- .../directx/graphics_windows.go | 71 ++++++++++++------- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/doc.go b/doc.go index e4d77f570..34967a09a 100644 --- a/doc.go +++ b/doc.go @@ -78,17 +78,19 @@ // `EBITENGINE_DIRECTX` environment variable specifies various parameters for DirectX. // You can specify multiple values separated by a comma. The default value is empty (i.e. no parameters). // -// "debug": Use a debug layer. -// "warp": Use WARP (i.e. software rendering). -// "version=11": Use DirectX 11 (default). -// "version=12": Use DirectX 12. +// "debug": Use a debug layer. +// "warp": Use WARP (i.e. software rendering). +// "version=VERSION": Specify a DirectX version (e.g. 11). +// "featurelevel=FEATURE_LEVEL": Specify a feature level (e.g. 11_0). This is for DirectX 12. // -// The options "version=..." are exclusive and if multiples are specified, the lastly specified value is adopted. -// On Xbox, the version options are ignored and DirectX 12 is always adopted. +// The options taking arguments are exclusive, and if multiples are specified, the lastly specified value is adopted. // -// `EBITENGINE_DIRECTX_FEATURE_LEVEL` environment variable specifies DirectX feature level. -// The possible values are "11_0", "11_1", "12_0", "12_1", and "12_2". -// The default value is "11_0". +// The possible values for the option "version" are "11" and "12". +// If the version is not specified, the default version 11 is adopted. +// On Xbox, the "version" option is ignored and DirectX 12 is always adopted. +// +// The option "featurelevel" is valid only for DirectX 12. +// The possible values are "11_0", "11_1", "12_0", "12_1", and "12_2". The default value is "11_0". // // `EBITENGINE_OPENGL` environment variable specifies various parameters for OpenGL. // You can specify multiple values separated by a comma. The default value is empty (i.e. no parameters). diff --git a/internal/graphicsdriver/directx/graphics_windows.go b/internal/graphicsdriver/directx/graphics_windows.go index 0683c8cd4..6a9bbee01 100644 --- a/internal/graphicsdriver/directx/graphics_windows.go +++ b/internal/graphicsdriver/directx/graphics_windows.go @@ -20,6 +20,7 @@ import ( "math" "os" "runtime" + "strconv" "strings" "time" "unsafe" @@ -52,6 +53,23 @@ func pow2(x uint32) uint32 { return p2 } +func parseFeatureLevel(str string) (_D3D_FEATURE_LEVEL, bool) { + switch str { + case "11_0": + return _D3D_FEATURE_LEVEL_11_0, true + case "11_1": + return _D3D_FEATURE_LEVEL_11_1, true + case "12_0": + return _D3D_FEATURE_LEVEL_12_0, true + case "12_1": + return _D3D_FEATURE_LEVEL_12_1, true + case "12_2": + return _D3D_FEATURE_LEVEL_12_2, true + default: + return 0, false + } +} + // NewGraphics creates an implementation of graphicsdriver.Graphics for DirectX. // The returned graphics value is nil iff the error is not nil. func NewGraphics() (graphicsdriver.Graphics, error) { @@ -59,22 +77,43 @@ func NewGraphics() (graphicsdriver.Graphics, error) { var useDebugLayer bool version := 11 + // Specify the feature level 11 by default. + // Some old cards don't work well with the default feature level (#2447, #2486). + featureLevel := _D3D_FEATURE_LEVEL_11_0 + + // Parse a special environment variable for backward compatibility. + if env := os.Getenv("EBITENGINE_DIRECTX_FEATURE_LEVEL"); env != "" { + if fl, ok := parseFeatureLevel(env); ok { + featureLevel = fl + } + } + env := os.Getenv("EBITENGINE_DIRECTX") if env == "" { // For backward compatibility, read the EBITEN_ version. env = os.Getenv("EBITEN_DIRECTX") } + for _, t := range strings.Split(env, ",") { - switch strings.TrimSpace(t) { - case "warp": + t := strings.TrimSpace(t) + switch { + case t == "warp": // TODO: Is WARP available on Xbox? useWARP = true - case "debug": + case t == "debug": useDebugLayer = true - case "version=11": - version = 11 - case "version=12": - version = 12 + case strings.HasPrefix(t, "version="): + v, err := strconv.Atoi(t[len("version="):]) + if err != nil { + continue + } + version = v + case strings.HasPrefix(t, "featurelevel="): + fl, ok := parseFeatureLevel(t[len("featurelevel="):]) + if !ok { + continue + } + featureLevel = fl } } @@ -91,24 +130,6 @@ func NewGraphics() (graphicsdriver.Graphics, error) { } return g, nil case 12: - // Specify the feature level 11 by default. - // Some old cards don't work well with the default feature level (#2447, #2486). - var featureLevel _D3D_FEATURE_LEVEL = _D3D_FEATURE_LEVEL_11_0 - if env := os.Getenv("EBITENGINE_DIRECTX_FEATURE_LEVEL"); env != "" { - switch env { - case "11_0": - featureLevel = _D3D_FEATURE_LEVEL_11_0 - case "11_1": - featureLevel = _D3D_FEATURE_LEVEL_11_1 - case "12_0": - featureLevel = _D3D_FEATURE_LEVEL_12_0 - case "12_1": - featureLevel = _D3D_FEATURE_LEVEL_12_1 - case "12_2": - featureLevel = _D3D_FEATURE_LEVEL_12_2 - } - } - g, err := newGraphics12(useWARP, useDebugLayer, featureLevel) if err != nil { return nil, err