xref: /reactos/dll/directx/wine/d3dx9_36/render.c (revision 224d70bd)
1*edca86daSJérôme Gardou #ifdef __REACTOS__
2*edca86daSJérôme Gardou #include "precomp.h"
3*edca86daSJérôme Gardou #else
4c2c66affSColin Finck /*
5c2c66affSColin Finck  * Copyright (C) 2012 Józef Kucia
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  *
21c2c66affSColin Finck  */
22c2c66affSColin Finck 
23e5c42da4SAmine Khaldi 
24e5c42da4SAmine Khaldi #include "d3dx9_private.h"
25*edca86daSJérôme Gardou #endif /* __REACTOS__ */
26e5c42da4SAmine Khaldi 
27e5c42da4SAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
28c2c66affSColin Finck 
29c2c66affSColin Finck struct device_state
30c2c66affSColin Finck {
31c2c66affSColin Finck     DWORD num_render_targets;
32c2c66affSColin Finck     IDirect3DSurface9 **render_targets;
33c2c66affSColin Finck     IDirect3DSurface9 *depth_stencil;
34c2c66affSColin Finck     D3DVIEWPORT9 viewport;
35c2c66affSColin Finck };
36c2c66affSColin Finck 
device_state_init(IDirect3DDevice9 * device,struct device_state * state)37c2c66affSColin Finck static HRESULT device_state_init(IDirect3DDevice9 *device, struct device_state *state)
38c2c66affSColin Finck {
39c2c66affSColin Finck     HRESULT hr;
40c2c66affSColin Finck     D3DCAPS9 caps;
41c2c66affSColin Finck     unsigned int i;
42c2c66affSColin Finck 
43c2c66affSColin Finck     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
44c2c66affSColin Finck     if (FAILED(hr)) return hr;
45c2c66affSColin Finck 
46c2c66affSColin Finck     state->num_render_targets = caps.NumSimultaneousRTs;
47c2c66affSColin Finck     state->render_targets = HeapAlloc(GetProcessHeap(), 0,
48c2c66affSColin Finck         state->num_render_targets * sizeof(IDirect3DSurface9 *));
49c2c66affSColin Finck     if (!state->render_targets)
50c2c66affSColin Finck         return E_OUTOFMEMORY;
51c2c66affSColin Finck 
52c2c66affSColin Finck     for (i = 0; i < state->num_render_targets; i++)
53c2c66affSColin Finck         state->render_targets[i] = NULL;
54c2c66affSColin Finck     state->depth_stencil = NULL;
55c2c66affSColin Finck     return D3D_OK;
56c2c66affSColin Finck }
57c2c66affSColin Finck 
device_state_capture(IDirect3DDevice9 * device,struct device_state * state)58c2c66affSColin Finck static void device_state_capture(IDirect3DDevice9 *device, struct device_state *state)
59c2c66affSColin Finck {
60c2c66affSColin Finck     HRESULT hr;
61c2c66affSColin Finck     unsigned int i;
62c2c66affSColin Finck 
63c2c66affSColin Finck     IDirect3DDevice9_GetViewport(device, &state->viewport);
64c2c66affSColin Finck 
65c2c66affSColin Finck     for (i = 0; i < state->num_render_targets; i++)
66c2c66affSColin Finck     {
67c2c66affSColin Finck         hr = IDirect3DDevice9_GetRenderTarget(device, i, &state->render_targets[i]);
68c2c66affSColin Finck         if (FAILED(hr)) state->render_targets[i] = NULL;
69c2c66affSColin Finck     }
70c2c66affSColin Finck 
71c2c66affSColin Finck     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &state->depth_stencil);
72c2c66affSColin Finck     if (FAILED(hr)) state->depth_stencil = NULL;
73c2c66affSColin Finck }
74c2c66affSColin Finck 
device_state_restore(IDirect3DDevice9 * device,struct device_state * state)75c2c66affSColin Finck static void device_state_restore(IDirect3DDevice9 *device, struct device_state *state)
76c2c66affSColin Finck {
77c2c66affSColin Finck     unsigned int i;
78c2c66affSColin Finck 
79c2c66affSColin Finck     for (i = 0; i < state->num_render_targets; i++)
80c2c66affSColin Finck     {
81c2c66affSColin Finck         IDirect3DDevice9_SetRenderTarget(device, i, state->render_targets[i]);
82c2c66affSColin Finck         if (state->render_targets[i])
83c2c66affSColin Finck             IDirect3DSurface9_Release(state->render_targets[i]);
84c2c66affSColin Finck         state->render_targets[i] = NULL;
85c2c66affSColin Finck     }
86c2c66affSColin Finck 
87c2c66affSColin Finck     IDirect3DDevice9_SetDepthStencilSurface(device, state->depth_stencil);
88c2c66affSColin Finck     if (state->depth_stencil)
89c2c66affSColin Finck     {
90c2c66affSColin Finck         IDirect3DSurface9_Release(state->depth_stencil);
91c2c66affSColin Finck         state->depth_stencil = NULL;
92c2c66affSColin Finck     }
93c2c66affSColin Finck 
94c2c66affSColin Finck     IDirect3DDevice9_SetViewport(device, &state->viewport);
95c2c66affSColin Finck }
96c2c66affSColin Finck 
device_state_release(struct device_state * state)97c2c66affSColin Finck static void device_state_release(struct device_state *state)
98c2c66affSColin Finck {
99c2c66affSColin Finck     unsigned int i;
100c2c66affSColin Finck 
101c2c66affSColin Finck     for (i = 0; i < state->num_render_targets; i++)
102c2c66affSColin Finck     {
103c2c66affSColin Finck         if (state->render_targets[i])
104c2c66affSColin Finck             IDirect3DSurface9_Release(state->render_targets[i]);
105c2c66affSColin Finck     }
106c2c66affSColin Finck 
107c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, state->render_targets);
108c2c66affSColin Finck 
109c2c66affSColin Finck     if (state->depth_stencil) IDirect3DSurface9_Release(state->depth_stencil);
110c2c66affSColin Finck }
111c2c66affSColin Finck 
112c2c66affSColin Finck struct render_to_surface
113c2c66affSColin Finck {
114c2c66affSColin Finck     ID3DXRenderToSurface ID3DXRenderToSurface_iface;
115c2c66affSColin Finck     LONG ref;
116c2c66affSColin Finck 
117c2c66affSColin Finck     IDirect3DDevice9 *device;
118c2c66affSColin Finck     D3DXRTS_DESC desc;
119c2c66affSColin Finck 
120c2c66affSColin Finck     IDirect3DSurface9 *dst_surface;
121c2c66affSColin Finck 
122c2c66affSColin Finck     IDirect3DSurface9 *render_target;
123c2c66affSColin Finck     IDirect3DSurface9 *depth_stencil;
124c2c66affSColin Finck 
125c2c66affSColin Finck     struct device_state previous_state;
126c2c66affSColin Finck };
127c2c66affSColin Finck 
impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface * iface)128c2c66affSColin Finck static inline struct render_to_surface *impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface *iface)
129c2c66affSColin Finck {
130c2c66affSColin Finck     return CONTAINING_RECORD(iface, struct render_to_surface, ID3DXRenderToSurface_iface);
131c2c66affSColin Finck }
132c2c66affSColin Finck 
D3DXRenderToSurface_QueryInterface(ID3DXRenderToSurface * iface,REFIID riid,void ** out)133c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToSurface_QueryInterface(ID3DXRenderToSurface *iface,
134c2c66affSColin Finck                                                          REFIID riid,
135c2c66affSColin Finck                                                          void **out)
136c2c66affSColin Finck {
137c2c66affSColin Finck     TRACE("iface %p, riid %s, out %p\n", iface, debugstr_guid(riid), out);
138c2c66affSColin Finck 
139c2c66affSColin Finck     if (IsEqualGUID(riid, &IID_ID3DXRenderToSurface)
140c2c66affSColin Finck             || IsEqualGUID(riid, &IID_IUnknown))
141c2c66affSColin Finck     {
142c2c66affSColin Finck         IUnknown_AddRef(iface);
143c2c66affSColin Finck         *out = iface;
144c2c66affSColin Finck         return S_OK;
145c2c66affSColin Finck     }
146c2c66affSColin Finck 
147c2c66affSColin Finck     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
148c2c66affSColin Finck 
149c2c66affSColin Finck     *out = NULL;
150c2c66affSColin Finck     return E_NOINTERFACE;
151c2c66affSColin Finck }
152c2c66affSColin Finck 
D3DXRenderToSurface_AddRef(ID3DXRenderToSurface * iface)153c2c66affSColin Finck static ULONG WINAPI D3DXRenderToSurface_AddRef(ID3DXRenderToSurface *iface)
154c2c66affSColin Finck {
155c2c66affSColin Finck     struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
156c2c66affSColin Finck     ULONG ref = InterlockedIncrement(&render->ref);
157c2c66affSColin Finck 
158c2c66affSColin Finck     TRACE("%p increasing refcount to %u\n", iface, ref);
159c2c66affSColin Finck 
160c2c66affSColin Finck     return ref;
161c2c66affSColin Finck }
162c2c66affSColin Finck 
D3DXRenderToSurface_Release(ID3DXRenderToSurface * iface)163c2c66affSColin Finck static ULONG WINAPI D3DXRenderToSurface_Release(ID3DXRenderToSurface *iface)
164c2c66affSColin Finck {
165c2c66affSColin Finck     struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
166c2c66affSColin Finck     ULONG ref = InterlockedDecrement(&render->ref);
167c2c66affSColin Finck 
168c2c66affSColin Finck     TRACE("%p decreasing refcount to %u\n", iface, ref);
169c2c66affSColin Finck 
170c2c66affSColin Finck     if (!ref)
171c2c66affSColin Finck     {
172c2c66affSColin Finck         if (render->dst_surface) IDirect3DSurface9_Release(render->dst_surface);
173c2c66affSColin Finck 
174c2c66affSColin Finck         if (render->render_target) IDirect3DSurface9_Release(render->render_target);
175c2c66affSColin Finck         if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
176c2c66affSColin Finck 
177c2c66affSColin Finck         device_state_release(&render->previous_state);
178c2c66affSColin Finck 
179c2c66affSColin Finck         IDirect3DDevice9_Release(render->device);
180c2c66affSColin Finck 
181c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, render);
182c2c66affSColin Finck     }
183c2c66affSColin Finck 
184c2c66affSColin Finck     return ref;
185c2c66affSColin Finck }
186c2c66affSColin Finck 
D3DXRenderToSurface_GetDevice(ID3DXRenderToSurface * iface,IDirect3DDevice9 ** device)187c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToSurface_GetDevice(ID3DXRenderToSurface *iface,
188c2c66affSColin Finck                                                     IDirect3DDevice9 **device)
189c2c66affSColin Finck {
190c2c66affSColin Finck     struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
191c2c66affSColin Finck 
192c2c66affSColin Finck     TRACE("(%p)->(%p)\n", iface, device);
193c2c66affSColin Finck 
194c2c66affSColin Finck     if (!device) return D3DERR_INVALIDCALL;
195c2c66affSColin Finck 
196c2c66affSColin Finck     IDirect3DDevice9_AddRef(render->device);
197c2c66affSColin Finck     *device = render->device;
198c2c66affSColin Finck     return D3D_OK;
199c2c66affSColin Finck }
200c2c66affSColin Finck 
D3DXRenderToSurface_GetDesc(ID3DXRenderToSurface * iface,D3DXRTS_DESC * desc)201c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToSurface_GetDesc(ID3DXRenderToSurface *iface,
202c2c66affSColin Finck                                                   D3DXRTS_DESC *desc)
203c2c66affSColin Finck {
204c2c66affSColin Finck     struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
205c2c66affSColin Finck 
206c2c66affSColin Finck     TRACE("(%p)->(%p)\n", iface, desc);
207c2c66affSColin Finck 
208c2c66affSColin Finck     if (!desc) return D3DERR_INVALIDCALL;
209c2c66affSColin Finck 
210c2c66affSColin Finck     *desc = render->desc;
211c2c66affSColin Finck     return D3D_OK;
212c2c66affSColin Finck }
213c2c66affSColin Finck 
D3DXRenderToSurface_BeginScene(ID3DXRenderToSurface * iface,IDirect3DSurface9 * surface,const D3DVIEWPORT9 * viewport)214c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToSurface_BeginScene(ID3DXRenderToSurface *iface,
215c2c66affSColin Finck                                                      IDirect3DSurface9 *surface,
216c2c66affSColin Finck                                                      const D3DVIEWPORT9 *viewport)
217c2c66affSColin Finck {
218c2c66affSColin Finck     struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
219c2c66affSColin Finck     unsigned int i;
220c2c66affSColin Finck     IDirect3DDevice9 *device;
221c2c66affSColin Finck     D3DSURFACE_DESC surface_desc;
222c2c66affSColin Finck     HRESULT hr = D3DERR_INVALIDCALL;
223c2c66affSColin Finck     D3DMULTISAMPLE_TYPE multi_sample_type = D3DMULTISAMPLE_NONE;
224c2c66affSColin Finck     DWORD multi_sample_quality = 0;
225c2c66affSColin Finck 
226c2c66affSColin Finck     TRACE("(%p)->(%p, %p)\n", iface, surface, viewport);
227c2c66affSColin Finck 
228c2c66affSColin Finck     if (!surface || render->dst_surface) return D3DERR_INVALIDCALL;
229c2c66affSColin Finck 
230c2c66affSColin Finck     IDirect3DSurface9_GetDesc(surface, &surface_desc);
231c2c66affSColin Finck     if (surface_desc.Format != render->desc.Format
232c2c66affSColin Finck             || surface_desc.Width != render->desc.Width
233c2c66affSColin Finck             || surface_desc.Height != render->desc.Height)
234c2c66affSColin Finck         return D3DERR_INVALIDCALL;
235c2c66affSColin Finck 
236c2c66affSColin Finck     if (viewport)
237c2c66affSColin Finck     {
238c2c66affSColin Finck         if (viewport->X > render->desc.Width || viewport->Y > render->desc.Height
239c2c66affSColin Finck                 || viewport->X + viewport->Width > render->desc.Width
240c2c66affSColin Finck                 || viewport->Y + viewport->Height > render->desc.Height)
241c2c66affSColin Finck             return D3DERR_INVALIDCALL;
242c2c66affSColin Finck 
243c2c66affSColin Finck         if (!(surface_desc.Usage & D3DUSAGE_RENDERTARGET)
244c2c66affSColin Finck                 && (viewport->X != 0 || viewport->Y != 0
245c2c66affSColin Finck                 || viewport->Width != render->desc.Width
246c2c66affSColin Finck                 || viewport->Height != render->desc.Height))
247c2c66affSColin Finck             return D3DERR_INVALIDCALL;
248c2c66affSColin Finck     }
249c2c66affSColin Finck 
250c2c66affSColin Finck     device = render->device;
251c2c66affSColin Finck 
252c2c66affSColin Finck     device_state_capture(device, &render->previous_state);
253c2c66affSColin Finck 
254c2c66affSColin Finck     /* prepare for rendering to surface */
255c2c66affSColin Finck     for (i = 1; i < render->previous_state.num_render_targets; i++)
256c2c66affSColin Finck         IDirect3DDevice9_SetRenderTarget(device, i, NULL);
257c2c66affSColin Finck 
258c2c66affSColin Finck     if (surface_desc.Usage & D3DUSAGE_RENDERTARGET)
259c2c66affSColin Finck     {
260c2c66affSColin Finck         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
261c2c66affSColin Finck         multi_sample_type = surface_desc.MultiSampleType;
262c2c66affSColin Finck         multi_sample_quality = surface_desc.MultiSampleQuality;
263c2c66affSColin Finck     }
264c2c66affSColin Finck     else
265c2c66affSColin Finck     {
266c2c66affSColin Finck         hr = IDirect3DDevice9_CreateRenderTarget(device, render->desc.Width, render->desc.Height,
267c2c66affSColin Finck                 render->desc.Format, multi_sample_type, multi_sample_quality, FALSE,
268c2c66affSColin Finck                 &render->render_target, NULL);
269c2c66affSColin Finck         if (FAILED(hr)) goto cleanup;
270c2c66affSColin Finck         hr = IDirect3DDevice9_SetRenderTarget(device, 0, render->render_target);
271c2c66affSColin Finck     }
272c2c66affSColin Finck 
273c2c66affSColin Finck     if (FAILED(hr)) goto cleanup;
274c2c66affSColin Finck 
275c2c66affSColin Finck     if (render->desc.DepthStencil)
276c2c66affSColin Finck     {
277c2c66affSColin Finck         hr = IDirect3DDevice9_CreateDepthStencilSurface(device, render->desc.Width, render->desc.Height,
278c2c66affSColin Finck                 render->desc.DepthStencilFormat, multi_sample_type, multi_sample_quality, TRUE,
279c2c66affSColin Finck                 &render->depth_stencil, NULL);
280c2c66affSColin Finck     }
281c2c66affSColin Finck     else render->depth_stencil = NULL;
282c2c66affSColin Finck 
283c2c66affSColin Finck     if (FAILED(hr)) goto cleanup;
284c2c66affSColin Finck 
285c2c66affSColin Finck     hr = IDirect3DDevice9_SetDepthStencilSurface(device, render->depth_stencil);
286c2c66affSColin Finck     if (FAILED(hr)) goto cleanup;
287c2c66affSColin Finck 
288c2c66affSColin Finck     if (viewport) IDirect3DDevice9_SetViewport(device, viewport);
289c2c66affSColin Finck 
290c2c66affSColin Finck     IDirect3DSurface9_AddRef(surface);
291c2c66affSColin Finck     render->dst_surface = surface;
292c2c66affSColin Finck     return IDirect3DDevice9_BeginScene(device);
293c2c66affSColin Finck 
294c2c66affSColin Finck cleanup:
295c2c66affSColin Finck     device_state_restore(device, &render->previous_state);
296c2c66affSColin Finck 
297c2c66affSColin Finck     if (render->dst_surface) IDirect3DSurface9_Release(render->dst_surface);
298c2c66affSColin Finck     render->dst_surface = NULL;
299c2c66affSColin Finck 
300c2c66affSColin Finck     if (render->render_target) IDirect3DSurface9_Release(render->render_target);
301c2c66affSColin Finck     render->render_target = NULL;
302c2c66affSColin Finck     if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
303c2c66affSColin Finck     render->depth_stencil = NULL;
304c2c66affSColin Finck 
305c2c66affSColin Finck     return hr;
306c2c66affSColin Finck }
307c2c66affSColin Finck 
D3DXRenderToSurface_EndScene(ID3DXRenderToSurface * iface,DWORD filter)308c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToSurface_EndScene(ID3DXRenderToSurface *iface,
309c2c66affSColin Finck                                                    DWORD filter)
310c2c66affSColin Finck {
311c2c66affSColin Finck     struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
312c2c66affSColin Finck     HRESULT hr;
313c2c66affSColin Finck 
314c2c66affSColin Finck     TRACE("(%p)->(%#x)\n", iface, filter);
315c2c66affSColin Finck 
316c2c66affSColin Finck     if (!render->dst_surface) return D3DERR_INVALIDCALL;
317c2c66affSColin Finck 
318c2c66affSColin Finck     hr = IDirect3DDevice9_EndScene(render->device);
319c2c66affSColin Finck 
320c2c66affSColin Finck     /* copy render target data to destination surface, if needed */
321c2c66affSColin Finck     if (render->render_target)
322c2c66affSColin Finck     {
323c2c66affSColin Finck         hr = D3DXLoadSurfaceFromSurface(render->dst_surface, NULL, NULL,
324c2c66affSColin Finck                 render->render_target, NULL, NULL, filter, 0);
325c2c66affSColin Finck         if (FAILED(hr)) ERR("Copying render target data to surface failed %#x\n", hr);
326c2c66affSColin Finck     }
327c2c66affSColin Finck 
328c2c66affSColin Finck     device_state_restore(render->device, &render->previous_state);
329c2c66affSColin Finck 
330c2c66affSColin Finck     /* release resources */
331c2c66affSColin Finck     if (render->render_target)
332c2c66affSColin Finck     {
333c2c66affSColin Finck         IDirect3DSurface9_Release(render->render_target);
334c2c66affSColin Finck         render->render_target = NULL;
335c2c66affSColin Finck     }
336c2c66affSColin Finck 
337c2c66affSColin Finck     if (render->depth_stencil)
338c2c66affSColin Finck     {
339c2c66affSColin Finck         IDirect3DSurface9_Release(render->depth_stencil);
340c2c66affSColin Finck         render->depth_stencil = NULL;
341c2c66affSColin Finck     }
342c2c66affSColin Finck 
343c2c66affSColin Finck     IDirect3DSurface9_Release(render->dst_surface);
344c2c66affSColin Finck     render->dst_surface = NULL;
345c2c66affSColin Finck 
346c2c66affSColin Finck     return hr;
347c2c66affSColin Finck }
348c2c66affSColin Finck 
D3DXRenderToSurface_OnLostDevice(ID3DXRenderToSurface * iface)349c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToSurface_OnLostDevice(ID3DXRenderToSurface *iface)
350c2c66affSColin Finck {
351c2c66affSColin Finck     FIXME("(%p)->(): stub\n", iface);
352c2c66affSColin Finck     return D3D_OK;
353c2c66affSColin Finck }
354c2c66affSColin Finck 
D3DXRenderToSurface_OnResetDevice(ID3DXRenderToSurface * iface)355c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToSurface_OnResetDevice(ID3DXRenderToSurface *iface)
356c2c66affSColin Finck {
357c2c66affSColin Finck     FIXME("(%p)->(): stub\n", iface);
358c2c66affSColin Finck     return D3D_OK;
359c2c66affSColin Finck }
360c2c66affSColin Finck 
361c2c66affSColin Finck static const ID3DXRenderToSurfaceVtbl render_to_surface_vtbl =
362c2c66affSColin Finck {
363c2c66affSColin Finck     /* IUnknown methods */
364c2c66affSColin Finck     D3DXRenderToSurface_QueryInterface,
365c2c66affSColin Finck     D3DXRenderToSurface_AddRef,
366c2c66affSColin Finck     D3DXRenderToSurface_Release,
367c2c66affSColin Finck     /* ID3DXRenderToSurface methods */
368c2c66affSColin Finck     D3DXRenderToSurface_GetDevice,
369c2c66affSColin Finck     D3DXRenderToSurface_GetDesc,
370c2c66affSColin Finck     D3DXRenderToSurface_BeginScene,
371c2c66affSColin Finck     D3DXRenderToSurface_EndScene,
372c2c66affSColin Finck     D3DXRenderToSurface_OnLostDevice,
373c2c66affSColin Finck     D3DXRenderToSurface_OnResetDevice
374c2c66affSColin Finck };
375c2c66affSColin Finck 
D3DXCreateRenderToSurface(IDirect3DDevice9 * device,UINT width,UINT height,D3DFORMAT format,BOOL depth_stencil,D3DFORMAT depth_stencil_format,ID3DXRenderToSurface ** out)376c2c66affSColin Finck HRESULT WINAPI D3DXCreateRenderToSurface(IDirect3DDevice9 *device,
377c2c66affSColin Finck                                          UINT width,
378c2c66affSColin Finck                                          UINT height,
379c2c66affSColin Finck                                          D3DFORMAT format,
380c2c66affSColin Finck                                          BOOL depth_stencil,
381c2c66affSColin Finck                                          D3DFORMAT depth_stencil_format,
382c2c66affSColin Finck                                          ID3DXRenderToSurface **out)
383c2c66affSColin Finck {
384c2c66affSColin Finck     HRESULT hr;
385c2c66affSColin Finck     struct render_to_surface *render;
386c2c66affSColin Finck 
387c2c66affSColin Finck     TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device, width, height, format,
388c2c66affSColin Finck             depth_stencil, depth_stencil_format, out);
389c2c66affSColin Finck 
390c2c66affSColin Finck     if (!device || !out) return D3DERR_INVALIDCALL;
391c2c66affSColin Finck 
392c2c66affSColin Finck     render = HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_surface));
393c2c66affSColin Finck     if (!render) return E_OUTOFMEMORY;
394c2c66affSColin Finck 
395c2c66affSColin Finck     render->ID3DXRenderToSurface_iface.lpVtbl = &render_to_surface_vtbl;
396c2c66affSColin Finck     render->ref = 1;
397c2c66affSColin Finck 
398c2c66affSColin Finck     render->desc.Width = width;
399c2c66affSColin Finck     render->desc.Height = height;
400c2c66affSColin Finck     render->desc.Format = format;
401c2c66affSColin Finck     render->desc.DepthStencil = depth_stencil;
402c2c66affSColin Finck     render->desc.DepthStencilFormat = depth_stencil_format;
403c2c66affSColin Finck 
404c2c66affSColin Finck     render->dst_surface = NULL;
405c2c66affSColin Finck     render->render_target = NULL;
406c2c66affSColin Finck     render->depth_stencil = NULL;
407c2c66affSColin Finck 
408c2c66affSColin Finck     hr = device_state_init(device, &render->previous_state);
409c2c66affSColin Finck     if (FAILED(hr))
410c2c66affSColin Finck     {
411c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, render);
412c2c66affSColin Finck         return hr;
413c2c66affSColin Finck     }
414c2c66affSColin Finck 
415c2c66affSColin Finck     IDirect3DDevice9_AddRef(device);
416c2c66affSColin Finck     render->device = device;
417c2c66affSColin Finck 
418c2c66affSColin Finck     *out = &render->ID3DXRenderToSurface_iface;
419c2c66affSColin Finck     return D3D_OK;
420c2c66affSColin Finck }
421c2c66affSColin Finck 
422c2c66affSColin Finck 
423c2c66affSColin Finck enum render_state
424c2c66affSColin Finck {
425c2c66affSColin Finck     INITIAL,
426c2c66affSColin Finck 
427c2c66affSColin Finck     CUBE_BEGIN,
428c2c66affSColin Finck     CUBE_FACE
429c2c66affSColin Finck };
430c2c66affSColin Finck 
431c2c66affSColin Finck struct render_to_envmap
432c2c66affSColin Finck {
433c2c66affSColin Finck     ID3DXRenderToEnvMap ID3DXRenderToEnvMap_iface;
434c2c66affSColin Finck     LONG ref;
435c2c66affSColin Finck 
436c2c66affSColin Finck     IDirect3DDevice9 *device;
437c2c66affSColin Finck     D3DXRTE_DESC desc;
438c2c66affSColin Finck 
439c2c66affSColin Finck     enum render_state state;
440c2c66affSColin Finck     struct device_state previous_device_state;
441c2c66affSColin Finck 
442c2c66affSColin Finck     D3DCUBEMAP_FACES face;
443c2c66affSColin Finck     DWORD filter;
444c2c66affSColin Finck 
445c2c66affSColin Finck     IDirect3DSurface9 *render_target;
446c2c66affSColin Finck     IDirect3DSurface9 *depth_stencil;
447c2c66affSColin Finck 
448c2c66affSColin Finck     IDirect3DCubeTexture9 *dst_cube_texture;
449c2c66affSColin Finck };
450c2c66affSColin Finck 
copy_render_target_to_cube_texture_face(IDirect3DCubeTexture9 * cube_texture,D3DCUBEMAP_FACES face,IDirect3DSurface9 * render_target,DWORD filter)451c2c66affSColin Finck static void copy_render_target_to_cube_texture_face(IDirect3DCubeTexture9 *cube_texture,
452c2c66affSColin Finck         D3DCUBEMAP_FACES face, IDirect3DSurface9 *render_target, DWORD filter)
453c2c66affSColin Finck {
454c2c66affSColin Finck     HRESULT hr;
455c2c66affSColin Finck     IDirect3DSurface9 *cube_surface;
456c2c66affSColin Finck 
457c2c66affSColin Finck     IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, face, 0, &cube_surface);
458c2c66affSColin Finck 
459c2c66affSColin Finck     hr = D3DXLoadSurfaceFromSurface(cube_surface, NULL, NULL, render_target, NULL, NULL, filter, 0);
460c2c66affSColin Finck     if (FAILED(hr)) ERR("Copying render target data to surface failed %#x\n", hr);
461c2c66affSColin Finck 
462c2c66affSColin Finck     IDirect3DSurface9_Release(cube_surface);
463c2c66affSColin Finck }
464c2c66affSColin Finck 
impl_from_ID3DXRenderToEnvMap(ID3DXRenderToEnvMap * iface)465c2c66affSColin Finck static inline struct render_to_envmap *impl_from_ID3DXRenderToEnvMap(ID3DXRenderToEnvMap *iface)
466c2c66affSColin Finck {
467c2c66affSColin Finck     return CONTAINING_RECORD(iface, struct render_to_envmap, ID3DXRenderToEnvMap_iface);
468c2c66affSColin Finck }
469c2c66affSColin Finck 
D3DXRenderToEnvMap_QueryInterface(ID3DXRenderToEnvMap * iface,REFIID riid,void ** out)470c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_QueryInterface(ID3DXRenderToEnvMap *iface,
471c2c66affSColin Finck                                                         REFIID riid,
472c2c66affSColin Finck                                                         void **out)
473c2c66affSColin Finck {
474c2c66affSColin Finck     TRACE("iface %p, riid %s, out %p\n", iface, debugstr_guid(riid), out);
475c2c66affSColin Finck 
476c2c66affSColin Finck     if (IsEqualGUID(riid, &IID_ID3DXRenderToEnvMap)
477c2c66affSColin Finck             || IsEqualGUID(riid, &IID_IUnknown))
478c2c66affSColin Finck     {
479c2c66affSColin Finck         IUnknown_AddRef(iface);
480c2c66affSColin Finck         *out = iface;
481c2c66affSColin Finck         return S_OK;
482c2c66affSColin Finck     }
483c2c66affSColin Finck 
484c2c66affSColin Finck     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
485c2c66affSColin Finck 
486c2c66affSColin Finck     *out = NULL;
487c2c66affSColin Finck     return E_NOINTERFACE;
488c2c66affSColin Finck }
489c2c66affSColin Finck 
D3DXRenderToEnvMap_AddRef(ID3DXRenderToEnvMap * iface)490c2c66affSColin Finck static ULONG WINAPI D3DXRenderToEnvMap_AddRef(ID3DXRenderToEnvMap *iface)
491c2c66affSColin Finck {
492c2c66affSColin Finck     struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
493c2c66affSColin Finck     ULONG ref = InterlockedIncrement(&render->ref);
494c2c66affSColin Finck 
495c2c66affSColin Finck     TRACE("%p increasing refcount to %u\n", iface, ref);
496c2c66affSColin Finck 
497c2c66affSColin Finck     return ref;
498c2c66affSColin Finck }
499c2c66affSColin Finck 
D3DXRenderToEnvMap_Release(ID3DXRenderToEnvMap * iface)500c2c66affSColin Finck static ULONG WINAPI D3DXRenderToEnvMap_Release(ID3DXRenderToEnvMap *iface)
501c2c66affSColin Finck {
502c2c66affSColin Finck     struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
503c2c66affSColin Finck     ULONG ref = InterlockedDecrement(&render->ref);
504c2c66affSColin Finck 
505c2c66affSColin Finck     TRACE("%p decreasing refcount to %u\n", iface, ref);
506c2c66affSColin Finck 
507c2c66affSColin Finck     if (!ref)
508c2c66affSColin Finck     {
509c2c66affSColin Finck         if (render->dst_cube_texture) IDirect3DSurface9_Release(render->dst_cube_texture);
510c2c66affSColin Finck 
511c2c66affSColin Finck         if (render->render_target) IDirect3DSurface9_Release(render->render_target);
512c2c66affSColin Finck         if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
513c2c66affSColin Finck 
514c2c66affSColin Finck         device_state_release(&render->previous_device_state);
515c2c66affSColin Finck 
516c2c66affSColin Finck         IDirect3DDevice9_Release(render->device);
517c2c66affSColin Finck 
518c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, render);
519c2c66affSColin Finck     }
520c2c66affSColin Finck 
521c2c66affSColin Finck     return ref;
522c2c66affSColin Finck }
523c2c66affSColin Finck 
D3DXRenderToEnvMap_GetDevice(ID3DXRenderToEnvMap * iface,IDirect3DDevice9 ** device)524c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_GetDevice(ID3DXRenderToEnvMap *iface,
525c2c66affSColin Finck                                                    IDirect3DDevice9 **device)
526c2c66affSColin Finck {
527c2c66affSColin Finck     struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
528c2c66affSColin Finck 
529c2c66affSColin Finck     TRACE("(%p)->(%p)\n", iface, device);
530c2c66affSColin Finck 
531c2c66affSColin Finck     if (!device) return D3DERR_INVALIDCALL;
532c2c66affSColin Finck 
533c2c66affSColin Finck     IDirect3DDevice9_AddRef(render->device);
534c2c66affSColin Finck     *device = render->device;
535c2c66affSColin Finck     return D3D_OK;
536c2c66affSColin Finck }
537c2c66affSColin Finck 
D3DXRenderToEnvMap_GetDesc(ID3DXRenderToEnvMap * iface,D3DXRTE_DESC * desc)538c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_GetDesc(ID3DXRenderToEnvMap *iface,
539c2c66affSColin Finck                                                  D3DXRTE_DESC *desc)
540c2c66affSColin Finck {
541c2c66affSColin Finck     struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
542c2c66affSColin Finck 
543c2c66affSColin Finck     TRACE("(%p)->(%p)\n", iface, desc);
544c2c66affSColin Finck 
545c2c66affSColin Finck     if (!desc) return D3DERR_INVALIDCALL;
546c2c66affSColin Finck 
547c2c66affSColin Finck     *desc = render->desc;
548c2c66affSColin Finck     return D3D_OK;
549c2c66affSColin Finck }
550c2c66affSColin Finck 
D3DXRenderToEnvMap_BeginCube(ID3DXRenderToEnvMap * iface,IDirect3DCubeTexture9 * texture)551c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_BeginCube(ID3DXRenderToEnvMap *iface,
552c2c66affSColin Finck                                                    IDirect3DCubeTexture9 *texture)
553c2c66affSColin Finck {
554c2c66affSColin Finck     struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
555c2c66affSColin Finck     HRESULT hr;
556c2c66affSColin Finck     D3DSURFACE_DESC level_desc;
557c2c66affSColin Finck 
558c2c66affSColin Finck     TRACE("(%p)->(%p)\n", iface, texture);
559c2c66affSColin Finck 
560c2c66affSColin Finck     if (!texture) return D3DERR_INVALIDCALL;
561c2c66affSColin Finck 
562c2c66affSColin Finck     if (render->state != INITIAL) return D3DERR_INVALIDCALL;
563c2c66affSColin Finck 
564c2c66affSColin Finck     IDirect3DCubeTexture9_GetLevelDesc(texture, 0, &level_desc);
565c2c66affSColin Finck     if (level_desc.Format != render->desc.Format || level_desc.Width != render->desc.Size)
566c2c66affSColin Finck         return D3DERR_INVALIDCALL;
567c2c66affSColin Finck 
568c2c66affSColin Finck     if (!(level_desc.Usage & D3DUSAGE_RENDERTARGET))
569c2c66affSColin Finck     {
570c2c66affSColin Finck         hr = IDirect3DDevice9_CreateRenderTarget(render->device, level_desc.Width, level_desc.Height,
571c2c66affSColin Finck                 level_desc.Format, level_desc.MultiSampleType, level_desc.MultiSampleQuality,
572c2c66affSColin Finck                 TRUE, &render->render_target, NULL);
573c2c66affSColin Finck         if (FAILED(hr)) goto cleanup;
574c2c66affSColin Finck         IDirect3DCubeTexture9_GetLevelDesc(texture, 0, &level_desc);
575c2c66affSColin Finck     }
576c2c66affSColin Finck 
577c2c66affSColin Finck     if (render->desc.DepthStencil)
578c2c66affSColin Finck     {
579c2c66affSColin Finck         hr = IDirect3DDevice9_CreateDepthStencilSurface(render->device, level_desc.Width, level_desc.Height,
580c2c66affSColin Finck                 render->desc.DepthStencilFormat, level_desc.MultiSampleType, level_desc.MultiSampleQuality,
581c2c66affSColin Finck                 TRUE, &render->depth_stencil, NULL);
582c2c66affSColin Finck         if (FAILED(hr)) goto cleanup;
583c2c66affSColin Finck     }
584c2c66affSColin Finck 
585c2c66affSColin Finck     IDirect3DCubeTexture9_AddRef(texture);
586c2c66affSColin Finck     render->dst_cube_texture = texture;
587c2c66affSColin Finck     render->state = CUBE_BEGIN;
588c2c66affSColin Finck     return D3D_OK;
589c2c66affSColin Finck 
590c2c66affSColin Finck cleanup:
591c2c66affSColin Finck     if (render->dst_cube_texture) IDirect3DSurface9_Release(render->dst_cube_texture);
592c2c66affSColin Finck     render->dst_cube_texture = NULL;
593c2c66affSColin Finck 
594c2c66affSColin Finck     if (render->render_target) IDirect3DSurface9_Release(render->render_target);
595c2c66affSColin Finck     render->render_target = NULL;
596c2c66affSColin Finck     if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
597c2c66affSColin Finck     render->depth_stencil = NULL;
598c2c66affSColin Finck 
599c2c66affSColin Finck     return hr;
600c2c66affSColin Finck }
601c2c66affSColin Finck 
D3DXRenderToEnvMap_BeginSphere(ID3DXRenderToEnvMap * iface,IDirect3DTexture9 * texture)602c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_BeginSphere(ID3DXRenderToEnvMap *iface,
603c2c66affSColin Finck                                                      IDirect3DTexture9 *texture)
604c2c66affSColin Finck {
605c2c66affSColin Finck     FIXME("(%p)->(%p): stub\n", iface, texture);
606c2c66affSColin Finck     return E_NOTIMPL;
607c2c66affSColin Finck }
608c2c66affSColin Finck 
D3DXRenderToEnvMap_BeginHemisphere(ID3DXRenderToEnvMap * iface,IDirect3DTexture9 * pos_z_texture,IDirect3DTexture9 * neg_z_texture)609c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_BeginHemisphere(ID3DXRenderToEnvMap *iface,
610c2c66affSColin Finck                                                          IDirect3DTexture9 *pos_z_texture,
611c2c66affSColin Finck                                                          IDirect3DTexture9 *neg_z_texture)
612c2c66affSColin Finck {
613c2c66affSColin Finck     FIXME("(%p)->(%p, %p): stub\n", iface, pos_z_texture, neg_z_texture);
614c2c66affSColin Finck     return E_NOTIMPL;
615c2c66affSColin Finck }
616c2c66affSColin Finck 
D3DXRenderToEnvMap_BeginParabolic(ID3DXRenderToEnvMap * iface,IDirect3DTexture9 * pos_z_texture,IDirect3DTexture9 * neg_z_texture)617c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_BeginParabolic(ID3DXRenderToEnvMap *iface,
618c2c66affSColin Finck                                                         IDirect3DTexture9 *pos_z_texture,
619c2c66affSColin Finck                                                         IDirect3DTexture9 *neg_z_texture)
620c2c66affSColin Finck {
621c2c66affSColin Finck     FIXME("(%p)->(%p, %p): stub\n", iface, pos_z_texture, neg_z_texture);
622c2c66affSColin Finck     return E_NOTIMPL;
623c2c66affSColin Finck }
624c2c66affSColin Finck 
D3DXRenderToEnvMap_Face(ID3DXRenderToEnvMap * iface,D3DCUBEMAP_FACES face,DWORD filter)625c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_Face(ID3DXRenderToEnvMap *iface,
626c2c66affSColin Finck                                               D3DCUBEMAP_FACES face,
627c2c66affSColin Finck                                               DWORD filter)
628c2c66affSColin Finck {
629c2c66affSColin Finck     struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
630c2c66affSColin Finck     HRESULT hr;
631c2c66affSColin Finck     unsigned int i;
632c2c66affSColin Finck 
633c2c66affSColin Finck     TRACE("(%p)->(%u, %#x)\n", iface, face, filter);
634c2c66affSColin Finck 
635c2c66affSColin Finck     if (render->state == CUBE_FACE)
636c2c66affSColin Finck     {
637c2c66affSColin Finck         IDirect3DDevice9_EndScene(render->device);
638c2c66affSColin Finck         if (render->render_target)
639c2c66affSColin Finck             copy_render_target_to_cube_texture_face(render->dst_cube_texture, render->face,
640c2c66affSColin Finck                     render->render_target, render->filter);
641c2c66affSColin Finck 
642c2c66affSColin Finck         device_state_restore(render->device, &render->previous_device_state);
643c2c66affSColin Finck 
644c2c66affSColin Finck         render->state = CUBE_BEGIN;
645c2c66affSColin Finck     }
646c2c66affSColin Finck     else if (render->state != CUBE_BEGIN)
647c2c66affSColin Finck         return D3DERR_INVALIDCALL;
648c2c66affSColin Finck 
649c2c66affSColin Finck     device_state_capture(render->device, &render->previous_device_state);
650c2c66affSColin Finck 
651c2c66affSColin Finck     for (i = 1; i < render->previous_device_state.num_render_targets; i++)
652c2c66affSColin Finck         IDirect3DDevice9_SetRenderTarget(render->device, i, NULL);
653c2c66affSColin Finck 
654c2c66affSColin Finck     if (!render->render_target)
655c2c66affSColin Finck     {
656c2c66affSColin Finck         IDirect3DSurface9 *render_target;
657c2c66affSColin Finck         IDirect3DCubeTexture9_GetCubeMapSurface(render->dst_cube_texture, face, 0, &render_target);
658c2c66affSColin Finck         hr = IDirect3DDevice9_SetRenderTarget(render->device, 0, render_target);
659c2c66affSColin Finck         IDirect3DSurface9_Release(render_target);
660c2c66affSColin Finck     }
661c2c66affSColin Finck     else hr = IDirect3DDevice9_SetRenderTarget(render->device, 0, render->render_target);
662c2c66affSColin Finck 
663c2c66affSColin Finck     if (FAILED(hr)) goto cleanup;
664c2c66affSColin Finck 
665c2c66affSColin Finck     hr = IDirect3DDevice9_SetDepthStencilSurface(render->device, render->depth_stencil);
666c2c66affSColin Finck     if (FAILED(hr)) goto cleanup;
667c2c66affSColin Finck 
668c2c66affSColin Finck     render->state = CUBE_FACE;
669c2c66affSColin Finck     render->face = face;
670c2c66affSColin Finck     render->filter = filter;
671c2c66affSColin Finck     return IDirect3DDevice9_BeginScene(render->device);
672c2c66affSColin Finck 
673c2c66affSColin Finck cleanup:
674c2c66affSColin Finck     device_state_restore(render->device, &render->previous_device_state);
675c2c66affSColin Finck     return hr;
676c2c66affSColin Finck }
677c2c66affSColin Finck 
D3DXRenderToEnvMap_End(ID3DXRenderToEnvMap * iface,DWORD filter)678c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_End(ID3DXRenderToEnvMap *iface,
679c2c66affSColin Finck                                              DWORD filter)
680c2c66affSColin Finck {
681c2c66affSColin Finck     struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
682c2c66affSColin Finck 
683c2c66affSColin Finck     TRACE("(%p)->(%#x)\n", iface, filter);
684c2c66affSColin Finck 
685c2c66affSColin Finck     if (render->state == INITIAL) return D3DERR_INVALIDCALL;
686c2c66affSColin Finck 
687c2c66affSColin Finck     if (render->state == CUBE_FACE)
688c2c66affSColin Finck     {
689c2c66affSColin Finck         IDirect3DDevice9_EndScene(render->device);
690c2c66affSColin Finck         if (render->render_target)
691c2c66affSColin Finck             copy_render_target_to_cube_texture_face(render->dst_cube_texture, render->face,
692c2c66affSColin Finck                     render->render_target, render->filter);
693c2c66affSColin Finck 
694c2c66affSColin Finck         device_state_restore(render->device, &render->previous_device_state);
695c2c66affSColin Finck     }
696c2c66affSColin Finck 
697c2c66affSColin Finck     D3DXFilterTexture((IDirect3DBaseTexture9 *)render->dst_cube_texture, NULL, 0, filter);
698c2c66affSColin Finck 
699c2c66affSColin Finck     if (render->render_target)
700c2c66affSColin Finck     {
701c2c66affSColin Finck         IDirect3DSurface9_Release(render->render_target);
702c2c66affSColin Finck         render->render_target = NULL;
703c2c66affSColin Finck     }
704c2c66affSColin Finck 
705c2c66affSColin Finck     if (render->depth_stencil)
706c2c66affSColin Finck     {
707c2c66affSColin Finck         IDirect3DSurface9_Release(render->depth_stencil);
708c2c66affSColin Finck         render->depth_stencil = NULL;
709c2c66affSColin Finck     }
710c2c66affSColin Finck 
711c2c66affSColin Finck     IDirect3DSurface9_Release(render->dst_cube_texture);
712c2c66affSColin Finck     render->dst_cube_texture = NULL;
713c2c66affSColin Finck 
714c2c66affSColin Finck     render->state = INITIAL;
715c2c66affSColin Finck     return D3D_OK;
716c2c66affSColin Finck }
717c2c66affSColin Finck 
D3DXRenderToEnvMap_OnLostDevice(ID3DXRenderToEnvMap * iface)718c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_OnLostDevice(ID3DXRenderToEnvMap *iface)
719c2c66affSColin Finck {
720c2c66affSColin Finck     FIXME("(%p)->(): stub\n", iface);
721c2c66affSColin Finck     return D3D_OK;
722c2c66affSColin Finck }
723c2c66affSColin Finck 
D3DXRenderToEnvMap_OnResetDevice(ID3DXRenderToEnvMap * iface)724c2c66affSColin Finck static HRESULT WINAPI D3DXRenderToEnvMap_OnResetDevice(ID3DXRenderToEnvMap *iface)
725c2c66affSColin Finck {
726c2c66affSColin Finck     FIXME("(%p)->(): stub\n", iface);
727c2c66affSColin Finck     return D3D_OK;
728c2c66affSColin Finck }
729c2c66affSColin Finck 
730c2c66affSColin Finck static const ID3DXRenderToEnvMapVtbl render_to_envmap_vtbl =
731c2c66affSColin Finck {
732c2c66affSColin Finck     /* IUnknown methods */
733c2c66affSColin Finck     D3DXRenderToEnvMap_QueryInterface,
734c2c66affSColin Finck     D3DXRenderToEnvMap_AddRef,
735c2c66affSColin Finck     D3DXRenderToEnvMap_Release,
736c2c66affSColin Finck     /* ID3DXRenderToEnvMap methods */
737c2c66affSColin Finck     D3DXRenderToEnvMap_GetDevice,
738c2c66affSColin Finck     D3DXRenderToEnvMap_GetDesc,
739c2c66affSColin Finck     D3DXRenderToEnvMap_BeginCube,
740c2c66affSColin Finck     D3DXRenderToEnvMap_BeginSphere,
741c2c66affSColin Finck     D3DXRenderToEnvMap_BeginHemisphere,
742c2c66affSColin Finck     D3DXRenderToEnvMap_BeginParabolic,
743c2c66affSColin Finck     D3DXRenderToEnvMap_Face,
744c2c66affSColin Finck     D3DXRenderToEnvMap_End,
745c2c66affSColin Finck     D3DXRenderToEnvMap_OnLostDevice,
746c2c66affSColin Finck     D3DXRenderToEnvMap_OnResetDevice
747c2c66affSColin Finck };
748c2c66affSColin Finck 
D3DXCreateRenderToEnvMap(IDirect3DDevice9 * device,UINT size,UINT mip_levels,D3DFORMAT format,BOOL depth_stencil,D3DFORMAT depth_stencil_format,ID3DXRenderToEnvMap ** out)749c2c66affSColin Finck HRESULT WINAPI D3DXCreateRenderToEnvMap(IDirect3DDevice9 *device,
750c2c66affSColin Finck                                         UINT size,
751c2c66affSColin Finck                                         UINT mip_levels,
752c2c66affSColin Finck                                         D3DFORMAT format,
753c2c66affSColin Finck                                         BOOL depth_stencil,
754c2c66affSColin Finck                                         D3DFORMAT depth_stencil_format,
755c2c66affSColin Finck                                         ID3DXRenderToEnvMap **out)
756c2c66affSColin Finck {
757c2c66affSColin Finck     HRESULT hr;
758c2c66affSColin Finck     struct render_to_envmap *render;
759c2c66affSColin Finck 
760c2c66affSColin Finck     TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device, size, mip_levels,
761c2c66affSColin Finck             format, depth_stencil, depth_stencil_format, out);
762c2c66affSColin Finck 
763c2c66affSColin Finck     if (!device || !out) return D3DERR_INVALIDCALL;
764c2c66affSColin Finck 
765c2c66affSColin Finck     hr = D3DXCheckTextureRequirements(device, &size, &size, &mip_levels,
766c2c66affSColin Finck             D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
767c2c66affSColin Finck     if (FAILED(hr)) return hr;
768c2c66affSColin Finck 
769c2c66affSColin Finck     render = HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_envmap));
770c2c66affSColin Finck     if (!render) return E_OUTOFMEMORY;
771c2c66affSColin Finck 
772c2c66affSColin Finck     render->ID3DXRenderToEnvMap_iface.lpVtbl = &render_to_envmap_vtbl;
773c2c66affSColin Finck     render->ref = 1;
774c2c66affSColin Finck 
775c2c66affSColin Finck     render->desc.Size = size;
776c2c66affSColin Finck     render->desc.MipLevels = mip_levels;
777c2c66affSColin Finck     render->desc.Format = format;
778c2c66affSColin Finck     render->desc.DepthStencil = depth_stencil;
779c2c66affSColin Finck     render->desc.DepthStencilFormat = depth_stencil_format;
780c2c66affSColin Finck 
781c2c66affSColin Finck     render->state = INITIAL;
782c2c66affSColin Finck     render->render_target = NULL;
783c2c66affSColin Finck     render->depth_stencil = NULL;
784c2c66affSColin Finck     render->dst_cube_texture = NULL;
785c2c66affSColin Finck 
786c2c66affSColin Finck     hr = device_state_init(device, &render->previous_device_state);
787c2c66affSColin Finck     if (FAILED(hr))
788c2c66affSColin Finck     {
789c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, render);
790c2c66affSColin Finck         return hr;
791c2c66affSColin Finck     }
792c2c66affSColin Finck 
793c2c66affSColin Finck     IDirect3DDevice9_AddRef(device);
794c2c66affSColin Finck     render->device = device;
795c2c66affSColin Finck 
796c2c66affSColin Finck     *out = &render->ID3DXRenderToEnvMap_iface;
797c2c66affSColin Finck     return D3D_OK;
798c2c66affSColin Finck }
799