2018-01-31 01:57:43 +01:00
# include <algorithm>
2017-10-11 09:51:48 +02:00
# include <cstring>
2019-02-11 19:48:47 +01:00
# include "../dxgi/dxgi_monitor.h"
2018-12-21 12:23:45 +01:00
# include "../dxgi/dxgi_swapchain.h"
2018-08-07 14:58:08 +02:00
# include "../dxvk/dxvk_adapter.h"
# include "../dxvk/dxvk_instance.h"
2017-10-15 21:38:09 +02:00
# include "d3d11_buffer.h"
2017-12-12 01:07:07 +01:00
# include "d3d11_class_linkage.h"
2018-01-23 09:23:31 +01:00
# include "d3d11_context_def.h"
2018-01-20 13:22:44 +01:00
# include "d3d11_context_imm.h"
2017-10-11 09:51:48 +02:00
# include "d3d11_device.h"
2021-10-22 17:22:41 +02:00
# include "d3d11_fence.h"
2017-12-07 12:45:02 +01:00
# include "d3d11_input_layout.h"
2018-04-20 00:19:03 +02:00
# include "d3d11_interop.h"
2017-12-29 22:20:31 +01:00
# include "d3d11_query.h"
2018-08-05 18:56:42 +02:00
# include "d3d11_resource.h"
2017-12-09 20:49:56 +01:00
# include "d3d11_sampler.h"
2020-07-18 00:10:31 +02:00
# include "d3d11_shader.h"
2019-05-03 16:41:16 +02:00
# include "d3d11_state_object.h"
2019-02-11 19:57:26 +01:00
# include "d3d11_swapchain.h"
2017-11-29 07:55:44 +01:00
# include "d3d11_texture.h"
2021-05-04 16:50:23 +02:00
# include "d3d11_video.h"
2017-10-11 09:51:48 +02:00
2022-08-09 13:06:48 +01:00
# include "../wsi/wsi_window.h"
2022-02-23 16:18:07 -05:00
# include "../util/util_shared_res.h"
2017-10-11 09:51:48 +02:00
namespace dxvk {
2018-12-03 19:26:29 +01:00
constexpr uint32_t D3D11DXGIDevice : : DefaultFrameLatency ;
2018-11-29 20:13:36 +01:00
2018-03-28 21:24:52 +02:00
2017-10-11 09:51:48 +02:00
D3D11Device : : D3D11Device (
2018-12-03 19:26:29 +01:00
D3D11DXGIDevice * pContainer ,
2018-03-28 21:24:52 +02:00
D3D_FEATURE_LEVEL FeatureLevel ,
UINT FeatureFlags )
: m_container ( pContainer ) ,
m_featureLevel ( FeatureLevel ) ,
m_featureFlags ( FeatureFlags ) ,
2018-12-03 19:26:29 +01:00
m_dxvkDevice ( pContainer - > GetDXVKDevice ( ) ) ,
2018-01-07 20:05:27 +01:00
m_dxvkAdapter ( m_dxvkDevice - > adapter ( ) ) ,
2022-08-17 15:06:36 +02:00
m_d3d11Formats ( m_dxvkDevice ) ,
2019-11-08 11:25:58 +01:00
m_d3d11Options ( m_dxvkDevice - > instance ( ) - > config ( ) , m_dxvkDevice ) ,
2019-10-27 11:00:59 +01:00
m_dxbcOptions ( m_dxvkDevice , m_d3d11Options ) {
2019-03-26 17:49:14 +01:00
m_initializer = new D3D11Initializer ( this ) ;
2018-08-11 16:36:54 +02:00
m_context = new D3D11ImmediateContext ( this , m_dxvkDevice ) ;
2021-01-07 20:08:55 +00:00
m_d3d10Device = new D3D10Device ( this , m_context . ptr ( ) ) ;
2017-10-11 09:51:48 +02:00
}
D3D11Device : : ~ D3D11Device ( ) {
2018-08-11 16:36:54 +02:00
delete m_d3d10Device ;
2021-01-07 20:08:55 +00:00
m_context = nullptr ;
2018-07-23 15:21:17 +02:00
delete m_initializer ;
2017-10-11 09:51:48 +02:00
}
2018-03-28 21:24:52 +02:00
ULONG STDMETHODCALLTYPE D3D11Device : : AddRef ( ) {
return m_container - > AddRef ( ) ;
}
ULONG STDMETHODCALLTYPE D3D11Device : : Release ( ) {
return m_container - > Release ( ) ;
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : QueryInterface ( REFIID riid , void * * ppvObject ) {
2018-03-28 21:24:52 +02:00
return m_container - > QueryInterface ( riid , ppvObject ) ;
2017-10-11 09:51:48 +02:00
}
2017-10-11 15:32:24 +02:00
2017-10-11 09:51:48 +02:00
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateBuffer (
2017-10-11 09:51:48 +02:00
const D3D11_BUFFER_DESC * pDesc ,
const D3D11_SUBRESOURCE_DATA * pInitialData ,
ID3D11Buffer * * ppBuffer ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppBuffer ) ;
2019-09-16 16:04:06 +02:00
if ( ! pDesc )
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2019-06-13 03:06:11 +02:00
2019-10-11 17:23:02 +02:00
D3D11_BUFFER_DESC desc = * pDesc ;
HRESULT hr = D3D11Buffer : : NormalizeBufferProperties ( & desc ) ;
2019-09-16 16:04:06 +02:00
if ( FAILED ( hr ) )
return hr ;
2019-02-27 20:21:52 +00:00
2019-09-16 16:04:06 +02:00
if ( ! ppBuffer )
2018-02-27 08:54:24 +01:00
return S_FALSE ;
try {
2019-10-11 17:23:02 +02:00
const Com < D3D11Buffer > buffer = new D3D11Buffer ( this , & desc ) ;
2018-07-23 15:21:17 +02:00
m_initializer - > InitBuffer ( buffer . ptr ( ) , pInitialData ) ;
2017-12-14 15:59:55 +01:00
* ppBuffer = buffer . ref ( ) ;
2018-02-27 08:54:24 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-07 13:17:16 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateTexture1D (
2017-10-11 09:51:48 +02:00
const D3D11_TEXTURE1D_DESC * pDesc ,
const D3D11_SUBRESOURCE_DATA * pInitialData ,
ID3D11Texture1D * * ppTexture1D ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppTexture1D ) ;
2019-02-27 20:21:52 +00:00
2019-09-16 16:04:06 +02:00
if ( ! pDesc )
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2018-03-13 23:51:30 +01:00
D3D11_COMMON_TEXTURE_DESC desc ;
desc . Width = pDesc - > Width ;
desc . Height = 1 ;
desc . Depth = 1 ;
desc . MipLevels = pDesc - > MipLevels ;
desc . ArraySize = pDesc - > ArraySize ;
desc . Format = pDesc - > Format ;
desc . SampleDesc = DXGI_SAMPLE_DESC { 1 , 0 } ;
desc . Usage = pDesc - > Usage ;
desc . BindFlags = pDesc - > BindFlags ;
desc . CPUAccessFlags = pDesc - > CPUAccessFlags ;
desc . MiscFlags = pDesc - > MiscFlags ;
2019-09-16 13:50:39 +02:00
desc . TextureLayout = D3D11_TEXTURE_LAYOUT_UNDEFINED ;
2018-03-13 23:51:30 +01:00
2019-09-16 16:04:06 +02:00
HRESULT hr = D3D11CommonTexture : : NormalizeTextureProperties ( & desc ) ;
if ( FAILED ( hr ) )
return hr ;
2018-03-13 23:51:30 +01:00
2019-09-16 16:04:06 +02:00
if ( ! ppTexture1D )
2018-02-27 08:54:24 +01:00
return S_FALSE ;
try {
2018-03-14 00:45:07 +01:00
const Com < D3D11Texture1D > texture = new D3D11Texture1D ( this , & desc ) ;
2018-07-23 15:21:17 +02:00
m_initializer - > InitTexture ( texture - > GetCommonTexture ( ) , pInitialData ) ;
2017-12-23 17:05:07 +01:00
* ppTexture1D = texture . ref ( ) ;
2018-02-27 08:54:24 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-23 17:05:07 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateTexture2D (
2017-10-11 09:51:48 +02:00
const D3D11_TEXTURE2D_DESC * pDesc ,
const D3D11_SUBRESOURCE_DATA * pInitialData ,
ID3D11Texture2D * * ppTexture2D ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppTexture2D ) ;
2019-02-27 20:21:52 +00:00
2019-09-16 16:04:06 +02:00
if ( ! pDesc )
return E_INVALIDARG ;
D3D11_TEXTURE2D_DESC1 desc ;
desc . Width = pDesc - > Width ;
desc . Height = pDesc - > Height ;
desc . MipLevels = pDesc - > MipLevels ;
desc . ArraySize = pDesc - > ArraySize ;
desc . Format = pDesc - > Format ;
desc . SampleDesc = pDesc - > SampleDesc ;
desc . Usage = pDesc - > Usage ;
desc . BindFlags = pDesc - > BindFlags ;
desc . CPUAccessFlags = pDesc - > CPUAccessFlags ;
desc . MiscFlags = pDesc - > MiscFlags ;
desc . TextureLayout = D3D11_TEXTURE_LAYOUT_UNDEFINED ;
ID3D11Texture2D1 * texture2D = nullptr ;
HRESULT hr = CreateTexture2D1 ( & desc , pInitialData , ppTexture2D ? & texture2D : nullptr ) ;
if ( hr ! = S_OK )
return hr ;
* ppTexture2D = texture2D ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateTexture2D1 (
const D3D11_TEXTURE2D_DESC1 * pDesc ,
const D3D11_SUBRESOURCE_DATA * pInitialData ,
ID3D11Texture2D1 * * ppTexture2D ) {
InitReturnPtr ( ppTexture2D ) ;
if ( ! pDesc )
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2018-03-13 23:51:30 +01:00
D3D11_COMMON_TEXTURE_DESC desc ;
desc . Width = pDesc - > Width ;
desc . Height = pDesc - > Height ;
desc . Depth = 1 ;
desc . MipLevels = pDesc - > MipLevels ;
desc . ArraySize = pDesc - > ArraySize ;
desc . Format = pDesc - > Format ;
desc . SampleDesc = pDesc - > SampleDesc ;
desc . Usage = pDesc - > Usage ;
desc . BindFlags = pDesc - > BindFlags ;
desc . CPUAccessFlags = pDesc - > CPUAccessFlags ;
desc . MiscFlags = pDesc - > MiscFlags ;
2019-09-16 16:04:06 +02:00
desc . TextureLayout = pDesc - > TextureLayout ;
2018-03-13 23:51:30 +01:00
2019-09-16 16:04:06 +02:00
HRESULT hr = D3D11CommonTexture : : NormalizeTextureProperties ( & desc ) ;
if ( FAILED ( hr ) )
return hr ;
2018-03-13 23:51:30 +01:00
2019-09-16 16:04:06 +02:00
if ( ! ppTexture2D )
2018-02-27 08:54:24 +01:00
return S_FALSE ;
try {
2022-02-23 16:18:07 -05:00
Com < D3D11Texture2D > texture = new D3D11Texture2D ( this , & desc , nullptr ) ;
2018-07-23 15:21:17 +02:00
m_initializer - > InitTexture ( texture - > GetCommonTexture ( ) , pInitialData ) ;
2017-12-19 16:01:50 +01:00
* ppTexture2D = texture . ref ( ) ;
2018-02-27 08:54:24 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-08 23:13:15 +01:00
}
2017-10-11 09:51:48 +02:00
}
2019-09-16 16:04:06 +02:00
2017-10-11 09:51:48 +02:00
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateTexture3D (
2017-10-11 09:51:48 +02:00
const D3D11_TEXTURE3D_DESC * pDesc ,
const D3D11_SUBRESOURCE_DATA * pInitialData ,
ID3D11Texture3D * * ppTexture3D ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppTexture3D ) ;
2019-02-27 20:21:52 +00:00
2019-09-16 16:04:06 +02:00
if ( ! pDesc )
return E_INVALIDARG ;
D3D11_TEXTURE3D_DESC1 desc ;
desc . Width = pDesc - > Width ;
desc . Height = pDesc - > Height ;
desc . Depth = pDesc - > Depth ;
desc . MipLevels = pDesc - > MipLevels ;
desc . Format = pDesc - > Format ;
desc . Usage = pDesc - > Usage ;
desc . BindFlags = pDesc - > BindFlags ;
desc . CPUAccessFlags = pDesc - > CPUAccessFlags ;
desc . MiscFlags = pDesc - > MiscFlags ;
desc . TextureLayout = D3D11_TEXTURE_LAYOUT_UNDEFINED ;
ID3D11Texture3D1 * texture3D = nullptr ;
HRESULT hr = CreateTexture3D1 ( & desc , pInitialData , ppTexture3D ? & texture3D : nullptr ) ;
if ( hr ! = S_OK )
return hr ;
* ppTexture3D = texture3D ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateTexture3D1 (
const D3D11_TEXTURE3D_DESC1 * pDesc ,
const D3D11_SUBRESOURCE_DATA * pInitialData ,
ID3D11Texture3D1 * * ppTexture3D ) {
InitReturnPtr ( ppTexture3D ) ;
if ( ! pDesc )
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2018-03-13 23:51:30 +01:00
D3D11_COMMON_TEXTURE_DESC desc ;
desc . Width = pDesc - > Width ;
desc . Height = pDesc - > Height ;
desc . Depth = pDesc - > Depth ;
desc . MipLevels = pDesc - > MipLevels ;
desc . ArraySize = 1 ;
desc . Format = pDesc - > Format ;
desc . SampleDesc = DXGI_SAMPLE_DESC { 1 , 0 } ;
desc . Usage = pDesc - > Usage ;
desc . BindFlags = pDesc - > BindFlags ;
desc . CPUAccessFlags = pDesc - > CPUAccessFlags ;
desc . MiscFlags = pDesc - > MiscFlags ;
2019-09-16 16:04:06 +02:00
desc . TextureLayout = pDesc - > TextureLayout ;
2018-03-13 23:51:30 +01:00
2019-09-16 16:04:06 +02:00
HRESULT hr = D3D11CommonTexture : : NormalizeTextureProperties ( & desc ) ;
if ( FAILED ( hr ) )
return hr ;
2018-03-13 23:51:30 +01:00
2019-09-16 16:04:06 +02:00
if ( ! ppTexture3D )
2018-02-27 08:54:24 +01:00
return S_FALSE ;
try {
2019-09-16 16:04:06 +02:00
Com < D3D11Texture3D > texture = new D3D11Texture3D ( this , & desc ) ;
2018-07-23 15:21:17 +02:00
m_initializer - > InitTexture ( texture - > GetCommonTexture ( ) , pInitialData ) ;
2017-12-23 17:05:07 +01:00
* ppTexture3D = texture . ref ( ) ;
2018-02-27 08:54:24 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-23 17:05:07 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateShaderResourceView (
2017-10-11 09:51:48 +02:00
ID3D11Resource * pResource ,
const D3D11_SHADER_RESOURCE_VIEW_DESC * pDesc ,
ID3D11ShaderResourceView * * ppSRView ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppSRView ) ;
2018-08-10 02:15:51 +02:00
2021-05-20 16:50:15 +02:00
uint32_t plane = GetViewPlaneIndex ( pResource , pDesc ? pDesc - > Format : DXGI_FORMAT_UNKNOWN ) ;
2019-09-16 16:04:06 +02:00
D3D11_SHADER_RESOURCE_VIEW_DESC1 desc = pDesc
2021-05-20 16:50:15 +02:00
? D3D11ShaderResourceView : : PromoteDesc ( pDesc , plane )
2019-09-16 16:04:06 +02:00
: D3D11_SHADER_RESOURCE_VIEW_DESC1 ( ) ;
ID3D11ShaderResourceView1 * view = nullptr ;
HRESULT hr = CreateShaderResourceView1 ( pResource ,
pDesc ? & desc : nullptr ,
ppSRView ? & view : nullptr ) ;
if ( hr ! = S_OK )
return hr ;
* ppSRView = view ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateShaderResourceView1 (
ID3D11Resource * pResource ,
const D3D11_SHADER_RESOURCE_VIEW_DESC1 * pDesc ,
ID3D11ShaderResourceView1 * * ppSRView ) {
InitReturnPtr ( ppSRView ) ;
if ( ! pResource )
2018-09-19 11:55:11 +02:00
return E_INVALIDARG ;
2018-08-10 02:15:51 +02:00
D3D11_COMMON_RESOURCE_DESC resourceDesc ;
GetCommonResourceDesc ( pResource , & resourceDesc ) ;
2018-04-02 12:04:20 +02:00
2017-12-09 19:36:38 +01:00
// The description is optional. If omitted, we'll create
// a view that covers all subresources of the image.
2019-09-16 14:24:46 +02:00
D3D11_SHADER_RESOURCE_VIEW_DESC1 desc ;
2017-12-09 15:57:05 +01:00
2019-09-16 16:04:06 +02:00
if ( ! pDesc ) {
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11ShaderResourceView : : GetDescFromResource ( pResource , & desc ) ) )
2017-12-09 19:06:51 +01:00
return E_INVALIDARG ;
} else {
2019-09-16 16:04:06 +02:00
desc = * pDesc ;
2018-01-17 15:19:55 +01:00
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11ShaderResourceView : : NormalizeDesc ( pResource , & desc ) ) )
2018-01-17 15:19:55 +01:00
return E_INVALIDARG ;
2017-12-09 19:06:51 +01:00
}
2021-05-20 16:50:15 +02:00
uint32_t plane = D3D11ShaderResourceView : : GetPlaneSlice ( & desc ) ;
2017-12-09 19:06:51 +01:00
2021-05-20 16:50:15 +02:00
if ( ! CheckResourceViewCompatibility ( pResource , D3D11_BIND_SHADER_RESOURCE , desc . Format , plane ) ) {
2018-08-10 02:15:51 +02:00
Logger : : err ( str : : format ( " D3D11: Cannot create shader resource view: " ,
" \n Resource type: " , resourceDesc . Dim ,
2018-08-10 02:39:14 +02:00
" \n Resource usage: " , resourceDesc . BindFlags ,
2018-08-10 02:15:51 +02:00
" \n Resource format: " , resourceDesc . Format ,
2021-05-20 16:50:15 +02:00
" \n View format: " , desc . Format ,
" \n View plane: " , plane ) ) ;
2018-08-05 18:56:42 +02:00
return E_INVALIDARG ;
2018-08-10 02:15:51 +02:00
}
2018-08-05 18:56:42 +02:00
2019-09-16 16:04:06 +02:00
if ( ! ppSRView )
2018-08-05 19:20:12 +02:00
return S_FALSE ;
try {
* ppSRView = ref ( new D3D11ShaderResourceView ( this , pResource , & desc ) ) ;
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-09 19:06:51 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateUnorderedAccessView (
2017-10-11 09:51:48 +02:00
ID3D11Resource * pResource ,
const D3D11_UNORDERED_ACCESS_VIEW_DESC * pDesc ,
ID3D11UnorderedAccessView * * ppUAView ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppUAView ) ;
2019-09-16 16:04:06 +02:00
2021-05-28 16:20:24 +02:00
uint32_t plane = GetViewPlaneIndex ( pResource , pDesc ? pDesc - > Format : DXGI_FORMAT_UNKNOWN ) ;
2019-09-16 16:04:06 +02:00
D3D11_UNORDERED_ACCESS_VIEW_DESC1 desc = pDesc
2021-05-28 16:20:24 +02:00
? D3D11UnorderedAccessView : : PromoteDesc ( pDesc , plane )
2019-09-16 16:04:06 +02:00
: D3D11_UNORDERED_ACCESS_VIEW_DESC1 ( ) ;
2018-04-02 12:04:20 +02:00
2019-09-16 16:04:06 +02:00
ID3D11UnorderedAccessView1 * view = nullptr ;
HRESULT hr = CreateUnorderedAccessView1 ( pResource ,
pDesc ? & desc : nullptr ,
ppUAView ? & view : nullptr ) ;
if ( hr ! = S_OK )
return hr ;
* ppUAView = view ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateUnorderedAccessView1 (
ID3D11Resource * pResource ,
const D3D11_UNORDERED_ACCESS_VIEW_DESC1 * pDesc ,
ID3D11UnorderedAccessView1 * * ppUAView ) {
InitReturnPtr ( ppUAView ) ;
if ( ! pResource )
2018-09-19 11:55:11 +02:00
return E_INVALIDARG ;
2018-08-10 02:15:51 +02:00
D3D11_COMMON_RESOURCE_DESC resourceDesc ;
GetCommonResourceDesc ( pResource , & resourceDesc ) ;
2017-12-28 19:05:53 +01:00
// The description is optional. If omitted, we'll create
// a view that covers all subresources of the image.
2019-09-16 14:37:33 +02:00
D3D11_UNORDERED_ACCESS_VIEW_DESC1 desc ;
2017-12-28 19:05:53 +01:00
2019-09-16 16:04:06 +02:00
if ( ! pDesc ) {
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11UnorderedAccessView : : GetDescFromResource ( pResource , & desc ) ) )
2017-12-28 19:05:53 +01:00
return E_INVALIDARG ;
} else {
2019-09-16 16:04:06 +02:00
desc = * pDesc ;
2018-01-28 11:30:15 +01:00
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11UnorderedAccessView : : NormalizeDesc ( pResource , & desc ) ) )
2018-01-28 11:30:15 +01:00
return E_INVALIDARG ;
2017-12-28 19:05:53 +01:00
}
2021-05-28 16:20:24 +02:00
uint32_t plane = D3D11UnorderedAccessView : : GetPlaneSlice ( & desc ) ;
if ( ! CheckResourceViewCompatibility ( pResource , D3D11_BIND_UNORDERED_ACCESS , desc . Format , plane ) ) {
2018-08-10 02:15:51 +02:00
Logger : : err ( str : : format ( " D3D11: Cannot create unordered access view: " ,
" \n Resource type: " , resourceDesc . Dim ,
2018-08-10 02:39:14 +02:00
" \n Resource usage: " , resourceDesc . BindFlags ,
2018-08-10 02:15:51 +02:00
" \n Resource format: " , resourceDesc . Format ,
2021-05-28 16:20:24 +02:00
" \n View format: " , desc . Format ,
" \n View plane: " , plane ) ) ;
2018-08-05 18:56:42 +02:00
return E_INVALIDARG ;
2018-08-10 02:15:51 +02:00
}
2018-08-05 19:28:39 +02:00
2019-09-16 16:04:06 +02:00
if ( ! ppUAView )
2018-08-05 19:28:39 +02:00
return S_FALSE ;
2018-08-05 18:56:42 +02:00
2018-08-05 19:28:39 +02:00
try {
2019-11-18 18:38:27 +01:00
auto uav = new D3D11UnorderedAccessView ( this , pResource , & desc ) ;
m_initializer - > InitUavCounter ( uav ) ;
* ppUAView = ref ( uav ) ;
2018-08-05 19:28:39 +02:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-28 19:05:53 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateRenderTargetView (
2017-10-11 09:51:48 +02:00
ID3D11Resource * pResource ,
const D3D11_RENDER_TARGET_VIEW_DESC * pDesc ,
ID3D11RenderTargetView * * ppRTView ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppRTView ) ;
2018-09-19 11:55:11 +02:00
2021-05-28 17:28:30 +02:00
uint32_t plane = GetViewPlaneIndex ( pResource , pDesc ? pDesc - > Format : DXGI_FORMAT_UNKNOWN ) ;
2019-09-16 16:04:06 +02:00
D3D11_RENDER_TARGET_VIEW_DESC1 desc = pDesc
2021-05-28 17:28:30 +02:00
? D3D11RenderTargetView : : PromoteDesc ( pDesc , plane )
2019-09-16 16:04:06 +02:00
: D3D11_RENDER_TARGET_VIEW_DESC1 ( ) ;
ID3D11RenderTargetView1 * view = nullptr ;
HRESULT hr = CreateRenderTargetView1 ( pResource ,
pDesc ? & desc : nullptr ,
ppRTView ? & view : nullptr ) ;
if ( hr ! = S_OK )
return hr ;
* ppRTView = view ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateRenderTargetView1 (
ID3D11Resource * pResource ,
const D3D11_RENDER_TARGET_VIEW_DESC1 * pDesc ,
ID3D11RenderTargetView1 * * ppRTView ) {
InitReturnPtr ( ppRTView ) ;
if ( ! pResource )
2018-09-19 11:55:11 +02:00
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2018-03-18 21:38:48 +01:00
// DXVK only supports render target views for image resources
2018-09-19 11:55:11 +02:00
D3D11_COMMON_RESOURCE_DESC resourceDesc ;
GetCommonResourceDesc ( pResource , & resourceDesc ) ;
2017-11-29 15:16:07 +01:00
2018-09-19 11:55:11 +02:00
if ( resourceDesc . Dim = = D3D11_RESOURCE_DIMENSION_BUFFER ) {
2018-03-31 21:47:54 +02:00
Logger : : warn ( " D3D11: Cannot create render target view for a buffer " ) ;
return S_OK ; // It is required to run Battlefield 3 and Battlefield 4.
2018-03-18 21:38:48 +01:00
}
2017-11-29 20:19:40 +01:00
// The view description is optional. If not defined, it
2017-12-08 23:25:38 +01:00
// will use the resource's format and all array layers.
2019-09-16 14:12:14 +02:00
D3D11_RENDER_TARGET_VIEW_DESC1 desc ;
2017-11-29 20:19:40 +01:00
2019-09-16 16:04:06 +02:00
if ( ! pDesc ) {
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11RenderTargetView : : GetDescFromResource ( pResource , & desc ) ) )
2017-12-09 19:36:38 +01:00
return E_INVALIDARG ;
2017-11-29 20:19:40 +01:00
} else {
2019-09-16 16:04:06 +02:00
desc = * pDesc ;
2018-02-14 01:29:50 +01:00
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11RenderTargetView : : NormalizeDesc ( pResource , & desc ) ) )
2018-02-14 01:29:50 +01:00
return E_INVALIDARG ;
2017-11-29 20:19:40 +01:00
}
2021-05-28 17:28:30 +02:00
uint32_t plane = D3D11RenderTargetView : : GetPlaneSlice ( & desc ) ;
if ( ! CheckResourceViewCompatibility ( pResource , D3D11_BIND_RENDER_TARGET , desc . Format , plane ) ) {
2018-08-10 02:15:51 +02:00
Logger : : err ( str : : format ( " D3D11: Cannot create render target view: " ,
" \n Resource type: " , resourceDesc . Dim ,
2018-08-10 02:39:14 +02:00
" \n Resource usage: " , resourceDesc . BindFlags ,
2018-08-10 02:15:51 +02:00
" \n Resource format: " , resourceDesc . Format ,
2021-05-28 17:28:30 +02:00
" \n View format: " , desc . Format ,
" \n View plane: " , plane ) ) ;
2018-02-22 21:38:45 +01:00
return E_INVALIDARG ;
2018-08-10 02:15:51 +02:00
}
2018-08-05 18:56:42 +02:00
2019-09-16 16:04:06 +02:00
if ( ! ppRTView )
2017-12-27 14:32:07 +01:00
return S_FALSE ;
2017-11-29 15:16:07 +01:00
2017-11-29 20:19:40 +01:00
try {
2018-08-05 19:07:53 +02:00
* ppRTView = ref ( new D3D11RenderTargetView ( this , pResource , & desc ) ) ;
2017-11-29 20:19:40 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-11-29 20:19:40 +01:00
}
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDepthStencilView (
2017-11-29 20:19:40 +01:00
ID3D11Resource * pResource ,
const D3D11_DEPTH_STENCIL_VIEW_DESC * pDesc ,
ID3D11DepthStencilView * * ppDepthStencilView ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppDepthStencilView ) ;
2018-09-19 11:55:11 +02:00
if ( pResource = = nullptr )
return E_INVALIDARG ;
2018-08-10 02:15:51 +02:00
D3D11_COMMON_RESOURCE_DESC resourceDesc ;
GetCommonResourceDesc ( pResource , & resourceDesc ) ;
2017-12-08 23:25:38 +01:00
// The view description is optional. If not defined, it
// will use the resource's format and all array layers.
D3D11_DEPTH_STENCIL_VIEW_DESC desc ;
2017-12-09 19:36:38 +01:00
if ( pDesc = = nullptr ) {
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11DepthStencilView : : GetDescFromResource ( pResource , & desc ) ) )
2017-12-09 19:36:38 +01:00
return E_INVALIDARG ;
2017-12-08 23:25:38 +01:00
} else {
2017-12-09 19:36:38 +01:00
desc = * pDesc ;
2018-02-14 01:29:50 +01:00
2018-03-17 13:42:37 +01:00
if ( FAILED ( D3D11DepthStencilView : : NormalizeDesc ( pResource , & desc ) ) )
2018-02-14 01:29:50 +01:00
return E_INVALIDARG ;
2017-12-08 23:25:38 +01:00
}
2021-05-20 16:50:15 +02:00
if ( ! CheckResourceViewCompatibility ( pResource , D3D11_BIND_DEPTH_STENCIL , desc . Format , 0 ) ) {
2018-08-10 02:15:51 +02:00
Logger : : err ( str : : format ( " D3D11: Cannot create depth-stencil view: " ,
" \n Resource type: " , resourceDesc . Dim ,
2018-08-10 02:39:14 +02:00
" \n Resource usage: " , resourceDesc . BindFlags ,
2018-08-10 02:15:51 +02:00
" \n Resource format: " , resourceDesc . Format ,
" \n View format: " , desc . Format ) ) ;
2018-02-22 21:38:45 +01:00
return E_INVALIDARG ;
2018-08-10 02:15:51 +02:00
}
2018-05-05 15:13:35 +02:00
2017-12-08 23:25:38 +01:00
if ( ppDepthStencilView = = nullptr )
2017-12-27 14:32:07 +01:00
return S_FALSE ;
2017-12-08 23:25:38 +01:00
try {
2018-08-05 19:02:45 +02:00
* ppDepthStencilView = ref ( new D3D11DepthStencilView ( this , pResource , & desc ) ) ;
2017-12-08 23:25:38 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-08 23:25:38 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateInputLayout (
2017-10-11 09:51:48 +02:00
const D3D11_INPUT_ELEMENT_DESC * pInputElementDescs ,
UINT NumElements ,
const void * pShaderBytecodeWithInputSignature ,
SIZE_T BytecodeLength ,
ID3D11InputLayout * * ppInputLayout ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppInputLayout ) ;
2019-02-27 20:21:52 +00:00
2022-08-10 14:12:39 +02:00
// This check is somehow even correct, passing null with zero
// size will always fail but passing non-null with zero size
// works, provided the shader does not have any actual inputs
if ( ! pInputElementDescs )
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2017-12-07 12:45:02 +01:00
try {
DxbcReader dxbcReader ( reinterpret_cast < const char * > (
pShaderBytecodeWithInputSignature ) , BytecodeLength ) ;
DxbcModule dxbcModule ( dxbcReader ) ;
2018-01-08 20:23:21 +01:00
const Rc < DxbcIsgn > inputSignature = dxbcModule . isgn ( ) ;
2018-05-30 13:33:48 +02:00
uint32_t attrMask = 0 ;
uint32_t bindMask = 0 ;
2022-08-10 14:12:39 +02:00
uint32_t locationMask = 0 ;
2022-08-07 16:47:52 +02:00
uint32_t bindingsDefined = 0 ;
2017-12-07 12:45:02 +01:00
2022-08-07 16:47:52 +02:00
std : : array < DxvkVertexAttribute , D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT > attrList = { } ;
std : : array < DxvkVertexBinding , D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT > bindList = { } ;
2017-12-07 12:45:02 +01:00
for ( uint32_t i = 0 ; i < NumElements ; i + + ) {
const DxbcSgnEntry * entry = inputSignature - > find (
pInputElementDescs [ i ] . SemanticName ,
2018-06-23 20:13:00 +02:00
pInputElementDescs [ i ] . SemanticIndex , 0 ) ;
2022-08-07 16:47:52 +02:00
2017-12-07 12:45:02 +01:00
// Create vertex input attribute description
2017-12-08 00:44:58 +01:00
DxvkVertexAttribute attrib ;
2018-05-30 13:33:48 +02:00
attrib . location = entry ! = nullptr ? entry - > registerId : 0 ;
2017-12-07 12:45:02 +01:00
attrib . binding = pInputElementDescs [ i ] . InputSlot ;
2018-11-28 18:34:05 +01:00
attrib . format = LookupFormat ( pInputElementDescs [ i ] . Format , DXGI_VK_FORMAT_MODE_COLOR ) . Format ;
2017-12-07 12:45:02 +01:00
attrib . offset = pInputElementDescs [ i ] . AlignedByteOffset ;
2022-08-07 16:47:52 +02:00
2017-12-18 23:24:10 +01:00
// The application may choose to let the implementation
// generate the exact vertex layout. In that case we'll
// pack attributes on the same binding in the order they
// are declared, aligning each attribute to four bytes.
2022-07-15 17:23:54 +02:00
const DxvkFormatInfo * formatInfo = lookupFormatInfo ( attrib . format ) ;
2021-02-08 14:55:18 +01:00
VkDeviceSize alignment = std : : min < VkDeviceSize > ( formatInfo - > elementSize , 4 ) ;
2017-12-07 12:45:02 +01:00
if ( attrib . offset = = D3D11_APPEND_ALIGNED_ELEMENT ) {
2017-12-18 23:24:10 +01:00
attrib . offset = 0 ;
2022-08-07 16:47:52 +02:00
2017-12-18 23:24:10 +01:00
for ( uint32_t j = 1 ; j < = i ; j + + ) {
2018-05-30 13:33:48 +02:00
const DxvkVertexAttribute & prev = attrList . at ( i - j ) ;
2022-08-07 16:47:52 +02:00
2017-12-18 23:24:10 +01:00
if ( prev . binding = = attrib . binding ) {
2022-07-15 17:23:54 +02:00
attrib . offset = align ( prev . offset + lookupFormatInfo ( prev . format ) - > elementSize , alignment ) ;
2017-12-18 23:24:10 +01:00
break ;
}
}
2021-02-08 14:55:18 +01:00
} else if ( attrib . offset & ( alignment - 1 ) )
return E_INVALIDARG ;
2018-05-30 13:33:48 +02:00
attrList . at ( i ) = attrib ;
2022-08-07 16:47:52 +02:00
2017-12-07 19:28:54 +01:00
// Create vertex input binding description. The
// stride is dynamic state in D3D11 and will be
2018-01-08 20:23:21 +01:00
// set by D3D11DeviceContext::IASetVertexBuffers.
2017-12-08 00:44:58 +01:00
DxvkVertexBinding binding ;
2017-12-07 12:45:02 +01:00
binding . binding = pInputElementDescs [ i ] . InputSlot ;
2018-02-01 20:15:25 +01:00
binding . fetchRate = pInputElementDescs [ i ] . InstanceDataStepRate ;
binding . inputRate = pInputElementDescs [ i ] . InputSlotClass = = D3D11_INPUT_PER_INSTANCE_DATA
2018-05-30 13:33:48 +02:00
? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX ;
2022-08-07 16:47:52 +02:00
binding . extent = entry ? uint32_t ( attrib . offset + formatInfo - > elementSize ) : 0u ;
2017-12-07 12:45:02 +01:00
// Check if the binding was already defined. If so, the
// parameters must be identical (namely, the input rate).
2022-08-07 16:47:52 +02:00
if ( bindingsDefined & ( 1u < < binding . binding ) ) {
if ( bindList . at ( binding . binding ) . inputRate ! = binding . inputRate )
return E_INVALIDARG ;
2018-05-30 13:33:48 +02:00
2022-08-07 16:47:52 +02:00
bindList . at ( binding . binding ) . extent = std : : max (
bindList . at ( binding . binding ) . extent , binding . extent ) ;
} else {
2018-05-30 13:33:48 +02:00
bindList . at ( binding . binding ) = binding ;
2022-08-07 16:47:52 +02:00
bindingsDefined | = 1u < < binding . binding ;
}
if ( entry ) {
2018-05-30 13:33:48 +02:00
attrMask | = 1u < < i ;
bindMask | = 1u < < binding . binding ;
2022-08-10 14:12:39 +02:00
locationMask | = 1u < < attrib . location ;
2018-05-30 13:33:48 +02:00
}
2017-12-07 12:45:02 +01:00
}
2018-05-30 13:33:48 +02:00
2022-08-10 14:12:39 +02:00
// Ensure that all inputs used by the shader are defined
for ( auto i = inputSignature - > begin ( ) ; i ! = inputSignature - > end ( ) ; i + + ) {
bool isBuiltIn = DxbcIsgn : : compareSemanticNames ( i - > semanticName , " sv_instanceid " )
| | DxbcIsgn : : compareSemanticNames ( i - > semanticName , " sv_vertexid " ) ;
if ( ! isBuiltIn & & ! ( locationMask & ( 1u < < i - > registerId ) ) )
return E_INVALIDARG ;
}
2018-05-30 13:33:48 +02:00
// Compact the attribute and binding lists to filter
// out attributes and bindings not used by the shader
uint32_t attrCount = CompactSparseList ( attrList . data ( ) , attrMask ) ;
uint32_t bindCount = CompactSparseList ( bindList . data ( ) , bindMask ) ;
2022-08-07 16:47:52 +02:00
if ( ! ppInputLayout )
return S_FALSE ;
* ppInputLayout = ref (
new D3D11InputLayout ( this ,
attrCount , attrList . data ( ) ,
bindCount , bindList . data ( ) ) ) ;
2017-12-07 12:45:02 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-07 12:45:02 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateVertexShader (
2017-10-11 09:51:48 +02:00
const void * pShaderBytecode ,
SIZE_T BytecodeLength ,
ID3D11ClassLinkage * pClassLinkage ,
ID3D11VertexShader * * ppVertexShader ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppVertexShader ) ;
2018-07-30 19:34:48 +02:00
D3D11CommonShader module ;
2018-06-23 17:14:35 +02:00
DxbcModuleInfo moduleInfo ;
moduleInfo . options = m_dxbcOptions ;
2018-09-09 23:14:00 +02:00
moduleInfo . tess = nullptr ;
2018-06-23 20:19:46 +02:00
moduleInfo . xfb = nullptr ;
2018-10-25 11:28:02 +02:00
Sha1Hash hash = Sha1Hash : : compute (
pShaderBytecode , BytecodeLength ) ;
2017-12-06 18:54:01 +01:00
2019-10-21 12:09:53 +02:00
HRESULT hr = CreateShaderModule ( & module ,
DxvkShaderKey ( VK_SHADER_STAGE_VERTEX_BIT , hash ) ,
pShaderBytecode , BytecodeLength , pClassLinkage ,
& moduleInfo ) ;
if ( FAILED ( hr ) )
return hr ;
2017-12-06 18:54:01 +01:00
2019-10-21 12:09:53 +02:00
if ( ! ppVertexShader )
2018-02-26 17:04:45 +01:00
return S_FALSE ;
2017-12-06 18:54:01 +01:00
2018-06-23 17:14:35 +02:00
* ppVertexShader = ref ( new D3D11VertexShader ( this , module ) ) ;
2017-12-06 18:54:01 +01:00
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateGeometryShader (
2017-10-11 09:51:48 +02:00
const void * pShaderBytecode ,
SIZE_T BytecodeLength ,
ID3D11ClassLinkage * pClassLinkage ,
ID3D11GeometryShader * * ppGeometryShader ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppGeometryShader ) ;
2018-07-30 19:34:48 +02:00
D3D11CommonShader module ;
2017-12-18 12:53:53 +01:00
2018-06-23 17:14:35 +02:00
DxbcModuleInfo moduleInfo ;
moduleInfo . options = m_dxbcOptions ;
2018-09-09 23:14:00 +02:00
moduleInfo . tess = nullptr ;
2018-06-23 20:19:46 +02:00
moduleInfo . xfb = nullptr ;
2018-06-23 17:14:35 +02:00
2018-10-25 11:28:02 +02:00
Sha1Hash hash = Sha1Hash : : compute (
pShaderBytecode , BytecodeLength ) ;
2019-10-21 12:09:53 +02:00
HRESULT hr = CreateShaderModule ( & module ,
DxvkShaderKey ( VK_SHADER_STAGE_GEOMETRY_BIT , hash ) ,
pShaderBytecode , BytecodeLength , pClassLinkage ,
& moduleInfo ) ;
if ( FAILED ( hr ) )
return hr ;
2017-12-18 12:53:53 +01:00
2019-10-21 12:09:53 +02:00
if ( ! ppGeometryShader )
2018-02-26 17:04:45 +01:00
return S_FALSE ;
2017-12-18 12:53:53 +01:00
2018-06-23 17:14:35 +02:00
* ppGeometryShader = ref ( new D3D11GeometryShader ( this , module ) ) ;
2017-12-18 12:53:53 +01:00
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateGeometryShaderWithStreamOutput (
2017-10-11 09:51:48 +02:00
const void * pShaderBytecode ,
SIZE_T BytecodeLength ,
const D3D11_SO_DECLARATION_ENTRY * pSODeclaration ,
UINT NumEntries ,
const UINT * pBufferStrides ,
UINT NumStrides ,
UINT RasterizedStream ,
ID3D11ClassLinkage * pClassLinkage ,
ID3D11GeometryShader * * ppGeometryShader ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppGeometryShader ) ;
2018-07-24 16:20:38 +02:00
D3D11CommonShader module ;
2020-05-30 15:55:27 +02:00
if ( ! m_dxvkDevice - > features ( ) . extTransformFeedback . transformFeedback )
return DXGI_ERROR_INVALID_CALL ;
2018-07-24 16:20:38 +02:00
// Zero-init some counterss so that we can increment
// them while walking over the stream output entries
2018-10-25 11:28:02 +02:00
DxbcXfbInfo xfb = { } ;
2018-07-24 16:20:38 +02:00
for ( uint32_t i = 0 ; i < NumEntries ; i + + ) {
const D3D11_SO_DECLARATION_ENTRY * so = & pSODeclaration [ i ] ;
if ( so - > OutputSlot > = D3D11_SO_BUFFER_SLOT_COUNT )
return E_INVALIDARG ;
if ( so - > SemanticName ! = nullptr ) {
if ( so - > Stream > = D3D11_SO_BUFFER_SLOT_COUNT
| | so - > StartComponent > = 4
| | so - > ComponentCount < 1
| | so - > ComponentCount > 4 )
return E_INVALIDARG ;
DxbcXfbEntry * entry = & xfb . entries [ xfb . entryCount + + ] ;
entry - > semanticName = so - > SemanticName ;
entry - > semanticIndex = so - > SemanticIndex ;
entry - > componentIndex = so - > StartComponent ;
entry - > componentCount = so - > ComponentCount ;
entry - > streamId = so - > Stream ;
entry - > bufferId = so - > OutputSlot ;
entry - > offset = xfb . strides [ so - > OutputSlot ] ;
}
xfb . strides [ so - > OutputSlot ] + = so - > ComponentCount * sizeof ( uint32_t ) ;
}
// If necessary, override the buffer strides
for ( uint32_t i = 0 ; i < NumStrides ; i + + )
xfb . strides [ i ] = pBufferStrides [ i ] ;
// Set stream to rasterize, if any
xfb . rasterizedStream = - 1 ;
2018-05-25 23:53:34 +02:00
2018-07-24 16:20:38 +02:00
if ( RasterizedStream ! = D3D11_SO_NO_RASTERIZED_STREAM )
Logger : : err ( " D3D11: CreateGeometryShaderWithStreamOutput: Rasterized stream not supported " ) ;
2018-10-25 11:28:02 +02:00
// Compute hash from both the xfb info and the source
// code, because both influence the generated code
2019-04-15 03:09:31 +02:00
DxbcXfbInfo hashXfb = xfb ;
std : : vector < Sha1Data > chunks = { {
{ pShaderBytecode , BytecodeLength } ,
{ & hashXfb , sizeof ( hashXfb ) } ,
2018-10-25 11:28:02 +02:00
} } ;
2018-07-24 16:20:38 +02:00
2019-04-15 03:09:31 +02:00
for ( uint32_t i = 0 ; i < hashXfb . entryCount ; i + + ) {
const char * semantic = hashXfb . entries [ i ] . semanticName ;
if ( semantic ) {
chunks . push_back ( { semantic , std : : strlen ( semantic ) } ) ;
hashXfb . entries [ i ] . semanticName = nullptr ;
}
}
2018-10-25 11:28:02 +02:00
Sha1Hash hash = Sha1Hash : : compute ( chunks . size ( ) , chunks . data ( ) ) ;
2018-07-24 16:20:38 +02:00
// Create the actual shader module
DxbcModuleInfo moduleInfo ;
moduleInfo . options = m_dxbcOptions ;
moduleInfo . tess = nullptr ;
moduleInfo . xfb = & xfb ;
2019-10-21 12:09:53 +02:00
HRESULT hr = CreateShaderModule ( & module ,
DxvkShaderKey ( VK_SHADER_STAGE_GEOMETRY_BIT , hash ) ,
pShaderBytecode , BytecodeLength , pClassLinkage ,
& moduleInfo ) ;
if ( FAILED ( hr ) )
2018-07-24 16:20:38 +02:00
return E_INVALIDARG ;
2019-10-21 12:09:53 +02:00
if ( ! ppGeometryShader )
2018-07-24 16:20:38 +02:00
return S_FALSE ;
* ppGeometryShader = ref ( new D3D11GeometryShader ( this , module ) ) ;
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreatePixelShader (
2017-10-11 09:51:48 +02:00
const void * pShaderBytecode ,
SIZE_T BytecodeLength ,
ID3D11ClassLinkage * pClassLinkage ,
ID3D11PixelShader * * ppPixelShader ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppPixelShader ) ;
2018-07-30 19:34:48 +02:00
D3D11CommonShader module ;
2017-12-06 18:54:01 +01:00
2018-06-23 17:14:35 +02:00
DxbcModuleInfo moduleInfo ;
moduleInfo . options = m_dxbcOptions ;
2018-09-09 23:14:00 +02:00
moduleInfo . tess = nullptr ;
2018-06-23 20:19:46 +02:00
moduleInfo . xfb = nullptr ;
2018-06-23 17:14:35 +02:00
2018-10-25 11:28:02 +02:00
Sha1Hash hash = Sha1Hash : : compute (
pShaderBytecode , BytecodeLength ) ;
2019-10-21 12:09:53 +02:00
HRESULT hr = CreateShaderModule ( & module ,
DxvkShaderKey ( VK_SHADER_STAGE_FRAGMENT_BIT , hash ) ,
pShaderBytecode , BytecodeLength , pClassLinkage ,
& moduleInfo ) ;
if ( FAILED ( hr ) )
return hr ;
2017-12-06 18:54:01 +01:00
2019-10-21 12:09:53 +02:00
if ( ! ppPixelShader )
2018-02-26 17:04:45 +01:00
return S_FALSE ;
2017-12-06 18:54:01 +01:00
2018-06-23 17:14:35 +02:00
* ppPixelShader = ref ( new D3D11PixelShader ( this , module ) ) ;
2017-12-06 18:54:01 +01:00
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateHullShader (
2017-10-11 09:51:48 +02:00
const void * pShaderBytecode ,
SIZE_T BytecodeLength ,
ID3D11ClassLinkage * pClassLinkage ,
ID3D11HullShader * * ppHullShader ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppHullShader ) ;
2018-07-30 19:34:48 +02:00
D3D11CommonShader module ;
2018-01-29 11:53:57 +01:00
2018-09-09 23:14:00 +02:00
DxbcTessInfo tessInfo ;
tessInfo . maxTessFactor = float ( m_d3d11Options . maxTessFactor ) ;
2018-06-23 17:14:35 +02:00
DxbcModuleInfo moduleInfo ;
moduleInfo . options = m_dxbcOptions ;
2018-09-09 23:14:00 +02:00
moduleInfo . tess = nullptr ;
2018-06-23 20:19:46 +02:00
moduleInfo . xfb = nullptr ;
2018-09-09 23:14:00 +02:00
if ( tessInfo . maxTessFactor > = 8.0f )
moduleInfo . tess = & tessInfo ;
2018-06-23 17:14:35 +02:00
2018-10-25 11:28:02 +02:00
Sha1Hash hash = Sha1Hash : : compute (
pShaderBytecode , BytecodeLength ) ;
2019-10-21 12:09:53 +02:00
HRESULT hr = CreateShaderModule ( & module ,
DxvkShaderKey ( VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT , hash ) ,
pShaderBytecode , BytecodeLength , pClassLinkage , & moduleInfo ) ;
if ( FAILED ( hr ) )
return hr ;
2018-01-29 11:53:57 +01:00
2019-10-21 12:09:53 +02:00
if ( ! ppHullShader )
2018-02-26 17:04:45 +01:00
return S_FALSE ;
2018-01-29 11:53:57 +01:00
2018-06-23 17:14:35 +02:00
* ppHullShader = ref ( new D3D11HullShader ( this , module ) ) ;
2018-01-29 11:53:57 +01:00
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDomainShader (
2017-10-11 09:51:48 +02:00
const void * pShaderBytecode ,
SIZE_T BytecodeLength ,
ID3D11ClassLinkage * pClassLinkage ,
ID3D11DomainShader * * ppDomainShader ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppDomainShader ) ;
2018-07-30 19:34:48 +02:00
D3D11CommonShader module ;
2018-02-26 17:04:45 +01:00
2018-06-23 17:14:35 +02:00
DxbcModuleInfo moduleInfo ;
moduleInfo . options = m_dxbcOptions ;
2018-09-09 23:14:00 +02:00
moduleInfo . tess = nullptr ;
2018-06-23 20:19:46 +02:00
moduleInfo . xfb = nullptr ;
2018-06-23 17:14:35 +02:00
2018-10-25 11:28:02 +02:00
Sha1Hash hash = Sha1Hash : : compute (
pShaderBytecode , BytecodeLength ) ;
2019-10-21 12:09:53 +02:00
HRESULT hr = CreateShaderModule ( & module ,
DxvkShaderKey ( VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT , hash ) ,
pShaderBytecode , BytecodeLength , pClassLinkage , & moduleInfo ) ;
if ( FAILED ( hr ) )
return hr ;
2018-01-29 11:53:57 +01:00
2018-02-26 17:04:45 +01:00
if ( ppDomainShader = = nullptr )
return S_FALSE ;
2018-01-29 11:53:57 +01:00
2018-06-23 17:14:35 +02:00
* ppDomainShader = ref ( new D3D11DomainShader ( this , module ) ) ;
2018-01-29 11:53:57 +01:00
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateComputeShader (
2017-10-11 09:51:48 +02:00
const void * pShaderBytecode ,
SIZE_T BytecodeLength ,
ID3D11ClassLinkage * pClassLinkage ,
ID3D11ComputeShader * * ppComputeShader ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppComputeShader ) ;
2018-07-30 19:34:48 +02:00
D3D11CommonShader module ;
2017-12-21 17:27:40 +01:00
2018-06-23 17:14:35 +02:00
DxbcModuleInfo moduleInfo ;
moduleInfo . options = m_dxbcOptions ;
2018-09-09 23:14:00 +02:00
moduleInfo . tess = nullptr ;
2018-06-23 20:19:46 +02:00
moduleInfo . xfb = nullptr ;
2018-06-23 17:14:35 +02:00
2018-10-25 11:28:02 +02:00
Sha1Hash hash = Sha1Hash : : compute (
pShaderBytecode , BytecodeLength ) ;
2019-10-21 12:09:53 +02:00
HRESULT hr = CreateShaderModule ( & module ,
DxvkShaderKey ( VK_SHADER_STAGE_COMPUTE_BIT , hash ) ,
pShaderBytecode , BytecodeLength , pClassLinkage ,
& moduleInfo ) ;
if ( FAILED ( hr ) )
return hr ;
2017-12-21 17:27:40 +01:00
2019-10-21 12:09:53 +02:00
if ( ! ppComputeShader )
2018-02-26 17:04:45 +01:00
return S_FALSE ;
2017-12-21 17:27:40 +01:00
2018-06-23 17:14:35 +02:00
* ppComputeShader = ref ( new D3D11ComputeShader ( this , module ) ) ;
2017-12-21 17:27:40 +01:00
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateClassLinkage ( ID3D11ClassLinkage * * ppLinkage ) {
2017-12-12 01:07:07 +01:00
* ppLinkage = ref ( new D3D11ClassLinkage ( this ) ) ;
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateBlendState (
2017-10-11 09:51:48 +02:00
const D3D11_BLEND_DESC * pBlendStateDesc ,
ID3D11BlendState * * ppBlendState ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppBlendState ) ;
2019-10-14 01:08:31 +02:00
if ( ! pBlendStateDesc )
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2019-10-14 01:08:31 +02:00
D3D11_BLEND_DESC1 desc = D3D11BlendState : : PromoteDesc ( pBlendStateDesc ) ;
2017-12-11 13:03:07 +01:00
2018-03-18 23:27:29 +01:00
if ( FAILED ( D3D11BlendState : : NormalizeDesc ( & desc ) ) )
return E_INVALIDARG ;
2017-12-11 13:03:07 +01:00
2017-12-27 14:32:07 +01:00
if ( ppBlendState ! = nullptr ) {
2017-12-11 13:03:07 +01:00
* ppBlendState = m_bsStateObjects . Create ( this , desc ) ;
2017-12-27 14:32:07 +01:00
return S_OK ;
} return S_FALSE ;
2017-10-11 09:51:48 +02:00
}
2018-03-17 22:11:00 +03:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateBlendState1 (
const D3D11_BLEND_DESC1 * pBlendStateDesc ,
ID3D11BlendState1 * * ppBlendState ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppBlendState ) ;
2019-10-14 01:08:31 +02:00
if ( ! pBlendStateDesc )
return E_INVALIDARG ;
D3D11_BLEND_DESC1 desc = * pBlendStateDesc ;
2018-03-18 23:27:29 +01:00
if ( FAILED ( D3D11BlendState : : NormalizeDesc ( & desc ) ) )
return E_INVALIDARG ;
if ( ppBlendState ! = nullptr ) {
* ppBlendState = m_bsStateObjects . Create ( this , desc ) ;
return S_OK ;
} return S_FALSE ;
2018-03-17 22:11:00 +03:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDepthStencilState (
2017-10-11 09:51:48 +02:00
const D3D11_DEPTH_STENCIL_DESC * pDepthStencilDesc ,
ID3D11DepthStencilState * * ppDepthStencilState ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppDepthStencilState ) ;
2019-10-14 01:08:31 +02:00
if ( ! pDepthStencilDesc )
return E_INVALIDARG ;
D3D11_DEPTH_STENCIL_DESC desc = * pDepthStencilDesc ;
2017-12-11 01:43:15 +01:00
2018-03-18 23:32:01 +01:00
if ( FAILED ( D3D11DepthStencilState : : NormalizeDesc ( & desc ) ) )
return E_INVALIDARG ;
2017-12-11 01:43:15 +01:00
2017-12-27 14:32:07 +01:00
if ( ppDepthStencilState ! = nullptr ) {
2017-12-11 01:43:15 +01:00
* ppDepthStencilState = m_dsStateObjects . Create ( this , desc ) ;
2017-12-27 14:32:07 +01:00
return S_OK ;
} return S_FALSE ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateRasterizerState (
2017-10-11 09:51:48 +02:00
const D3D11_RASTERIZER_DESC * pRasterizerDesc ,
ID3D11RasterizerState * * ppRasterizerState ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppRasterizerState ) ;
2019-10-14 01:08:31 +02:00
if ( ! pRasterizerDesc )
return E_INVALIDARG ;
D3D11_RASTERIZER_DESC2 desc = D3D11RasterizerState : : PromoteDesc ( pRasterizerDesc ) ;
2017-12-06 13:16:54 +01:00
2018-03-18 22:53:20 +01:00
if ( FAILED ( D3D11RasterizerState : : NormalizeDesc ( & desc ) ) )
return E_INVALIDARG ;
2017-12-06 13:16:54 +01:00
2019-09-16 16:04:06 +02:00
if ( ! ppRasterizerState )
return S_FALSE ;
* ppRasterizerState = m_rsStateObjects . Create ( this , desc ) ;
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2018-03-18 22:53:20 +01:00
2018-03-17 22:11:00 +03:00
HRESULT D3D11Device : : CreateRasterizerState1 (
const D3D11_RASTERIZER_DESC1 * pRasterizerDesc ,
ID3D11RasterizerState1 * * ppRasterizerState ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppRasterizerState ) ;
2019-10-14 01:08:31 +02:00
if ( ! pRasterizerDesc )
return E_INVALIDARG ;
D3D11_RASTERIZER_DESC2 desc = D3D11RasterizerState : : PromoteDesc ( pRasterizerDesc ) ;
2018-03-18 22:53:20 +01:00
if ( FAILED ( D3D11RasterizerState : : NormalizeDesc ( & desc ) ) )
return E_INVALIDARG ;
2019-09-16 16:04:06 +02:00
if ( ! ppRasterizerState )
return S_FALSE ;
* ppRasterizerState = m_rsStateObjects . Create ( this , desc ) ;
return S_OK ;
}
HRESULT D3D11Device : : CreateRasterizerState2 (
const D3D11_RASTERIZER_DESC2 * pRasterizerDesc ,
ID3D11RasterizerState2 * * ppRasterizerState ) {
InitReturnPtr ( ppRasterizerState ) ;
2019-10-14 01:08:31 +02:00
if ( ! pRasterizerDesc )
return E_INVALIDARG ;
D3D11_RASTERIZER_DESC2 desc = * pRasterizerDesc ;
2019-09-16 16:04:06 +02:00
if ( FAILED ( D3D11RasterizerState : : NormalizeDesc ( & desc ) ) )
return E_INVALIDARG ;
2021-03-13 20:01:27 +01:00
if ( desc . ConservativeRaster ! = D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF
& & ! m_dxvkDevice - > extensions ( ) . extConservativeRasterization )
return E_INVALIDARG ;
2019-09-16 16:04:06 +02:00
if ( ! ppRasterizerState )
return S_FALSE ;
* ppRasterizerState = m_rsStateObjects . Create ( this , desc ) ;
return S_OK ;
2018-03-17 22:11:00 +03:00
}
2017-10-11 09:51:48 +02:00
2018-03-18 22:53:20 +01:00
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateSamplerState (
2017-10-11 09:51:48 +02:00
const D3D11_SAMPLER_DESC * pSamplerDesc ,
ID3D11SamplerState * * ppSamplerState ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppSamplerState ) ;
2019-02-27 20:21:52 +00:00
if ( pSamplerDesc = = nullptr )
return E_INVALIDARG ;
2018-03-18 23:35:40 +01:00
D3D11_SAMPLER_DESC desc = * pSamplerDesc ;
2017-12-09 20:49:56 +01:00
2018-03-18 23:35:40 +01:00
if ( FAILED ( D3D11SamplerState : : NormalizeDesc ( & desc ) ) )
return E_INVALIDARG ;
2017-12-09 20:49:56 +01:00
if ( ppSamplerState = = nullptr )
2017-12-27 14:32:07 +01:00
return S_FALSE ;
2017-12-09 20:49:56 +01:00
try {
2018-03-18 23:35:40 +01:00
* ppSamplerState = m_samplerObjects . Create ( this , desc ) ;
2017-12-09 20:49:56 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-09 20:49:56 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateQuery (
2017-10-11 09:51:48 +02:00
const D3D11_QUERY_DESC * pQueryDesc ,
ID3D11Query * * ppQuery ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppQuery ) ;
2019-02-27 20:21:52 +00:00
2019-09-16 15:13:48 +02:00
if ( ! pQueryDesc )
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2019-09-16 15:13:48 +02:00
D3D11_QUERY_DESC1 desc ;
desc . Query = pQueryDesc - > Query ;
desc . MiscFlags = pQueryDesc - > MiscFlags ;
desc . ContextType = D3D11_CONTEXT_TYPE_ALL ;
2019-09-16 16:04:06 +02:00
ID3D11Query1 * query = nullptr ;
HRESULT hr = CreateQuery1 ( & desc , ppQuery ? & query : nullptr ) ;
if ( hr ! = S_OK )
return hr ;
* ppQuery = query ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateQuery1 (
const D3D11_QUERY_DESC1 * pQueryDesc ,
ID3D11Query1 * * ppQuery ) {
InitReturnPtr ( ppQuery ) ;
if ( ! pQueryDesc )
return E_INVALIDARG ;
HRESULT hr = D3D11Query : : ValidateDesc ( pQueryDesc ) ;
if ( FAILED ( hr ) )
return hr ;
2019-09-16 15:13:48 +02:00
if ( ! ppQuery )
2017-12-29 22:20:31 +01:00
return S_FALSE ;
2018-02-18 22:34:23 +01:00
2017-12-29 22:20:31 +01:00
try {
2019-09-16 16:04:06 +02:00
* ppQuery = ref ( new D3D11Query ( this , * pQueryDesc ) ) ;
2017-12-29 22:20:31 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2017-12-29 22:20:31 +01:00
}
2017-10-11 09:51:48 +02:00
}
2019-09-16 16:04:06 +02:00
2017-10-11 09:51:48 +02:00
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreatePredicate (
2017-10-11 09:51:48 +02:00
const D3D11_QUERY_DESC * pPredicateDesc ,
ID3D11Predicate * * ppPredicate ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppPredicate ) ;
2019-09-16 15:13:48 +02:00
if ( ! pPredicateDesc )
2018-02-18 22:34:23 +01:00
return E_INVALIDARG ;
2019-04-25 11:50:43 +01:00
2019-09-16 15:13:48 +02:00
D3D11_QUERY_DESC1 desc ;
desc . Query = pPredicateDesc - > Query ;
desc . MiscFlags = pPredicateDesc - > MiscFlags ;
desc . ContextType = D3D11_CONTEXT_TYPE_ALL ;
if ( desc . Query ! = D3D11_QUERY_OCCLUSION_PREDICATE ) {
2019-04-25 11:50:43 +01:00
Logger : : warn ( str : : format ( " D3D11: Unhandled predicate type: " , pPredicateDesc - > Query ) ) ;
return E_INVALIDARG ;
}
2018-02-18 22:34:23 +01:00
2019-09-16 15:13:48 +02:00
if ( ! ppPredicate )
2018-02-18 22:34:23 +01:00
return S_FALSE ;
try {
2019-09-16 15:13:48 +02:00
* ppPredicate = D3D11Query : : AsPredicate (
ref ( new D3D11Query ( this , desc ) ) ) ;
2018-02-18 22:34:23 +01:00
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-02-27 20:21:52 +00:00
return E_INVALIDARG ;
2018-02-18 22:34:23 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateCounter (
2017-10-11 09:51:48 +02:00
const D3D11_COUNTER_DESC * pCounterDesc ,
ID3D11Counter * * ppCounter ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppCounter ) ;
2018-06-11 14:01:45 +02:00
Logger : : err ( str : : format ( " D3D11: Unsupported counter: " , pCounterDesc - > Counter ) ) ;
return E_INVALIDARG ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDeferredContext (
2017-10-11 09:51:48 +02:00
UINT ContextFlags ,
ID3D11DeviceContext * * ppDeferredContext ) {
2018-01-23 09:23:31 +01:00
* ppDeferredContext = ref ( new D3D11DeferredContext ( this , m_dxvkDevice , ContextFlags ) ) ;
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2019-09-16 16:04:06 +02:00
2018-03-17 22:11:00 +03:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDeferredContext1 (
UINT ContextFlags ,
ID3D11DeviceContext1 * * ppDeferredContext ) {
* ppDeferredContext = ref ( new D3D11DeferredContext ( this , m_dxvkDevice , ContextFlags ) ) ;
return S_OK ;
}
2019-09-16 16:04:06 +02:00
2019-09-15 18:40:57 +02:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDeferredContext2 (
UINT ContextFlags ,
ID3D11DeviceContext2 * * ppDeferredContext ) {
* ppDeferredContext = ref ( new D3D11DeferredContext ( this , m_dxvkDevice , ContextFlags ) ) ;
return S_OK ;
}
2019-09-16 16:04:06 +02:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDeferredContext3 (
UINT ContextFlags ,
ID3D11DeviceContext3 * * ppDeferredContext ) {
* ppDeferredContext = ref ( new D3D11DeferredContext ( this , m_dxvkDevice , ContextFlags ) ) ;
return S_OK ;
}
2018-03-17 22:11:00 +03:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateDeviceContextState (
UINT Flags ,
const D3D_FEATURE_LEVEL * pFeatureLevels ,
UINT FeatureLevels ,
UINT SDKVersion ,
REFIID EmulatedInterface ,
D3D_FEATURE_LEVEL * pChosenFeatureLevel ,
ID3DDeviceContextState * * ppContextState ) {
2018-04-02 12:04:20 +02:00
InitReturnPtr ( ppContextState ) ;
2019-05-03 16:41:16 +02:00
if ( ! pFeatureLevels | | FeatureLevels = = 0 )
return E_INVALIDARG ;
2018-04-02 12:04:20 +02:00
2019-05-03 16:41:16 +02:00
if ( EmulatedInterface ! = __uuidof ( ID3D10Device )
& & EmulatedInterface ! = __uuidof ( ID3D10Device1 )
& & EmulatedInterface ! = __uuidof ( ID3D11Device )
& & EmulatedInterface ! = __uuidof ( ID3D11Device1 ) )
return E_INVALIDARG ;
UINT flId ;
for ( flId = 0 ; flId < FeatureLevels ; flId + + ) {
2019-11-08 11:25:58 +01:00
if ( CheckFeatureLevelSupport ( m_dxvkDevice - > instance ( ) , m_dxvkAdapter , pFeatureLevels [ flId ] ) )
2019-05-03 16:41:16 +02:00
break ;
}
if ( flId = = FeatureLevels )
return E_INVALIDARG ;
if ( pFeatureLevels [ flId ] > m_featureLevel )
m_featureLevel = pFeatureLevels [ flId ] ;
if ( pChosenFeatureLevel )
* pChosenFeatureLevel = pFeatureLevels [ flId ] ;
if ( ! ppContextState )
return S_FALSE ;
* ppContextState = ref ( new D3D11DeviceContextState ( this ) ) ;
return S_OK ;
2018-03-17 22:11:00 +03:00
}
2017-10-11 09:51:48 +02:00
2019-09-16 16:04:06 +02:00
2019-09-16 16:37:37 +02:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CreateFence (
UINT64 InitialValue ,
D3D11_FENCE_FLAG Flags ,
2021-10-22 17:22:41 +02:00
REFIID riid ,
2019-09-16 16:37:37 +02:00
void * * ppFence ) {
InitReturnPtr ( ppFence ) ;
2021-10-22 17:22:41 +02:00
try {
2022-07-19 22:28:26 -04:00
Com < D3D11Fence > fence = new D3D11Fence ( this , InitialValue , Flags , INVALID_HANDLE_VALUE ) ;
2021-10-22 17:22:41 +02:00
return fence - > QueryInterface ( riid , ppFence ) ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
return E_FAIL ;
}
2019-09-16 16:37:37 +02:00
}
2019-09-16 16:04:06 +02:00
void STDMETHODCALLTYPE D3D11Device : : ReadFromSubresource (
void * pDstData ,
UINT DstRowPitch ,
UINT DstDepthPitch ,
ID3D11Resource * pSrcResource ,
UINT SrcSubresource ,
const D3D11_BOX * pSrcBox ) {
2019-09-17 19:13:49 +02:00
CopySubresourceData (
pDstData , DstRowPitch , DstDepthPitch ,
pSrcResource , SrcSubresource , pSrcBox ) ;
2019-09-16 16:04:06 +02:00
}
void STDMETHODCALLTYPE D3D11Device : : WriteToSubresource (
ID3D11Resource * pDstResource ,
UINT DstSubresource ,
const D3D11_BOX * pDstBox ,
const void * pSrcData ,
UINT SrcRowPitch ,
UINT SrcDepthPitch ) {
2019-09-17 19:13:49 +02:00
CopySubresourceData (
pSrcData , SrcRowPitch , SrcRowPitch ,
pDstResource , DstSubresource , pDstBox ) ;
2019-09-16 16:04:06 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : OpenSharedResource (
2017-10-11 09:51:48 +02:00
HANDLE hResource ,
REFIID ReturnedInterface ,
void * * ppResource ) {
2022-02-23 16:18:07 -05:00
return OpenSharedResourceGeneric < true > (
hResource , ReturnedInterface , ppResource ) ;
2017-10-11 09:51:48 +02:00
}
2018-03-17 22:11:00 +03:00
HRESULT STDMETHODCALLTYPE D3D11Device : : OpenSharedResource1 (
HANDLE hResource ,
REFIID ReturnedInterface ,
void * * ppResource ) {
2022-02-23 16:18:07 -05:00
return OpenSharedResourceGeneric < false > (
hResource , ReturnedInterface , ppResource ) ;
2018-03-17 22:11:00 +03:00
}
HRESULT STDMETHODCALLTYPE D3D11Device : : OpenSharedResourceByName (
LPCWSTR lpName ,
DWORD dwDesiredAccess ,
REFIID returnedInterface ,
2018-04-02 12:04:20 +02:00
void * * ppResource ) {
InitReturnPtr ( ppResource ) ;
2018-03-17 22:11:00 +03:00
Logger : : err ( " D3D11Device::OpenSharedResourceByName: Not implemented " ) ;
return E_NOTIMPL ;
}
2019-09-16 16:37:37 +02:00
HRESULT STDMETHODCALLTYPE D3D11Device : : OpenSharedFence (
HANDLE hFence ,
REFIID ReturnedInterface ,
void * * ppFence ) {
InitReturnPtr ( ppFence ) ;
2022-07-19 22:28:26 -04:00
if ( ppFence = = nullptr )
return S_FALSE ;
try {
Com < D3D11Fence > fence = new D3D11Fence ( this , 0 , D3D11_FENCE_FLAG_SHARED , hFence ) ;
return fence - > QueryInterface ( ReturnedInterface , ppFence ) ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
return E_FAIL ;
}
2019-09-16 16:37:37 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CheckFormatSupport (
2017-10-11 09:51:48 +02:00
DXGI_FORMAT Format ,
UINT * pFormatSupport ) {
2018-03-21 13:31:22 +01:00
return GetFormatSupportFlags ( Format , pFormatSupport , nullptr ) ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CheckMultisampleQualityLevels (
2017-10-11 09:51:48 +02:00
DXGI_FORMAT Format ,
UINT SampleCount ,
UINT * pNumQualityLevels ) {
2019-09-15 18:40:57 +02:00
return CheckMultisampleQualityLevels1 ( Format , SampleCount , 0 , pNumQualityLevels ) ;
}
HRESULT STDMETHODCALLTYPE D3D11Device : : CheckMultisampleQualityLevels1 (
DXGI_FORMAT Format ,
UINT SampleCount ,
UINT Flags ,
UINT * pNumQualityLevels ) {
2017-12-09 19:44:06 +01:00
// There are many error conditions, so we'll just assume
// that we will fail and return a non-zero value in case
// the device does actually support the format.
2019-01-09 00:24:44 +01:00
if ( ! pNumQualityLevels )
return E_INVALIDARG ;
2019-09-15 18:40:57 +02:00
// We don't support tiled resources, but it's unclear what
// we are supposed to return in this case. Be conservative.
if ( Flags ) {
* pNumQualityLevels = 0 ;
return E_FAIL ;
}
2019-01-09 00:24:44 +01:00
// For some reason, we can query DXGI_FORMAT_UNKNOWN
if ( Format = = DXGI_FORMAT_UNKNOWN ) {
* pNumQualityLevels = SampleCount = = 1 ? 1 : 0 ;
2019-06-14 13:37:01 +02:00
return SampleCount ? S_OK : E_FAIL ;
2019-01-09 00:24:44 +01:00
}
2017-12-09 14:46:23 +01:00
2019-01-09 00:24:44 +01:00
// All other unknown formats should result in an error return.
VkFormat format = LookupFormat ( Format , DXGI_VK_FORMAT_MODE_ANY ) . Format ;
if ( format = = VK_FORMAT_UNDEFINED )
2017-12-09 14:46:23 +01:00
return E_INVALIDARG ;
2019-06-14 13:37:01 +02:00
// Zero-init now, leave value undefined otherwise.
// This does actually match native D3D11 behaviour.
* pNumQualityLevels = 0 ;
2019-01-09 00:24:44 +01:00
// Non-power of two sample counts are not supported, but querying
// support for them is legal, so we return zero quality levels.
2017-12-09 14:46:23 +01:00
VkSampleCountFlagBits sampleCountFlag = VK_SAMPLE_COUNT_1_BIT ;
2018-04-13 13:46:45 +02:00
if ( FAILED ( DecodeSampleCount ( SampleCount , & sampleCountFlag ) ) )
2019-06-14 13:37:01 +02:00
return SampleCount & & SampleCount < = 32 ? S_OK : E_FAIL ;
2017-12-09 14:46:23 +01:00
2017-12-09 19:44:06 +01:00
// Check if the device supports the given combination of format
// and sample count. D3D exposes the opaque concept of quality
// levels to the application, we'll just define one such level.
2022-08-17 14:30:00 +02:00
auto properties = m_dxvkDevice - > getFormatLimits ( format ,
VK_IMAGE_TYPE_2D , VK_IMAGE_TILING_OPTIMAL , VK_IMAGE_USAGE_SAMPLED_BIT , 0 ) ;
2017-12-09 14:46:23 +01:00
2022-08-17 14:30:00 +02:00
if ( properties & & ( properties - > sampleCounts & sampleCountFlag ) )
2017-12-09 14:46:23 +01:00
* pNumQualityLevels = 1 ;
return S_OK ;
2017-10-11 09:51:48 +02:00
}
2019-09-15 18:40:57 +02:00
2017-12-12 12:50:52 +01:00
void STDMETHODCALLTYPE D3D11Device : : CheckCounterInfo ( D3D11_COUNTER_INFO * pCounterInfo ) {
2018-06-11 14:01:45 +02:00
// We basically don't support counters
pCounterInfo - > LastDeviceDependentCounter = D3D11_COUNTER ( 0 ) ;
pCounterInfo - > NumSimultaneousCounters = 0 ;
pCounterInfo - > NumDetectableParallelUnits = 0 ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CheckCounter (
2017-10-11 09:51:48 +02:00
const D3D11_COUNTER_DESC * pDesc ,
D3D11_COUNTER_TYPE * pType ,
UINT * pActiveCounters ,
LPSTR szName ,
UINT * pNameLength ,
LPSTR szUnits ,
UINT * pUnitsLength ,
LPSTR szDescription ,
UINT * pDescriptionLength ) {
2018-06-11 14:01:45 +02:00
Logger : : err ( " D3D11: Counters not supported " ) ;
return E_INVALIDARG ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : CheckFeatureSupport (
2017-10-11 09:51:48 +02:00
D3D11_FEATURE Feature ,
void * pFeatureSupportData ,
UINT FeatureSupportDataSize ) {
2017-12-19 11:05:41 +01:00
switch ( Feature ) {
case D3D11_FEATURE_THREADING : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_THREADING * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2017-12-19 11:05:41 +01:00
return E_INVALIDARG ;
2018-03-21 04:58:31 +01:00
// We report native support for command lists here so that we do not actually
// have to re-implement the UpdateSubresource bug from the D3D11 runtime, see
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx)
2017-12-19 11:05:41 +01:00
info - > DriverConcurrentCreates = TRUE ;
2018-03-19 17:57:20 +01:00
info - > DriverCommandLists = TRUE ;
2017-12-19 11:05:41 +01:00
} return S_OK ;
case D3D11_FEATURE_DOUBLES : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_DOUBLES * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2017-12-19 11:05:41 +01:00
return E_INVALIDARG ;
2018-07-31 16:58:25 +02:00
info - > DoublePrecisionFloatShaderOps = m_dxvkDevice - > features ( ) . core . features . shaderFloat64
& & m_dxvkDevice - > features ( ) . core . features . shaderInt64 ;
2017-12-19 11:05:41 +01:00
} return S_OK ;
case D3D11_FEATURE_FORMAT_SUPPORT : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_FORMAT_SUPPORT * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2017-12-19 11:05:41 +01:00
return E_INVALIDARG ;
2018-03-21 13:31:22 +01:00
return GetFormatSupportFlags ( info - > InFormat , & info - > OutFormatSupport , nullptr ) ;
} return S_OK ;
case D3D11_FEATURE_FORMAT_SUPPORT2 : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_FORMAT_SUPPORT2 * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2018-03-21 13:31:22 +01:00
return E_INVALIDARG ;
return GetFormatSupportFlags ( info - > InFormat , nullptr , & info - > OutFormatSupport2 ) ;
2017-12-19 11:05:41 +01:00
} return S_OK ;
2017-12-29 12:51:54 +01:00
case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2017-12-29 12:51:54 +01:00
return E_INVALIDARG ;
info - > ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = TRUE ;
} return S_OK ;
2018-03-17 22:11:00 +03:00
case D3D11_FEATURE_D3D11_OPTIONS : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D11_OPTIONS * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2018-03-17 22:11:00 +03:00
return E_INVALIDARG ;
2018-03-20 23:25:23 +01:00
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh404457(v=vs.85).aspx
2018-09-18 13:23:28 +02:00
const auto & features = m_dxvkDevice - > features ( ) ;
2018-07-31 16:58:25 +02:00
info - > OutputMergerLogicOp = features . core . features . logicOp ;
2018-09-18 13:23:28 +02:00
info - > UAVOnlyRenderingForcedSampleCount = features . core . features . variableMultisampleRate ;
2018-08-03 11:10:40 +02:00
info - > DiscardAPIsSeenByDriver = TRUE ;
2018-08-03 11:22:26 +02:00
info - > FlagsForUpdateAndCopySeenByDriver = TRUE ;
2018-08-15 19:02:14 +02:00
info - > ClearView = TRUE ;
2018-09-18 16:22:47 +02:00
info - > CopyWithOverlap = TRUE ;
2018-03-20 23:25:23 +01:00
info - > ConstantBufferPartialUpdate = TRUE ;
info - > ConstantBufferOffsetting = TRUE ;
info - > MapNoOverwriteOnDynamicConstantBuffer = TRUE ;
info - > MapNoOverwriteOnDynamicBufferSRV = TRUE ;
2018-09-18 13:23:28 +02:00
info - > MultisampleRTVWithForcedSampleCountOne = TRUE ; /* not really */
2019-09-16 00:48:39 +02:00
info - > SAD4ShaderInstructions = TRUE ;
2018-08-15 20:12:41 +02:00
info - > ExtendedDoublesShaderInstructions = TRUE ;
2022-08-26 04:56:40 +02:00
info - > ExtendedResourceSharing = TRUE ;
2018-03-17 22:11:00 +03:00
} return S_OK ;
case D3D11_FEATURE_ARCHITECTURE_INFO : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_ARCHITECTURE_INFO * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2018-03-17 22:11:00 +03:00
return E_INVALIDARG ;
2018-03-21 04:58:31 +01:00
info - > TileBasedDeferredRenderer = FALSE ;
2018-03-17 22:11:00 +03:00
} return S_OK ;
2019-09-15 14:03:42 +02:00
case D3D11_FEATURE_D3D9_OPTIONS : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D9_OPTIONS * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-15 14:03:42 +02:00
return E_INVALIDARG ;
info - > FullNonPow2TextureSupport = TRUE ;
} return S_OK ;
2018-03-21 04:58:31 +01:00
case D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2018-03-21 04:58:31 +01:00
return E_INVALIDARG ;
// Report that we only support full 32-bit operations
info - > PixelShaderMinPrecision = 0 ;
info - > AllOtherShaderStagesMinPrecision = 0 ;
} return S_OK ;
case D3D11_FEATURE_D3D9_SHADOW_SUPPORT : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2018-03-21 04:58:31 +01:00
return E_INVALIDARG ;
info - > SupportsDepthAsTextureWithLessEqualComparisonFilter = TRUE ;
2019-09-15 13:53:44 +02:00
} return S_OK ;
case D3D11_FEATURE_D3D11_OPTIONS1 : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D11_OPTIONS1 * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-15 13:53:44 +02:00
return E_INVALIDARG ;
// Min/Max filtering requires Tiled Resources Tier 2 for some reason,
// so we cannot support it even though Vulkan exposes this feature
info - > TiledResourcesTier = D3D11_TILED_RESOURCES_NOT_SUPPORTED ;
info - > MinMaxFiltering = FALSE ;
info - > ClearViewAlsoSupportsDepthOnlyFormats = TRUE ;
2019-09-17 17:25:09 +02:00
info - > MapOnDefaultBuffers = TRUE ;
2019-09-15 13:53:44 +02:00
} return S_OK ;
case D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-15 13:53:44 +02:00
return E_INVALIDARG ;
info - > SimpleInstancingSupported = TRUE ;
} return S_OK ;
case D3D11_FEATURE_MARKER_SUPPORT : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_MARKER_SUPPORT * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-15 13:53:44 +02:00
return E_INVALIDARG ;
2022-08-26 04:55:38 +02:00
info - > Profile = m_context - > IsAnnotationEnabled ( ) ;
2019-09-15 13:53:44 +02:00
} return S_OK ;
case D3D11_FEATURE_D3D9_OPTIONS1 : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D9_OPTIONS1 * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-15 13:53:44 +02:00
return E_INVALIDARG ;
info - > FullNonPow2TextureSupported = TRUE ;
info - > DepthAsTextureWithLessEqualComparisonFilterSupported = TRUE ;
info - > SimpleInstancingSupported = TRUE ;
info - > TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported = TRUE ;
} return S_OK ;
2018-03-17 22:11:00 +03:00
2019-09-15 13:57:26 +02:00
case D3D11_FEATURE_D3D11_OPTIONS2 : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D11_OPTIONS2 * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-15 13:57:26 +02:00
return E_INVALIDARG ;
2019-09-15 14:56:23 +02:00
const auto & extensions = m_dxvkDevice - > extensions ( ) ;
2019-09-15 14:21:25 +02:00
2019-09-15 14:56:23 +02:00
info - > PSSpecifiedStencilRefSupported = extensions . extShaderStencilExport ;
2022-08-17 14:37:18 +02:00
info - > TypedUAVLoadAdditionalFormats = m_dxbcOptions . supportsTypedUavLoadExtended ;
2019-09-15 13:57:26 +02:00
info - > ROVsSupported = FALSE ;
info - > ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED ;
2019-09-17 19:14:14 +02:00
info - > MapOnDefaultTextures = TRUE ;
2019-09-15 13:57:26 +02:00
info - > TiledResourcesTier = D3D11_TILED_RESOURCES_NOT_SUPPORTED ;
info - > StandardSwizzle = FALSE ;
2020-01-28 12:12:03 +01:00
info - > UnifiedMemoryArchitecture = m_dxvkDevice - > isUnifiedMemoryArchitecture ( ) ;
2021-03-13 20:01:27 +01:00
if ( m_dxvkDevice - > extensions ( ) . extConservativeRasterization ) {
// We don't have a way to query uncertainty regions, so just check degenerate triangle behaviour
info - > ConservativeRasterizationTier = m_dxvkDevice - > properties ( ) . extConservativeRasterization . degenerateTrianglesRasterized
? D3D11_CONSERVATIVE_RASTERIZATION_TIER_2 : D3D11_CONSERVATIVE_RASTERIZATION_TIER_1 ;
}
2019-09-15 13:57:26 +02:00
} return S_OK ;
2019-09-16 16:22:52 +02:00
case D3D11_FEATURE_D3D11_OPTIONS3 : {
if ( FeatureSupportDataSize ! = sizeof ( D3D11_FEATURE_DATA_D3D11_OPTIONS3 ) )
return E_INVALIDARG ;
2022-07-14 20:03:53 +02:00
const auto & features = m_dxvkDevice - > features ( ) ;
2019-09-16 16:22:52 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D11_OPTIONS3 * > ( pFeatureSupportData ) ;
2022-07-14 20:03:53 +02:00
info - > VPAndRTArrayIndexFromAnyShaderFeedingRasterizer =
features . vk12 . shaderOutputViewportIndex & &
features . vk12 . shaderOutputLayer ;
2019-09-16 16:22:52 +02:00
} return S_OK ;
case D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-16 16:22:52 +02:00
return E_INVALIDARG ;
// These numbers are not accurate, but it should not have any effect on D3D11 apps
info - > MaxGPUVirtualAddressBitsPerResource = 32 ;
info - > MaxGPUVirtualAddressBitsPerProcess = 40 ;
} return S_OK ;
case D3D11_FEATURE_D3D11_OPTIONS4 : {
2019-09-22 15:00:26 +02:00
auto info = static_cast < D3D11_FEATURE_DATA_D3D11_OPTIONS4 * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
2019-09-16 16:22:52 +02:00
return E_INVALIDARG ;
2022-08-26 04:56:40 +02:00
info - > ExtendedNV12SharedTextureSupported = TRUE ;
2019-09-16 16:22:52 +02:00
} return S_OK ;
2022-08-26 04:58:33 +02:00
case D3D11_FEATURE_SHADER_CACHE : {
auto info = static_cast < D3D11_FEATURE_DATA_SHADER_CACHE * > ( pFeatureSupportData ) ;
if ( FeatureSupportDataSize ! = sizeof ( * info ) )
return E_INVALIDARG ;
// DXVK will keep all shaders in memory once created, and all Vulkan
// drivers that we know of that can run DXVK have an on-disk cache.
info - > SupportFlags = D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE
| D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE ;
} return S_OK ;
2019-09-16 16:22:52 +02:00
2017-12-19 11:05:41 +01:00
default :
2019-09-22 15:00:26 +02:00
Logger : : err ( str : : format ( " D3D11Device: CheckFeatureSupport: Unknown feature: " , Feature ) ) ;
return E_INVALIDARG ;
2017-12-19 11:05:41 +01:00
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : GetPrivateData (
2017-10-11 09:51:48 +02:00
REFGUID guid , UINT * pDataSize , void * pData ) {
2018-03-28 21:24:52 +02:00
return m_container - > GetPrivateData ( guid , pDataSize , pData ) ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : SetPrivateData (
2017-10-11 09:51:48 +02:00
REFGUID guid , UINT DataSize , const void * pData ) {
2018-03-28 21:24:52 +02:00
return m_container - > SetPrivateData ( guid , DataSize , pData ) ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : SetPrivateDataInterface (
2017-10-11 09:51:48 +02:00
REFGUID guid , const IUnknown * pData ) {
2018-03-28 21:24:52 +02:00
return m_container - > SetPrivateDataInterface ( guid , pData ) ;
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
D3D_FEATURE_LEVEL STDMETHODCALLTYPE D3D11Device : : GetFeatureLevel ( ) {
2017-10-11 09:51:48 +02:00
return m_featureLevel ;
}
2017-12-12 12:50:52 +01:00
UINT STDMETHODCALLTYPE D3D11Device : : GetCreationFlags ( ) {
2017-10-11 09:51:48 +02:00
return m_featureFlags ;
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : GetDeviceRemovedReason ( ) {
2019-09-22 19:07:48 +02:00
VkResult status = m_dxvkDevice - > getDeviceStatus ( ) ;
switch ( status ) {
case VK_SUCCESS : return S_OK ;
default : return DXGI_ERROR_DEVICE_RESET ;
}
2017-10-11 09:51:48 +02:00
}
2017-12-12 12:50:52 +01:00
void STDMETHODCALLTYPE D3D11Device : : GetImmediateContext ( ID3D11DeviceContext * * ppImmediateContext ) {
2021-01-07 20:08:55 +00:00
* ppImmediateContext = m_context . ref ( ) ;
2017-10-11 09:51:48 +02:00
}
2018-03-17 22:11:00 +03:00
2019-09-15 18:40:57 +02:00
void STDMETHODCALLTYPE D3D11Device : : GetImmediateContext1 ( ID3D11DeviceContext1 * * ppImmediateContext ) {
2021-01-07 20:08:55 +00:00
* ppImmediateContext = m_context . ref ( ) ;
2019-09-15 18:40:57 +02:00
}
void STDMETHODCALLTYPE D3D11Device : : GetImmediateContext2 ( ID3D11DeviceContext2 * * ppImmediateContext ) {
2021-01-07 20:08:55 +00:00
* ppImmediateContext = m_context . ref ( ) ;
2018-03-17 22:11:00 +03:00
}
2017-10-11 09:51:48 +02:00
2019-09-16 16:04:06 +02:00
void STDMETHODCALLTYPE D3D11Device : : GetImmediateContext3 ( ID3D11DeviceContext3 * * ppImmediateContext ) {
2021-01-07 20:08:55 +00:00
* ppImmediateContext = m_context . ref ( ) ;
2019-09-16 16:04:06 +02:00
}
2017-12-12 12:50:52 +01:00
HRESULT STDMETHODCALLTYPE D3D11Device : : SetExceptionMode ( UINT RaiseFlags ) {
2017-10-11 09:51:48 +02:00
Logger : : err ( " D3D11Device::SetExceptionMode: Not implemented " ) ;
return E_NOTIMPL ;
}
2017-12-12 12:50:52 +01:00
UINT STDMETHODCALLTYPE D3D11Device : : GetExceptionMode ( ) {
2017-10-11 09:51:48 +02:00
Logger : : err ( " D3D11Device::GetExceptionMode: Not implemented " ) ;
return 0 ;
}
2019-09-15 18:40:57 +02:00
void STDMETHODCALLTYPE D3D11Device : : GetResourceTiling (
ID3D11Resource * pTiledResource ,
UINT * pNumTilesForEntireResource ,
D3D11_PACKED_MIP_DESC * pPackedMipDesc ,
D3D11_TILE_SHAPE * pStandardTileShapeForNonPackedMips ,
UINT * pNumSubresourceTilings ,
UINT FirstSubresourceTilingToGet ,
D3D11_SUBRESOURCE_TILING * pSubresourceTilingsForNonPackedMips ) {
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
2019-09-16 12:39:28 +02:00
Logger : : err ( " D3D11Device::GetResourceTiling: Tiled resources not supported " ) ;
if ( pNumTilesForEntireResource )
* pNumTilesForEntireResource = 0 ;
if ( pPackedMipDesc )
* pPackedMipDesc = D3D11_PACKED_MIP_DESC ( ) ;
if ( pStandardTileShapeForNonPackedMips )
* pStandardTileShapeForNonPackedMips = D3D11_TILE_SHAPE ( ) ;
if ( pNumSubresourceTilings ) {
if ( pSubresourceTilingsForNonPackedMips ) {
for ( uint32_t i = 0 ; i < * pNumSubresourceTilings ; i + + )
pSubresourceTilingsForNonPackedMips [ i ] = D3D11_SUBRESOURCE_TILING ( ) ;
}
* pNumSubresourceTilings = 0 ;
}
2019-09-15 18:40:57 +02:00
}
2017-10-11 09:51:48 +02:00
2017-10-11 15:32:24 +02:00
2019-09-16 16:26:03 +02:00
HRESULT STDMETHODCALLTYPE D3D11Device : : RegisterDeviceRemovedEvent (
HANDLE hEvent ,
DWORD * pdwCookie ) {
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
Logger : : err ( " D3D11Device::RegisterDeviceRemovedEvent: Not implemented " ) ;
return E_NOTIMPL ;
}
void STDMETHODCALLTYPE D3D11Device : : UnregisterDeviceRemoved (
DWORD dwCookie ) {
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
Logger : : err ( " D3D11Device::UnregisterDeviceRemovedEvent: Not implemented " ) ;
}
2018-05-05 12:57:22 +02:00
DXGI_VK_FORMAT_INFO D3D11Device : : LookupFormat (
DXGI_FORMAT Format ,
DXGI_VK_FORMAT_MODE Mode ) const {
2018-11-28 18:34:05 +01:00
return m_d3d11Formats . GetFormatInfo ( Format , Mode ) ;
2017-12-19 16:01:50 +01:00
}
2019-03-26 17:19:32 +01:00
DXGI_VK_FORMAT_INFO D3D11Device : : LookupPackedFormat (
DXGI_FORMAT Format ,
DXGI_VK_FORMAT_MODE Mode ) const {
return m_d3d11Formats . GetPackedFormatInfo ( Format , Mode ) ;
}
2018-07-03 12:44:56 +02:00
DXGI_VK_FORMAT_FAMILY D3D11Device : : LookupFamily (
DXGI_FORMAT Format ,
DXGI_VK_FORMAT_MODE Mode ) const {
2018-11-28 18:34:05 +01:00
return m_d3d11Formats . GetFormatFamily ( Format , Mode ) ;
2018-07-03 12:44:56 +02:00
}
2018-01-13 05:00:27 +01:00
void D3D11Device : : FlushInitContext ( ) {
2018-07-23 15:21:17 +02:00
m_initializer - > Flush ( ) ;
2018-01-13 05:00:27 +01:00
}
2017-10-11 15:32:24 +02:00
bool D3D11Device : : CheckFeatureLevelSupport (
2019-11-08 11:25:58 +01:00
const Rc < DxvkInstance > & instance ,
2017-12-02 16:47:06 +01:00
const Rc < DxvkAdapter > & adapter ,
2017-10-11 15:32:24 +02:00
D3D_FEATURE_LEVEL featureLevel ) {
2019-11-08 11:25:58 +01:00
if ( featureLevel > GetMaxFeatureLevel ( instance ) )
2017-12-02 16:47:06 +01:00
return false ;
// Check whether all features are supported
2018-07-31 16:58:25 +02:00
const DxvkDeviceFeatures features
2017-12-02 16:47:06 +01:00
= GetDeviceFeatures ( adapter , featureLevel ) ;
if ( ! adapter - > checkFeatureSupport ( features ) )
return false ;
// TODO also check for required limits
return true ;
}
2018-07-31 16:58:25 +02:00
DxvkDeviceFeatures D3D11Device : : GetDeviceFeatures (
2017-12-02 16:47:06 +01:00
const Rc < DxvkAdapter > & adapter ,
D3D_FEATURE_LEVEL featureLevel ) {
2018-07-31 16:58:25 +02:00
DxvkDeviceFeatures supported = adapter - > features ( ) ;
DxvkDeviceFeatures enabled = { } ;
2019-02-15 10:05:17 +01:00
enabled . core . features . geometryShader = VK_TRUE ;
enabled . core . features . robustBufferAccess = VK_TRUE ;
2019-04-24 22:48:07 +02:00
enabled . core . features . depthBounds = supported . core . features . depthBounds ;
2018-09-10 22:10:16 +02:00
2022-07-14 19:30:35 +02:00
enabled . vk11 . shaderDrawParameters = VK_TRUE ;
2020-01-16 20:37:41 +01:00
2022-07-14 19:45:37 +02:00
enabled . vk12 . samplerMirrorClampToEdge = VK_TRUE ;
2022-08-17 17:34:18 +02:00
enabled . vk13 . shaderDemoteToHelperInvocation = VK_TRUE ;
2019-01-30 13:04:32 +01:00
2022-07-14 21:04:32 +02:00
enabled . extMemoryPriority . memoryPriority = supported . extMemoryPriority . memoryPriority ;
2019-07-02 21:47:49 +02:00
2019-02-15 10:05:17 +01:00
enabled . extVertexAttributeDivisor . vertexAttributeInstanceRateDivisor = supported . extVertexAttributeDivisor . vertexAttributeInstanceRateDivisor ;
enabled . extVertexAttributeDivisor . vertexAttributeInstanceRateZeroDivisor = supported . extVertexAttributeDivisor . vertexAttributeInstanceRateZeroDivisor ;
2017-12-02 16:47:06 +01:00
2020-05-04 13:51:23 +02:00
if ( supported . extCustomBorderColor . customBorderColorWithoutFormat ) {
enabled . extCustomBorderColor . customBorderColors = VK_TRUE ;
enabled . extCustomBorderColor . customBorderColorWithoutFormat = VK_TRUE ;
}
2017-12-02 16:47:06 +01:00
if ( featureLevel > = D3D_FEATURE_LEVEL_9_1 ) {
2018-07-31 16:58:25 +02:00
enabled . core . features . depthClamp = VK_TRUE ;
enabled . core . features . depthBiasClamp = VK_TRUE ;
enabled . core . features . fillModeNonSolid = VK_TRUE ;
enabled . core . features . pipelineStatisticsQuery = supported . core . features . pipelineStatisticsQuery ;
enabled . core . features . sampleRateShading = VK_TRUE ;
2021-04-04 20:23:56 +02:00
enabled . core . features . samplerAnisotropy = supported . core . features . samplerAnisotropy ;
2018-07-31 16:58:25 +02:00
enabled . core . features . shaderClipDistance = VK_TRUE ;
enabled . core . features . shaderCullDistance = VK_TRUE ;
2019-02-15 10:05:17 +01:00
enabled . core . features . textureCompressionBC = VK_TRUE ;
2019-02-19 13:57:34 +01:00
enabled . extDepthClipEnable . depthClipEnable = supported . extDepthClipEnable . depthClipEnable ;
2017-12-02 16:47:06 +01:00
}
if ( featureLevel > = D3D_FEATURE_LEVEL_9_2 ) {
2018-07-31 16:58:25 +02:00
enabled . core . features . occlusionQueryPrecise = VK_TRUE ;
2017-12-02 16:47:06 +01:00
}
if ( featureLevel > = D3D_FEATURE_LEVEL_9_3 ) {
2018-07-31 16:58:25 +02:00
enabled . core . features . independentBlend = VK_TRUE ;
2019-02-15 10:05:17 +01:00
enabled . core . features . multiViewport = VK_TRUE ;
2017-12-02 16:47:06 +01:00
}
if ( featureLevel > = D3D_FEATURE_LEVEL_10_0 ) {
2018-07-31 16:58:25 +02:00
enabled . core . features . fullDrawIndexUint32 = VK_TRUE ;
enabled . core . features . logicOp = supported . core . features . logicOp ;
enabled . core . features . shaderImageGatherExtended = VK_TRUE ;
2018-09-18 13:23:28 +02:00
enabled . core . features . variableMultisampleRate = supported . core . features . variableMultisampleRate ;
2020-05-30 15:55:27 +02:00
enabled . extTransformFeedback . transformFeedback = VK_TRUE ;
enabled . extTransformFeedback . geometryStreams = VK_TRUE ;
2017-12-02 16:47:06 +01:00
}
if ( featureLevel > = D3D_FEATURE_LEVEL_10_1 ) {
2018-07-31 16:58:25 +02:00
enabled . core . features . dualSrcBlend = VK_TRUE ;
enabled . core . features . imageCubeArray = VK_TRUE ;
2017-12-02 16:47:06 +01:00
}
if ( featureLevel > = D3D_FEATURE_LEVEL_11_0 ) {
2018-08-10 04:34:54 +02:00
enabled . core . features . drawIndirectFirstInstance = VK_TRUE ;
2019-02-15 10:05:17 +01:00
enabled . core . features . fragmentStoresAndAtomics = VK_TRUE ;
2020-05-11 01:13:42 +02:00
enabled . core . features . multiDrawIndirect = VK_TRUE ;
2018-07-31 16:58:25 +02:00
enabled . core . features . shaderFloat64 = supported . core . features . shaderFloat64 ;
enabled . core . features . shaderInt64 = supported . core . features . shaderInt64 ;
2019-02-15 10:05:17 +01:00
enabled . core . features . tessellationShader = VK_TRUE ;
2017-12-02 16:47:06 +01:00
}
2018-03-18 23:39:40 +01:00
if ( featureLevel > = D3D_FEATURE_LEVEL_11_1 ) {
2018-07-31 16:58:25 +02:00
enabled . core . features . logicOp = VK_TRUE ;
2018-09-18 13:23:28 +02:00
enabled . core . features . variableMultisampleRate = VK_TRUE ;
2018-07-31 16:58:25 +02:00
enabled . core . features . vertexPipelineStoresAndAtomics = VK_TRUE ;
2018-03-18 23:39:40 +01:00
}
2017-12-02 16:47:06 +01:00
return enabled ;
2017-10-11 15:32:24 +02:00
}
2017-12-06 18:54:01 +01:00
HRESULT D3D11Device : : CreateShaderModule (
2018-07-30 19:34:48 +02:00
D3D11CommonShader * pShaderModule ,
2018-10-25 11:28:02 +02:00
DxvkShaderKey ShaderKey ,
2017-12-06 18:54:01 +01:00
const void * pShaderBytecode ,
size_t BytecodeLength ,
2018-04-06 17:54:02 +02:00
ID3D11ClassLinkage * pClassLinkage ,
2018-10-25 11:28:02 +02:00
const DxbcModuleInfo * pModuleInfo ) {
2017-12-12 01:07:07 +01:00
if ( pClassLinkage ! = nullptr )
Logger : : warn ( " D3D11Device::CreateShaderModule: Class linkage not supported " ) ;
2019-10-21 12:09:53 +02:00
D3D11CommonShader commonShader ;
HRESULT hr = m_shaderModules . GetShaderModule ( this ,
& ShaderKey , pModuleInfo , pShaderBytecode , BytecodeLength ,
& commonShader ) ;
if ( FAILED ( hr ) )
return hr ;
2019-10-21 12:10:05 +02:00
auto shader = commonShader . GetShader ( ) ;
2019-11-12 18:05:03 +01:00
if ( shader - > flags ( ) . test ( DxvkShaderFlag : : ExportsStencilRef )
2019-10-21 12:10:05 +02:00
& & ! m_dxvkDevice - > extensions ( ) . extShaderStencilExport )
return E_INVALIDARG ;
2019-11-12 18:05:03 +01:00
if ( shader - > flags ( ) . test ( DxvkShaderFlag : : ExportsViewportIndexLayerFromVertexStage )
2022-07-14 20:03:53 +02:00
& & ( ! m_dxvkDevice - > features ( ) . vk12 . shaderOutputViewportIndex
| | ! m_dxvkDevice - > features ( ) . vk12 . shaderOutputLayer ) )
2019-10-21 12:10:05 +02:00
return E_INVALIDARG ;
2019-10-21 12:09:53 +02:00
* pShaderModule = std : : move ( commonShader ) ;
return S_OK ;
2017-12-06 18:54:01 +01:00
}
2018-08-30 15:24:47 +02:00
2018-03-21 13:31:22 +01:00
HRESULT D3D11Device : : GetFormatSupportFlags ( DXGI_FORMAT Format , UINT * pFlags1 , UINT * pFlags2 ) const {
2018-11-28 18:34:05 +01:00
const DXGI_VK_FORMAT_INFO fmtMapping = LookupFormat ( Format , DXGI_VK_FORMAT_MODE_ANY ) ;
2019-06-13 16:32:41 +02:00
2018-04-14 16:07:01 +02:00
// Reset output flags preemptively
if ( pFlags1 ! = nullptr ) * pFlags1 = 0 ;
if ( pFlags2 ! = nullptr ) * pFlags2 = 0 ;
2019-06-13 16:32:41 +02:00
2018-04-14 16:07:01 +02:00
// Unsupported or invalid format
2022-08-17 14:30:00 +02:00
if ( Format & & fmtMapping . Format = = VK_FORMAT_UNDEFINED )
2019-06-13 16:32:41 +02:00
return E_FAIL ;
// Query Vulkan format properties and supported features for it
2022-07-15 17:23:54 +02:00
const DxvkFormatInfo * fmtProperties = lookupFormatInfo ( fmtMapping . Format ) ;
2019-06-13 16:32:41 +02:00
2022-08-17 14:30:00 +02:00
DxvkFormatFeatures fmtSupport = fmtMapping . Format ! = VK_FORMAT_UNDEFINED
? m_dxvkDevice - > getFormatFeatures ( fmtMapping . Format )
: DxvkFormatFeatures ( ) ;
2019-06-13 16:32:41 +02:00
2022-08-17 14:30:00 +02:00
VkFormatFeatureFlags2 bufFeatures = fmtSupport . buffer ;
VkFormatFeatureFlags2 imgFeatures = fmtSupport . optimal | fmtSupport . linear ;
2021-05-19 19:29:04 +02:00
// For multi-plane images, we want to check available view formats as well
if ( fmtProperties - > flags . test ( DxvkFormatFlag : : MultiPlane ) ) {
2022-08-17 14:30:00 +02:00
const VkFormatFeatureFlags2 featureMask
= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT
| VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT
| VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT
| VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT
| VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT ;
2021-05-19 19:29:04 +02:00
DXGI_VK_FORMAT_FAMILY formatFamily = LookupFamily ( Format , DXGI_VK_FORMAT_MODE_ANY ) ;
for ( uint32_t i = 0 ; i < formatFamily . FormatCount ; i + + ) {
2022-08-17 14:30:00 +02:00
DxvkFormatFeatures viewFmtSupport = m_dxvkDevice - > getFormatFeatures ( formatFamily . Formats [ i ] ) ;
imgFeatures | = ( viewFmtSupport . optimal | viewFmtSupport . linear ) & featureMask ;
2021-05-19 19:29:04 +02:00
}
}
2017-12-19 11:05:41 +01:00
2018-03-21 13:31:22 +01:00
UINT flags1 = 0 ;
UINT flags2 = 0 ;
2019-06-13 16:32:41 +02:00
2018-04-14 16:07:01 +02:00
// Format can be used for shader resource views with buffers
2022-08-17 14:30:00 +02:00
if ( ( bufFeatures & VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT ) | | ! Format )
2018-03-21 13:31:22 +01:00
flags1 | = D3D11_FORMAT_SUPPORT_BUFFER ;
2017-12-19 11:05:41 +01:00
2018-04-14 16:07:01 +02:00
// Format can be used for vertex data
2022-08-17 14:30:00 +02:00
if ( bufFeatures & VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT )
2018-03-21 13:31:22 +01:00
flags1 | = D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER ;
2017-12-19 11:05:41 +01:00
2018-04-14 16:07:01 +02:00
// Format can be used for index data. Only
// these two formats are supported by D3D11.
if ( Format = = DXGI_FORMAT_R16_UINT
| | Format = = DXGI_FORMAT_R32_UINT )
2018-03-21 13:31:22 +01:00
flags1 | = D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER ;
2017-12-19 11:05:41 +01:00
2018-07-25 11:42:05 +02:00
// These formats are technically irrelevant since
// SO buffers are passed in as raw buffers and not
// as views, but the feature flag exists regardless
if ( Format = = DXGI_FORMAT_R32_FLOAT
| | Format = = DXGI_FORMAT_R32_UINT
| | Format = = DXGI_FORMAT_R32_SINT
| | Format = = DXGI_FORMAT_R32G32_FLOAT
| | Format = = DXGI_FORMAT_R32G32_UINT
| | Format = = DXGI_FORMAT_R32G32_SINT
| | Format = = DXGI_FORMAT_R32G32B32_FLOAT
| | Format = = DXGI_FORMAT_R32G32B32_UINT
| | Format = = DXGI_FORMAT_R32G32B32_SINT
| | Format = = DXGI_FORMAT_R32G32B32A32_FLOAT
| | Format = = DXGI_FORMAT_R32G32B32A32_UINT
| | Format = = DXGI_FORMAT_R32G32B32A32_SINT )
flags1 | = D3D11_FORMAT_SUPPORT_SO_BUFFER ;
2017-12-19 11:05:41 +01:00
2022-08-17 14:30:00 +02:00
if ( imgFeatures & ( VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT ) ) {
2018-11-28 18:34:05 +01:00
const VkFormat depthFormat = LookupFormat ( Format , DXGI_VK_FORMAT_MODE_DEPTH ) . Format ;
2018-04-14 16:07:01 +02:00
if ( GetImageTypeSupport ( fmtMapping . Format , VK_IMAGE_TYPE_1D ) ) flags1 | = D3D11_FORMAT_SUPPORT_TEXTURE1D ;
if ( GetImageTypeSupport ( fmtMapping . Format , VK_IMAGE_TYPE_2D ) ) flags1 | = D3D11_FORMAT_SUPPORT_TEXTURE2D ;
if ( GetImageTypeSupport ( fmtMapping . Format , VK_IMAGE_TYPE_3D ) ) flags1 | = D3D11_FORMAT_SUPPORT_TEXTURE3D ;
2022-08-17 14:30:00 +02:00
2018-04-14 16:07:01 +02:00
flags1 | = D3D11_FORMAT_SUPPORT_MIP
2018-03-21 13:31:22 +01:00
| D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT ;
2022-08-17 14:30:00 +02:00
2018-04-14 16:07:01 +02:00
// Format can be read
2022-08-17 14:30:00 +02:00
if ( imgFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT ) {
2018-04-14 16:07:01 +02:00
flags1 | = D3D11_FORMAT_SUPPORT_TEXTURECUBE
| D3D11_FORMAT_SUPPORT_SHADER_LOAD
| D3D11_FORMAT_SUPPORT_SHADER_GATHER
2021-05-19 19:29:04 +02:00
| D3D11_FORMAT_SUPPORT_SHADER_SAMPLE
| D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT ;
2018-04-14 16:07:01 +02:00
if ( depthFormat ! = VK_FORMAT_UNDEFINED ) {
flags1 | = D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON
| D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON ;
}
}
2018-03-21 13:31:22 +01:00
2018-04-14 16:07:01 +02:00
// Format is a color format that can be used for rendering
2022-08-17 14:30:00 +02:00
if ( imgFeatures & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT ) {
2018-04-14 16:07:01 +02:00
flags1 | = D3D11_FORMAT_SUPPORT_RENDER_TARGET
2021-05-19 19:29:04 +02:00
| D3D11_FORMAT_SUPPORT_MIP_AUTOGEN
| D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT ;
2018-04-14 16:07:01 +02:00
2018-07-31 16:58:25 +02:00
if ( m_dxvkDevice - > features ( ) . core . features . logicOp )
2018-04-14 16:07:01 +02:00
flags2 | = D3D11_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP ;
}
// Format supports blending when used for rendering
2022-08-17 14:30:00 +02:00
if ( imgFeatures & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT )
2018-04-14 16:07:01 +02:00
flags1 | = D3D11_FORMAT_SUPPORT_BLENDABLE ;
// Format is a depth-stencil format that can be used for rendering
2022-08-17 14:30:00 +02:00
if ( imgFeatures & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT )
2018-04-14 16:07:01 +02:00
flags1 | = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL ;
2022-08-17 14:30:00 +02:00
// Report supported swap chain formats
2018-04-14 16:07:01 +02:00
if ( Format = = DXGI_FORMAT_R8G8B8A8_UNORM
| | Format = = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
| | Format = = DXGI_FORMAT_B8G8R8A8_UNORM
| | Format = = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
| | Format = = DXGI_FORMAT_R16G16B16A16_FLOAT
| | Format = = DXGI_FORMAT_R10G10B10A2_UNORM
| | Format = = DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM )
flags1 | = D3D11_FORMAT_SUPPORT_DISPLAY ;
// Query multisample support for this format
2022-08-17 14:30:00 +02:00
VkImageUsageFlags usage = ( fmtProperties - > aspectMask & VK_IMAGE_ASPECT_COLOR_BIT )
? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
: VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ;
auto limits = m_dxvkDevice - > getFormatLimits ( fmtMapping . Format ,
VK_IMAGE_TYPE_2D , VK_IMAGE_TILING_OPTIMAL , usage , 0 ) ;
if ( limits & & limits - > sampleCounts > VK_SAMPLE_COUNT_1_BIT ) {
2018-04-14 16:07:01 +02:00
flags1 | = D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET
| D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE
| D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD ;
}
2018-03-21 13:31:22 +01:00
}
2017-12-19 11:05:41 +01:00
2018-04-14 16:07:01 +02:00
// Format can be used for storage images or storage texel buffers
2022-08-17 14:30:00 +02:00
if ( ( bufFeatures & VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT )
& & ( imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT )
& & ( imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT ) ) {
2018-03-21 13:31:22 +01:00
flags1 | = D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW ;
flags2 | = D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE ;
2022-08-17 14:30:00 +02:00
if ( m_dxbcOptions . supportsTypedUavLoadR32 ) {
// If the R32 formats are supported without format declarations,
// we can optionally support additional formats for typed loads
if ( imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT )
flags2 | = D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD ;
} else {
// Otherwise, we need to emit format declarations, so we can
// only support the basic set of R32 formats for typed loads
if ( Format = = DXGI_FORMAT_R32_FLOAT
| | Format = = DXGI_FORMAT_R32_UINT
| | Format = = DXGI_FORMAT_R32_SINT )
flags2 | = D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD ;
}
2018-04-14 16:07:01 +02:00
2022-08-17 14:30:00 +02:00
if ( Format = = DXGI_FORMAT_R32_UINT | | Format = = DXGI_FORMAT_R32_SINT ) {
2018-04-14 16:07:01 +02:00
flags2 | = D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD
| D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS
| D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE
| D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE ;
}
if ( Format = = DXGI_FORMAT_R32_SINT )
flags2 | = D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX ;
if ( Format = = DXGI_FORMAT_R32_UINT )
flags2 | = D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX ;
2018-03-21 13:31:22 +01:00
}
2019-06-13 16:32:41 +02:00
// Mark everyting as CPU lockable
if ( flags1 | flags2 )
flags1 | = D3D11_FORMAT_SUPPORT_CPU_LOCKABLE ;
2017-12-19 11:05:41 +01:00
2018-04-14 16:07:01 +02:00
// Write back format support flags
2018-03-21 13:31:22 +01:00
if ( pFlags1 ! = nullptr ) * pFlags1 = flags1 ;
if ( pFlags2 ! = nullptr ) * pFlags2 = flags2 ;
2019-06-13 16:32:41 +02:00
return ( pFlags1 & & flags1 ) | | ( pFlags2 & & flags2 ) ? S_OK : E_FAIL ;
2017-12-19 11:05:41 +01:00
}
2018-01-11 12:23:55 +01:00
2018-04-14 16:07:01 +02:00
BOOL D3D11Device : : GetImageTypeSupport ( VkFormat Format , VkImageType Type ) const {
2022-08-17 14:30:00 +02:00
auto properties = m_dxvkDevice - > getFormatLimits ( Format ,
Type , VK_IMAGE_TILING_OPTIMAL , VK_IMAGE_USAGE_SAMPLED_BIT , 0 ) ;
2018-04-14 16:07:01 +02:00
2022-08-17 14:30:00 +02:00
if ( ! properties ) {
properties = m_dxvkDevice - > getFormatLimits ( Format ,
Type , VK_IMAGE_TILING_LINEAR , VK_IMAGE_USAGE_SAMPLED_BIT , 0 ) ;
2019-06-13 16:32:41 +02:00
}
2022-08-17 14:30:00 +02:00
return properties . has_value ( ) ;
2018-04-14 16:07:01 +02:00
}
2021-05-20 16:50:15 +02:00
uint32_t D3D11Device : : GetViewPlaneIndex (
ID3D11Resource * pResource ,
DXGI_FORMAT ViewFormat ) {
auto texture = GetCommonTexture ( pResource ) ;
if ( ! texture )
return 0 ;
uint32_t planeCount = texture - > GetPlaneCount ( ) ;
if ( planeCount = = 1 )
return 0 ;
auto formatMode = texture - > GetFormatMode ( ) ;
auto formatFamily = LookupFamily ( texture - > Desc ( ) - > Format , formatMode ) ;
auto viewFormat = LookupFormat ( ViewFormat , formatMode ) ;
for ( uint32_t i = 0 ; i < formatFamily . FormatCount ; i + + ) {
if ( formatFamily . Formats [ i ] = = viewFormat . Format )
return i % planeCount ;
}
return ~ 0u ;
}
2022-02-23 16:18:07 -05:00
template < bool IsKmtHandle >
HRESULT D3D11Device : : OpenSharedResourceGeneric (
HANDLE hResource ,
REFIID ReturnedInterface ,
void * * ppResource ) {
InitReturnPtr ( ppResource ) ;
if ( ppResource = = nullptr )
return S_FALSE ;
2022-08-21 19:05:59 +00:00
# ifdef _WIN32
2022-02-23 16:18:07 -05:00
HANDLE ntHandle = IsKmtHandle ? openKmtHandle ( hResource ) : hResource ;
if ( ntHandle = = INVALID_HANDLE_VALUE ) {
Logger : : warn ( str : : format ( " D3D11Device::OpenSharedResourceGeneric: Handle not found: " , hResource ) ) ;
return E_INVALIDARG ;
}
DxvkSharedTextureMetadata metadata ;
bool ret = getSharedMetadata ( ntHandle , & metadata , sizeof ( metadata ) , NULL ) ;
if ( IsKmtHandle )
: : CloseHandle ( ntHandle ) ;
if ( ! ret ) {
Logger : : warn ( " D3D11Device::OpenSharedResourceGeneric: Failed to get shared resource info for a texture " ) ;
return E_INVALIDARG ;
}
D3D11_COMMON_TEXTURE_DESC d3d11Desc ;
d3d11Desc . Width = metadata . Width ;
d3d11Desc . Height = metadata . Height ;
d3d11Desc . Depth = 1 ,
d3d11Desc . MipLevels = metadata . MipLevels ;
d3d11Desc . ArraySize = metadata . ArraySize ;
d3d11Desc . Format = metadata . Format ;
d3d11Desc . SampleDesc = metadata . SampleDesc ;
d3d11Desc . Usage = metadata . Usage ;
d3d11Desc . BindFlags = metadata . BindFlags ;
d3d11Desc . CPUAccessFlags = metadata . CPUAccessFlags ;
d3d11Desc . MiscFlags = metadata . MiscFlags ;
d3d11Desc . TextureLayout = metadata . TextureLayout ;
// Only 2D textures may be shared
try {
const Com < D3D11Texture2D > texture = new D3D11Texture2D ( this , & d3d11Desc , hResource ) ;
texture - > QueryInterface ( ReturnedInterface , ppResource ) ;
return S_OK ;
}
catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
return E_INVALIDARG ;
}
2022-08-21 19:05:59 +00:00
# else
Logger : : warn ( " D3D11Device::OpenSharedResourceGeneric: Not supported on this platform. " ) ;
return E_INVALIDARG ;
# endif
2022-02-23 16:18:07 -05:00
}
2019-09-17 19:13:49 +02:00
template < typename Void >
void D3D11Device : : CopySubresourceData (
Void * pData ,
UINT RowPitch ,
UINT DepthPitch ,
ID3D11Resource * pResource ,
UINT Subresource ,
const D3D11_BOX * pBox ) {
auto texture = GetCommonTexture ( pResource ) ;
if ( ! texture )
return ;
// Validate texture state and skip invalid calls
if ( texture - > Desc ( ) - > Usage ! = D3D11_USAGE_DEFAULT
| | texture - > GetMapMode ( ) = = D3D11_COMMON_TEXTURE_MAP_MODE_NONE
| | texture - > CountSubresources ( ) < = Subresource
| | texture - > GetMapType ( Subresource ) = = D3D11_MAP ( ~ 0u ) )
return ;
// Retrieve image format information
VkFormat packedFormat = LookupPackedFormat (
texture - > Desc ( ) - > Format ,
texture - > GetFormatMode ( ) ) . Format ;
2022-07-15 17:23:54 +02:00
auto formatInfo = lookupFormatInfo ( packedFormat ) ;
2019-09-17 19:13:49 +02:00
// Validate box against subresource dimensions
Rc < DxvkImage > image = texture - > GetImage ( ) ;
auto subresource = texture - > GetSubresourceFromIndex (
formatInfo - > aspectMask , Subresource ) ;
VkOffset3D offset = { 0 , 0 , 0 } ;
VkExtent3D extent = image - > mipLevelExtent ( subresource . mipLevel ) ;
if ( pBox ) {
if ( pBox - > left > = pBox - > right
| | pBox - > top > = pBox - > bottom
| | pBox - > front > = pBox - > back )
return ; // legal, but no-op
if ( pBox - > right > extent . width
| | pBox - > bottom > extent . height
| | pBox - > back > extent . depth )
return ; // out of bounds
offset = VkOffset3D {
int32_t ( pBox - > left ) ,
int32_t ( pBox - > top ) ,
int32_t ( pBox - > front ) } ;
extent = VkExtent3D {
pBox - > right - pBox - > left ,
pBox - > bottom - pBox - > top ,
pBox - > back - pBox - > front } ;
}
// We can only operate on full blocks of compressed images
offset = util : : computeBlockOffset ( offset , formatInfo - > blockSize ) ;
extent = util : : computeBlockCount ( extent , formatInfo - > blockSize ) ;
// Determine the memory layout of the image data
D3D11_MAPPED_SUBRESOURCE subresourceData = { } ;
if ( texture - > GetMapMode ( ) = = D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT ) {
VkSubresourceLayout layout = image - > querySubresourceLayout ( subresource ) ;
subresourceData . pData = image - > mapPtr ( layout . offset ) ;
subresourceData . RowPitch = layout . rowPitch ;
subresourceData . DepthPitch = layout . depthPitch ;
} else {
subresourceData . pData = texture - > GetMappedBuffer ( Subresource ) - > mapPtr ( 0 ) ;
subresourceData . RowPitch = formatInfo - > elementSize * extent . width ;
subresourceData . DepthPitch = formatInfo - > elementSize * extent . width * extent . height ;
}
if constexpr ( std : : is_const < Void > : : value ) {
// WriteToSubresource
auto src = reinterpret_cast < const char * > ( pData ) ;
auto dst = reinterpret_cast < char * > ( subresourceData . pData ) ;
for ( uint32_t z = 0 ; z < extent . depth ; z + + ) {
for ( uint32_t y = 0 ; y < extent . height ; y + + ) {
std : : memcpy (
dst + ( offset . z + z ) * subresourceData . DepthPitch
+ ( offset . y + y ) * subresourceData . RowPitch
+ ( offset . x ) * formatInfo - > elementSize ,
src + z * DepthPitch
+ y * RowPitch ,
formatInfo - > elementSize * extent . width ) ;
}
}
} else {
// ReadFromSubresource
auto src = reinterpret_cast < const char * > ( subresourceData . pData ) ;
auto dst = reinterpret_cast < char * > ( pData ) ;
for ( uint32_t z = 0 ; z < extent . depth ; z + + ) {
for ( uint32_t y = 0 ; y < extent . height ; y + + ) {
std : : memcpy (
dst + z * DepthPitch
+ y * RowPitch ,
src + ( offset . z + z ) * subresourceData . DepthPitch
+ ( offset . y + y ) * subresourceData . RowPitch
+ ( offset . x ) * formatInfo - > elementSize ,
formatInfo - > elementSize * extent . width ) ;
}
}
}
}
2019-11-08 11:25:58 +01:00
D3D_FEATURE_LEVEL D3D11Device : : GetMaxFeatureLevel ( const Rc < DxvkInstance > & pInstance ) {
2019-09-16 02:28:18 +02:00
static const std : : array < std : : pair < std : : string , D3D_FEATURE_LEVEL > , 9 > s_featureLevels = { {
{ " 12_1 " , D3D_FEATURE_LEVEL_12_1 } ,
{ " 12_0 " , D3D_FEATURE_LEVEL_12_0 } ,
2018-03-18 23:39:40 +01:00
{ " 11_1 " , D3D_FEATURE_LEVEL_11_1 } ,
2018-01-30 12:19:53 +01:00
{ " 11_0 " , D3D_FEATURE_LEVEL_11_0 } ,
{ " 10_1 " , D3D_FEATURE_LEVEL_10_1 } ,
{ " 10_0 " , D3D_FEATURE_LEVEL_10_0 } ,
{ " 9_3 " , D3D_FEATURE_LEVEL_9_3 } ,
{ " 9_2 " , D3D_FEATURE_LEVEL_9_2 } ,
{ " 9_1 " , D3D_FEATURE_LEVEL_9_1 } ,
} } ;
2019-11-08 11:25:58 +01:00
const std : : string maxLevel = pInstance - > config ( )
2018-08-09 21:08:03 +02:00
. getOption < std : : string > ( " d3d11.maxFeatureLevel " ) ;
2018-01-30 12:19:53 +01:00
auto entry = std : : find_if ( s_featureLevels . begin ( ) , s_featureLevels . end ( ) ,
[ & ] ( const std : : pair < std : : string , D3D_FEATURE_LEVEL > & pair ) {
return pair . first = = maxLevel ;
} ) ;
return entry ! = s_featureLevels . end ( )
? entry - > second
2018-09-18 16:27:40 +02:00
: D3D_FEATURE_LEVEL_11_1 ;
2018-01-30 12:19:53 +01:00
}
2018-12-03 19:26:29 +01:00
2019-04-24 19:49:03 +02:00
D3D11DeviceExt : : D3D11DeviceExt (
D3D11DXGIDevice * pContainer ,
D3D11Device * pDevice )
: m_container ( pContainer ) , m_device ( pDevice ) {
}
ULONG STDMETHODCALLTYPE D3D11DeviceExt : : AddRef ( ) {
return m_container - > AddRef ( ) ;
}
ULONG STDMETHODCALLTYPE D3D11DeviceExt : : Release ( ) {
return m_container - > Release ( ) ;
}
HRESULT STDMETHODCALLTYPE D3D11DeviceExt : : QueryInterface (
REFIID riid ,
void * * ppvObject ) {
return m_container - > QueryInterface ( riid , ppvObject ) ;
}
BOOL STDMETHODCALLTYPE D3D11DeviceExt : : GetExtensionSupport (
D3D11_VK_EXTENSION Extension ) {
2019-04-24 20:26:21 +02:00
const auto & deviceFeatures = m_device - > GetDXVKDevice ( ) - > features ( ) ;
2019-04-24 22:06:23 +02:00
const auto & deviceExtensions = m_device - > GetDXVKDevice ( ) - > extensions ( ) ;
2019-04-24 20:26:21 +02:00
2019-04-24 20:18:02 +02:00
switch ( Extension ) {
case D3D11_VK_EXT_BARRIER_CONTROL :
return true ;
2019-04-24 20:26:21 +02:00
case D3D11_VK_EXT_MULTI_DRAW_INDIRECT :
return deviceFeatures . core . features . multiDrawIndirect ;
2019-04-24 20:18:02 +02:00
2019-04-24 22:06:23 +02:00
case D3D11_VK_EXT_MULTI_DRAW_INDIRECT_COUNT :
return deviceFeatures . core . features . multiDrawIndirect
2022-07-14 19:50:38 +02:00
& & deviceFeatures . vk12 . drawIndirectCount ;
2019-04-24 22:48:07 +02:00
case D3D11_VK_EXT_DEPTH_BOUNDS :
return deviceFeatures . core . features . depthBounds ;
2021-09-17 13:30:49 -07:00
case D3D11_VK_NVX_IMAGE_VIEW_HANDLE :
return deviceExtensions . nvxImageViewHandle ;
case D3D11_VK_NVX_BINARY_IMPORT :
return deviceExtensions . nvxBinaryImport
2022-07-14 19:59:20 +02:00
& & deviceFeatures . vk12 . bufferDeviceAddress ;
2021-09-17 13:30:49 -07:00
2019-04-24 20:18:02 +02:00
default :
return false ;
}
2019-04-24 19:49:03 +02:00
}
2021-09-17 13:30:49 -07:00
bool STDMETHODCALLTYPE D3D11DeviceExt : : GetCudaTextureObjectNVX ( uint32_t srvDriverHandle , uint32_t samplerDriverHandle , uint32_t * pCudaTextureHandle ) {
ID3D11ShaderResourceView * srv = HandleToSrvNVX ( srvDriverHandle ) ;
if ( ! srv ) {
Logger : : warn ( str : : format ( " GetCudaTextureObjectNVX() failure - srv handle wasn't found: " , srvDriverHandle ) ) ;
return false ;
}
ID3D11SamplerState * samplerState = HandleToSamplerNVX ( samplerDriverHandle ) ;
if ( ! samplerState ) {
Logger : : warn ( str : : format ( " GetCudaTextureObjectNVX() failure - sampler handle wasn't found: " , samplerDriverHandle ) ) ;
return false ;
}
D3D11SamplerState * pSS = static_cast < D3D11SamplerState * > ( samplerState ) ;
Rc < DxvkSampler > pDSS = pSS - > GetDXVKSampler ( ) ;
VkSampler vkSampler = pDSS - > handle ( ) ;
D3D11ShaderResourceView * pSRV = static_cast < D3D11ShaderResourceView * > ( srv ) ;
Rc < DxvkImageView > pIV = pSRV - > GetImageView ( ) ;
VkImageView vkImageView = pIV - > handle ( ) ;
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX } ;
imageViewHandleInfo . imageView = vkImageView ;
imageViewHandleInfo . sampler = vkSampler ;
imageViewHandleInfo . descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ;
// note: there's no implicit lifetime management here; it's up to the
// app to keep the sampler and SRV alive as long as it wants to use this
// derived handle.
VkDevice vkDevice = m_device - > GetDXVKDevice ( ) - > handle ( ) ;
* pCudaTextureHandle = m_device - > GetDXVKDevice ( ) - > vkd ( ) - > vkGetImageViewHandleNVX ( vkDevice , & imageViewHandleInfo ) ;
if ( ! * pCudaTextureHandle ) {
Logger : : warn ( " GetCudaTextureObjectNVX() handle==0 - failed " ) ;
return false ;
}
return true ;
}
bool STDMETHODCALLTYPE D3D11DeviceExt : : CreateCubinComputeShaderWithNameNVX ( const void * pCubin , uint32_t size ,
uint32_t blockX , uint32_t blockY , uint32_t blockZ , const char * pShaderName , IUnknown * * phShader ) {
Rc < DxvkDevice > dxvkDevice = m_device - > GetDXVKDevice ( ) ;
VkDevice vkDevice = dxvkDevice - > handle ( ) ;
VkCuModuleCreateInfoNVX moduleCreateInfo = { VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX } ;
moduleCreateInfo . pData = pCubin ;
moduleCreateInfo . dataSize = size ;
VkCuModuleNVX cuModule ;
VkCuFunctionNVX cuFunction ;
VkResult result ;
if ( ( result = dxvkDevice - > vkd ( ) - > vkCreateCuModuleNVX ( vkDevice , & moduleCreateInfo , nullptr , & cuModule ) ) ) {
Logger : : warn ( str : : format ( " CreateCubinComputeShaderWithNameNVX() - failure to create module - result= " , result , " pcubindata= " , pCubin , " cubinsize= " , size ) ) ;
return false ; // failure
}
VkCuFunctionCreateInfoNVX functionCreateInfo = { VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX } ;
functionCreateInfo . module = cuModule ;
functionCreateInfo . pName = pShaderName ;
if ( ( result = dxvkDevice - > vkd ( ) - > vkCreateCuFunctionNVX ( vkDevice , & functionCreateInfo , nullptr , & cuFunction ) ) ) {
dxvkDevice - > vkd ( ) - > vkDestroyCuModuleNVX ( vkDevice , cuModule , nullptr ) ;
Logger : : warn ( str : : format ( " CreateCubinComputeShaderWithNameNVX() - failure to create function - result= " , result ) ) ;
return false ;
}
* phShader = ref ( new CubinShaderWrapper ( dxvkDevice ,
cuModule , cuFunction , { blockX , blockY , blockZ } ) ) ;
return true ;
}
bool STDMETHODCALLTYPE D3D11DeviceExt : : GetResourceHandleGPUVirtualAddressAndSizeNVX ( void * hObject , uint64_t * gpuVAStart , uint64_t * gpuVASize ) {
// The hObject 'opaque driver handle' is really just a straight cast
// of the corresponding ID3D11Resource* in dxvk/dxvknvapi
ID3D11Resource * pResource = static_cast < ID3D11Resource * > ( hObject ) ;
D3D11_COMMON_RESOURCE_DESC resourceDesc ;
if ( FAILED ( GetCommonResourceDesc ( pResource , & resourceDesc ) ) ) {
Logger : : warn ( " GetResourceHandleGPUVirtualAddressAndSize() - GetCommonResourceDesc() failed " ) ;
return false ;
}
switch ( resourceDesc . Dim ) {
case D3D11_RESOURCE_DIMENSION_BUFFER :
case D3D11_RESOURCE_DIMENSION_TEXTURE2D :
// okay - we can deal with those two dimensions
break ;
case D3D11_RESOURCE_DIMENSION_TEXTURE1D :
case D3D11_RESOURCE_DIMENSION_TEXTURE3D :
case D3D11_RESOURCE_DIMENSION_UNKNOWN :
default :
Logger : : warn ( str : : format ( " GetResourceHandleGPUVirtualAddressAndSize(?) - failure - unsupported dimension: " , resourceDesc . Dim ) ) ;
return false ;
}
Rc < DxvkDevice > dxvkDevice = m_device - > GetDXVKDevice ( ) ;
VkDevice vkDevice = dxvkDevice - > handle ( ) ;
if ( resourceDesc . Dim = = D3D11_RESOURCE_DIMENSION_TEXTURE2D ) {
D3D11CommonTexture * texture = GetCommonTexture ( pResource ) ;
Rc < DxvkImage > dxvkImage = texture - > GetImage ( ) ;
if ( 0 = = ( dxvkImage - > info ( ) . usage & ( VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT ) ) ) {
Logger : : warn ( str : : format ( " GetResourceHandleGPUVirtualAddressAndSize(res= " , pResource , " ) image info missing required usage bit(s); can't be used for vkGetImageViewHandleNVX - failure " ) ) ;
return false ;
}
// The d3d11 nvapi provides us a texture but vulkan only lets us get the GPU address from an imageview. So, make a private imageview and get the address from that...
D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc ;
const D3D11_COMMON_TEXTURE_DESC * texDesc = texture - > Desc ( ) ;
if ( texDesc - > ArraySize ! = 1 ) {
Logger : : debug ( str : : format ( " GetResourceHandleGPUVirtualAddressAndSize(?) - unexpected array size: " , texDesc - > ArraySize ) ) ;
}
resourceViewDesc . Format = texDesc - > Format ;
resourceViewDesc . ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D ;
resourceViewDesc . Texture2D . MostDetailedMip = 0 ;
resourceViewDesc . Texture2D . MipLevels = texDesc - > MipLevels ;
Com < ID3D11ShaderResourceView > pNewSRV ;
HRESULT hr = m_device - > CreateShaderResourceView ( pResource , & resourceViewDesc , & pNewSRV ) ;
if ( FAILED ( hr ) ) {
Logger : : warn ( " GetResourceHandleGPUVirtualAddressAndSize() - private CreateShaderResourceView() failed " ) ;
return false ;
}
Rc < DxvkImageView > dxvkImageView = static_cast < D3D11ShaderResourceView * > ( pNewSRV . ptr ( ) ) - > GetImageView ( ) ;
VkImageView vkImageView = dxvkImageView - > handle ( ) ;
VkImageViewAddressPropertiesNVX imageViewAddressProperties = { VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX } ;
VkResult res = dxvkDevice - > vkd ( ) - > vkGetImageViewAddressNVX ( vkDevice , vkImageView , & imageViewAddressProperties ) ;
if ( res ! = VK_SUCCESS ) {
Logger : : warn ( str : : format ( " GetResourceHandleGPUVirtualAddressAndSize(): vkGetImageViewAddressNVX() result is failure: " , res ) ) ;
return false ;
}
* gpuVAStart = imageViewAddressProperties . deviceAddress ;
* gpuVASize = imageViewAddressProperties . size ;
}
else if ( resourceDesc . Dim = = D3D11_RESOURCE_DIMENSION_BUFFER ) {
D3D11Buffer * buffer = GetCommonBuffer ( pResource ) ;
const DxvkBufferSliceHandle bufSliceHandle = buffer - > GetBuffer ( ) - > getSliceHandle ( ) ;
VkBuffer vkBuffer = bufSliceHandle . handle ;
2022-07-14 19:59:20 +02:00
VkBufferDeviceAddressInfo bdaInfo = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO } ;
2021-09-17 13:30:49 -07:00
bdaInfo . buffer = vkBuffer ;
2022-07-14 19:59:20 +02:00
VkDeviceAddress bufAddr = dxvkDevice - > vkd ( ) - > vkGetBufferDeviceAddress ( vkDevice , & bdaInfo ) ;
2021-09-17 13:30:49 -07:00
* gpuVAStart = uint64_t ( bufAddr ) + bufSliceHandle . offset ;
* gpuVASize = bufSliceHandle . length ;
}
if ( ! * gpuVAStart )
Logger : : warn ( " GetResourceHandleGPUVirtualAddressAndSize() addr==0 - unexpected " ) ; // ... but not explicitly a failure; continue
return true ;
}
bool STDMETHODCALLTYPE D3D11DeviceExt : : CreateUnorderedAccessViewAndGetDriverHandleNVX ( ID3D11Resource * pResource , const D3D11_UNORDERED_ACCESS_VIEW_DESC * pDesc , ID3D11UnorderedAccessView * * ppUAV , uint32_t * pDriverHandle ) {
D3D11_COMMON_RESOURCE_DESC resourceDesc ;
if ( ! SUCCEEDED ( GetCommonResourceDesc ( pResource , & resourceDesc ) ) ) {
Logger : : warn ( " CreateUnorderedAccessViewAndGetDriverHandleNVX() - GetCommonResourceDesc() failed " ) ;
return false ;
}
if ( resourceDesc . Dim ! = D3D11_RESOURCE_DIMENSION_TEXTURE2D ) {
Logger : : warn ( str : : format ( " CreateUnorderedAccessViewAndGetDriverHandleNVX() - failure - unsupported dimension: " , resourceDesc . Dim ) ) ;
return false ;
}
auto texture = GetCommonTexture ( pResource ) ;
Rc < DxvkImage > dxvkImage = texture - > GetImage ( ) ;
if ( 0 = = ( dxvkImage - > info ( ) . usage & ( VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT ) ) ) {
Logger : : warn ( str : : format ( " CreateUnorderedAccessViewAndGetDriverHandleNVX(res= " , pResource , " ) image info missing required usage bit(s); can't be used for vkGetImageViewHandleNVX - failure " ) ) ;
return false ;
}
if ( ! SUCCEEDED ( m_device - > CreateUnorderedAccessView ( pResource , pDesc , ppUAV ) ) ) {
return false ;
}
D3D11UnorderedAccessView * pUAV = static_cast < D3D11UnorderedAccessView * > ( * ppUAV ) ;
Rc < DxvkDevice > dxvkDevice = m_device - > GetDXVKDevice ( ) ;
VkDevice vkDevice = dxvkDevice - > handle ( ) ;
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX } ;
Rc < DxvkImageView > dxvkImageView = pUAV - > GetImageView ( ) ;
VkImageView vkImageView = dxvkImageView - > handle ( ) ;
imageViewHandleInfo . imageView = vkImageView ;
imageViewHandleInfo . descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ;
* pDriverHandle = dxvkDevice - > vkd ( ) - > vkGetImageViewHandleNVX ( vkDevice , & imageViewHandleInfo ) ;
if ( ! * pDriverHandle ) {
Logger : : warn ( " CreateUnorderedAccessViewAndGetDriverHandleNVX() handle==0 - failure " ) ;
pUAV - > Release ( ) ;
return false ;
}
return true ;
}
bool STDMETHODCALLTYPE D3D11DeviceExt : : CreateShaderResourceViewAndGetDriverHandleNVX ( ID3D11Resource * pResource , const D3D11_SHADER_RESOURCE_VIEW_DESC * pDesc , ID3D11ShaderResourceView * * ppSRV , uint32_t * pDriverHandle ) {
D3D11_COMMON_RESOURCE_DESC resourceDesc ;
if ( ! SUCCEEDED ( GetCommonResourceDesc ( pResource , & resourceDesc ) ) ) {
Logger : : warn ( " CreateShaderResourceViewAndGetDriverHandleNVX() - GetCommonResourceDesc() failed " ) ;
return false ;
}
if ( resourceDesc . Dim ! = D3D11_RESOURCE_DIMENSION_TEXTURE2D ) {
Logger : : warn ( str : : format ( " CreateShaderResourceViewAndGetDriverHandleNVX() - failure - unsupported dimension: " , resourceDesc . Dim ) ) ;
return false ;
}
auto texture = GetCommonTexture ( pResource ) ;
Rc < DxvkImage > dxvkImage = texture - > GetImage ( ) ;
if ( 0 = = ( dxvkImage - > info ( ) . usage & ( VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT ) ) ) {
Logger : : warn ( str : : format ( " CreateShaderResourceViewAndGetDriverHandleNVX(res= " , pResource , " ) image info missing required usage bit(s); can't be used for vkGetImageViewHandleNVX - failure " ) ) ;
return false ;
}
if ( ! SUCCEEDED ( m_device - > CreateShaderResourceView ( pResource , pDesc , ppSRV ) ) ) {
return false ;
}
D3D11ShaderResourceView * pSRV = static_cast < D3D11ShaderResourceView * > ( * ppSRV ) ;
Rc < DxvkDevice > dxvkDevice = m_device - > GetDXVKDevice ( ) ;
VkDevice vkDevice = dxvkDevice - > handle ( ) ;
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX } ;
Rc < DxvkImageView > dxvkImageView = pSRV - > GetImageView ( ) ;
VkImageView vkImageView = dxvkImageView - > handle ( ) ;
imageViewHandleInfo . imageView = vkImageView ;
imageViewHandleInfo . descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ;
* pDriverHandle = dxvkDevice - > vkd ( ) - > vkGetImageViewHandleNVX ( vkDevice , & imageViewHandleInfo ) ;
if ( ! * pDriverHandle ) {
Logger : : warn ( " CreateShaderResourceViewAndGetDriverHandleNVX() handle==0 - failure " ) ;
pSRV - > Release ( ) ;
return false ;
}
// will need to look-up resource from uint32 handle later
AddSrvAndHandleNVX ( * ppSRV , * pDriverHandle ) ;
return true ;
}
bool STDMETHODCALLTYPE D3D11DeviceExt : : CreateSamplerStateAndGetDriverHandleNVX ( const D3D11_SAMPLER_DESC * pSamplerDesc , ID3D11SamplerState * * ppSamplerState , uint32_t * pDriverHandle ) {
if ( ! SUCCEEDED ( m_device - > CreateSamplerState ( pSamplerDesc , ppSamplerState ) ) ) {
return false ;
}
// for our purposes the actual value doesn't matter, only its uniqueness
2021-10-21 23:56:11 +00:00
static std : : atomic < ULONG > s_seqNum = 0 ;
* pDriverHandle = + + s_seqNum ;
2021-09-17 13:30:49 -07:00
// will need to look-up sampler from uint32 handle later
AddSamplerAndHandleNVX ( * ppSamplerState , * pDriverHandle ) ;
return true ;
}
void D3D11DeviceExt : : AddSamplerAndHandleNVX ( ID3D11SamplerState * pSampler , uint32_t Handle ) {
std : : lock_guard lock ( m_mapLock ) ;
m_samplerHandleToPtr [ Handle ] = pSampler ;
}
ID3D11SamplerState * D3D11DeviceExt : : HandleToSamplerNVX ( uint32_t Handle ) {
std : : lock_guard lock ( m_mapLock ) ;
auto got = m_samplerHandleToPtr . find ( Handle ) ;
if ( got = = m_samplerHandleToPtr . end ( ) )
return nullptr ;
return static_cast < ID3D11SamplerState * > ( got - > second ) ;
}
void D3D11DeviceExt : : AddSrvAndHandleNVX ( ID3D11ShaderResourceView * pSrv , uint32_t Handle ) {
std : : lock_guard lock ( m_mapLock ) ;
m_srvHandleToPtr [ Handle ] = pSrv ;
}
ID3D11ShaderResourceView * D3D11DeviceExt : : HandleToSrvNVX ( uint32_t Handle ) {
std : : lock_guard lock ( m_mapLock ) ;
auto got = m_srvHandleToPtr . find ( Handle ) ;
if ( got = = m_srvHandleToPtr . end ( ) )
return nullptr ;
return static_cast < ID3D11ShaderResourceView * > ( got - > second ) ;
}
2019-04-24 19:49:03 +02:00
2021-05-04 16:17:37 +02:00
D3D11VideoDevice : : D3D11VideoDevice (
D3D11DXGIDevice * pContainer ,
D3D11Device * pDevice )
: m_container ( pContainer ) , m_device ( pDevice ) {
}
D3D11VideoDevice : : ~ D3D11VideoDevice ( ) {
}
ULONG STDMETHODCALLTYPE D3D11VideoDevice : : AddRef ( ) {
return m_container - > AddRef ( ) ;
}
ULONG STDMETHODCALLTYPE D3D11VideoDevice : : Release ( ) {
return m_container - > Release ( ) ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : QueryInterface (
REFIID riid ,
void * * ppvObject ) {
return m_container - > QueryInterface ( riid , ppvObject ) ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateVideoDecoder (
const D3D11_VIDEO_DECODER_DESC * pVideoDesc ,
const D3D11_VIDEO_DECODER_CONFIG * pConfig ,
ID3D11VideoDecoder * * ppDecoder ) {
Logger : : err ( " D3D11VideoDevice::CreateVideoDecoder: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateVideoProcessor (
ID3D11VideoProcessorEnumerator * pEnum ,
UINT RateConversionIndex ,
ID3D11VideoProcessor * * ppVideoProcessor ) {
2021-05-04 17:42:41 +02:00
try {
auto enumerator = static_cast < D3D11VideoProcessorEnumerator * > ( pEnum ) ;
* ppVideoProcessor = ref ( new D3D11VideoProcessor ( m_device , enumerator , RateConversionIndex ) ) ;
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
return E_FAIL ;
}
2021-05-04 16:17:37 +02:00
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateAuthenticatedChannel (
D3D11_AUTHENTICATED_CHANNEL_TYPE ChannelType ,
ID3D11AuthenticatedChannel * * ppAuthenticatedChannel ) {
Logger : : err ( " D3D11VideoDevice::CreateAuthenticatedChannel: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateCryptoSession (
const GUID * pCryptoType ,
const GUID * pDecoderProfile ,
const GUID * pKeyExchangeType ,
ID3D11CryptoSession * * ppCryptoSession ) {
Logger : : err ( " D3D11VideoDevice::CreateCryptoSession: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateVideoDecoderOutputView (
ID3D11Resource * pResource ,
const D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC * pDesc ,
ID3D11VideoDecoderOutputView * * ppVDOVView ) {
Logger : : err ( " D3D11VideoDevice::CreateVideoDecoderOutputView: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateVideoProcessorInputView (
ID3D11Resource * pResource ,
ID3D11VideoProcessorEnumerator * pEnum ,
const D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC * pDesc ,
ID3D11VideoProcessorInputView * * ppVPIView ) {
2021-05-06 15:46:44 +02:00
try {
* ppVPIView = ref ( new D3D11VideoProcessorInputView ( m_device , pResource , * pDesc ) ) ;
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
return E_FAIL ;
}
2021-05-04 16:17:37 +02:00
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateVideoProcessorOutputView (
ID3D11Resource * pResource ,
ID3D11VideoProcessorEnumerator * pEnum ,
const D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC * pDesc ,
ID3D11VideoProcessorOutputView * * ppVPOView ) {
2021-05-06 15:46:44 +02:00
try {
* ppVPOView = ref ( new D3D11VideoProcessorOutputView ( m_device , pResource , * pDesc ) ) ;
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
return E_FAIL ;
}
2021-05-04 16:17:37 +02:00
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CreateVideoProcessorEnumerator (
const D3D11_VIDEO_PROCESSOR_CONTENT_DESC * pDesc ,
ID3D11VideoProcessorEnumerator * * ppEnum ) {
2021-05-04 16:50:23 +02:00
try {
* ppEnum = ref ( new D3D11VideoProcessorEnumerator ( m_device , * pDesc ) ) ;
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
return E_FAIL ;
}
2021-05-04 16:17:37 +02:00
}
UINT STDMETHODCALLTYPE D3D11VideoDevice : : GetVideoDecoderProfileCount ( ) {
Logger : : err ( " D3D11VideoDevice::GetVideoDecoderProfileCount: Stub " ) ;
return 0 ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : GetVideoDecoderProfile (
UINT Index ,
GUID * pDecoderProfile ) {
Logger : : err ( " D3D11VideoDevice::GetVideoDecoderProfile: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CheckVideoDecoderFormat (
const GUID * pDecoderProfile ,
DXGI_FORMAT Format ,
BOOL * pSupported ) {
Logger : : err ( " D3D11VideoDevice::CheckVideoDecoderFormat: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : GetVideoDecoderConfigCount (
const D3D11_VIDEO_DECODER_DESC * pDesc ,
UINT * pCount ) {
Logger : : err ( " D3D11VideoDevice::GetVideoDecoderConfigCount: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : GetVideoDecoderConfig (
const D3D11_VIDEO_DECODER_DESC * pDesc ,
UINT Index ,
D3D11_VIDEO_DECODER_CONFIG * pConfig ) {
Logger : : err ( " D3D11VideoDevice::GetVideoDecoderConfig: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : GetContentProtectionCaps (
const GUID * pCryptoType ,
const GUID * pDecoderProfile ,
D3D11_VIDEO_CONTENT_PROTECTION_CAPS * pCaps ) {
Logger : : err ( " D3D11VideoDevice::GetContentProtectionCaps: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : CheckCryptoKeyExchange (
const GUID * pCryptoType ,
const GUID * pDecoderProfile ,
UINT Index ,
GUID * pKeyExchangeType ) {
Logger : : err ( " D3D11VideoDevice::CheckCryptoKeyExchange: Stub " ) ;
return E_NOTIMPL ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : SetPrivateData (
REFGUID Name ,
UINT DataSize ,
const void * pData ) {
return m_container - > SetPrivateData ( Name , DataSize , pData ) ;
}
HRESULT STDMETHODCALLTYPE D3D11VideoDevice : : SetPrivateDataInterface (
REFGUID Name ,
const IUnknown * pData ) {
return m_container - > SetPrivateDataInterface ( Name , pData ) ;
}
2018-12-21 15:53:29 +01:00
WineDXGISwapChainFactory : : WineDXGISwapChainFactory (
2019-02-11 19:54:01 +01:00
D3D11DXGIDevice * pContainer ,
D3D11Device * pDevice )
: m_container ( pContainer ) , m_device ( pDevice ) {
2018-12-21 12:23:45 +01:00
}
ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory : : AddRef ( ) {
2018-12-21 15:53:29 +01:00
return m_device - > AddRef ( ) ;
2018-12-21 12:23:45 +01:00
}
ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory : : Release ( ) {
2018-12-21 15:53:29 +01:00
return m_device - > Release ( ) ;
2018-12-21 12:23:45 +01:00
}
HRESULT STDMETHODCALLTYPE WineDXGISwapChainFactory : : QueryInterface (
REFIID riid ,
void * * ppvObject ) {
2018-12-21 15:53:29 +01:00
return m_device - > QueryInterface ( riid , ppvObject ) ;
2018-12-21 12:23:45 +01:00
}
HRESULT STDMETHODCALLTYPE WineDXGISwapChainFactory : : CreateSwapChainForHwnd (
IDXGIFactory * pFactory ,
HWND hWnd ,
const DXGI_SWAP_CHAIN_DESC1 * pDesc ,
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC * pFullscreenDesc ,
IDXGIOutput * pRestrictToOutput ,
IDXGISwapChain1 * * ppSwapChain ) {
InitReturnPtr ( ppSwapChain ) ;
2018-12-21 15:53:29 +01:00
if ( ! ppSwapChain | | ! pDesc | | ! hWnd )
2018-12-21 12:23:45 +01:00
return DXGI_ERROR_INVALID_CALL ;
2018-12-21 15:53:29 +01:00
2019-02-11 19:48:47 +01:00
// Make sure the back buffer size is not zero
DXGI_SWAP_CHAIN_DESC1 desc = * pDesc ;
2022-08-09 13:06:48 +01:00
wsi : : getWindowSize ( hWnd ,
2019-02-11 19:48:47 +01:00
desc . Width ? nullptr : & desc . Width ,
desc . Height ? nullptr : & desc . Height ) ;
// If necessary, set up a default set of
// fullscreen parameters for the swap chain
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc ;
if ( pFullscreenDesc ) {
fsDesc = * pFullscreenDesc ;
} else {
fsDesc . RefreshRate = { 0 , 0 } ;
fsDesc . ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED ;
fsDesc . Scaling = DXGI_MODE_SCALING_UNSPECIFIED ;
fsDesc . Windowed = TRUE ;
}
try {
2019-02-11 19:54:01 +01:00
// Create presenter for the device
Com < D3D11SwapChain > presenter = new D3D11SwapChain (
m_container , m_device , hWnd , & desc ) ;
// Create the actual swap chain
2019-02-11 19:48:47 +01:00
* ppSwapChain = ref ( new DxgiSwapChain (
pFactory , presenter . ptr ( ) , hWnd , & desc , & fsDesc ) ) ;
return S_OK ;
} catch ( const DxvkError & e ) {
Logger : : err ( e . message ( ) ) ;
2019-10-01 22:27:03 +02:00
return E_INVALIDARG ;
2019-02-11 19:48:47 +01:00
}
2018-12-21 12:23:45 +01:00
}
2020-01-28 13:38:27 +01:00
DXGIDXVKDevice : : DXGIDXVKDevice ( D3D11DXGIDevice * pContainer )
: m_container ( pContainer ) , m_apiVersion ( 11 ) {
}
ULONG STDMETHODCALLTYPE DXGIDXVKDevice : : AddRef ( ) {
return m_container - > AddRef ( ) ;
}
2018-12-21 12:23:45 +01:00
2020-01-28 13:38:27 +01:00
ULONG STDMETHODCALLTYPE DXGIDXVKDevice : : Release ( ) {
return m_container - > Release ( ) ;
}
HRESULT STDMETHODCALLTYPE DXGIDXVKDevice : : QueryInterface (
REFIID riid ,
void * * ppvObject ) {
return m_container - > QueryInterface ( riid , ppvObject ) ;
}
void STDMETHODCALLTYPE DXGIDXVKDevice : : SetAPIVersion (
UINT Version ) {
m_apiVersion = Version ;
}
UINT STDMETHODCALLTYPE DXGIDXVKDevice : : GetAPIVersion ( ) {
return m_apiVersion ;
}
2018-12-21 12:23:45 +01:00
2020-01-28 13:38:27 +01:00
2018-12-03 19:26:29 +01:00
D3D11DXGIDevice : : D3D11DXGIDevice (
IDXGIAdapter * pAdapter ,
2019-11-08 11:25:58 +01:00
const Rc < DxvkInstance > & pDxvkInstance ,
const Rc < DxvkAdapter > & pDxvkAdapter ,
2018-12-03 19:26:29 +01:00
D3D_FEATURE_LEVEL FeatureLevel ,
UINT FeatureFlags )
: m_dxgiAdapter ( pAdapter ) ,
2019-11-08 11:25:58 +01:00
m_dxvkInstance ( pDxvkInstance ) ,
2018-12-03 19:26:29 +01:00
m_dxvkAdapter ( pDxvkAdapter ) ,
m_dxvkDevice ( CreateDevice ( FeatureLevel ) ) ,
m_d3d11Device ( this , FeatureLevel , FeatureFlags ) ,
2019-04-24 19:49:03 +02:00
m_d3d11DeviceExt ( this , & m_d3d11Device ) ,
2018-12-21 12:23:45 +01:00
m_d3d11Interop ( this , & m_d3d11Device ) ,
2021-05-04 16:17:37 +02:00
m_d3d11Video ( this , & m_d3d11Device ) ,
2020-01-28 13:38:27 +01:00
m_metaDevice ( this ) ,
2019-11-25 17:45:28 +01:00
m_wineFactory ( this , & m_d3d11Device ) {
2018-12-03 19:26:29 +01:00
}
D3D11DXGIDevice : : ~ D3D11DXGIDevice ( ) {
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : QueryInterface ( REFIID riid , void * * ppvObject ) {
2019-02-10 07:01:01 +00:00
if ( ppvObject = = nullptr )
return E_POINTER ;
2018-12-03 19:26:29 +01:00
* ppvObject = nullptr ;
if ( riid = = __uuidof ( IUnknown )
| | riid = = __uuidof ( IDXGIObject )
| | riid = = __uuidof ( IDXGIDevice )
| | riid = = __uuidof ( IDXGIDevice1 )
| | riid = = __uuidof ( IDXGIDevice2 )
2019-09-20 16:59:31 +02:00
| | riid = = __uuidof ( IDXGIDevice3 )
| | riid = = __uuidof ( IDXGIDevice4 ) ) {
2018-12-03 19:26:29 +01:00
* ppvObject = ref ( this ) ;
return S_OK ;
}
2020-12-29 15:39:04 -06:00
if ( riid = = __uuidof ( IDXGIVkInteropDevice )
| | riid = = __uuidof ( IDXGIVkInteropDevice1 ) ) {
2018-12-03 19:26:29 +01:00
* ppvObject = ref ( & m_d3d11Interop ) ;
return S_OK ;
}
if ( riid = = __uuidof ( ID3D10Device )
| | riid = = __uuidof ( ID3D10Device1 ) ) {
* ppvObject = ref ( m_d3d11Device . GetD3D10Interface ( ) ) ;
return S_OK ;
}
if ( riid = = __uuidof ( ID3D11Device )
2019-09-15 18:40:57 +02:00
| | riid = = __uuidof ( ID3D11Device1 )
2019-09-16 16:04:06 +02:00
| | riid = = __uuidof ( ID3D11Device2 )
2019-09-16 16:26:03 +02:00
| | riid = = __uuidof ( ID3D11Device3 )
2019-09-16 16:37:37 +02:00
| | riid = = __uuidof ( ID3D11Device4 )
| | riid = = __uuidof ( ID3D11Device5 ) ) {
2018-12-03 19:26:29 +01:00
* ppvObject = ref ( & m_d3d11Device ) ;
return S_OK ;
}
2021-09-17 13:30:49 -07:00
if ( riid = = __uuidof ( ID3D11VkExtDevice )
| | riid = = __uuidof ( ID3D11VkExtDevice1 ) ) {
2019-04-24 19:49:03 +02:00
* ppvObject = ref ( & m_d3d11DeviceExt ) ;
return S_OK ;
}
2020-01-28 13:38:27 +01:00
if ( riid = = __uuidof ( IDXGIDXVKDevice ) ) {
* ppvObject = ref ( & m_metaDevice ) ;
return S_OK ;
}
2018-12-21 12:23:45 +01:00
if ( riid = = __uuidof ( IWineDXGISwapChainFactory ) ) {
* ppvObject = ref ( & m_wineFactory ) ;
return S_OK ;
}
2018-12-03 19:26:29 +01:00
2021-05-04 16:17:37 +02:00
if ( riid = = __uuidof ( ID3D11VideoDevice ) ) {
* ppvObject = ref ( & m_d3d11Video ) ;
return S_OK ;
}
2018-12-03 19:26:29 +01:00
if ( riid = = __uuidof ( ID3D10Multithread ) ) {
2018-12-30 20:38:35 +01:00
Com < ID3D11DeviceContext > context ;
m_d3d11Device . GetImmediateContext ( & context ) ;
return context - > QueryInterface ( riid , ppvObject ) ;
2018-12-03 19:26:29 +01:00
}
2021-05-04 16:17:37 +02:00
2018-12-03 19:26:29 +01:00
if ( riid = = __uuidof ( ID3D11Debug ) )
return E_NOINTERFACE ;
// Undocumented interfaces that are queried by some games
if ( riid = = GUID { 0xd56e2a4c , 0x5127 , 0x8437 , { 0x65 , 0x8a , 0x98 , 0xc5 , 0xbb , 0x78 , 0x94 , 0x98 } } )
return E_NOINTERFACE ;
Logger : : warn ( " D3D11DXGIDevice::QueryInterface: Unknown interface query " ) ;
Logger : : warn ( str : : format ( riid ) ) ;
return E_NOINTERFACE ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : GetParent (
REFIID riid ,
void * * ppParent ) {
return m_dxgiAdapter - > QueryInterface ( riid , ppParent ) ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : CreateSurface (
const DXGI_SURFACE_DESC * pDesc ,
UINT NumSurfaces ,
DXGI_USAGE Usage ,
const DXGI_SHARED_RESOURCE * pSharedResource ,
IDXGISurface * * ppSurface ) {
2019-10-02 02:29:06 +02:00
if ( ! pDesc | | ( NumSurfaces & & ! ppSurface ) )
return E_INVALIDARG ;
2018-12-03 19:26:29 +01:00
2019-10-02 02:29:06 +02:00
D3D11_TEXTURE2D_DESC desc ;
desc . Width = pDesc - > Width ;
desc . Height = pDesc - > Height ;
desc . MipLevels = 1 ;
desc . ArraySize = 1 ;
desc . Format = pDesc - > Format ;
desc . SampleDesc = pDesc - > SampleDesc ;
desc . BindFlags = 0 ;
desc . MiscFlags = 0 ;
// Handle bind flags
if ( Usage & DXGI_USAGE_RENDER_TARGET_OUTPUT )
desc . BindFlags | = D3D11_BIND_RENDER_TARGET ;
if ( Usage & DXGI_USAGE_SHADER_INPUT )
desc . BindFlags | = D3D11_BIND_SHADER_RESOURCE ;
if ( Usage & DXGI_USAGE_UNORDERED_ACCESS )
desc . BindFlags | = D3D11_BIND_UNORDERED_ACCESS ;
// Handle CPU access flags
switch ( Usage & DXGI_CPU_ACCESS_FIELD ) {
case DXGI_CPU_ACCESS_NONE :
desc . Usage = D3D11_USAGE_DEFAULT ;
desc . CPUAccessFlags = 0 ;
break ;
case DXGI_CPU_ACCESS_DYNAMIC :
desc . Usage = D3D11_USAGE_DYNAMIC ;
desc . CPUAccessFlags = D3D11_CPU_ACCESS_WRITE ;
break ;
case DXGI_CPU_ACCESS_READ_WRITE :
case DXGI_CPU_ACCESS_SCRATCH :
desc . Usage = D3D11_USAGE_STAGING ;
desc . CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE ;
2019-10-02 12:04:43 +02:00
break ;
2019-10-02 02:29:06 +02:00
default :
return E_INVALIDARG ;
}
// Restrictions and limitations of CreateSurface are not
// well-documented, so we'll be a lenient on validation.
HRESULT hr = m_d3d11Device . CreateTexture2D ( & desc , nullptr , nullptr ) ;
if ( FAILED ( hr ) )
return hr ;
// We don't support shared resources
if ( NumSurfaces & & pSharedResource )
Logger : : err ( " D3D11: CreateSurface: Shared surfaces not supported " ) ;
// Try to create the given number of surfaces
uint32_t surfacesCreated = 0 ;
hr = S_OK ;
for ( uint32_t i = 0 ; i < NumSurfaces ; i + + ) {
Com < ID3D11Texture2D > texture ;
hr = m_d3d11Device . CreateTexture2D ( & desc , nullptr , & texture ) ;
if ( SUCCEEDED ( hr ) ) {
hr = texture - > QueryInterface ( __uuidof ( IDXGISurface ) ,
reinterpret_cast < void * * > ( & ppSurface [ i ] ) ) ;
surfacesCreated = i + 1 ;
}
if ( FAILED ( hr ) )
break ;
}
// Don't leak surfaces if we failed to create one
if ( FAILED ( hr ) ) {
for ( uint32_t i = 0 ; i < surfacesCreated ; i + + )
ppSurface [ i ] - > Release ( ) ;
}
return hr ;
2018-12-03 19:26:29 +01:00
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : GetAdapter (
IDXGIAdapter * * pAdapter ) {
if ( pAdapter = = nullptr )
return DXGI_ERROR_INVALID_CALL ;
* pAdapter = m_dxgiAdapter . ref ( ) ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : GetGPUThreadPriority (
INT * pPriority ) {
* pPriority = 0 ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : QueryResourceResidency (
IUnknown * const * ppResources ,
DXGI_RESIDENCY * pResidencyStatus ,
UINT NumResources ) {
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
Logger : : err ( " D3D11DXGIDevice::QueryResourceResidency: Stub " ) ;
if ( ! ppResources | | ! pResidencyStatus )
return E_INVALIDARG ;
for ( uint32_t i = 0 ; i < NumResources ; i + + )
pResidencyStatus [ i ] = DXGI_RESIDENCY_FULLY_RESIDENT ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : SetGPUThreadPriority (
INT Priority ) {
if ( Priority < - 7 | | Priority > 7 )
return E_INVALIDARG ;
Logger : : err ( " DXGI: SetGPUThreadPriority: Ignoring " ) ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : GetMaximumFrameLatency (
UINT * pMaxLatency ) {
2019-06-11 16:36:43 +02:00
if ( ! pMaxLatency )
return DXGI_ERROR_INVALID_CALL ;
2018-12-03 19:26:29 +01:00
* pMaxLatency = m_frameLatency ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : SetMaximumFrameLatency (
UINT MaxLatency ) {
if ( MaxLatency = = 0 )
MaxLatency = DefaultFrameLatency ;
2019-11-25 17:45:28 +01:00
if ( MaxLatency > DXGI_MAX_SWAP_CHAIN_BUFFERS )
2019-10-01 22:10:34 +02:00
return DXGI_ERROR_INVALID_CALL ;
2018-12-03 19:26:29 +01:00
m_frameLatency = MaxLatency ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : OfferResources (
UINT NumResources ,
IDXGIResource * const * ppResources ,
DXGI_OFFER_RESOURCE_PRIORITY Priority ) {
2019-09-20 16:59:31 +02:00
return OfferResources1 ( NumResources , ppResources , Priority , 0 ) ;
2018-12-03 19:26:29 +01:00
}
2019-09-20 16:59:31 +02:00
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : OfferResources1 (
UINT NumResources ,
IDXGIResource * const * ppResources ,
DXGI_OFFER_RESOURCE_PRIORITY Priority ,
UINT Flags ) {
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
Logger : : warn ( " D3D11DXGIDevice::OfferResources1: Stub " ) ;
return S_OK ;
}
2018-12-03 19:26:29 +01:00
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : ReclaimResources (
UINT NumResources ,
IDXGIResource * const * ppResources ,
BOOL * pDiscarded ) {
2019-09-20 16:59:31 +02:00
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
Logger : : warn ( " D3D11DXGIDevice::ReclaimResources: Stub " ) ;
if ( pDiscarded )
* pDiscarded = false ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : ReclaimResources1 (
UINT NumResources ,
IDXGIResource * const * ppResources ,
DXGI_RECLAIM_RESOURCE_RESULTS * pResults ) {
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
Logger : : warn ( " D3D11DXGIDevice::ReclaimResources1: Stub " ) ;
if ( pResults ) {
for ( uint32_t i = 0 ; i < NumResources ; i + + )
pResults [ i ] = DXGI_RECLAIM_RESOURCE_RESULT_OK ;
}
return S_OK ;
2018-12-03 19:26:29 +01:00
}
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice : : EnqueueSetEvent ( HANDLE hEvent ) {
Logger : : err ( " D3D11DXGIDevice::EnqueueSetEvent: Not implemented " ) ;
return DXGI_ERROR_UNSUPPORTED ;
}
void STDMETHODCALLTYPE D3D11DXGIDevice : : Trim ( ) {
static bool s_errorShown = false ;
if ( ! std : : exchange ( s_errorShown , true ) )
Logger : : warn ( " D3D11DXGIDevice::Trim: Stub " ) ;
}
Rc < DxvkDevice > STDMETHODCALLTYPE D3D11DXGIDevice : : GetDXVKDevice ( ) {
return m_dxvkDevice ;
}
Rc < DxvkDevice > D3D11DXGIDevice : : CreateDevice ( D3D_FEATURE_LEVEL FeatureLevel ) {
DxvkDeviceFeatures deviceFeatures = D3D11Device : : GetDeviceFeatures ( m_dxvkAdapter , FeatureLevel ) ;
2020-01-28 13:03:50 +01:00
return m_dxvkAdapter - > createDevice ( m_dxvkInstance , deviceFeatures ) ;
2018-12-03 19:26:29 +01:00
}
2017-10-11 09:51:48 +02:00
}