2 * Copyright (C) 2012 Józef Kucia
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
21 #include "wine/port.h"
23 #include "d3dx9_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
29 DWORD num_render_targets
;
30 IDirect3DSurface9
**render_targets
;
31 IDirect3DSurface9
*depth_stencil
;
32 D3DVIEWPORT9 viewport
;
35 static HRESULT
device_state_init(IDirect3DDevice9
*device
, struct device_state
*state
)
41 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
42 if (FAILED(hr
)) return hr
;
44 state
->num_render_targets
= caps
.NumSimultaneousRTs
;
45 state
->render_targets
= HeapAlloc(GetProcessHeap(), 0,
46 state
->num_render_targets
* sizeof(IDirect3DSurface9
*));
47 if (!state
->render_targets
)
50 for (i
= 0; i
< state
->num_render_targets
; i
++)
51 state
->render_targets
[i
] = NULL
;
52 state
->depth_stencil
= NULL
;
56 static void device_state_capture(IDirect3DDevice9
*device
, struct device_state
*state
)
61 IDirect3DDevice9_GetViewport(device
, &state
->viewport
);
63 for (i
= 0; i
< state
->num_render_targets
; i
++)
65 hr
= IDirect3DDevice9_GetRenderTarget(device
, i
, &state
->render_targets
[i
]);
66 if (FAILED(hr
)) state
->render_targets
[i
] = NULL
;
69 hr
= IDirect3DDevice9_GetDepthStencilSurface(device
, &state
->depth_stencil
);
70 if (FAILED(hr
)) state
->depth_stencil
= NULL
;
73 static void device_state_restore(IDirect3DDevice9
*device
, struct device_state
*state
)
77 for (i
= 0; i
< state
->num_render_targets
; i
++)
79 IDirect3DDevice9_SetRenderTarget(device
, i
, state
->render_targets
[i
]);
80 if (state
->render_targets
[i
])
81 IDirect3DSurface9_Release(state
->render_targets
[i
]);
82 state
->render_targets
[i
] = NULL
;
85 IDirect3DDevice9_SetDepthStencilSurface(device
, state
->depth_stencil
);
86 if (state
->depth_stencil
)
88 IDirect3DSurface9_Release(state
->depth_stencil
);
89 state
->depth_stencil
= NULL
;
92 IDirect3DDevice9_SetViewport(device
, &state
->viewport
);
95 static void device_state_release(struct device_state
*state
)
99 for (i
= 0; i
< state
->num_render_targets
; i
++)
101 if (state
->render_targets
[i
])
102 IDirect3DSurface9_Release(state
->render_targets
[i
]);
105 HeapFree(GetProcessHeap(), 0, state
->render_targets
);
107 if (state
->depth_stencil
) IDirect3DSurface9_Release(state
->depth_stencil
);
110 struct render_to_surface
112 ID3DXRenderToSurface ID3DXRenderToSurface_iface
;
115 IDirect3DDevice9
*device
;
118 IDirect3DSurface9
*dst_surface
;
120 IDirect3DSurface9
*render_target
;
121 IDirect3DSurface9
*depth_stencil
;
123 struct device_state previous_state
;
126 static inline struct render_to_surface
*impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface
*iface
)
128 return CONTAINING_RECORD(iface
, struct render_to_surface
, ID3DXRenderToSurface_iface
);
131 static HRESULT WINAPI
D3DXRenderToSurface_QueryInterface(ID3DXRenderToSurface
*iface
,
135 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
137 if (IsEqualGUID(riid
, &IID_ID3DXRenderToSurface
)
138 || IsEqualGUID(riid
, &IID_IUnknown
))
140 IUnknown_AddRef(iface
);
145 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
148 return E_NOINTERFACE
;
151 static ULONG WINAPI
D3DXRenderToSurface_AddRef(ID3DXRenderToSurface
*iface
)
153 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
154 ULONG ref
= InterlockedIncrement(&render
->ref
);
156 TRACE("%p increasing refcount to %u\n", iface
, ref
);
161 static ULONG WINAPI
D3DXRenderToSurface_Release(ID3DXRenderToSurface
*iface
)
163 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
164 ULONG ref
= InterlockedDecrement(&render
->ref
);
166 TRACE("%p decreasing refcount to %u\n", iface
, ref
);
170 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
172 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
173 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
175 device_state_release(&render
->previous_state
);
177 IDirect3DDevice9_Release(render
->device
);
179 HeapFree(GetProcessHeap(), 0, render
);
185 static HRESULT WINAPI
D3DXRenderToSurface_GetDevice(ID3DXRenderToSurface
*iface
,
186 IDirect3DDevice9
**device
)
188 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
190 TRACE("(%p)->(%p)\n", iface
, device
);
192 if (!device
) return D3DERR_INVALIDCALL
;
194 IDirect3DDevice9_AddRef(render
->device
);
195 *device
= render
->device
;
199 static HRESULT WINAPI
D3DXRenderToSurface_GetDesc(ID3DXRenderToSurface
*iface
,
202 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
204 TRACE("(%p)->(%p)\n", iface
, desc
);
206 if (!desc
) return D3DERR_INVALIDCALL
;
208 *desc
= render
->desc
;
212 static HRESULT WINAPI
D3DXRenderToSurface_BeginScene(ID3DXRenderToSurface
*iface
,
213 IDirect3DSurface9
*surface
,
214 const D3DVIEWPORT9
*viewport
)
216 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
218 IDirect3DDevice9
*device
;
219 D3DSURFACE_DESC surface_desc
;
220 HRESULT hr
= D3DERR_INVALIDCALL
;
221 D3DMULTISAMPLE_TYPE multi_sample_type
= D3DMULTISAMPLE_NONE
;
222 DWORD multi_sample_quality
= 0;
224 TRACE("(%p)->(%p, %p)\n", iface
, surface
, viewport
);
226 if (!surface
|| render
->dst_surface
) return D3DERR_INVALIDCALL
;
228 IDirect3DSurface9_GetDesc(surface
, &surface_desc
);
229 if (surface_desc
.Format
!= render
->desc
.Format
230 || surface_desc
.Width
!= render
->desc
.Width
231 || surface_desc
.Height
!= render
->desc
.Height
)
232 return D3DERR_INVALIDCALL
;
236 if (viewport
->X
> render
->desc
.Width
|| viewport
->Y
> render
->desc
.Height
237 || viewport
->X
+ viewport
->Width
> render
->desc
.Width
238 || viewport
->Y
+ viewport
->Height
> render
->desc
.Height
)
239 return D3DERR_INVALIDCALL
;
241 if (!(surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
242 && (viewport
->X
!= 0 || viewport
->Y
!= 0
243 || viewport
->Width
!= render
->desc
.Width
244 || viewport
->Height
!= render
->desc
.Height
))
245 return D3DERR_INVALIDCALL
;
248 device
= render
->device
;
250 device_state_capture(device
, &render
->previous_state
);
252 /* prepare for rendering to surface */
253 for (i
= 1; i
< render
->previous_state
.num_render_targets
; i
++)
254 IDirect3DDevice9_SetRenderTarget(device
, i
, NULL
);
256 if (surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
258 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, surface
);
259 multi_sample_type
= surface_desc
.MultiSampleType
;
260 multi_sample_quality
= surface_desc
.MultiSampleQuality
;
264 hr
= IDirect3DDevice9_CreateRenderTarget(device
, render
->desc
.Width
, render
->desc
.Height
,
265 render
->desc
.Format
, multi_sample_type
, multi_sample_quality
, FALSE
,
266 &render
->render_target
, NULL
);
267 if (FAILED(hr
)) goto cleanup
;
268 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, render
->render_target
);
271 if (FAILED(hr
)) goto cleanup
;
273 if (render
->desc
.DepthStencil
)
275 hr
= IDirect3DDevice9_CreateDepthStencilSurface(device
, render
->desc
.Width
, render
->desc
.Height
,
276 render
->desc
.DepthStencilFormat
, multi_sample_type
, multi_sample_quality
, TRUE
,
277 &render
->depth_stencil
, NULL
);
279 else render
->depth_stencil
= NULL
;
281 if (FAILED(hr
)) goto cleanup
;
283 hr
= IDirect3DDevice9_SetDepthStencilSurface(device
, render
->depth_stencil
);
284 if (FAILED(hr
)) goto cleanup
;
286 if (viewport
) IDirect3DDevice9_SetViewport(device
, viewport
);
288 IDirect3DSurface9_AddRef(surface
);
289 render
->dst_surface
= surface
;
290 return IDirect3DDevice9_BeginScene(device
);
293 device_state_restore(device
, &render
->previous_state
);
295 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
296 render
->dst_surface
= NULL
;
298 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
299 render
->render_target
= NULL
;
300 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
301 render
->depth_stencil
= NULL
;
306 static HRESULT WINAPI
D3DXRenderToSurface_EndScene(ID3DXRenderToSurface
*iface
,
309 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
312 TRACE("(%p)->(%#x)\n", iface
, filter
);
314 if (!render
->dst_surface
) return D3DERR_INVALIDCALL
;
316 hr
= IDirect3DDevice9_EndScene(render
->device
);
318 /* copy render target data to destination surface, if needed */
319 if (render
->render_target
)
321 hr
= D3DXLoadSurfaceFromSurface(render
->dst_surface
, NULL
, NULL
,
322 render
->render_target
, NULL
, NULL
, filter
, 0);
323 if (FAILED(hr
)) ERR("Copying render target data to surface failed %#x\n", hr
);
326 device_state_restore(render
->device
, &render
->previous_state
);
328 /* release resources */
329 if (render
->render_target
)
331 IDirect3DSurface9_Release(render
->render_target
);
332 render
->render_target
= NULL
;
335 if (render
->depth_stencil
)
337 IDirect3DSurface9_Release(render
->depth_stencil
);
338 render
->depth_stencil
= NULL
;
341 IDirect3DSurface9_Release(render
->dst_surface
);
342 render
->dst_surface
= NULL
;
347 static HRESULT WINAPI
D3DXRenderToSurface_OnLostDevice(ID3DXRenderToSurface
*iface
)
349 FIXME("(%p)->(): stub\n", iface
);
353 static HRESULT WINAPI
D3DXRenderToSurface_OnResetDevice(ID3DXRenderToSurface
*iface
)
355 FIXME("(%p)->(): stub\n", iface
);
359 static const ID3DXRenderToSurfaceVtbl render_to_surface_vtbl
=
361 /* IUnknown methods */
362 D3DXRenderToSurface_QueryInterface
,
363 D3DXRenderToSurface_AddRef
,
364 D3DXRenderToSurface_Release
,
365 /* ID3DXRenderToSurface methods */
366 D3DXRenderToSurface_GetDevice
,
367 D3DXRenderToSurface_GetDesc
,
368 D3DXRenderToSurface_BeginScene
,
369 D3DXRenderToSurface_EndScene
,
370 D3DXRenderToSurface_OnLostDevice
,
371 D3DXRenderToSurface_OnResetDevice
374 HRESULT WINAPI
D3DXCreateRenderToSurface(IDirect3DDevice9
*device
,
379 D3DFORMAT depth_stencil_format
,
380 ID3DXRenderToSurface
**out
)
383 struct render_to_surface
*render
;
385 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device
, width
, height
, format
,
386 depth_stencil
, depth_stencil_format
, out
);
388 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
390 render
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_surface
));
391 if (!render
) return E_OUTOFMEMORY
;
393 render
->ID3DXRenderToSurface_iface
.lpVtbl
= &render_to_surface_vtbl
;
396 render
->desc
.Width
= width
;
397 render
->desc
.Height
= height
;
398 render
->desc
.Format
= format
;
399 render
->desc
.DepthStencil
= depth_stencil
;
400 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
402 render
->dst_surface
= NULL
;
403 render
->render_target
= NULL
;
404 render
->depth_stencil
= NULL
;
406 hr
= device_state_init(device
, &render
->previous_state
);
409 HeapFree(GetProcessHeap(), 0, render
);
413 IDirect3DDevice9_AddRef(device
);
414 render
->device
= device
;
416 *out
= &render
->ID3DXRenderToSurface_iface
;
429 struct render_to_envmap
431 ID3DXRenderToEnvMap ID3DXRenderToEnvMap_iface
;
434 IDirect3DDevice9
*device
;
437 enum render_state state
;
438 struct device_state previous_device_state
;
440 D3DCUBEMAP_FACES face
;
443 IDirect3DSurface9
*render_target
;
444 IDirect3DSurface9
*depth_stencil
;
446 IDirect3DCubeTexture9
*dst_cube_texture
;
449 static void copy_render_target_to_cube_texture_face(IDirect3DCubeTexture9
*cube_texture
,
450 D3DCUBEMAP_FACES face
, IDirect3DSurface9
*render_target
, DWORD filter
)
453 IDirect3DSurface9
*cube_surface
;
455 IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture
, face
, 0, &cube_surface
);
457 hr
= D3DXLoadSurfaceFromSurface(cube_surface
, NULL
, NULL
, render_target
, NULL
, NULL
, filter
, 0);
458 if (FAILED(hr
)) ERR("Copying render target data to surface failed %#x\n", hr
);
460 IDirect3DSurface9_Release(cube_surface
);
463 static inline struct render_to_envmap
*impl_from_ID3DXRenderToEnvMap(ID3DXRenderToEnvMap
*iface
)
465 return CONTAINING_RECORD(iface
, struct render_to_envmap
, ID3DXRenderToEnvMap_iface
);
468 static HRESULT WINAPI
D3DXRenderToEnvMap_QueryInterface(ID3DXRenderToEnvMap
*iface
,
472 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
474 if (IsEqualGUID(riid
, &IID_ID3DXRenderToEnvMap
)
475 || IsEqualGUID(riid
, &IID_IUnknown
))
477 IUnknown_AddRef(iface
);
482 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
485 return E_NOINTERFACE
;
488 static ULONG WINAPI
D3DXRenderToEnvMap_AddRef(ID3DXRenderToEnvMap
*iface
)
490 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
491 ULONG ref
= InterlockedIncrement(&render
->ref
);
493 TRACE("%p increasing refcount to %u\n", iface
, ref
);
498 static ULONG WINAPI
D3DXRenderToEnvMap_Release(ID3DXRenderToEnvMap
*iface
)
500 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
501 ULONG ref
= InterlockedDecrement(&render
->ref
);
503 TRACE("%p decreasing refcount to %u\n", iface
, ref
);
507 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
509 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
510 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
512 device_state_release(&render
->previous_device_state
);
514 IDirect3DDevice9_Release(render
->device
);
516 HeapFree(GetProcessHeap(), 0, render
);
522 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDevice(ID3DXRenderToEnvMap
*iface
,
523 IDirect3DDevice9
**device
)
525 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
527 TRACE("(%p)->(%p)\n", iface
, device
);
529 if (!device
) return D3DERR_INVALIDCALL
;
531 IDirect3DDevice9_AddRef(render
->device
);
532 *device
= render
->device
;
536 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDesc(ID3DXRenderToEnvMap
*iface
,
539 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
541 TRACE("(%p)->(%p)\n", iface
, desc
);
543 if (!desc
) return D3DERR_INVALIDCALL
;
545 *desc
= render
->desc
;
549 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginCube(ID3DXRenderToEnvMap
*iface
,
550 IDirect3DCubeTexture9
*texture
)
552 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
554 D3DSURFACE_DESC level_desc
;
556 TRACE("(%p)->(%p)\n", iface
, texture
);
558 if (!texture
) return D3DERR_INVALIDCALL
;
560 if (render
->state
!= INITIAL
) return D3DERR_INVALIDCALL
;
562 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
563 if (level_desc
.Format
!= render
->desc
.Format
|| level_desc
.Width
!= render
->desc
.Size
)
564 return D3DERR_INVALIDCALL
;
566 if (!(level_desc
.Usage
& D3DUSAGE_RENDERTARGET
))
568 hr
= IDirect3DDevice9_CreateRenderTarget(render
->device
, level_desc
.Width
, level_desc
.Height
,
569 level_desc
.Format
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
570 TRUE
, &render
->render_target
, NULL
);
571 if (FAILED(hr
)) goto cleanup
;
572 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
575 if (render
->desc
.DepthStencil
)
577 hr
= IDirect3DDevice9_CreateDepthStencilSurface(render
->device
, level_desc
.Width
, level_desc
.Height
,
578 render
->desc
.DepthStencilFormat
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
579 TRUE
, &render
->depth_stencil
, NULL
);
580 if (FAILED(hr
)) goto cleanup
;
583 IDirect3DCubeTexture9_AddRef(texture
);
584 render
->dst_cube_texture
= texture
;
585 render
->state
= CUBE_BEGIN
;
589 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
590 render
->dst_cube_texture
= NULL
;
592 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
593 render
->render_target
= NULL
;
594 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
595 render
->depth_stencil
= NULL
;
600 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginSphere(ID3DXRenderToEnvMap
*iface
,
601 IDirect3DTexture9
*texture
)
603 FIXME("(%p)->(%p): stub\n", iface
, texture
);
607 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginHemisphere(ID3DXRenderToEnvMap
*iface
,
608 IDirect3DTexture9
*pos_z_texture
,
609 IDirect3DTexture9
*neg_z_texture
)
611 FIXME("(%p)->(%p, %p): stub\n", iface
, pos_z_texture
, neg_z_texture
);
615 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginParabolic(ID3DXRenderToEnvMap
*iface
,
616 IDirect3DTexture9
*pos_z_texture
,
617 IDirect3DTexture9
*neg_z_texture
)
619 FIXME("(%p)->(%p, %p): stub\n", iface
, pos_z_texture
, neg_z_texture
);
623 static HRESULT WINAPI
D3DXRenderToEnvMap_Face(ID3DXRenderToEnvMap
*iface
,
624 D3DCUBEMAP_FACES face
,
627 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
631 TRACE("(%p)->(%u, %#x)\n", iface
, face
, filter
);
633 if (render
->state
== CUBE_FACE
)
635 IDirect3DDevice9_EndScene(render
->device
);
636 if (render
->render_target
)
637 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
638 render
->render_target
, render
->filter
);
640 device_state_restore(render
->device
, &render
->previous_device_state
);
642 render
->state
= CUBE_BEGIN
;
644 else if (render
->state
!= CUBE_BEGIN
)
645 return D3DERR_INVALIDCALL
;
647 device_state_capture(render
->device
, &render
->previous_device_state
);
649 for (i
= 1; i
< render
->previous_device_state
.num_render_targets
; i
++)
650 IDirect3DDevice9_SetRenderTarget(render
->device
, i
, NULL
);
652 if (!render
->render_target
)
654 IDirect3DSurface9
*render_target
;
655 IDirect3DCubeTexture9_GetCubeMapSurface(render
->dst_cube_texture
, face
, 0, &render_target
);
656 hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render_target
);
657 IDirect3DSurface9_Release(render_target
);
659 else hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render
->render_target
);
661 if (FAILED(hr
)) goto cleanup
;
663 hr
= IDirect3DDevice9_SetDepthStencilSurface(render
->device
, render
->depth_stencil
);
664 if (FAILED(hr
)) goto cleanup
;
666 render
->state
= CUBE_FACE
;
668 render
->filter
= filter
;
669 return IDirect3DDevice9_BeginScene(render
->device
);
672 device_state_restore(render
->device
, &render
->previous_device_state
);
676 static HRESULT WINAPI
D3DXRenderToEnvMap_End(ID3DXRenderToEnvMap
*iface
,
679 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
681 TRACE("(%p)->(%#x)\n", iface
, filter
);
683 if (render
->state
== INITIAL
) return D3DERR_INVALIDCALL
;
685 if (render
->state
== CUBE_FACE
)
687 IDirect3DDevice9_EndScene(render
->device
);
688 if (render
->render_target
)
689 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
690 render
->render_target
, render
->filter
);
692 device_state_restore(render
->device
, &render
->previous_device_state
);
695 D3DXFilterTexture((IDirect3DBaseTexture9
*)render
->dst_cube_texture
, NULL
, 0, filter
);
697 if (render
->render_target
)
699 IDirect3DSurface9_Release(render
->render_target
);
700 render
->render_target
= NULL
;
703 if (render
->depth_stencil
)
705 IDirect3DSurface9_Release(render
->depth_stencil
);
706 render
->depth_stencil
= NULL
;
709 IDirect3DSurface9_Release(render
->dst_cube_texture
);
710 render
->dst_cube_texture
= NULL
;
712 render
->state
= INITIAL
;
716 static HRESULT WINAPI
D3DXRenderToEnvMap_OnLostDevice(ID3DXRenderToEnvMap
*iface
)
718 FIXME("(%p)->(): stub\n", iface
);
722 static HRESULT WINAPI
D3DXRenderToEnvMap_OnResetDevice(ID3DXRenderToEnvMap
*iface
)
724 FIXME("(%p)->(): stub\n", iface
);
728 static const ID3DXRenderToEnvMapVtbl render_to_envmap_vtbl
=
730 /* IUnknown methods */
731 D3DXRenderToEnvMap_QueryInterface
,
732 D3DXRenderToEnvMap_AddRef
,
733 D3DXRenderToEnvMap_Release
,
734 /* ID3DXRenderToEnvMap methods */
735 D3DXRenderToEnvMap_GetDevice
,
736 D3DXRenderToEnvMap_GetDesc
,
737 D3DXRenderToEnvMap_BeginCube
,
738 D3DXRenderToEnvMap_BeginSphere
,
739 D3DXRenderToEnvMap_BeginHemisphere
,
740 D3DXRenderToEnvMap_BeginParabolic
,
741 D3DXRenderToEnvMap_Face
,
742 D3DXRenderToEnvMap_End
,
743 D3DXRenderToEnvMap_OnLostDevice
,
744 D3DXRenderToEnvMap_OnResetDevice
747 HRESULT WINAPI
D3DXCreateRenderToEnvMap(IDirect3DDevice9
*device
,
752 D3DFORMAT depth_stencil_format
,
753 ID3DXRenderToEnvMap
**out
)
756 struct render_to_envmap
*render
;
758 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device
, size
, mip_levels
,
759 format
, depth_stencil
, depth_stencil_format
, out
);
761 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
763 hr
= D3DXCheckTextureRequirements(device
, &size
, &size
, &mip_levels
,
764 D3DUSAGE_RENDERTARGET
, &format
, D3DPOOL_DEFAULT
);
765 if (FAILED(hr
)) return hr
;
767 render
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_envmap
));
768 if (!render
) return E_OUTOFMEMORY
;
770 render
->ID3DXRenderToEnvMap_iface
.lpVtbl
= &render_to_envmap_vtbl
;
773 render
->desc
.Size
= size
;
774 render
->desc
.MipLevels
= mip_levels
;
775 render
->desc
.Format
= format
;
776 render
->desc
.DepthStencil
= depth_stencil
;
777 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
779 render
->state
= INITIAL
;
780 render
->render_target
= NULL
;
781 render
->depth_stencil
= NULL
;
782 render
->dst_cube_texture
= NULL
;
784 hr
= device_state_init(device
, &render
->previous_device_state
);
787 HeapFree(GetProcessHeap(), 0, render
);
791 IDirect3DDevice9_AddRef(device
);
792 render
->device
= device
;
794 *out
= &render
->ID3DXRenderToEnvMap_iface
;