mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +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
|
||||
}
|
||||
|
||||
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 {
|
||||
vtbl *_ID3D11DeviceContext_Vtbl
|
||||
}
|
||||
|
@ -190,6 +190,16 @@ func (i *_IDXGIAdapter) EnumOutputs(output uint32) (*_IDXGIOutput, error) {
|
||||
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 {
|
||||
r, _, _ := syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
|
||||
return uint32(r)
|
||||
|
@ -154,18 +154,6 @@ func newGraphics11(useWARP bool, useDebugLayer bool) (gr11 *graphics11, ferr err
|
||||
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
|
||||
if useWARP {
|
||||
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.
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
g.device = (*_ID3D11Device)(d)
|
||||
g.featureLevel = f
|
||||
g.featureLevel = fl
|
||||
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)
|
||||
|
||||
// Set the rasterizer state.
|
||||
|
@ -148,7 +148,11 @@ func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, feature
|
||||
g.debug.EnableDebugLayer()
|
||||
}
|
||||
|
||||
gi, err := newGraphicsInfra()
|
||||
f, err := _CreateDXGIFactory()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gi, err := newGraphicsInfra(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -159,14 +159,10 @@ type graphicsInfra struct {
|
||||
bufferCount int
|
||||
}
|
||||
|
||||
func newGraphicsInfra() (*graphicsInfra, error) {
|
||||
f, err := _CreateDXGIFactory()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// newGraphicsInfra takes the ownership of the given factory.
|
||||
func newGraphicsInfra(factory *_IDXGIFactory) (*graphicsInfra, error) {
|
||||
g := &graphicsInfra{
|
||||
factory: f,
|
||||
factory: factory,
|
||||
}
|
||||
runtime.SetFinalizer(g, (*graphicsInfra).release)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user