diff --git a/doc.go b/doc.go index a2b5eec57..9d1dce203 100644 --- a/doc.go +++ b/doc.go @@ -81,6 +81,10 @@ // "warp": Use WARP (i.e. software rendering). // "debug": Use a debug layer. // +// `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 "12_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/api_windows.go b/internal/graphicsdriver/directx/api_windows.go index aee9deccf..ea67a45c9 100644 --- a/internal/graphicsdriver/directx/api_windows.go +++ b/internal/graphicsdriver/directx/api_windows.go @@ -73,7 +73,11 @@ const ( type _D3D_FEATURE_LEVEL int32 const ( + _D3D_FEATURE_LEVEL_11_0 _D3D_FEATURE_LEVEL = 0xb000 + _D3D_FEATURE_LEVEL_11_1 _D3D_FEATURE_LEVEL = 0xb100 _D3D_FEATURE_LEVEL_12_0 _D3D_FEATURE_LEVEL = 0xc000 + _D3D_FEATURE_LEVEL_12_1 _D3D_FEATURE_LEVEL = 0xc100 + _D3D_FEATURE_LEVEL_12_2 _D3D_FEATURE_LEVEL = 0xc200 ) type _D3D_PRIMITIVE_TOPOLOGY int32 diff --git a/internal/graphicsdriver/directx/graphics_windows.go b/internal/graphicsdriver/directx/graphics_windows.go index 00c4dc33a..6befeb356 100644 --- a/internal/graphicsdriver/directx/graphics_windows.go +++ b/internal/graphicsdriver/directx/graphics_windows.go @@ -173,6 +173,24 @@ func (g *Graphics) initialize() (ferr error) { } } + // Ebitengine itself doesn't require the features level 12 and 11 should be enough, + // but some old cards don't work well (#2447). Specify the level 12 by default. + var featureLevel _D3D_FEATURE_LEVEL = _D3D_FEATURE_LEVEL_12_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 + } + } + // Initialize not only a device but also other members like a fence. // Even if initializing a device succeeds, initializing a fence might fail (#2142). @@ -181,7 +199,7 @@ func (g *Graphics) initialize() (ferr error) { return err } } else { - if err := g.initializeDesktop(useWARP, useDebugLayer); err != nil { + if err := g.initializeDesktop(useWARP, useDebugLayer, featureLevel); err != nil { return err } } @@ -189,7 +207,7 @@ func (g *Graphics) initialize() (ferr error) { return nil } -func (g *Graphics) initializeDesktop(useWARP bool, useDebugLayer bool) (ferr error) { +func (g *Graphics) initializeDesktop(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_LEVEL) (ferr error) { if err := d3d12.Load(); err != nil { return err } @@ -256,9 +274,7 @@ func (g *Graphics) initializeDesktop(useWARP bool, useDebugLayer bool) (ferr err continue } // Test D3D12CreateDevice without creating an actual device. - // Ebitengine itself doesn't require the features level 12 and 11 should be enough, - // but some old cards don't work well (#2447). Specify the level 12 here. - if _, err := _D3D12CreateDevice(unsafe.Pointer(a), _D3D_FEATURE_LEVEL_12_0, &_IID_ID3D12Device, false); err != nil { + if _, err := _D3D12CreateDevice(unsafe.Pointer(a), featureLevel, &_IID_ID3D12Device, false); err != nil { continue } @@ -271,7 +287,7 @@ func (g *Graphics) initializeDesktop(useWARP bool, useDebugLayer bool) (ferr err return errors.New("directx: DirectX 12 is not supported") } - d, err := _D3D12CreateDevice(unsafe.Pointer(adapter), _D3D_FEATURE_LEVEL_12_0, &_IID_ID3D12Device, true) + d, err := _D3D12CreateDevice(unsafe.Pointer(adapter), featureLevel, &_IID_ID3D12Device, true) if err != nil { return err }