mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
internal/graphicsdriver/directx: bug fix: use an associated IDXGIFactory
In DirectX 11, if a device and a factory are independently created, some functions like MakeWindowAssociation doe't work well. This change fixes the issue by getting a factory from a device and using it. Closes #2661
This commit is contained in:
parent
b32258ab8c
commit
d16b591a35
@ -821,6 +821,16 @@ func (i *_ID3D11Device) CreateVertexShader(pShaderBytecode unsafe.Pointer, bytec
|
|||||||
return vertexShader, nil
|
return vertexShader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *_ID3D11Device) QueryInterface(riid *windows.GUID) (unsafe.Pointer, error) {
|
||||||
|
var v unsafe.Pointer
|
||||||
|
r, _, _ := syscall.Syscall(i.vtbl.QueryInterface, 3, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(riid)), uintptr(unsafe.Pointer(&v)))
|
||||||
|
runtime.KeepAlive(riid)
|
||||||
|
if uint32(r) != uint32(windows.S_OK) {
|
||||||
|
return nil, fmt.Errorf("directx: ID3D11Device::QueryInterface failed: %w", handleError(windows.Handle(uint32(r))))
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
type _ID3D11DeviceContext struct {
|
type _ID3D11DeviceContext struct {
|
||||||
vtbl *_ID3D11DeviceContext_Vtbl
|
vtbl *_ID3D11DeviceContext_Vtbl
|
||||||
}
|
}
|
||||||
|
@ -190,6 +190,16 @@ func (i *_IDXGIAdapter) EnumOutputs(output uint32) (*_IDXGIOutput, error) {
|
|||||||
return pOutput, nil
|
return pOutput, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *_IDXGIAdapter) GetParent(riid *windows.GUID) (unsafe.Pointer, error) {
|
||||||
|
var v unsafe.Pointer
|
||||||
|
r, _, _ := syscall.Syscall(i.vtbl.GetParent, 3, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(riid)), uintptr(unsafe.Pointer(&v)))
|
||||||
|
runtime.KeepAlive(riid)
|
||||||
|
if uint32(r) != uint32(windows.S_OK) {
|
||||||
|
return nil, fmt.Errorf("directx: IDXGIAdapter::GetParent failed: %w", handleError(windows.Handle(uint32(r))))
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (i *_IDXGIAdapter) Release() uint32 {
|
func (i *_IDXGIAdapter) Release() uint32 {
|
||||||
r, _, _ := syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
|
r, _, _ := syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
|
||||||
return uint32(r)
|
return uint32(r)
|
||||||
|
@ -154,18 +154,6 @@ func newGraphics11(useWARP bool, useDebugLayer bool) (gr11 *graphics11, ferr err
|
|||||||
vsyncEnabled: true,
|
vsyncEnabled: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
gi, err := newGraphicsInfra()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
g.graphicsInfra = gi
|
|
||||||
defer func() {
|
|
||||||
if ferr != nil {
|
|
||||||
g.graphicsInfra.release()
|
|
||||||
g.graphicsInfra = nil
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
driverType := _D3D_DRIVER_TYPE_HARDWARE
|
driverType := _D3D_DRIVER_TYPE_HARDWARE
|
||||||
if useWARP {
|
if useWARP {
|
||||||
driverType = _D3D_DRIVER_TYPE_WARP
|
driverType = _D3D_DRIVER_TYPE_WARP
|
||||||
@ -186,14 +174,47 @@ func newGraphics11(useWARP bool, useDebugLayer bool) (gr11 *graphics11, ferr err
|
|||||||
|
|
||||||
// Apparently, adapter must be nil if the driver type is not unknown. This is not documented explicitly.
|
// Apparently, adapter must be nil if the driver type is not unknown. This is not documented explicitly.
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-d3d11createdevice
|
// https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-d3d11createdevice
|
||||||
d, f, ctx, err := _D3D11CreateDevice(nil, driverType, 0, uint32(flags), featureLevels, true, true)
|
d, fl, ctx, err := _D3D11CreateDevice(nil, driverType, 0, uint32(flags), featureLevels, true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
g.device = (*_ID3D11Device)(d)
|
g.device = (*_ID3D11Device)(d)
|
||||||
g.featureLevel = f
|
g.featureLevel = fl
|
||||||
g.deviceContext = (*_ID3D11DeviceContext)(ctx)
|
g.deviceContext = (*_ID3D11DeviceContext)(ctx)
|
||||||
|
|
||||||
|
// Get IDXGIFactory from the current device and use it, instead of CreateDXGIFactory.
|
||||||
|
// Or, MakeWindowAssociation doesn't work well (#2661).
|
||||||
|
dd, err := g.device.QueryInterface(&_IID_IDXGIDevice)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dxgiDevice := (*_IDXGIDevice)(dd)
|
||||||
|
defer dxgiDevice.Release()
|
||||||
|
|
||||||
|
dxgiAdapter, err := dxgiDevice.GetAdapter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer dxgiAdapter.Release()
|
||||||
|
|
||||||
|
df, err := dxgiAdapter.GetParent(&_IID_IDXGIFactory)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dxgiFactory := (*_IDXGIFactory)(df)
|
||||||
|
|
||||||
|
gi, err := newGraphicsInfra(dxgiFactory)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
g.graphicsInfra = gi
|
||||||
|
defer func() {
|
||||||
|
if ferr != nil {
|
||||||
|
g.graphicsInfra.release()
|
||||||
|
g.graphicsInfra = nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
g.deviceContext.IASetPrimitiveTopology(_D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
|
g.deviceContext.IASetPrimitiveTopology(_D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
|
||||||
|
|
||||||
// Set the rasterizer state.
|
// Set the rasterizer state.
|
||||||
|
@ -148,7 +148,11 @@ func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, feature
|
|||||||
g.debug.EnableDebugLayer()
|
g.debug.EnableDebugLayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
gi, err := newGraphicsInfra()
|
f, err := _CreateDXGIFactory()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gi, err := newGraphicsInfra(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -159,14 +159,10 @@ type graphicsInfra struct {
|
|||||||
bufferCount int
|
bufferCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGraphicsInfra() (*graphicsInfra, error) {
|
// newGraphicsInfra takes the ownership of the given factory.
|
||||||
f, err := _CreateDXGIFactory()
|
func newGraphicsInfra(factory *_IDXGIFactory) (*graphicsInfra, error) {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
g := &graphicsInfra{
|
g := &graphicsInfra{
|
||||||
factory: f,
|
factory: factory,
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(g, (*graphicsInfra).release)
|
runtime.SetFinalizer(g, (*graphicsInfra).release)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user