wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / dxva2 / main.c
blob069f03d80774700ff92ffa8c17b177fd2e91cd00
1 /*
2 * Copyright 2014 Michael Müller for Pipelight
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include <stdarg.h>
22 #include <limits.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "d3d9.h"
26 #include "physicalmonitorenumerationapi.h"
27 #include "lowlevelmonitorconfigurationapi.h"
28 #include "highlevelmonitorconfigurationapi.h"
29 #include "initguid.h"
30 #include "dxva2api.h"
32 #include "wine/debug.h"
33 #include "wine/heap.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dxva2);
37 enum device_handle_flags
39 HANDLE_FLAG_OPEN = 0x1,
40 HANDLE_FLAG_INVALID = 0x2,
43 struct device_handle
45 unsigned int flags;
46 IDirect3DStateBlock9 *state_block;
49 struct device_manager
51 IDirect3DDeviceManager9 IDirect3DDeviceManager9_iface;
52 IDirectXVideoProcessorService IDirectXVideoProcessorService_iface;
53 IDirectXVideoDecoderService IDirectXVideoDecoderService_iface;
54 LONG refcount;
56 IDirect3DDevice9 *device;
57 UINT token;
59 struct device_handle *handles;
60 size_t count;
61 size_t capacity;
63 HANDLE locking_handle;
65 CRITICAL_SECTION cs;
66 CONDITION_VARIABLE lock;
69 struct video_processor
71 IDirectXVideoProcessor IDirectXVideoProcessor_iface;
72 LONG refcount;
74 IDirectXVideoProcessorService *service;
75 GUID device;
76 DXVA2_VideoDesc video_desc;
77 D3DFORMAT rt_format;
78 unsigned int max_substreams;
81 static BOOL dxva_array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
83 size_t new_capacity, max_capacity;
84 void *new_elements;
86 if (count <= *capacity)
87 return TRUE;
89 max_capacity = ~(SIZE_T)0 / size;
90 if (count > max_capacity)
91 return FALSE;
93 new_capacity = max(4, *capacity);
94 while (new_capacity < count && new_capacity <= max_capacity / 2)
95 new_capacity *= 2;
96 if (new_capacity < count)
97 new_capacity = max_capacity;
99 if (!(new_elements = heap_realloc(*elements, new_capacity * size)))
100 return FALSE;
102 *elements = new_elements;
103 *capacity = new_capacity;
105 return TRUE;
108 static struct device_manager *impl_from_IDirect3DDeviceManager9(IDirect3DDeviceManager9 *iface)
110 return CONTAINING_RECORD(iface, struct device_manager, IDirect3DDeviceManager9_iface);
113 static struct device_manager *impl_from_IDirectXVideoProcessorService(IDirectXVideoProcessorService *iface)
115 return CONTAINING_RECORD(iface, struct device_manager, IDirectXVideoProcessorService_iface);
118 static struct device_manager *impl_from_IDirectXVideoDecoderService(IDirectXVideoDecoderService *iface)
120 return CONTAINING_RECORD(iface, struct device_manager, IDirectXVideoDecoderService_iface);
123 static struct video_processor *impl_from_IDirectXVideoProcessor(IDirectXVideoProcessor *iface)
125 return CONTAINING_RECORD(iface, struct video_processor, IDirectXVideoProcessor_iface);
128 static HRESULT WINAPI video_processor_QueryInterface(IDirectXVideoProcessor *iface, REFIID riid, void **obj)
130 if (IsEqualIID(riid, &IID_IDirectXVideoProcessor) ||
131 IsEqualIID(riid, &IID_IUnknown))
133 *obj = iface;
134 IDirectXVideoProcessor_AddRef(iface);
135 return S_OK;
138 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
139 *obj = NULL;
140 return E_NOINTERFACE;
143 static ULONG WINAPI video_processor_AddRef(IDirectXVideoProcessor *iface)
145 struct video_processor *processor = impl_from_IDirectXVideoProcessor(iface);
146 ULONG refcount = InterlockedIncrement(&processor->refcount);
148 TRACE("%p, refcount %u.\n", iface, refcount);
150 return refcount;
153 static ULONG WINAPI video_processor_Release(IDirectXVideoProcessor *iface)
155 struct video_processor *processor = impl_from_IDirectXVideoProcessor(iface);
156 ULONG refcount = InterlockedDecrement(&processor->refcount);
158 TRACE("%p, refcount %u.\n", iface, refcount);
160 if (!refcount)
162 IDirectXVideoProcessorService_Release(processor->service);
163 heap_free(processor);
166 return refcount;
169 static HRESULT WINAPI video_processor_GetVideoProcessorService(IDirectXVideoProcessor *iface,
170 IDirectXVideoProcessorService **service)
172 struct video_processor *processor = impl_from_IDirectXVideoProcessor(iface);
174 TRACE("%p, %p.\n", iface, service);
176 *service = processor->service;
177 IDirectXVideoProcessorService_AddRef(*service);
179 return S_OK;
182 static HRESULT WINAPI video_processor_GetCreationParameters(IDirectXVideoProcessor *iface,
183 GUID *device, DXVA2_VideoDesc *video_desc, D3DFORMAT *rt_format, UINT *max_substreams)
185 struct video_processor *processor = impl_from_IDirectXVideoProcessor(iface);
187 TRACE("%p, %p, %p, %p, %p.\n", iface, device, video_desc, rt_format, max_substreams);
189 if (!device && !video_desc && !rt_format && !max_substreams)
190 return E_INVALIDARG;
192 if (device)
193 *device = processor->device;
194 if (video_desc)
195 *video_desc = processor->video_desc;
196 if (rt_format)
197 *rt_format = processor->rt_format;
198 if (max_substreams)
199 *max_substreams = processor->max_substreams;
201 return S_OK;
204 static HRESULT WINAPI video_processor_GetVideoProcessorCaps(IDirectXVideoProcessor *iface,
205 DXVA2_VideoProcessorCaps *caps)
207 FIXME("%p, %p.\n", iface, caps);
209 return E_NOTIMPL;
212 static HRESULT WINAPI video_processor_GetProcAmpRange(IDirectXVideoProcessor *iface, UINT cap, DXVA2_ValueRange *range)
214 FIXME("%p, %u, %p.\n", iface, cap, range);
216 return E_NOTIMPL;
219 static HRESULT WINAPI video_processor_GetFilterPropertyRange(IDirectXVideoProcessor *iface, UINT setting,
220 DXVA2_ValueRange *range)
222 FIXME("%p, %u, %p.\n", iface, setting, range);
224 return E_NOTIMPL;
227 static BOOL intersect_rect(RECT *dest, const RECT *src1, const RECT *src2)
229 if (IsRectEmpty(src1) || IsRectEmpty(src2) ||
230 (src1->left >= src2->right) || (src2->left >= src1->right) ||
231 (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
233 SetRectEmpty(dest);
234 return FALSE;
236 dest->left = max(src1->left, src2->left);
237 dest->right = min(src1->right, src2->right);
238 dest->top = max(src1->top, src2->top);
239 dest->bottom = min(src1->bottom, src2->bottom);
241 return TRUE;
244 static HRESULT WINAPI video_processor_VideoProcessBlt(IDirectXVideoProcessor *iface, IDirect3DSurface9 *rt,
245 const DXVA2_VideoProcessBltParams *params, const DXVA2_VideoSample *samples, UINT sample_count,
246 HANDLE *complete_handle)
248 IDirect3DDevice9 *device;
249 unsigned int i;
250 RECT dst_rect;
251 HRESULT hr;
253 TRACE("%p, %p, %p, %p, %u, %p.\n", iface, rt, params, samples, sample_count, complete_handle);
255 if (FAILED(hr = IDirect3DSurface9_GetDevice(rt, &device)))
257 WARN("Failed to get surface device, hr %#x.\n", hr);
258 return hr;
261 /* FIXME: use specified color */
262 IDirect3DDevice9_ColorFill(device, rt, NULL, 0);
264 for (i = 0; i < sample_count; ++i)
266 dst_rect = params->TargetRect;
268 if (!intersect_rect(&dst_rect, &dst_rect, &samples[i].DstRect))
269 continue;
271 if (FAILED(hr = IDirect3DDevice9_StretchRect(device, samples[i].SrcSurface, &samples[i].SrcRect,
272 rt, &dst_rect, D3DTEXF_POINT)))
274 WARN("Failed to copy sample %u, hr %#x.\n", i, hr);
278 IDirect3DDevice9_Release(device);
280 return S_OK;
283 static const IDirectXVideoProcessorVtbl video_processor_vtbl =
285 video_processor_QueryInterface,
286 video_processor_AddRef,
287 video_processor_Release,
288 video_processor_GetVideoProcessorService,
289 video_processor_GetCreationParameters,
290 video_processor_GetVideoProcessorCaps,
291 video_processor_GetProcAmpRange,
292 video_processor_GetFilterPropertyRange,
293 video_processor_VideoProcessBlt,
296 static HRESULT WINAPI device_manager_processor_service_QueryInterface(IDirectXVideoProcessorService *iface,
297 REFIID riid, void **obj)
299 struct device_manager *manager = impl_from_IDirectXVideoProcessorService(iface);
301 if (IsEqualIID(riid, &IID_IDirectXVideoProcessorService) ||
302 IsEqualIID(riid, &IID_IDirectXVideoAccelerationService) ||
303 IsEqualIID(riid, &IID_IUnknown))
305 *obj = iface;
307 else if (IsEqualIID(riid, &IID_IDirectXVideoDecoderService))
309 *obj = &manager->IDirectXVideoDecoderService_iface;
311 else
313 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
314 *obj = NULL;
315 return E_NOINTERFACE;
318 IUnknown_AddRef((IUnknown *)*obj);
319 return S_OK;
322 static ULONG WINAPI device_manager_processor_service_AddRef(IDirectXVideoProcessorService *iface)
324 struct device_manager *manager = impl_from_IDirectXVideoProcessorService(iface);
325 return IDirect3DDeviceManager9_AddRef(&manager->IDirect3DDeviceManager9_iface);
328 static ULONG WINAPI device_manager_processor_service_Release(IDirectXVideoProcessorService *iface)
330 struct device_manager *manager = impl_from_IDirectXVideoProcessorService(iface);
331 return IDirect3DDeviceManager9_Release(&manager->IDirect3DDeviceManager9_iface);
334 static HRESULT WINAPI device_manager_processor_service_CreateSurface(IDirectXVideoProcessorService *iface,
335 UINT width, UINT height, UINT backbuffers, D3DFORMAT format, D3DPOOL pool, DWORD usage, DWORD dxvaType,
336 IDirect3DSurface9 **surfaces, HANDLE *shared_handle)
338 struct device_manager *manager = impl_from_IDirectXVideoProcessorService(iface);
339 unsigned int i, j;
340 HRESULT hr;
342 TRACE("%p, %u, %u, %u, %u, %u, %u, %u, %p, %p.\n", iface, width, height, backbuffers, format, pool, usage, dxvaType,
343 surfaces, shared_handle);
345 if (backbuffers >= UINT_MAX)
346 return E_INVALIDARG;
348 memset(surfaces, 0, (backbuffers + 1) * sizeof(*surfaces));
350 for (i = 0; i < backbuffers + 1; ++i)
352 if (FAILED(hr = IDirect3DDevice9_CreateOffscreenPlainSurface(manager->device, width, height, format,
353 pool, &surfaces[i], NULL)))
354 break;
357 if (FAILED(hr))
359 for (j = 0; j < i; ++j)
361 if (surfaces[j])
363 IDirect3DSurface9_Release(surfaces[j]);
364 surfaces[j] = NULL;
369 return hr;
372 static HRESULT WINAPI device_manager_processor_service_RegisterVideoProcessorSoftwareDevice(
373 IDirectXVideoProcessorService *iface, void *callbacks)
375 FIXME("%p, %p.\n", iface, callbacks);
377 return E_NOTIMPL;
380 static HRESULT WINAPI device_manager_processor_service_GetVideoProcessorDeviceGuids(
381 IDirectXVideoProcessorService *iface, const DXVA2_VideoDesc *video_desc, UINT *count, GUID **guids)
383 FIXME("%p, %p, %p, %p semi-stub.\n", iface, video_desc, count, guids);
385 if (!(*guids = CoTaskMemAlloc(sizeof(**guids))))
386 return E_OUTOFMEMORY;
388 memcpy(*guids, &DXVA2_VideoProcSoftwareDevice, sizeof(**guids));
389 *count = 1;
391 return S_OK;
394 static HRESULT WINAPI device_manager_processor_service_GetVideoProcessorRenderTargets(
395 IDirectXVideoProcessorService *iface, REFGUID deviceguid, const DXVA2_VideoDesc *video_desc, UINT *count,
396 D3DFORMAT **formats)
398 TRACE("%p, %s, %p, %p, %p.\n", iface, debugstr_guid(deviceguid), video_desc, count, formats);
400 if (IsEqualGUID(deviceguid, &DXVA2_VideoProcSoftwareDevice))
402 /* FIXME: filter some input formats */
404 if (!(*formats = CoTaskMemAlloc(2 * sizeof(**formats))))
405 return E_OUTOFMEMORY;
407 *count = 2;
408 (*formats)[0] = D3DFMT_X8R8G8B8;
409 (*formats)[1] = D3DFMT_A8R8G8B8;
411 return S_OK;
413 else
414 FIXME("Unsupported device %s.\n", debugstr_guid(deviceguid));
416 return E_NOTIMPL;
419 static HRESULT WINAPI device_manager_processor_service_GetVideoProcessorSubStreamFormats(
420 IDirectXVideoProcessorService *iface, REFGUID deviceguid, const DXVA2_VideoDesc *video_desc,
421 D3DFORMAT rt_format, UINT *count, D3DFORMAT **formats)
423 FIXME("%p, %s, %p, %u, %p, %p.\n", iface, debugstr_guid(deviceguid), video_desc, rt_format, count, formats);
425 return E_NOTIMPL;
428 static HRESULT WINAPI device_manager_processor_service_GetVideoProcessorCaps(
429 IDirectXVideoProcessorService *iface, REFGUID deviceguid, const DXVA2_VideoDesc *video_desc,
430 D3DFORMAT rt_format, DXVA2_VideoProcessorCaps *caps)
432 FIXME("%p, %s, %p, %u, %p.\n", iface, debugstr_guid(deviceguid), video_desc, rt_format, caps);
434 return E_NOTIMPL;
437 static HRESULT WINAPI device_manager_processor_service_GetProcAmpRange(
438 IDirectXVideoProcessorService *iface, REFGUID deviceguid, const DXVA2_VideoDesc *video_desc,
439 D3DFORMAT rt_format, UINT ProcAmpCap, DXVA2_ValueRange *range)
441 FIXME("%p, %s, %p, %u, %u, %p.\n", iface, debugstr_guid(deviceguid), video_desc, rt_format, ProcAmpCap, range);
443 return E_NOTIMPL;
446 static HRESULT WINAPI device_manager_processor_service_GetFilterPropertyRange(
447 IDirectXVideoProcessorService *iface, REFGUID deviceguid, const DXVA2_VideoDesc *video_desc,
448 D3DFORMAT rt_format, UINT filter_setting, DXVA2_ValueRange *range)
450 FIXME("%p, %s, %p, %d, %d, %p.\n", iface, debugstr_guid(deviceguid), video_desc, rt_format, filter_setting, range);
452 return E_NOTIMPL;
455 static HRESULT WINAPI device_manager_processor_service_CreateVideoProcessor(IDirectXVideoProcessorService *iface,
456 REFGUID device, const DXVA2_VideoDesc *video_desc, D3DFORMAT rt_format, UINT max_substreams,
457 IDirectXVideoProcessor **processor)
459 struct video_processor *object;
461 FIXME("%p, %s, %p, %d, %u, %p.\n", iface, debugstr_guid(device), video_desc, rt_format, max_substreams,
462 processor);
464 /* FIXME: validate render target format */
466 if (!(object = heap_alloc_zero(sizeof(*object))))
467 return E_OUTOFMEMORY;
469 object->IDirectXVideoProcessor_iface.lpVtbl = &video_processor_vtbl;
470 object->refcount = 1;
471 object->service = iface;
472 IDirectXVideoProcessorService_AddRef(object->service);
473 object->device = *device;
474 object->video_desc = *video_desc;
475 object->rt_format = rt_format;
476 object->max_substreams = max_substreams;
478 *processor = &object->IDirectXVideoProcessor_iface;
480 return S_OK;
483 static const IDirectXVideoProcessorServiceVtbl device_manager_processor_service_vtbl =
485 device_manager_processor_service_QueryInterface,
486 device_manager_processor_service_AddRef,
487 device_manager_processor_service_Release,
488 device_manager_processor_service_CreateSurface,
489 device_manager_processor_service_RegisterVideoProcessorSoftwareDevice,
490 device_manager_processor_service_GetVideoProcessorDeviceGuids,
491 device_manager_processor_service_GetVideoProcessorRenderTargets,
492 device_manager_processor_service_GetVideoProcessorSubStreamFormats,
493 device_manager_processor_service_GetVideoProcessorCaps,
494 device_manager_processor_service_GetProcAmpRange,
495 device_manager_processor_service_GetFilterPropertyRange,
496 device_manager_processor_service_CreateVideoProcessor,
499 static HRESULT WINAPI device_manager_decoder_service_QueryInterface(IDirectXVideoDecoderService *iface,
500 REFIID riid, void **obj)
502 if (IsEqualIID(riid, &IID_IDirectXVideoDecoderService) ||
503 IsEqualIID(riid, &IID_IDirectXVideoAccelerationService) ||
504 IsEqualIID(riid, &IID_IUnknown))
506 *obj = iface;
507 IDirectXVideoDecoderService_AddRef(iface);
508 return S_OK;
511 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
512 *obj = NULL;
513 return E_NOINTERFACE;
516 static ULONG WINAPI device_manager_decoder_service_AddRef(IDirectXVideoDecoderService *iface)
518 struct device_manager *manager = impl_from_IDirectXVideoDecoderService(iface);
519 return IDirect3DDeviceManager9_AddRef(&manager->IDirect3DDeviceManager9_iface);
522 static ULONG WINAPI device_manager_decoder_service_Release(IDirectXVideoDecoderService *iface)
524 struct device_manager *manager = impl_from_IDirectXVideoDecoderService(iface);
525 return IDirect3DDeviceManager9_Release(&manager->IDirect3DDeviceManager9_iface);
528 static HRESULT WINAPI device_manager_decoder_service_CreateSurface(IDirectXVideoDecoderService *iface,
529 UINT width, UINT height, UINT backbuffers, D3DFORMAT format, D3DPOOL pool, DWORD usage, DWORD dxvaType,
530 IDirect3DSurface9 **surfaces, HANDLE *shared_handle)
532 FIXME("%p, %u, %u, %u, %#x, %d, %d, %d, %p, %p.\n", iface, width, height, backbuffers, format, pool, usage,
533 dxvaType, surfaces, shared_handle);
535 return E_NOTIMPL;
538 static HRESULT WINAPI device_manager_decoder_service_GetDecoderDeviceGuids(IDirectXVideoDecoderService *iface,
539 UINT *count, GUID **guids)
541 FIXME("%p, %p, %p.\n", iface, count, guids);
543 return E_NOTIMPL;
546 static HRESULT WINAPI device_manager_decoder_service_GetDecoderRenderTargets(IDirectXVideoDecoderService *iface,
547 REFGUID guid, UINT *count, D3DFORMAT **formats)
549 FIXME("%p, %s, %p, %p.\n", iface, debugstr_guid(guid), count, formats);
551 return E_NOTIMPL;
554 static HRESULT WINAPI device_manager_decoder_service_GetDecoderConfigurations(IDirectXVideoDecoderService *iface,
555 REFGUID guid, const DXVA2_VideoDesc *video_desc, IUnknown *reserved, UINT *count, DXVA2_ConfigPictureDecode **configs)
557 FIXME("%p, %s, %p, %p, %p, %p.\n", iface, debugstr_guid(guid), video_desc, reserved, count, configs);
559 return E_NOTIMPL;
562 static HRESULT WINAPI device_manager_decoder_service_CreateVideoDecoder(IDirectXVideoDecoderService *iface,
563 REFGUID guid, const DXVA2_VideoDesc *video_desc, DXVA2_ConfigPictureDecode *config, IDirect3DSurface9 **rts,
564 UINT num_surfaces, IDirectXVideoDecoder **decoder)
566 FIXME("%p, %s, %p, %p, %p, %u, %p.\n", iface, debugstr_guid(guid), video_desc, config, rts, num_surfaces,
567 decoder);
569 return E_NOTIMPL;
572 static const IDirectXVideoDecoderServiceVtbl device_manager_decoder_service_vtbl =
574 device_manager_decoder_service_QueryInterface,
575 device_manager_decoder_service_AddRef,
576 device_manager_decoder_service_Release,
577 device_manager_decoder_service_CreateSurface,
578 device_manager_decoder_service_GetDecoderDeviceGuids,
579 device_manager_decoder_service_GetDecoderRenderTargets,
580 device_manager_decoder_service_GetDecoderConfigurations,
581 device_manager_decoder_service_CreateVideoDecoder,
584 static HRESULT WINAPI device_manager_QueryInterface(IDirect3DDeviceManager9 *iface, REFIID riid, void **obj)
586 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
588 if (IsEqualIID(&IID_IDirect3DDeviceManager9, riid) ||
589 IsEqualIID(&IID_IUnknown, riid))
591 *obj = iface;
592 IDirect3DDeviceManager9_AddRef(iface);
593 return S_OK;
596 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
597 *obj = NULL;
598 return E_NOINTERFACE;
601 static ULONG WINAPI device_manager_AddRef(IDirect3DDeviceManager9 *iface)
603 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
604 ULONG refcount = InterlockedIncrement(&manager->refcount);
606 TRACE("%p, refcount %u.\n", iface, refcount);
608 return refcount;
611 static ULONG WINAPI device_manager_Release(IDirect3DDeviceManager9 *iface)
613 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
614 ULONG refcount = InterlockedDecrement(&manager->refcount);
615 size_t i;
617 TRACE("%p, refcount %u.\n", iface, refcount);
619 if (!refcount)
621 if (manager->device)
622 IDirect3DDevice9_Release(manager->device);
623 DeleteCriticalSection(&manager->cs);
624 for (i = 0; i < manager->count; ++i)
626 if (manager->handles[i].state_block)
627 IDirect3DStateBlock9_Release(manager->handles[i].state_block);
629 heap_free(manager->handles);
630 heap_free(manager);
633 return refcount;
636 static HRESULT WINAPI device_manager_ResetDevice(IDirect3DDeviceManager9 *iface, IDirect3DDevice9 *device,
637 UINT token)
639 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
640 size_t i;
642 TRACE("%p, %p, %#x.\n", iface, device, token);
644 if (token != manager->token)
645 return E_INVALIDARG;
647 EnterCriticalSection(&manager->cs);
648 if (manager->device)
650 for (i = 0; i < manager->count; ++i)
652 if (manager->handles[i].state_block)
653 IDirect3DStateBlock9_Release(manager->handles[i].state_block);
654 manager->handles[i].state_block = NULL;
655 manager->handles[i].flags |= HANDLE_FLAG_INVALID;
657 manager->locking_handle = NULL;
658 IDirect3DDevice9_Release(manager->device);
660 manager->device = device;
661 IDirect3DDevice9_AddRef(manager->device);
662 LeaveCriticalSection(&manager->cs);
664 WakeAllConditionVariable(&manager->lock);
666 return S_OK;
669 static HRESULT WINAPI device_manager_OpenDeviceHandle(IDirect3DDeviceManager9 *iface, HANDLE *hdevice)
671 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
672 HRESULT hr = S_OK;
673 size_t i;
675 TRACE("%p, %p.\n", iface, hdevice);
677 *hdevice = NULL;
679 EnterCriticalSection(&manager->cs);
680 if (!manager->device)
681 hr = DXVA2_E_NOT_INITIALIZED;
682 else
684 for (i = 0; i < manager->count; ++i)
686 if (!(manager->handles[i].flags & HANDLE_FLAG_OPEN))
688 manager->handles[i].flags |= HANDLE_FLAG_OPEN;
689 *hdevice = ULongToHandle(i + 1);
690 break;
694 if (dxva_array_reserve((void **)&manager->handles, &manager->capacity, manager->count + 1,
695 sizeof(*manager->handles)))
697 *hdevice = ULongToHandle(manager->count + 1);
698 manager->handles[manager->count].flags = HANDLE_FLAG_OPEN;
699 manager->handles[manager->count].state_block = NULL;
700 manager->count++;
702 else
703 hr = E_OUTOFMEMORY;
705 LeaveCriticalSection(&manager->cs);
707 return hr;
710 static HRESULT device_manager_get_handle_index(struct device_manager *manager, HANDLE hdevice, size_t *idx)
712 if (!hdevice || hdevice > ULongToHandle(manager->count))
713 return E_HANDLE;
714 *idx = (ULONG_PTR)hdevice - 1;
715 return S_OK;
718 static HRESULT WINAPI device_manager_CloseDeviceHandle(IDirect3DDeviceManager9 *iface, HANDLE hdevice)
720 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
721 HRESULT hr;
722 size_t idx;
724 TRACE("%p, %p.\n", iface, hdevice);
726 EnterCriticalSection(&manager->cs);
727 if (SUCCEEDED(hr = device_manager_get_handle_index(manager, hdevice, &idx)))
729 if (manager->handles[idx].flags & HANDLE_FLAG_OPEN)
731 if (manager->locking_handle == hdevice)
732 manager->locking_handle = NULL;
733 manager->handles[idx].flags = 0;
734 if (idx == manager->count - 1)
735 manager->count--;
736 if (manager->handles[idx].state_block)
737 IDirect3DStateBlock9_Release(manager->handles[idx].state_block);
738 manager->handles[idx].state_block = NULL;
740 else
741 hr = E_HANDLE;
743 LeaveCriticalSection(&manager->cs);
745 WakeAllConditionVariable(&manager->lock);
747 return hr;
750 static HRESULT WINAPI device_manager_TestDevice(IDirect3DDeviceManager9 *iface, HANDLE hdevice)
752 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
753 HRESULT hr;
754 size_t idx;
756 TRACE("%p, %p.\n", iface, hdevice);
758 EnterCriticalSection(&manager->cs);
759 if (SUCCEEDED(hr = device_manager_get_handle_index(manager, hdevice, &idx)))
761 unsigned int flags = manager->handles[idx].flags;
763 if (flags & HANDLE_FLAG_INVALID)
764 hr = DXVA2_E_NEW_VIDEO_DEVICE;
765 else if (!(flags & HANDLE_FLAG_OPEN))
766 hr = E_HANDLE;
768 LeaveCriticalSection(&manager->cs);
770 return hr;
773 static HRESULT WINAPI device_manager_LockDevice(IDirect3DDeviceManager9 *iface, HANDLE hdevice,
774 IDirect3DDevice9 **device, BOOL block)
776 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
777 HRESULT hr;
778 size_t idx;
780 TRACE("%p, %p, %p, %d.\n", iface, hdevice, device, block);
782 EnterCriticalSection(&manager->cs);
783 if (!manager->device)
784 hr = DXVA2_E_NOT_INITIALIZED;
785 else if (SUCCEEDED(hr = device_manager_get_handle_index(manager, hdevice, &idx)))
787 if (manager->locking_handle && !block)
788 hr = DXVA2_E_VIDEO_DEVICE_LOCKED;
789 else
791 while (manager->locking_handle && block)
793 SleepConditionVariableCS(&manager->lock, &manager->cs, INFINITE);
796 if (SUCCEEDED(hr = device_manager_get_handle_index(manager, hdevice, &idx)))
798 if (manager->handles[idx].flags & HANDLE_FLAG_INVALID)
799 hr = DXVA2_E_NEW_VIDEO_DEVICE;
800 else
802 if (manager->handles[idx].state_block)
804 if (FAILED(IDirect3DStateBlock9_Apply(manager->handles[idx].state_block)))
805 WARN("Failed to apply state.\n");
806 IDirect3DStateBlock9_Release(manager->handles[idx].state_block);
807 manager->handles[idx].state_block = NULL;
809 *device = manager->device;
810 IDirect3DDevice9_AddRef(*device);
811 manager->locking_handle = hdevice;
816 LeaveCriticalSection(&manager->cs);
818 return hr;
821 static HRESULT WINAPI device_manager_UnlockDevice(IDirect3DDeviceManager9 *iface, HANDLE hdevice, BOOL savestate)
823 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
824 HRESULT hr;
825 size_t idx;
827 TRACE("%p, %p, %d.\n", iface, hdevice, savestate);
829 EnterCriticalSection(&manager->cs);
831 if (hdevice != manager->locking_handle)
832 hr = E_INVALIDARG;
833 else if (SUCCEEDED(hr = device_manager_get_handle_index(manager, hdevice, &idx)))
835 manager->locking_handle = NULL;
836 if (savestate)
837 IDirect3DDevice9_CreateStateBlock(manager->device, D3DSBT_ALL, &manager->handles[idx].state_block);
840 LeaveCriticalSection(&manager->cs);
842 WakeAllConditionVariable(&manager->lock);
844 return hr;
847 static HRESULT WINAPI device_manager_GetVideoService(IDirect3DDeviceManager9 *iface, HANDLE hdevice, REFIID riid,
848 void **obj)
850 struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface);
851 HRESULT hr;
852 size_t idx;
854 TRACE("%p, %p, %s, %p.\n", iface, hdevice, debugstr_guid(riid), obj);
856 EnterCriticalSection(&manager->cs);
857 if (SUCCEEDED(hr = device_manager_get_handle_index(manager, hdevice, &idx)))
859 unsigned int flags = manager->handles[idx].flags;
861 if (flags & HANDLE_FLAG_INVALID)
862 hr = DXVA2_E_NEW_VIDEO_DEVICE;
863 else if (!(flags & HANDLE_FLAG_OPEN))
864 hr = E_HANDLE;
865 else
866 hr = IDirectXVideoProcessorService_QueryInterface(&manager->IDirectXVideoProcessorService_iface,
867 riid, obj);
869 LeaveCriticalSection(&manager->cs);
871 return hr;
874 static const IDirect3DDeviceManager9Vtbl device_manager_vtbl =
876 device_manager_QueryInterface,
877 device_manager_AddRef,
878 device_manager_Release,
879 device_manager_ResetDevice,
880 device_manager_OpenDeviceHandle,
881 device_manager_CloseDeviceHandle,
882 device_manager_TestDevice,
883 device_manager_LockDevice,
884 device_manager_UnlockDevice,
885 device_manager_GetVideoService,
888 BOOL WINAPI CapabilitiesRequestAndCapabilitiesReply( HMONITOR monitor, LPSTR buffer, DWORD length )
890 FIXME("(%p, %p, %d): stub\n", monitor, buffer, length);
892 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
893 return FALSE;
896 HRESULT WINAPI DXVA2CreateDirect3DDeviceManager9(UINT *token, IDirect3DDeviceManager9 **manager)
898 struct device_manager *object;
900 TRACE("%p, %p.\n", token, manager);
902 *manager = NULL;
904 if (!(object = heap_alloc_zero(sizeof(*object))))
905 return E_OUTOFMEMORY;
907 object->IDirect3DDeviceManager9_iface.lpVtbl = &device_manager_vtbl;
908 object->IDirectXVideoProcessorService_iface.lpVtbl = &device_manager_processor_service_vtbl;
909 object->IDirectXVideoDecoderService_iface.lpVtbl = &device_manager_decoder_service_vtbl;
910 object->refcount = 1;
911 object->token = GetTickCount();
912 InitializeCriticalSection(&object->cs);
913 InitializeConditionVariable(&object->lock);
915 *token = object->token;
916 *manager = &object->IDirect3DDeviceManager9_iface;
918 return S_OK;
921 HRESULT WINAPI DXVA2CreateVideoService(IDirect3DDevice9 *device, REFIID riid, void **obj)
923 IDirect3DDeviceManager9 *manager;
924 HANDLE handle;
925 HRESULT hr;
926 UINT token;
928 TRACE("%p, %s, %p.\n", device, debugstr_guid(riid), obj);
930 if (FAILED(hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager)))
931 return hr;
933 if (FAILED(hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token)))
934 goto done;
936 if (FAILED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle)))
937 goto done;
939 hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, riid, obj);
940 IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle);
942 done:
943 IDirect3DDeviceManager9_Release(manager);
945 return hr;
948 BOOL WINAPI DegaussMonitor( HMONITOR monitor )
950 FIXME("(%p): stub\n", monitor);
952 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
953 return FALSE;
956 BOOL WINAPI DestroyPhysicalMonitor( HMONITOR monitor )
958 FIXME("(%p): stub\n", monitor);
960 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
961 return FALSE;
964 BOOL WINAPI DestroyPhysicalMonitors( DWORD arraySize, LPPHYSICAL_MONITOR array )
966 FIXME("(0x%x, %p): stub\n", arraySize, array);
968 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
969 return FALSE;
972 BOOL WINAPI GetCapabilitiesStringLength( HMONITOR monitor, LPDWORD length )
974 FIXME("(%p, %p): stub\n", monitor, length);
976 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
977 return FALSE;
980 BOOL WINAPI GetMonitorBrightness( HMONITOR monitor, LPDWORD minimum, LPDWORD current, LPDWORD maximum )
982 FIXME("(%p, %p, %p, %p): stub\n", monitor, minimum, current, maximum);
984 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
985 return FALSE;
988 BOOL WINAPI GetMonitorCapabilities( HMONITOR monitor, LPDWORD capabilities, LPDWORD temperatures )
990 FIXME("(%p, %p, %p): stub\n", monitor, capabilities, temperatures);
992 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
993 return FALSE;
997 BOOL WINAPI GetMonitorColorTemperature( HMONITOR monitor, LPMC_COLOR_TEMPERATURE temperature )
999 FIXME("(%p, %p): stub\n", monitor, temperature);
1001 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1002 return FALSE;
1005 BOOL WINAPI GetMonitorContrast( HMONITOR monitor, LPDWORD minimum, LPDWORD current, LPDWORD maximum )
1007 FIXME("(%p, %p, %p, %p): stub\n", monitor, minimum, current, maximum);
1009 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1010 return FALSE;
1013 BOOL WINAPI GetMonitorDisplayAreaPosition( HMONITOR monitor, MC_POSITION_TYPE type, LPDWORD minimum,
1014 LPDWORD current, LPDWORD maximum )
1016 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor, type, minimum, current, maximum);
1018 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1019 return FALSE;
1022 BOOL WINAPI GetMonitorDisplayAreaSize( HMONITOR monitor, MC_SIZE_TYPE type, LPDWORD minimum,
1023 LPDWORD current, LPDWORD maximum )
1025 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor, type, minimum, current, maximum);
1027 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1028 return FALSE;
1031 BOOL WINAPI GetMonitorRedGreenOrBlueDrive( HMONITOR monitor, MC_DRIVE_TYPE type, LPDWORD minimum,
1032 LPDWORD current, LPDWORD maximum )
1034 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor, type, minimum, current, maximum);
1036 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1037 return FALSE;
1040 BOOL WINAPI GetMonitorRedGreenOrBlueGain( HMONITOR monitor, MC_GAIN_TYPE type, LPDWORD minimum,
1041 LPDWORD current, LPDWORD maximum )
1043 FIXME("(%p, 0x%x, %p, %p, %p): stub\n", monitor, type, minimum, current, maximum);
1045 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1046 return FALSE;
1049 BOOL WINAPI GetMonitorTechnologyType( HMONITOR monitor, LPMC_DISPLAY_TECHNOLOGY_TYPE type )
1051 FIXME("(%p, %p): stub\n", monitor, type);
1053 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1054 return FALSE;
1057 BOOL WINAPI GetNumberOfPhysicalMonitorsFromHMONITOR( HMONITOR monitor, LPDWORD number )
1059 FIXME("(%p, %p): stub\n", monitor, number);
1061 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1062 return FALSE;
1065 HRESULT WINAPI GetNumberOfPhysicalMonitorsFromIDirect3DDevice9( IDirect3DDevice9 *device, LPDWORD number )
1067 FIXME("(%p, %p): stub\n", device, number);
1069 return E_NOTIMPL;
1072 BOOL WINAPI GetPhysicalMonitorsFromHMONITOR( HMONITOR monitor, DWORD arraySize, LPPHYSICAL_MONITOR array )
1074 FIXME("(%p, 0x%x, %p): stub\n", monitor, arraySize, array);
1076 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1077 return FALSE;
1080 HRESULT WINAPI GetPhysicalMonitorsFromIDirect3DDevice9( IDirect3DDevice9 *device, DWORD arraySize, LPPHYSICAL_MONITOR array )
1082 FIXME("(%p, 0x%x, %p): stub\n", device, arraySize, array);
1084 return E_NOTIMPL;
1087 BOOL WINAPI GetTimingReport( HMONITOR monitor, LPMC_TIMING_REPORT timingReport )
1089 FIXME("(%p, %p): stub\n", monitor, timingReport);
1091 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1092 return FALSE;
1095 BOOL WINAPI GetVCPFeatureAndVCPFeatureReply( HMONITOR monitor, BYTE vcpCode, LPMC_VCP_CODE_TYPE pvct,
1096 LPDWORD current, LPDWORD maximum )
1098 FIXME("(%p, 0x%02x, %p, %p, %p): stub\n", monitor, vcpCode, pvct, current, maximum);
1100 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1101 return FALSE;
1104 HRESULT WINAPI OPMGetVideoOutputsFromHMONITOR( HMONITOR monitor, /* OPM_VIDEO_OUTPUT_SEMANTICS */ int vos,
1105 ULONG *numVideoOutputs, /* IOPMVideoOutput */ void ***videoOutputs )
1107 FIXME("(%p, 0x%x, %p, %p): stub\n", monitor, vos, numVideoOutputs, videoOutputs);
1109 return E_NOTIMPL;
1112 HRESULT WINAPI OPMGetVideoOutputsFromIDirect3DDevice9Object( IDirect3DDevice9 *device, /* OPM_VIDEO_OUTPUT_SEMANTICS */ int vos,
1113 ULONG *numVideoOutputs, /* IOPMVideoOutput */ void ***videoOutputs )
1115 FIXME("(%p, 0x%x, %p, %p): stub\n", device, vos, numVideoOutputs, videoOutputs);
1117 return E_NOTIMPL;
1120 BOOL WINAPI RestoreMonitorFactoryColorDefaults( HMONITOR monitor )
1122 FIXME("(%p): stub\n", monitor);
1124 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1125 return FALSE;
1128 BOOL WINAPI RestoreMonitorFactoryDefaults( HMONITOR monitor )
1130 FIXME("(%p): stub\n", monitor);
1132 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1133 return FALSE;
1136 BOOL WINAPI SaveCurrentMonitorSettings( HMONITOR monitor )
1138 FIXME("(%p): stub\n", monitor);
1140 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1141 return FALSE;
1144 BOOL WINAPI SaveCurrentSettings( HMONITOR monitor )
1146 FIXME("(%p): stub\n", monitor);
1148 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1149 return FALSE;
1152 BOOL WINAPI SetMonitorBrightness( HMONITOR monitor, DWORD brightness )
1154 FIXME("(%p, 0x%x): stub\n", monitor, brightness);
1156 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1157 return FALSE;
1160 BOOL WINAPI SetMonitorColorTemperature( HMONITOR monitor, MC_COLOR_TEMPERATURE temperature )
1162 FIXME("(%p, 0x%x): stub\n", monitor, temperature);
1164 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1165 return FALSE;
1168 BOOL WINAPI SetMonitorContrast( HMONITOR monitor, DWORD contrast )
1170 FIXME("(%p, 0x%x): stub\n", monitor, contrast);
1172 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1173 return FALSE;
1176 BOOL WINAPI SetMonitorDisplayAreaPosition( HMONITOR monitor, MC_POSITION_TYPE type, DWORD position )
1178 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor, type, position);
1180 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1181 return FALSE;
1184 BOOL WINAPI SetMonitorDisplayAreaSize( HMONITOR monitor, MC_SIZE_TYPE type, DWORD size )
1186 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor, type, size);
1188 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1189 return FALSE;
1192 BOOL WINAPI SetMonitorRedGreenOrBlueDrive( HMONITOR monitor, MC_DRIVE_TYPE type, DWORD drive )
1194 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor, type, drive);
1196 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1197 return FALSE;
1200 BOOL WINAPI SetMonitorRedGreenOrBlueGain( HMONITOR monitor, MC_GAIN_TYPE type, DWORD gain )
1202 FIXME("(%p, 0x%x, 0x%x): stub\n", monitor, type, gain);
1204 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1205 return FALSE;
1208 BOOL WINAPI SetVCPFeature( HMONITOR monitor, BYTE vcpCode, DWORD value )
1210 FIXME("(%p, 0x%02x, 0x%x): stub\n", monitor, vcpCode, value);
1212 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1213 return FALSE;