mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/graphicsdriver/directx: allow tearing when vsync is off
Updates #2034 Updates #2188
This commit is contained in:
parent
a32a137fa8
commit
0035ba0bd1
@ -577,6 +577,12 @@ const (
|
|||||||
|
|
||||||
type _DXGI_COLOR_SPACE_TYPE int32
|
type _DXGI_COLOR_SPACE_TYPE int32
|
||||||
|
|
||||||
|
type _DXGI_FEATURE int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
_DXGI_FEATURE_PRESENT_ALLOW_TEARING _DXGI_FEATURE = 0
|
||||||
|
)
|
||||||
|
|
||||||
type _DXGI_FORMAT int32
|
type _DXGI_FORMAT int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -593,8 +599,20 @@ type _DXGI_MODE_SCANLINE_ORDER int32
|
|||||||
|
|
||||||
type _DXGI_MODE_SCALING int32
|
type _DXGI_MODE_SCALING int32
|
||||||
|
|
||||||
|
type _DXGI_PRESENT uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
_DXGI_PRESENT_ALLOW_TEARING _DXGI_PRESENT = 0x00000200
|
||||||
|
)
|
||||||
|
|
||||||
type _DXGI_SCALING int32
|
type _DXGI_SCALING int32
|
||||||
|
|
||||||
|
type _DXGI_SWAP_CHAIN_FLAG int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
_DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING _DXGI_SWAP_CHAIN_FLAG = 2048
|
||||||
|
)
|
||||||
|
|
||||||
type _DXGI_SWAP_EFFECT int32
|
type _DXGI_SWAP_EFFECT int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -634,6 +652,7 @@ var (
|
|||||||
_IID_IDXGIAdapter1 = windows.GUID{Data1: 0x29038f61, Data2: 0x3839, Data3: 0x4626, Data4: [...]byte{0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05}}
|
_IID_IDXGIAdapter1 = windows.GUID{Data1: 0x29038f61, Data2: 0x3839, Data3: 0x4626, Data4: [...]byte{0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05}}
|
||||||
_IID_IDXGIDevice = windows.GUID{Data1: 0x54ec77fa, Data2: 0x1377, Data3: 0x44e6, Data4: [...]byte{0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c}}
|
_IID_IDXGIDevice = windows.GUID{Data1: 0x54ec77fa, Data2: 0x1377, Data3: 0x44e6, Data4: [...]byte{0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c}}
|
||||||
_IID_IDXGIFactory4 = windows.GUID{Data1: 0x1bc6ea02, Data2: 0xef36, Data3: 0x464f, Data4: [...]byte{0xbf, 0x0c, 0x21, 0xca, 0x39, 0xe5, 0x16, 0x8a}}
|
_IID_IDXGIFactory4 = windows.GUID{Data1: 0x1bc6ea02, Data2: 0xef36, Data3: 0x464f, Data4: [...]byte{0xbf, 0x0c, 0x21, 0xca, 0x39, 0xe5, 0x16, 0x8a}}
|
||||||
|
_IID_IDXGIFactory5 = windows.GUID{Data1: 0x7632e1f5, Data2: 0xee65, Data3: 0x4dca, Data4: [...]byte{0x87, 0xfd, 0x84, 0xcd, 0x75, 0xf8, 0x83, 0x8d}}
|
||||||
)
|
)
|
||||||
|
|
||||||
type _D3D12_BLEND_DESC struct {
|
type _D3D12_BLEND_DESC struct {
|
||||||
@ -2429,10 +2448,72 @@ func (i *_IDXGIFactory4) MakeWindowAssociation(windowHandle windows.HWND, flags
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *_IDXGIFactory4) QueryInterface(riid *windows.GUID, ppvObject *unsafe.Pointer) error {
|
||||||
|
r, _, _ := syscall.Syscall(i.vtbl.QueryInterface, 3, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(riid)), uintptr(unsafe.Pointer(ppvObject)))
|
||||||
|
runtime.KeepAlive(riid)
|
||||||
|
runtime.KeepAlive(ppvObject)
|
||||||
|
if uint32(r) != uint32(windows.S_OK) {
|
||||||
|
return fmt.Errorf("directx: IDXGIFactory4::QueryInterface failed: HRESULT(%d)", uint32(r))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (i *_IDXGIFactory4) Release() {
|
func (i *_IDXGIFactory4) Release() {
|
||||||
syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
|
syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type _IDXGIFactory5 struct {
|
||||||
|
vtbl *_IDXGIFactory5_Vtbl
|
||||||
|
}
|
||||||
|
|
||||||
|
type _IDXGIFactory5_Vtbl struct {
|
||||||
|
QueryInterface uintptr
|
||||||
|
AddRef uintptr
|
||||||
|
Release uintptr
|
||||||
|
|
||||||
|
SetPrivateData uintptr
|
||||||
|
SetPrivateDataInterface uintptr
|
||||||
|
GetPrivateData uintptr
|
||||||
|
GetParent uintptr
|
||||||
|
EnumAdapters uintptr
|
||||||
|
MakeWindowAssociation uintptr
|
||||||
|
GetWindowAssociation uintptr
|
||||||
|
CreateSwapChain uintptr
|
||||||
|
CreateSoftwareAdapter uintptr
|
||||||
|
EnumAdapters1 uintptr
|
||||||
|
IsCurrent uintptr
|
||||||
|
IsWindowedStereoEnabled uintptr
|
||||||
|
CreateSwapChainForHwnd uintptr
|
||||||
|
CreateSwapChainForCoreWindow uintptr
|
||||||
|
GetSharedResourceAdapterLuid uintptr
|
||||||
|
RegisterStereoStatusWindow uintptr
|
||||||
|
RegisterStereoStatusEvent uintptr
|
||||||
|
UnregisterStereoStatus uintptr
|
||||||
|
RegisterOcclusionStatusWindow uintptr
|
||||||
|
RegisterOcclusionStatusEvent uintptr
|
||||||
|
UnregisterOcclusionStatus uintptr
|
||||||
|
CreateSwapChainForComposition uintptr
|
||||||
|
GetCreationFlags uintptr
|
||||||
|
EnumAdapterByLuid uintptr
|
||||||
|
EnumWarpAdapter uintptr
|
||||||
|
CheckFeatureSupport uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *_IDXGIFactory5) CheckFeatureSupport(feature _DXGI_FEATURE, pFeatureSupportData unsafe.Pointer, featureSupportDataSize uint32) error {
|
||||||
|
r, _, _ := syscall.Syscall6(i.vtbl.CheckFeatureSupport, 4, uintptr(unsafe.Pointer(i)),
|
||||||
|
uintptr(feature), uintptr(pFeatureSupportData), uintptr(featureSupportDataSize),
|
||||||
|
0, 0)
|
||||||
|
runtime.KeepAlive(pFeatureSupportData)
|
||||||
|
if uint32(r) != uint32(windows.S_OK) {
|
||||||
|
return fmt.Errorf("directx: IDXGIFactory5::CheckFeatureSupport failed: HRESULT(%d)", uint32(r))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *_IDXGIFactory5) Release() {
|
||||||
|
syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
type _IDXGIOutput struct {
|
type _IDXGIOutput struct {
|
||||||
vtbl *_IDXGIOutput_Vtbl
|
vtbl *_IDXGIOutput_Vtbl
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,8 @@ type Graphics struct {
|
|||||||
fenceValues [frameCount]uint64
|
fenceValues [frameCount]uint64
|
||||||
fenceWaitEvent windows.Handle
|
fenceWaitEvent windows.Handle
|
||||||
|
|
||||||
|
allowTearing bool
|
||||||
|
|
||||||
// drawCommandAllocators are command allocators for a 3D engine (DrawIndexedInstanced).
|
// drawCommandAllocators are command allocators for a 3D engine (DrawIndexedInstanced).
|
||||||
// For the word 'engine', see https://docs.microsoft.com/en-us/windows/win32/direct3d12/user-mode-heap-synchronization.
|
// For the word 'engine', see https://docs.microsoft.com/en-us/windows/win32/direct3d12/user-mode-heap-synchronization.
|
||||||
// The term 'draw' is used instead of '3D' in this package.
|
// The term 'draw' is used instead of '3D' in this package.
|
||||||
@ -268,6 +270,15 @@ func (g *Graphics) initializeDesktop(useWARP bool, useDebugLayer bool) (ferr err
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var factory *_IDXGIFactory5
|
||||||
|
if err := g.factory.QueryInterface(&_IID_IDXGIFactory5, (*unsafe.Pointer)(unsafe.Pointer(&factory))); err == nil && factory != nil {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := g.initializeMembers(); err != nil {
|
if err := g.initializeMembers(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -524,7 +535,7 @@ func (g *Graphics) initSwapChainDesktop(width, height int) (ferr error) {
|
|||||||
//
|
//
|
||||||
// IDXGIFactory::CreateSwapChain: Alpha blended swapchains must be created with CreateSwapChainForComposition,
|
// IDXGIFactory::CreateSwapChain: Alpha blended swapchains must be created with CreateSwapChainForComposition,
|
||||||
// or CreateSwapChainForCoreWindow with the DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER flag
|
// or CreateSwapChainForCoreWindow with the DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER flag
|
||||||
s, err := g.factory.CreateSwapChainForHwnd(unsafe.Pointer(g.commandQueue), g.window, &_DXGI_SWAP_CHAIN_DESC1{
|
desc := &_DXGI_SWAP_CHAIN_DESC1{
|
||||||
Width: uint32(width),
|
Width: uint32(width),
|
||||||
Height: uint32(height),
|
Height: uint32(height),
|
||||||
Format: _DXGI_FORMAT_B8G8R8A8_UNORM,
|
Format: _DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
@ -535,7 +546,11 @@ func (g *Graphics) initSwapChainDesktop(width, height int) (ferr error) {
|
|||||||
Count: 1,
|
Count: 1,
|
||||||
Quality: 0,
|
Quality: 0,
|
||||||
},
|
},
|
||||||
}, nil, nil)
|
}
|
||||||
|
if g.allowTearing {
|
||||||
|
desc.Flags |= uint32(_DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING)
|
||||||
|
}
|
||||||
|
s, err := g.factory.CreateSwapChainForHwnd(unsafe.Pointer(g.commandQueue), g.window, desc, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -781,10 +796,13 @@ func (g *Graphics) presentDesktop() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var syncInterval uint32
|
var syncInterval uint32
|
||||||
|
var flags _DXGI_PRESENT
|
||||||
if g.vsyncEnabled {
|
if g.vsyncEnabled {
|
||||||
syncInterval = 1
|
syncInterval = 1
|
||||||
|
} else if g.allowTearing {
|
||||||
|
flags |= _DXGI_PRESENT_ALLOW_TEARING
|
||||||
}
|
}
|
||||||
if err := g.swapChain.Present(syncInterval, 0); err != nil {
|
if err := g.swapChain.Present(syncInterval, uint32(flags)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user