internal/graphicsdriver/directx: add 'tearing' for EBITENGINE_DIRECTX

Now tearing happens only when 'tearing' is specified and vsync is off.

Closes #2858
This commit is contained in:
Hajime Hoshi 2024-03-23 17:53:11 +09:00
parent 0651803c40
commit b6252a41f2
4 changed files with 21 additions and 15 deletions

1
doc.go
View File

@ -81,6 +81,7 @@
// //
// "debug": Use a debug layer. // "debug": Use a debug layer.
// "warp": Use WARP (i.e. software rendering). // "warp": Use WARP (i.e. software rendering).
// "tearing": Allow tearing when vsync is off.
// "version=VERSION": Specify a DirectX version (e.g. 11). // "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. // "featurelevel=FEATURE_LEVEL": Specify a feature level (e.g. 11_0). This is for DirectX 12.
// //

View File

@ -153,7 +153,7 @@ type graphics11 struct {
newScreenHeight int 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{ g := &graphics11{
vsyncEnabled: true, vsyncEnabled: true,
} }
@ -207,7 +207,7 @@ func newGraphics11(useWARP bool, useDebugLayer bool) (gr11 *graphics11, ferr err
} }
dxgiFactory := (*_IDXGIFactory)(df) dxgiFactory := (*_IDXGIFactory)(df)
gi, err := newGraphicsInfra(dxgiFactory) gi, err := newGraphicsInfra(dxgiFactory, allowTearing)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -106,7 +106,7 @@ type graphics12 struct {
pipelineStates 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{} g := &graphics12{}
// Initialize not only a device but also other members like a fence. // 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 return nil, err
} }
} else { } else {
if err := g.initializeDesktop(useWARP, useDebugLayer, featureLevel); err != nil { if err := g.initializeDesktop(useWARP, useDebugLayer, allowTearing, featureLevel); err != nil {
return nil, err return nil, err
} }
} }
@ -124,7 +124,7 @@ func newGraphics12(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_L
return g, nil 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 { if err := d3d12.Load(); err != nil {
return err return err
} }
@ -152,7 +152,7 @@ func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, feature
if err != nil { if err != nil {
return err return err
} }
gi, err := newGraphicsInfra(f) gi, err := newGraphicsInfra(f, allowTearing)
if err != nil { if err != nil {
return err return err
} }

View File

@ -81,6 +81,7 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
var useWARP bool var useWARP bool
var useDebugLayer bool var useDebugLayer bool
var allowTearing bool
version := 11 version := 11
// Specify the feature level 11 by default. // Specify the feature level 11 by default.
@ -108,6 +109,8 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
useWARP = true useWARP = true
case t == "debug": case t == "debug":
useDebugLayer = true useDebugLayer = true
case t == "tearing":
allowTearing = true
case strings.HasPrefix(t, "version="): case strings.HasPrefix(t, "version="):
v, err := strconv.Atoi(t[len("version="):]) v, err := strconv.Atoi(t[len("version="):])
if err != nil { if err != nil {
@ -130,13 +133,13 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
switch version { switch version {
case 11: case 11:
g, err := newGraphics11(useWARP, useDebugLayer) g, err := newGraphics11(useWARP, useDebugLayer, allowTearing)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return g, nil return g, nil
case 12: case 12:
g, err := newGraphics12(useWARP, useDebugLayer, featureLevel) g, err := newGraphics12(useWARP, useDebugLayer, allowTearing, featureLevel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -163,19 +166,21 @@ type graphicsInfra struct {
} }
// newGraphicsInfra takes the ownership of the given factory. // newGraphicsInfra takes the ownership of the given factory.
func newGraphicsInfra(factory *_IDXGIFactory) (*graphicsInfra, error) { func newGraphicsInfra(factory *_IDXGIFactory, allowTearing bool) (*graphicsInfra, error) {
g := &graphicsInfra{ g := &graphicsInfra{
factory: factory, factory: factory,
} }
runtime.SetFinalizer(g, (*graphicsInfra).release) runtime.SetFinalizer(g, (*graphicsInfra).release)
if f, err := g.factory.QueryInterface(&_IID_IDXGIFactory5); err == nil && f != nil { if allowTearing {
factory := (*_IDXGIFactory5)(f) if f, err := g.factory.QueryInterface(&_IID_IDXGIFactory5); err == nil && f != nil {
defer factory.Release() factory := (*_IDXGIFactory5)(f)
defer factory.Release()
var allowTearing int32 var allowTearing int32
if err := factory.CheckFeatureSupport(_DXGI_FEATURE_PRESENT_ALLOW_TEARING, unsafe.Pointer(&allowTearing), uint32(unsafe.Sizeof(allowTearing))); err == nil && allowTearing != 0 { if err := factory.CheckFeatureSupport(_DXGI_FEATURE_PRESENT_ALLOW_TEARING, unsafe.Pointer(&allowTearing), uint32(unsafe.Sizeof(allowTearing))); err == nil && allowTearing != 0 {
g.allowTearing = true g.allowTearing = true
}
} }
} }