1/*
2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
23#include "device9.h"
24#include "device9ex.h"
25#include "nine_pipe.h"
26#include "swapchain9ex.h"
27
28#include "nine_helpers.h"
29
30#define DBG_CHANNEL DBG_DEVICE
31
32static HRESULT
33NineDevice9Ex_ctor( struct NineDevice9Ex *This,
34                    struct NineUnknownParams *pParams,
35                    struct pipe_screen *pScreen,
36                    D3DDEVICE_CREATION_PARAMETERS *pCreationParameters,
37                    D3DCAPS9 *pCaps,
38                    D3DPRESENT_PARAMETERS *pPresentationParameters,
39                    D3DDISPLAYMODEEX *pFullscreenDisplayMode,
40                    IDirect3D9Ex *pD3D9Ex,
41                    ID3DPresentGroup *pPresentationGroup,
42                    struct d3dadapter9_context *pCTX,
43                    int minorVersionNum )
44{
45    DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p "
46        "pPresentationParameters=%p pFullscreenDisplayMode=%p "
47        "pD3D9Ex=%p pPresentationGroup=%p pCTX=%p\n",
48        This, pParams, pScreen, pCreationParameters, pCaps,
49        pPresentationParameters, pFullscreenDisplayMode,
50        pD3D9Ex, pPresentationGroup, pCTX);
51
52    return NineDevice9_ctor(&This->base, pParams,
53                            pScreen, pCreationParameters, pCaps,
54                            pPresentationParameters,
55                            (IDirect3D9 *)pD3D9Ex, pPresentationGroup, pCTX,
56                            TRUE, pFullscreenDisplayMode, minorVersionNum);
57}
58
59static void
60NineDevice9Ex_dtor( struct NineDevice9Ex *This )
61{
62    NineDevice9_dtor(&This->base);
63}
64
65HRESULT NINE_WINAPI
66NineDevice9Ex_SetConvolutionMonoKernel( struct NineDevice9Ex *This,
67                                        UINT width,
68                                        UINT height,
69                                        float *rows,
70                                        float *columns )
71{
72    STUB(D3DERR_INVALIDCALL);
73}
74
75HRESULT NINE_WINAPI
76NineDevice9Ex_ComposeRects( struct NineDevice9Ex *This,
77                            IDirect3DSurface9 *pSrc,
78                            IDirect3DSurface9 *pDst,
79                            IDirect3DVertexBuffer9 *pSrcRectDescs,
80                            UINT NumRects,
81                            IDirect3DVertexBuffer9 *pDstRectDescs,
82                            D3DCOMPOSERECTSOP Operation,
83                            int Xoffset,
84                            int Yoffset )
85{
86    STUB(D3DERR_INVALIDCALL);
87}
88
89HRESULT NINE_WINAPI
90NineDevice9Ex_PresentEx( struct NineDevice9Ex *This,
91                         const RECT *pSourceRect,
92                         const RECT *pDestRect,
93                         HWND hDestWindowOverride,
94                         const RGNDATA *pDirtyRegion,
95                         DWORD dwFlags )
96{
97    unsigned i;
98    HRESULT hr;
99
100    DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p "
101        "pDirtyRegion=%p dwFlags=%d\n",
102        This, pSourceRect, pDestRect, hDestWindowOverride,
103        pDirtyRegion, dwFlags);
104
105    for (i = 0; i < This->base.nswapchains; i++) {
106        hr = NineSwapChain9_Present(This->base.swapchains[i], pSourceRect, pDestRect,
107                                    hDestWindowOverride, pDirtyRegion, dwFlags);
108        if (FAILED(hr)) { return hr; }
109    }
110
111    return D3D_OK;
112}
113
114HRESULT NINE_WINAPI
115NineDevice9Ex_GetGPUThreadPriority( struct NineDevice9Ex *This,
116                                    INT *pPriority )
117{
118    STUB(D3DERR_INVALIDCALL);
119}
120
121HRESULT NINE_WINAPI
122NineDevice9Ex_SetGPUThreadPriority( struct NineDevice9Ex *This,
123                                    INT Priority )
124{
125    STUB(D3DERR_INVALIDCALL);
126}
127
128HRESULT NINE_WINAPI
129NineDevice9Ex_WaitForVBlank( struct NineDevice9Ex *This,
130                             UINT iSwapChain )
131{
132    STUB(D3DERR_INVALIDCALL);
133}
134
135HRESULT NINE_WINAPI
136NineDevice9Ex_CheckResourceResidency( struct NineDevice9Ex *This,
137                                      IDirect3DResource9 **pResourceArray,
138                                      UINT32 NumResources )
139{
140    STUB(D3DERR_INVALIDCALL);
141}
142
143HRESULT NINE_WINAPI
144NineDevice9Ex_SetMaximumFrameLatency( struct NineDevice9Ex *This,
145                                      UINT MaxLatency )
146{
147    STUB(D3DERR_INVALIDCALL);
148}
149
150HRESULT NINE_WINAPI
151NineDevice9Ex_GetMaximumFrameLatency( struct NineDevice9Ex *This,
152                                      UINT *pMaxLatency )
153{
154    STUB(D3DERR_INVALIDCALL);
155}
156
157HRESULT NINE_WINAPI
158NineDevice9Ex_CheckDeviceState( struct NineDevice9Ex *This,
159                                HWND hDestinationWindow )
160{
161    DBG("This=%p hDestinationWindow=%p\n",
162        This, hDestinationWindow);
163
164    user_assert(!This->base.swapchains[0]->params.Windowed, D3D_OK);
165
166    if (This->base.params.hFocusWindow == hDestinationWindow) {
167        if (NineSwapChain9_GetOccluded(This->base.swapchains[0]))
168            return S_PRESENT_OCCLUDED;
169    } else if(!NineSwapChain9_GetOccluded(This->base.swapchains[0])) {
170        return S_PRESENT_OCCLUDED;
171    }
172    /* TODO: handle the other return values */
173    return D3D_OK;
174}
175
176HRESULT NINE_WINAPI
177NineDevice9Ex_CreateRenderTargetEx( struct NineDevice9Ex *This,
178                                    UINT Width,
179                                    UINT Height,
180                                    D3DFORMAT Format,
181                                    D3DMULTISAMPLE_TYPE MultiSample,
182                                    DWORD MultisampleQuality,
183                                    BOOL Lockable,
184                                    IDirect3DSurface9 **ppSurface,
185                                    HANDLE *pSharedHandle,
186                                    DWORD Usage )
187{
188    STUB(D3DERR_INVALIDCALL);
189}
190
191HRESULT NINE_WINAPI
192NineDevice9Ex_CreateOffscreenPlainSurfaceEx( struct NineDevice9Ex *This,
193                                             UINT Width,
194                                             UINT Height,
195                                             D3DFORMAT Format,
196                                             D3DPOOL Pool,
197                                             IDirect3DSurface9 **ppSurface,
198                                             HANDLE *pSharedHandle,
199                                             DWORD Usage )
200{
201    STUB(D3DERR_INVALIDCALL);
202}
203
204HRESULT NINE_WINAPI
205NineDevice9Ex_CreateDepthStencilSurfaceEx( struct NineDevice9Ex *This,
206                                           UINT Width,
207                                           UINT Height,
208                                           D3DFORMAT Format,
209                                           D3DMULTISAMPLE_TYPE MultiSample,
210                                           DWORD MultisampleQuality,
211                                           BOOL Discard,
212                                           IDirect3DSurface9 **ppSurface,
213                                           HANDLE *pSharedHandle,
214                                           DWORD Usage )
215{
216    STUB(D3DERR_INVALIDCALL);
217}
218
219HRESULT NINE_WINAPI
220NineDevice9Ex_ResetEx( struct NineDevice9Ex *This,
221                       D3DPRESENT_PARAMETERS *pPresentationParameters,
222                       D3DDISPLAYMODEEX *pFullscreenDisplayMode )
223{
224    HRESULT hr = D3D_OK;
225    unsigned i;
226
227    DBG("This=%p pPresentationParameters=%p pFullscreenDisplayMode=%p\n", This, pPresentationParameters, pFullscreenDisplayMode);
228
229    for (i = 0; i < This->base.nswapchains; ++i) {
230        D3DDISPLAYMODEEX *mode = NULL;
231        D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i];
232        if (pFullscreenDisplayMode) mode = &(pFullscreenDisplayMode[i]);
233        hr = NineSwapChain9_Resize(This->base.swapchains[i], params, mode);
234        if (FAILED(hr))
235            break;
236    }
237
238    NineDevice9_SetRenderTarget(
239        (struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]);
240
241    return hr;
242}
243
244HRESULT NINE_WINAPI
245NineDevice9Ex_Reset( struct NineDevice9Ex *This,
246                     D3DPRESENT_PARAMETERS *pPresentationParameters )
247{
248    HRESULT hr = D3D_OK;
249    unsigned i;
250
251    DBG("This=%p pPresentationParameters=%p\n", This, pPresentationParameters);
252
253    for (i = 0; i < This->base.nswapchains; ++i) {
254        D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i];
255        hr = NineSwapChain9_Resize(This->base.swapchains[i], params, NULL);
256        if (FAILED(hr))
257            break;
258    }
259
260    nine_csmt_process(&This->base);
261    nine_device_state_clear((struct NineDevice9 *)This);
262    nine_context_clear(&This->base);
263
264    NineDevice9_SetDefaultState((struct NineDevice9 *)This, TRUE);
265    NineDevice9_SetRenderTarget(
266        (struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]);
267
268    return hr;
269}
270
271HRESULT NINE_WINAPI
272NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This,
273                                UINT iSwapChain,
274                                D3DDISPLAYMODEEX *pMode,
275                                D3DDISPLAYROTATION *pRotation )
276{
277    struct NineSwapChain9Ex *swapchain;
278
279    DBG("This=%p iSwapChain=%u pMode=%p pRotation=%p\n",
280        This, iSwapChain, pMode, pRotation);
281
282    user_assert(iSwapChain < This->base.nswapchains, D3DERR_INVALIDCALL);
283
284    swapchain = NineSwapChain9Ex(This->base.swapchains[iSwapChain]);
285    return NineSwapChain9Ex_GetDisplayModeEx(swapchain, pMode, pRotation);
286}
287
288HRESULT NINE_WINAPI
289NineDevice9Ex_TestCooperativeLevel( struct NineDevice9Ex *This )
290{
291    return D3D_OK;
292}
293
294
295IDirect3DDevice9ExVtbl NineDevice9Ex_vtable = {
296    (void *)NineUnknown_QueryInterface,
297    (void *)NineUnknown_AddRef,
298    (void *)NineUnknown_Release,
299    (void *)NineDevice9Ex_TestCooperativeLevel,
300    (void *)NineDevice9_GetAvailableTextureMem,
301    (void *)NineDevice9_EvictManagedResources,
302    (void *)NineDevice9_GetDirect3D,
303    (void *)NineDevice9_GetDeviceCaps,
304    (void *)NineDevice9_GetDisplayMode,
305    (void *)NineDevice9_GetCreationParameters,
306    (void *)NineDevice9_SetCursorProperties,
307    (void *)NineDevice9_SetCursorPosition,
308    (void *)NineDevice9_ShowCursor,
309    (void *)NineDevice9_CreateAdditionalSwapChain,
310    (void *)NineDevice9_GetSwapChain,
311    (void *)NineDevice9_GetNumberOfSwapChains,
312    (void *)NineDevice9Ex_Reset,
313    (void *)NineDevice9_Present,
314    (void *)NineDevice9_GetBackBuffer,
315    (void *)NineDevice9_GetRasterStatus,
316    (void *)NineDevice9_SetDialogBoxMode,
317    (void *)NineDevice9_SetGammaRamp,
318    (void *)NineDevice9_GetGammaRamp,
319    (void *)NineDevice9_CreateTexture,
320    (void *)NineDevice9_CreateVolumeTexture,
321    (void *)NineDevice9_CreateCubeTexture,
322    (void *)NineDevice9_CreateVertexBuffer,
323    (void *)NineDevice9_CreateIndexBuffer,
324    (void *)NineDevice9_CreateRenderTarget,
325    (void *)NineDevice9_CreateDepthStencilSurface,
326    (void *)NineDevice9_UpdateSurface,
327    (void *)NineDevice9_UpdateTexture,
328    (void *)NineDevice9_GetRenderTargetData,
329    (void *)NineDevice9_GetFrontBufferData,
330    (void *)NineDevice9_StretchRect,
331    (void *)NineDevice9_ColorFill,
332    (void *)NineDevice9_CreateOffscreenPlainSurface,
333    (void *)NineDevice9_SetRenderTarget,
334    (void *)NineDevice9_GetRenderTarget,
335    (void *)NineDevice9_SetDepthStencilSurface,
336    (void *)NineDevice9_GetDepthStencilSurface,
337    (void *)NineDevice9_BeginScene,
338    (void *)NineDevice9_EndScene,
339    (void *)NineDevice9_Clear,
340    (void *)NineDevice9_SetTransform,
341    (void *)NineDevice9_GetTransform,
342    (void *)NineDevice9_MultiplyTransform,
343    (void *)NineDevice9_SetViewport,
344    (void *)NineDevice9_GetViewport,
345    (void *)NineDevice9_SetMaterial,
346    (void *)NineDevice9_GetMaterial,
347    (void *)NineDevice9_SetLight,
348    (void *)NineDevice9_GetLight,
349    (void *)NineDevice9_LightEnable,
350    (void *)NineDevice9_GetLightEnable,
351    (void *)NineDevice9_SetClipPlane,
352    (void *)NineDevice9_GetClipPlane,
353    (void *)NineDevice9_SetRenderState,
354    (void *)NineDevice9_GetRenderState,
355    (void *)NineDevice9_CreateStateBlock,
356    (void *)NineDevice9_BeginStateBlock,
357    (void *)NineDevice9_EndStateBlock,
358    (void *)NineDevice9_SetClipStatus,
359    (void *)NineDevice9_GetClipStatus,
360    (void *)NineDevice9_GetTexture,
361    (void *)NineDevice9_SetTexture,
362    (void *)NineDevice9_GetTextureStageState,
363    (void *)NineDevice9_SetTextureStageState,
364    (void *)NineDevice9_GetSamplerState,
365    (void *)NineDevice9_SetSamplerState,
366    (void *)NineDevice9_ValidateDevice,
367    (void *)NineDevice9_SetPaletteEntries,
368    (void *)NineDevice9_GetPaletteEntries,
369    (void *)NineDevice9_SetCurrentTexturePalette,
370    (void *)NineDevice9_GetCurrentTexturePalette,
371    (void *)NineDevice9_SetScissorRect,
372    (void *)NineDevice9_GetScissorRect,
373    (void *)NineDevice9_SetSoftwareVertexProcessing,
374    (void *)NineDevice9_GetSoftwareVertexProcessing,
375    (void *)NineDevice9_SetNPatchMode,
376    (void *)NineDevice9_GetNPatchMode,
377    (void *)NineDevice9_DrawPrimitive,
378    (void *)NineDevice9_DrawIndexedPrimitive,
379    (void *)NineDevice9_DrawPrimitiveUP,
380    (void *)NineDevice9_DrawIndexedPrimitiveUP,
381    (void *)NineDevice9_ProcessVertices,
382    (void *)NineDevice9_CreateVertexDeclaration,
383    (void *)NineDevice9_SetVertexDeclaration,
384    (void *)NineDevice9_GetVertexDeclaration,
385    (void *)NineDevice9_SetFVF,
386    (void *)NineDevice9_GetFVF,
387    (void *)NineDevice9_CreateVertexShader,
388    (void *)NineDevice9_SetVertexShader,
389    (void *)NineDevice9_GetVertexShader,
390    (void *)NineDevice9_SetVertexShaderConstantF,
391    (void *)NineDevice9_GetVertexShaderConstantF,
392    (void *)NineDevice9_SetVertexShaderConstantI,
393    (void *)NineDevice9_GetVertexShaderConstantI,
394    (void *)NineDevice9_SetVertexShaderConstantB,
395    (void *)NineDevice9_GetVertexShaderConstantB,
396    (void *)NineDevice9_SetStreamSource,
397    (void *)NineDevice9_GetStreamSource,
398    (void *)NineDevice9_SetStreamSourceFreq,
399    (void *)NineDevice9_GetStreamSourceFreq,
400    (void *)NineDevice9_SetIndices,
401    (void *)NineDevice9_GetIndices,
402    (void *)NineDevice9_CreatePixelShader,
403    (void *)NineDevice9_SetPixelShader,
404    (void *)NineDevice9_GetPixelShader,
405    (void *)NineDevice9_SetPixelShaderConstantF,
406    (void *)NineDevice9_GetPixelShaderConstantF,
407    (void *)NineDevice9_SetPixelShaderConstantI,
408    (void *)NineDevice9_GetPixelShaderConstantI,
409    (void *)NineDevice9_SetPixelShaderConstantB,
410    (void *)NineDevice9_GetPixelShaderConstantB,
411    (void *)NineDevice9_DrawRectPatch,
412    (void *)NineDevice9_DrawTriPatch,
413    (void *)NineDevice9_DeletePatch,
414    (void *)NineDevice9_CreateQuery,
415    (void *)NineDevice9Ex_SetConvolutionMonoKernel,
416    (void *)NineDevice9Ex_ComposeRects,
417    (void *)NineDevice9Ex_PresentEx,
418    (void *)NineDevice9Ex_GetGPUThreadPriority,
419    (void *)NineDevice9Ex_SetGPUThreadPriority,
420    (void *)NineDevice9Ex_WaitForVBlank,
421    (void *)NineDevice9Ex_CheckResourceResidency,
422    (void *)NineDevice9Ex_SetMaximumFrameLatency,
423    (void *)NineDevice9Ex_GetMaximumFrameLatency,
424    (void *)NineDevice9Ex_CheckDeviceState,
425    (void *)NineDevice9Ex_CreateRenderTargetEx,
426    (void *)NineDevice9Ex_CreateOffscreenPlainSurfaceEx,
427    (void *)NineDevice9Ex_CreateDepthStencilSurfaceEx,
428    (void *)NineDevice9Ex_ResetEx,
429    (void *)NineDevice9Ex_GetDisplayModeEx
430};
431
432static const GUID *NineDevice9Ex_IIDs[] = {
433    &IID_IDirect3DDevice9Ex,
434    &IID_IDirect3DDevice9,
435    &IID_IUnknown,
436    NULL
437};
438
439HRESULT
440NineDevice9Ex_new( struct pipe_screen *pScreen,
441                   D3DDEVICE_CREATION_PARAMETERS *pCreationParameters,
442                   D3DCAPS9 *pCaps,
443                   D3DPRESENT_PARAMETERS *pPresentationParameters,
444                   D3DDISPLAYMODEEX *pFullscreenDisplayMode,
445                   IDirect3D9Ex *pD3D9Ex,
446                   ID3DPresentGroup *pPresentationGroup,
447                   struct d3dadapter9_context *pCTX,
448                   struct NineDevice9Ex **ppOut,
449                   int minorVersionNum )
450{
451    BOOL lock;
452    lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED);
453
454    NINE_NEW(Device9Ex, ppOut, lock,
455             pScreen, pCreationParameters, pCaps, pPresentationParameters,
456             pFullscreenDisplayMode, pD3D9Ex, pPresentationGroup, pCTX, minorVersionNum );
457}
458
459