diff --git a/app/internal/d3d11/backend_windows.go b/app/internal/d3d11/backend_windows.go index 0e87ae55..77586c21 100644 --- a/app/internal/d3d11/backend_windows.go +++ b/app/internal/d3d11/backend_windows.go @@ -20,6 +20,7 @@ type Device struct { dev *_ID3D11Device ctx *_ID3D11DeviceContext featLvl uint32 + floatFormat uint32 depthStates map[depthState]*_ID3D11DepthStencilState blendStates map[blendState]*_ID3D11BlendState } @@ -116,8 +117,21 @@ func NewDevice() (*Device, error) { dev := &Device{dev: d3ddev, ctx: d3dctx, featLvl: featLvl} if featLvl < _D3D_FEATURE_LEVEL_9_1 { _IUnknownRelease(unsafe.Pointer(d3ddev), d3ddev.vtbl.Release) + _IUnknownRelease(unsafe.Pointer(d3dctx), d3dctx.vtbl.Release) return nil, fmt.Errorf("d3d11: feature level too low: %d", featLvl) } + format := uint32(_DXGI_FORMAT_R16_FLOAT) + need := uint32(_D3D11_FORMAT_SUPPORT_TEXTURE2D | _D3D11_FORMAT_SUPPORT_RENDER_TARGET) + if use, _ := d3ddev.CheckFormatSupport(format); use&need == 0 { + // Fall back to a d3d 9.2 format. + format = _DXGI_FORMAT_R32_FLOAT + if use, _ = d3ddev.CheckFormatSupport(format); use&need == 0 { + _IUnknownRelease(unsafe.Pointer(d3ddev), d3ddev.vtbl.Release) + _IUnknownRelease(unsafe.Pointer(d3dctx), d3dctx.vtbl.Release) + return nil, fmt.Errorf("d3d11: no available floating point formats") + } + } + dev.floatFormat = format dev.depthStates = make(map[depthState]*_ID3D11DepthStencilState) dev.blendStates = make(map[blendState]*_ID3D11BlendState) return dev, nil @@ -257,7 +271,7 @@ func (b *Backend) NewTexture(format backend.TextureFormat, width, height int, mi var d3dfmt uint32 switch format { case backend.TextureFormatFloat: - d3dfmt = _DXGI_FORMAT_R16_FLOAT + d3dfmt = b.dev.floatFormat case backend.TextureFormatSRGB: d3dfmt = _DXGI_FORMAT_R8G8B8A8_UNORM_SRGB default: diff --git a/app/internal/d3d11/d3d11_windows.go b/app/internal/d3d11/d3d11_windows.go index a12750c9..0ac17c6d 100644 --- a/app/internal/d3d11/d3d11_windows.go +++ b/app/internal/d3d11/d3d11_windows.go @@ -565,6 +565,11 @@ const ( _DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29 _DXGI_FORMAT_R16_SINT = 59 _DXGI_FORMAT_R16G16_SINT = 38 + _DXGI_FORMAT_R16_UINT = 57 + _DXGI_FORMAT_D24_UNORM_S8_UINT = 45 + + _D3D11_FORMAT_SUPPORT_TEXTURE2D = 0x20 + _D3D11_FORMAT_SUPPORT_RENDER_TARGET = 0x4000 _DXGI_USAGE_RENDER_TARGET_OUTPUT = 1 << (1 + 4) @@ -574,8 +579,6 @@ const ( _DXGI_SWAP_EFFECT_DISCARD = 0 - _DXGI_FORMAT_R16_UINT = 57 - _D3D_FEATURE_LEVEL_9_1 = 0x9100 _D3D_FEATURE_LEVEL_9_3 = 0x9300 _D3D_FEATURE_LEVEL_11_0 = 0xb000 @@ -611,8 +614,6 @@ const ( _D3D11_CLEAR_DEPTH = 0x1 _D3D11_CLEAR_STENCIL = 0x2 - _DXGI_FORMAT_D24_UNORM_S8_UINT = 45 - _D3D11_DSV_DIMENSION_TEXTURE2D = 3 _D3D11_DEPTH_WRITE_MASK_ALL = 1 @@ -685,6 +686,21 @@ func _D3D11CreateDeviceAndSwapChain(driverType uint32, flags uint32, swapDesc *_ return dev, ctx, swchain, featLvl, nil } +func (d *_ID3D11Device) CheckFormatSupport(format uint32) (uint32, error) { + var support uint32 + r, _, _ := syscall.Syscall( + d.vtbl.CheckFormatSupport, + 3, + uintptr(unsafe.Pointer(d)), + uintptr(format), + uintptr(unsafe.Pointer(&support)), + ) + if r != 0 { + return 0, ErrorCode{Name: "ID3D11DeviceCheckFormatSupport", Code: uint32(r)} + } + return support, nil +} + func (d *_ID3D11Device) CreateBuffer(desc *_D3D11_BUFFER_DESC, data []byte) (*_ID3D11Buffer, error) { var dataDesc *_D3D11_SUBRESOURCE_DATA if len(data) > 0 {