From b6252a41f2ec14c6ff4568717df2e994e909cf20 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 23 Mar 2024 17:53:11 +0900 Subject: [PATCH] internal/graphicsdriver/directx: add 'tearing' for EBITENGINE_DIRECTX Now tearing happens only when 'tearing' is specified and vsync is off. Closes #2858 --- doc.go | 1 + .../directx/graphics11_windows.go | 4 ++-- .../directx/graphics12_windows.go | 8 +++---- .../directx/graphics_windows.go | 23 +++++++++++-------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/doc.go b/doc.go index aebd8ad2f..aa3f16b9c 100644 --- a/doc.go +++ b/doc.go @@ -81,6 +81,7 @@ // // "debug": Use a debug layer. // "warp": Use WARP (i.e. software rendering). +// "tearing": Allow tearing when vsync is off. // "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. // diff --git a/internal/graphicsdriver/directx/graphics11_windows.go b/internal/graphicsdriver/directx/graphics11_windows.go index 807009046..8aa7047c0 100644 --- a/internal/graphicsdriver/directx/graphics11_windows.go +++ b/internal/graphicsdriver/directx/graphics11_windows.go @@ -153,7 +153,7 @@ type graphics11 struct { newScreenHeight int } -func newGraphics11(useWARP bool, useDebugLayer bool) (gr11 *graphics11, ferr error) { +func newGraphics11(useWARP bool, useDebugLayer bool, allowTearing bool) (gr11 *graphics11, ferr error) { g := &graphics11{ vsyncEnabled: true, } @@ -207,7 +207,7 @@ func newGraphics11(useWARP bool, useDebugLayer bool) (gr11 *graphics11, ferr err } dxgiFactory := (*_IDXGIFactory)(df) - gi, err := newGraphicsInfra(dxgiFactory) + gi, err := newGraphicsInfra(dxgiFactory, allowTearing) if err != nil { return nil, err } diff --git a/internal/graphicsdriver/directx/graphics12_windows.go b/internal/graphicsdriver/directx/graphics12_windows.go index 69740b90e..068173f2d 100644 --- a/internal/graphicsdriver/directx/graphics12_windows.go +++ b/internal/graphicsdriver/directx/graphics12_windows.go @@ -106,7 +106,7 @@ type graphics12 struct { pipelineStates } -func newGraphics12(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_LEVEL) (*graphics12, error) { +func newGraphics12(useWARP bool, useDebugLayer bool, allowTearing bool, featureLevel _D3D_FEATURE_LEVEL) (*graphics12, error) { g := &graphics12{} // Initialize not only a device but also other members like a fence. @@ -116,7 +116,7 @@ func newGraphics12(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_L return nil, err } } else { - if err := g.initializeDesktop(useWARP, useDebugLayer, featureLevel); err != nil { + if err := g.initializeDesktop(useWARP, useDebugLayer, allowTearing, featureLevel); err != nil { return nil, err } } @@ -124,7 +124,7 @@ func newGraphics12(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_L return g, nil } -func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_LEVEL) (ferr error) { +func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, allowTearing bool, featureLevel _D3D_FEATURE_LEVEL) (ferr error) { if err := d3d12.Load(); err != nil { return err } @@ -152,7 +152,7 @@ func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, feature if err != nil { return err } - gi, err := newGraphicsInfra(f) + gi, err := newGraphicsInfra(f, allowTearing) if err != nil { return err } diff --git a/internal/graphicsdriver/directx/graphics_windows.go b/internal/graphicsdriver/directx/graphics_windows.go index 87f122c92..a87be91bb 100644 --- a/internal/graphicsdriver/directx/graphics_windows.go +++ b/internal/graphicsdriver/directx/graphics_windows.go @@ -81,6 +81,7 @@ func NewGraphics() (graphicsdriver.Graphics, error) { var useWARP bool var useDebugLayer bool + var allowTearing bool version := 11 // Specify the feature level 11 by default. @@ -108,6 +109,8 @@ func NewGraphics() (graphicsdriver.Graphics, error) { useWARP = true case t == "debug": useDebugLayer = true + case t == "tearing": + allowTearing = true case strings.HasPrefix(t, "version="): v, err := strconv.Atoi(t[len("version="):]) if err != nil { @@ -130,13 +133,13 @@ func NewGraphics() (graphicsdriver.Graphics, error) { switch version { case 11: - g, err := newGraphics11(useWARP, useDebugLayer) + g, err := newGraphics11(useWARP, useDebugLayer, allowTearing) if err != nil { return nil, err } return g, nil case 12: - g, err := newGraphics12(useWARP, useDebugLayer, featureLevel) + g, err := newGraphics12(useWARP, useDebugLayer, allowTearing, featureLevel) if err != nil { return nil, err } @@ -163,19 +166,21 @@ type graphicsInfra struct { } // newGraphicsInfra takes the ownership of the given factory. -func newGraphicsInfra(factory *_IDXGIFactory) (*graphicsInfra, error) { +func newGraphicsInfra(factory *_IDXGIFactory, allowTearing bool) (*graphicsInfra, error) { g := &graphicsInfra{ factory: factory, } runtime.SetFinalizer(g, (*graphicsInfra).release) - if f, err := g.factory.QueryInterface(&_IID_IDXGIFactory5); err == nil && f != nil { - factory := (*_IDXGIFactory5)(f) - defer factory.Release() + if allowTearing { + if f, err := g.factory.QueryInterface(&_IID_IDXGIFactory5); err == nil && f != nil { + factory := (*_IDXGIFactory5)(f) + defer factory.Release() - var allowTearing int32 - if err := factory.CheckFeatureSupport(_DXGI_FEATURE_PRESENT_ALLOW_TEARING, unsafe.Pointer(&allowTearing), uint32(unsafe.Sizeof(allowTearing))); err == nil && allowTearing != 0 { - g.allowTearing = true + var allowTearing int32 + if err := factory.CheckFeatureSupport(_DXGI_FEATURE_PRESENT_ALLOW_TEARING, unsafe.Pointer(&allowTearing), uint32(unsafe.Sizeof(allowTearing))); err == nil && allowTearing != 0 { + g.allowTearing = true + } } }