@@ -76,6 +76,160 @@ namespace dxvk {
76
76
return (count < maxCount) ? D3DERR_MOREDATA : D3D_OK;
77
77
}
78
78
79
+ HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::GetDeviceCreateInfo (
80
+ UINT Adapter,
81
+ D3D9VkDeviceCreateInfo** ppCreateInfo) {
82
+ if (unlikely (ppCreateInfo == nullptr ))
83
+ return D3DERR_INVALIDCALL;
84
+ InitReturnPtr (ppCreateInfo);
85
+
86
+ D3D9VkDeviceCreateInfo* pCreateInfo = new D3D9VkDeviceCreateInfo;
87
+
88
+ auto * adapter = m_interface->GetAdapter (Adapter);
89
+ if (unlikely (adapter == nullptr ))
90
+ return D3DERR_INVALIDCALL;
91
+
92
+ auto dxvkAdapter = adapter->GetDXVKAdapter ();
93
+
94
+ pCreateInfo->features = D3D9DeviceEx::GetDeviceFeatures (dxvkAdapter);
95
+
96
+ DxvkDeviceCreateExtInfo extInfo;
97
+ DxvkDeviceCreateQueueInfo queueInfo;
98
+ bool success = dxvkAdapter->getDeviceCreateInfo (
99
+ m_interface->GetInstance (),
100
+ pCreateInfo->info ,
101
+ pCreateInfo->features ,
102
+ extInfo,
103
+ queueInfo);
104
+
105
+ if (!success) {
106
+ delete pCreateInfo;
107
+ return D3DERR_INVALIDCALL;
108
+ }
109
+
110
+ // Queue family indices
111
+ pCreateInfo->graphicsQueueFamily = queueInfo.queueFamilies .graphics ;
112
+ pCreateInfo->transferQueueFamily = queueInfo.queueFamilies .transfer ;
113
+ pCreateInfo->sparseQueueFamily = queueInfo.queueFamilies .sparse ;
114
+
115
+ // Queue create infos
116
+ const size_t queueCount = queueInfo.queueInfos .size ();
117
+ pCreateInfo->pQueueCreateInfos = queueCount ? new VkDeviceQueueCreateInfo[queueCount] : nullptr ;
118
+ for (size_t i = 0 ; i < queueCount; i++) {
119
+ pCreateInfo->pQueueCreateInfos [i] = queueInfo.queueInfos [i];
120
+ }
121
+ pCreateInfo->info .pQueueCreateInfos = pCreateInfo->pQueueCreateInfos ;
122
+ pCreateInfo->info .queueCreateInfoCount = queueCount;
123
+
124
+ // Extension names
125
+ const uint32_t extCount = extInfo.extensionNameList .count ();
126
+ pCreateInfo->ppEnabledExtensionNames = extCount > 0 ? new const char *[extCount] : nullptr ;
127
+ for (uint32_t i = 0 ; i < extCount; i++) {
128
+ const char * nameStr = extInfo.extensionNameList .name (i);
129
+ size_t nameLen = std::strlen (nameStr);
130
+ char * name = new char [nameLen + 1 ];
131
+ std::strncpy (name, nameStr, nameLen);
132
+ name[nameLen] = ' \0 ' ;
133
+ pCreateInfo->ppEnabledExtensionNames [i] = name;
134
+ }
135
+ pCreateInfo->info .ppEnabledExtensionNames = pCreateInfo->ppEnabledExtensionNames ;
136
+ pCreateInfo->info .enabledExtensionCount = extCount;
137
+
138
+ *ppCreateInfo = pCreateInfo;
139
+ return D3D_OK;
140
+ }
141
+
142
+ void STDMETHODCALLTYPE D3D9VkInteropInterface::FreeDeviceCreateInfo (
143
+ D3D9VkDeviceCreateInfo* pCreateInfo) {
144
+ if (!pCreateInfo)
145
+ return ;
146
+
147
+ if (pCreateInfo->ppEnabledExtensionNames != nullptr ) {
148
+ for (uint32_t i = 0 ; i < pCreateInfo->info .enabledExtensionCount ; i++) {
149
+ delete pCreateInfo->ppEnabledExtensionNames [i];
150
+ }
151
+
152
+ delete[] pCreateInfo->ppEnabledExtensionNames ;
153
+ }
154
+
155
+ if (pCreateInfo->pQueueCreateInfos != nullptr )
156
+ delete[] pCreateInfo->pQueueCreateInfos ;
157
+ delete pCreateInfo;
158
+ }
159
+
160
+ HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::ImportDevice (
161
+ UINT Adapter,
162
+ D3DDEVTYPE DeviceType,
163
+ HWND hFocusWindow,
164
+ DWORD BehaviorFlags,
165
+ D3DPRESENT_PARAMETERS* pPresentationParameters,
166
+ D3DDISPLAYMODEEX* pFullscreenDisplayMode,
167
+ D3D9VkDeviceImportInfo* pInfo,
168
+ IDirect3DDevice9Ex** ppReturnedDevice) {
169
+ InitReturnPtr (ppReturnedDevice);
170
+
171
+ if (unlikely (ppReturnedDevice == nullptr
172
+ || pPresentationParameters == nullptr ))
173
+ return D3DERR_INVALIDCALL;
174
+
175
+ // Creating a device with D3DCREATE_PUREDEVICE only works in conjunction
176
+ // with D3DCREATE_HARDWARE_VERTEXPROCESSING on native drivers.
177
+ if (unlikely (BehaviorFlags & D3DCREATE_PUREDEVICE &&
178
+ !(BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)))
179
+ return D3DERR_INVALIDCALL;
180
+
181
+ HRESULT hr;
182
+ // Black Desert creates a D3DDEVTYPE_NULLREF device and
183
+ // expects it be created despite passing invalid parameters.
184
+ if (likely (DeviceType != D3DDEVTYPE_NULLREF)) {
185
+ hr = m_interface->ValidatePresentationParameters (pPresentationParameters);
186
+
187
+ if (unlikely (FAILED (hr)))
188
+ return hr;
189
+ }
190
+
191
+ auto * adapter = m_interface->GetAdapter (Adapter);
192
+
193
+ if (adapter == nullptr )
194
+ return D3DERR_INVALIDCALL;
195
+
196
+ auto dxvkAdapter = adapter->GetDXVKAdapter ();
197
+
198
+ DxvkDeviceImportInfo info;
199
+ info.device = pInfo->device ;
200
+ info.queue = pInfo->graphicsQueue ;
201
+ info.queueFamily = pInfo->graphicsQueueFamily ;
202
+ info.extensionCount = pInfo->extensionCount ;
203
+ info.extensionNames = pInfo->extensionNames ;
204
+ info.features = pInfo->features ;
205
+ info.queueCallback = pInfo->queueLockCallback ;
206
+
207
+ try {
208
+ auto dxvkDevice = dxvkAdapter->importDevice (m_interface->GetInstance (), info);
209
+
210
+ auto * device = new D3D9DeviceEx (
211
+ m_interface,
212
+ adapter,
213
+ DeviceType,
214
+ hFocusWindow,
215
+ BehaviorFlags,
216
+ dxvkDevice);
217
+
218
+ hr = device->InitialReset (pPresentationParameters, pFullscreenDisplayMode);
219
+
220
+ if (unlikely (FAILED (hr)))
221
+ return hr;
222
+
223
+ *ppReturnedDevice = ref (device);
224
+ }
225
+ catch (const DxvkError& e) {
226
+ Logger::err (e.message ());
227
+ return D3DERR_NOTAVAILABLE;
228
+ }
229
+
230
+ return D3D_OK;
231
+ }
232
+
79
233
// //////////////////////////////
80
234
// Texture Interop
81
235
// /////////////////////////////
0 commit comments