5 * Copyright (C) 2012 Józef Kucia
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "d3dx9_private.h"
25 #endif /* __REACTOS__ */
27 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
31 DWORD num_render_targets
;
32 IDirect3DSurface9
**render_targets
;
33 IDirect3DSurface9
*depth_stencil
;
34 D3DVIEWPORT9 viewport
;
37 static HRESULT
device_state_init(IDirect3DDevice9
*device
, struct device_state
*state
)
43 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
44 if (FAILED(hr
)) return hr
;
46 state
->num_render_targets
= caps
.NumSimultaneousRTs
;
47 state
->render_targets
= HeapAlloc(GetProcessHeap(), 0,
48 state
->num_render_targets
* sizeof(IDirect3DSurface9
*));
49 if (!state
->render_targets
)
52 for (i
= 0; i
< state
->num_render_targets
; i
++)
53 state
->render_targets
[i
] = NULL
;
54 state
->depth_stencil
= NULL
;
58 static void device_state_capture(IDirect3DDevice9
*device
, struct device_state
*state
)
63 IDirect3DDevice9_GetViewport(device
, &state
->viewport
);
65 for (i
= 0; i
< state
->num_render_targets
; i
++)
67 hr
= IDirect3DDevice9_GetRenderTarget(device
, i
, &state
->render_targets
[i
]);
68 if (FAILED(hr
)) state
->render_targets
[i
] = NULL
;
71 hr
= IDirect3DDevice9_GetDepthStencilSurface(device
, &state
->depth_stencil
);
72 if (FAILED(hr
)) state
->depth_stencil
= NULL
;
75 static void device_state_restore(IDirect3DDevice9
*device
, struct device_state
*state
)
79 for (i
= 0; i
< state
->num_render_targets
; i
++)
81 IDirect3DDevice9_SetRenderTarget(device
, i
, state
->render_targets
[i
]);
82 if (state
->render_targets
[i
])
83 IDirect3DSurface9_Release(state
->render_targets
[i
]);
84 state
->render_targets
[i
] = NULL
;
87 IDirect3DDevice9_SetDepthStencilSurface(device
, state
->depth_stencil
);
88 if (state
->depth_stencil
)
90 IDirect3DSurface9_Release(state
->depth_stencil
);
91 state
->depth_stencil
= NULL
;
94 IDirect3DDevice9_SetViewport(device
, &state
->viewport
);
97 static void device_state_release(struct device_state
*state
)
101 for (i
= 0; i
< state
->num_render_targets
; i
++)
103 if (state
->render_targets
[i
])
104 IDirect3DSurface9_Release(state
->render_targets
[i
]);
107 HeapFree(GetProcessHeap(), 0, state
->render_targets
);
109 if (state
->depth_stencil
) IDirect3DSurface9_Release(state
->depth_stencil
);
112 struct render_to_surface
114 ID3DXRenderToSurface ID3DXRenderToSurface_iface
;
117 IDirect3DDevice9
*device
;
120 IDirect3DSurface9
*dst_surface
;
122 IDirect3DSurface9
*render_target
;
123 IDirect3DSurface9
*depth_stencil
;
125 struct device_state previous_state
;
128 static inline struct render_to_surface
*impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface
*iface
)
130 return CONTAINING_RECORD(iface
, struct render_to_surface
, ID3DXRenderToSurface_iface
);
133 static HRESULT WINAPI
D3DXRenderToSurface_QueryInterface(ID3DXRenderToSurface
*iface
,
137 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
139 if (IsEqualGUID(riid
, &IID_ID3DXRenderToSurface
)
140 || IsEqualGUID(riid
, &IID_IUnknown
))
142 IUnknown_AddRef(iface
);
147 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
150 return E_NOINTERFACE
;
153 static ULONG WINAPI
D3DXRenderToSurface_AddRef(ID3DXRenderToSurface
*iface
)
155 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
156 ULONG ref
= InterlockedIncrement(&render
->ref
);
158 TRACE("%p increasing refcount to %u\n", iface
, ref
);
163 static ULONG WINAPI
D3DXRenderToSurface_Release(ID3DXRenderToSurface
*iface
)
165 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
166 ULONG ref
= InterlockedDecrement(&render
->ref
);
168 TRACE("%p decreasing refcount to %u\n", iface
, ref
);
172 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
174 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
175 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
177 device_state_release(&render
->previous_state
);
179 IDirect3DDevice9_Release(render
->device
);
181 HeapFree(GetProcessHeap(), 0, render
);
187 static HRESULT WINAPI
D3DXRenderToSurface_GetDevice(ID3DXRenderToSurface
*iface
,
188 IDirect3DDevice9
**device
)
190 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
192 TRACE("(%p)->(%p)\n", iface
, device
);
194 if (!device
) return D3DERR_INVALIDCALL
;
196 IDirect3DDevice9_AddRef(render
->device
);
197 *device
= render
->device
;
201 static HRESULT WINAPI
D3DXRenderToSurface_GetDesc(ID3DXRenderToSurface
*iface
,
204 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
206 TRACE("(%p)->(%p)\n", iface
, desc
);
208 if (!desc
) return D3DERR_INVALIDCALL
;
210 *desc
= render
->desc
;
214 static HRESULT WINAPI
D3DXRenderToSurface_BeginScene(ID3DXRenderToSurface
*iface
,
215 IDirect3DSurface9
*surface
,
216 const D3DVIEWPORT9
*viewport
)
218 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
220 IDirect3DDevice9
*device
;
221 D3DSURFACE_DESC surface_desc
;
222 HRESULT hr
= D3DERR_INVALIDCALL
;
223 D3DMULTISAMPLE_TYPE multi_sample_type
= D3DMULTISAMPLE_NONE
;
224 DWORD multi_sample_quality
= 0;
226 TRACE("(%p)->(%p, %p)\n", iface
, surface
, viewport
);
228 if (!surface
|| render
->dst_surface
) return D3DERR_INVALIDCALL
;
230 IDirect3DSurface9_GetDesc(surface
, &surface_desc
);
231 if (surface_desc
.Format
!= render
->desc
.Format
232 || surface_desc
.Width
!= render
->desc
.Width
233 || surface_desc
.Height
!= render
->desc
.Height
)
234 return D3DERR_INVALIDCALL
;
238 if (viewport
->X
> render
->desc
.Width
|| viewport
->Y
> render
->desc
.Height
239 || viewport
->X
+ viewport
->Width
> render
->desc
.Width
240 || viewport
->Y
+ viewport
->Height
> render
->desc
.Height
)
241 return D3DERR_INVALIDCALL
;
243 if (!(surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
244 && (viewport
->X
!= 0 || viewport
->Y
!= 0
245 || viewport
->Width
!= render
->desc
.Width
246 || viewport
->Height
!= render
->desc
.Height
))
247 return D3DERR_INVALIDCALL
;
250 device
= render
->device
;
252 device_state_capture(device
, &render
->previous_state
);
254 /* prepare for rendering to surface */
255 for (i
= 1; i
< render
->previous_state
.num_render_targets
; i
++)
256 IDirect3DDevice9_SetRenderTarget(device
, i
, NULL
);
258 if (surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
260 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, surface
);
261 multi_sample_type
= surface_desc
.MultiSampleType
;
262 multi_sample_quality
= surface_desc
.MultiSampleQuality
;
266 hr
= IDirect3DDevice9_CreateRenderTarget(device
, render
->desc
.Width
, render
->desc
.Height
,
267 render
->desc
.Format
, multi_sample_type
, multi_sample_quality
, FALSE
,
268 &render
->render_target
, NULL
);
269 if (FAILED(hr
)) goto cleanup
;
270 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, render
->render_target
);
273 if (FAILED(hr
)) goto cleanup
;
275 if (render
->desc
.DepthStencil
)
277 hr
= IDirect3DDevice9_CreateDepthStencilSurface(device
, render
->desc
.Width
, render
->desc
.Height
,
278 render
->desc
.DepthStencilFormat
, multi_sample_type
, multi_sample_quality
, TRUE
,
279 &render
->depth_stencil
, NULL
);
281 else render
->depth_stencil
= NULL
;
283 if (FAILED(hr
)) goto cleanup
;
285 hr
= IDirect3DDevice9_SetDepthStencilSurface(device
, render
->depth_stencil
);
286 if (FAILED(hr
)) goto cleanup
;
288 if (viewport
) IDirect3DDevice9_SetViewport(device
, viewport
);
290 IDirect3DSurface9_AddRef(surface
);
291 render
->dst_surface
= surface
;
292 return IDirect3DDevice9_BeginScene(device
);
295 device_state_restore(device
, &render
->previous_state
);
297 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
298 render
->dst_surface
= NULL
;
300 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
301 render
->render_target
= NULL
;
302 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
303 render
->depth_stencil
= NULL
;
308 static HRESULT WINAPI
D3DXRenderToSurface_EndScene(ID3DXRenderToSurface
*iface
,
311 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
314 TRACE("(%p)->(%#x)\n", iface
, filter
);
316 if (!render
->dst_surface
) return D3DERR_INVALIDCALL
;
318 hr
= IDirect3DDevice9_EndScene(render
->device
);
320 /* copy render target data to destination surface, if needed */
321 if (render
->render_target
)
323 hr
= D3DXLoadSurfaceFromSurface(render
->dst_surface
, NULL
, NULL
,
324 render
->render_target
, NULL
, NULL
, filter
, 0);
325 if (FAILED(hr
)) ERR("Copying render target data to surface failed %#x\n", hr
);
328 device_state_restore(render
->device
, &render
->previous_state
);
330 /* release resources */
331 if (render
->render_target
)
333 IDirect3DSurface9_Release(render
->render_target
);
334 render
->render_target
= NULL
;
337 if (render
->depth_stencil
)
339 IDirect3DSurface9_Release(render
->depth_stencil
);
340 render
->depth_stencil
= NULL
;
343 IDirect3DSurface9_Release(render
->dst_surface
);
344 render
->dst_surface
= NULL
;
349 static HRESULT WINAPI
D3DXRenderToSurface_OnLostDevice(ID3DXRenderToSurface
*iface
)
351 FIXME("(%p)->(): stub\n", iface
);
355 static HRESULT WINAPI
D3DXRenderToSurface_OnResetDevice(ID3DXRenderToSurface
*iface
)
357 FIXME("(%p)->(): stub\n", iface
);
361 static const ID3DXRenderToSurfaceVtbl render_to_surface_vtbl
=
363 /* IUnknown methods */
364 D3DXRenderToSurface_QueryInterface
,
365 D3DXRenderToSurface_AddRef
,
366 D3DXRenderToSurface_Release
,
367 /* ID3DXRenderToSurface methods */
368 D3DXRenderToSurface_GetDevice
,
369 D3DXRenderToSurface_GetDesc
,
370 D3DXRenderToSurface_BeginScene
,
371 D3DXRenderToSurface_EndScene
,
372 D3DXRenderToSurface_OnLostDevice
,
373 D3DXRenderToSurface_OnResetDevice
376 HRESULT WINAPI
D3DXCreateRenderToSurface(IDirect3DDevice9
*device
,
381 D3DFORMAT depth_stencil_format
,
382 ID3DXRenderToSurface
**out
)
385 struct render_to_surface
*render
;
387 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device
, width
, height
, format
,
388 depth_stencil
, depth_stencil_format
, out
);
390 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
392 render
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_surface
));
393 if (!render
) return E_OUTOFMEMORY
;
395 render
->ID3DXRenderToSurface_iface
.lpVtbl
= &render_to_surface_vtbl
;
398 render
->desc
.Width
= width
;
399 render
->desc
.Height
= height
;
400 render
->desc
.Format
= format
;
401 render
->desc
.DepthStencil
= depth_stencil
;
402 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
404 render
->dst_surface
= NULL
;
405 render
->render_target
= NULL
;
406 render
->depth_stencil
= NULL
;
408 hr
= device_state_init(device
, &render
->previous_state
);
411 HeapFree(GetProcessHeap(), 0, render
);
415 IDirect3DDevice9_AddRef(device
);
416 render
->device
= device
;
418 *out
= &render
->ID3DXRenderToSurface_iface
;
431 struct render_to_envmap
433 ID3DXRenderToEnvMap ID3DXRenderToEnvMap_iface
;
436 IDirect3DDevice9
*device
;
439 enum render_state state
;
440 struct device_state previous_device_state
;
442 D3DCUBEMAP_FACES face
;
445 IDirect3DSurface9
*render_target
;
446 IDirect3DSurface9
*depth_stencil
;
448 IDirect3DCubeTexture9
*dst_cube_texture
;
451 static void copy_render_target_to_cube_texture_face(IDirect3DCubeTexture9
*cube_texture
,
452 D3DCUBEMAP_FACES face
, IDirect3DSurface9
*render_target
, DWORD filter
)
455 IDirect3DSurface9
*cube_surface
;
457 IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture
, face
, 0, &cube_surface
);
459 hr
= D3DXLoadSurfaceFromSurface(cube_surface
, NULL
, NULL
, render_target
, NULL
, NULL
, filter
, 0);
460 if (FAILED(hr
)) ERR("Copying render target data to surface failed %#x\n", hr
);
462 IDirect3DSurface9_Release(cube_surface
);
465 static inline struct render_to_envmap
*impl_from_ID3DXRenderToEnvMap(ID3DXRenderToEnvMap
*iface
)
467 return CONTAINING_RECORD(iface
, struct render_to_envmap
, ID3DXRenderToEnvMap_iface
);
470 static HRESULT WINAPI
D3DXRenderToEnvMap_QueryInterface(ID3DXRenderToEnvMap
*iface
,
474 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
476 if (IsEqualGUID(riid
, &IID_ID3DXRenderToEnvMap
)
477 || IsEqualGUID(riid
, &IID_IUnknown
))
479 IUnknown_AddRef(iface
);
484 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
487 return E_NOINTERFACE
;
490 static ULONG WINAPI
D3DXRenderToEnvMap_AddRef(ID3DXRenderToEnvMap
*iface
)
492 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
493 ULONG ref
= InterlockedIncrement(&render
->ref
);
495 TRACE("%p increasing refcount to %u\n", iface
, ref
);
500 static ULONG WINAPI
D3DXRenderToEnvMap_Release(ID3DXRenderToEnvMap
*iface
)
502 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
503 ULONG ref
= InterlockedDecrement(&render
->ref
);
505 TRACE("%p decreasing refcount to %u\n", iface
, ref
);
509 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
511 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
512 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
514 device_state_release(&render
->previous_device_state
);
516 IDirect3DDevice9_Release(render
->device
);
518 HeapFree(GetProcessHeap(), 0, render
);
524 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDevice(ID3DXRenderToEnvMap
*iface
,
525 IDirect3DDevice9
**device
)
527 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
529 TRACE("(%p)->(%p)\n", iface
, device
);
531 if (!device
) return D3DERR_INVALIDCALL
;
533 IDirect3DDevice9_AddRef(render
->device
);
534 *device
= render
->device
;
538 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDesc(ID3DXRenderToEnvMap
*iface
,
541 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
543 TRACE("(%p)->(%p)\n", iface
, desc
);
545 if (!desc
) return D3DERR_INVALIDCALL
;
547 *desc
= render
->desc
;
551 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginCube(ID3DXRenderToEnvMap
*iface
,
552 IDirect3DCubeTexture9
*texture
)
554 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
556 D3DSURFACE_DESC level_desc
;
558 TRACE("(%p)->(%p)\n", iface
, texture
);
560 if (!texture
) return D3DERR_INVALIDCALL
;
562 if (render
->state
!= INITIAL
) return D3DERR_INVALIDCALL
;
564 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
565 if (level_desc
.Format
!= render
->desc
.Format
|| level_desc
.Width
!= render
->desc
.Size
)
566 return D3DERR_INVALIDCALL
;
568 if (!(level_desc
.Usage
& D3DUSAGE_RENDERTARGET
))
570 hr
= IDirect3DDevice9_CreateRenderTarget(render
->device
, level_desc
.Width
, level_desc
.Height
,
571 level_desc
.Format
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
572 TRUE
, &render
->render_target
, NULL
);
573 if (FAILED(hr
)) goto cleanup
;
574 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
577 if (render
->desc
.DepthStencil
)
579 hr
= IDirect3DDevice9_CreateDepthStencilSurface(render
->device
, level_desc
.Width
, level_desc
.Height
,
580 render
->desc
.DepthStencilFormat
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
581 TRUE
, &render
->depth_stencil
, NULL
);
582 if (FAILED(hr
)) goto cleanup
;
585 IDirect3DCubeTexture9_AddRef(texture
);
586 render
->dst_cube_texture
= texture
;
587 render
->state
= CUBE_BEGIN
;
591 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
592 render
->dst_cube_texture
= NULL
;
594 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
595 render
->render_target
= NULL
;
596 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
597 render
->depth_stencil
= NULL
;
602 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginSphere(ID3DXRenderToEnvMap
*iface
,
603 IDirect3DTexture9
*texture
)
605 FIXME("(%p)->(%p): stub\n", iface
, texture
);
609 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginHemisphere(ID3DXRenderToEnvMap
*iface
,
610 IDirect3DTexture9
*pos_z_texture
,
611 IDirect3DTexture9
*neg_z_texture
)
613 FIXME("(%p)->(%p, %p): stub\n", iface
, pos_z_texture
, neg_z_texture
);
617 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginParabolic(ID3DXRenderToEnvMap
*iface
,
618 IDirect3DTexture9
*pos_z_texture
,
619 IDirect3DTexture9
*neg_z_texture
)
621 FIXME("(%p)->(%p, %p): stub\n", iface
, pos_z_texture
, neg_z_texture
);
625 static HRESULT WINAPI
D3DXRenderToEnvMap_Face(ID3DXRenderToEnvMap
*iface
,
626 D3DCUBEMAP_FACES face
,
629 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
633 TRACE("(%p)->(%u, %#x)\n", iface
, face
, filter
);
635 if (render
->state
== CUBE_FACE
)
637 IDirect3DDevice9_EndScene(render
->device
);
638 if (render
->render_target
)
639 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
640 render
->render_target
, render
->filter
);
642 device_state_restore(render
->device
, &render
->previous_device_state
);
644 render
->state
= CUBE_BEGIN
;
646 else if (render
->state
!= CUBE_BEGIN
)
647 return D3DERR_INVALIDCALL
;
649 device_state_capture(render
->device
, &render
->previous_device_state
);
651 for (i
= 1; i
< render
->previous_device_state
.num_render_targets
; i
++)
652 IDirect3DDevice9_SetRenderTarget(render
->device
, i
, NULL
);
654 if (!render
->render_target
)
656 IDirect3DSurface9
*render_target
;
657 IDirect3DCubeTexture9_GetCubeMapSurface(render
->dst_cube_texture
, face
, 0, &render_target
);
658 hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render_target
);
659 IDirect3DSurface9_Release(render_target
);
661 else hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render
->render_target
);
663 if (FAILED(hr
)) goto cleanup
;
665 hr
= IDirect3DDevice9_SetDepthStencilSurface(render
->device
, render
->depth_stencil
);
666 if (FAILED(hr
)) goto cleanup
;
668 render
->state
= CUBE_FACE
;
670 render
->filter
= filter
;
671 return IDirect3DDevice9_BeginScene(render
->device
);
674 device_state_restore(render
->device
, &render
->previous_device_state
);
678 static HRESULT WINAPI
D3DXRenderToEnvMap_End(ID3DXRenderToEnvMap
*iface
,
681 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
683 TRACE("(%p)->(%#x)\n", iface
, filter
);
685 if (render
->state
== INITIAL
) return D3DERR_INVALIDCALL
;
687 if (render
->state
== CUBE_FACE
)
689 IDirect3DDevice9_EndScene(render
->device
);
690 if (render
->render_target
)
691 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
692 render
->render_target
, render
->filter
);
694 device_state_restore(render
->device
, &render
->previous_device_state
);
697 D3DXFilterTexture((IDirect3DBaseTexture9
*)render
->dst_cube_texture
, NULL
, 0, filter
);
699 if (render
->render_target
)
701 IDirect3DSurface9_Release(render
->render_target
);
702 render
->render_target
= NULL
;
705 if (render
->depth_stencil
)
707 IDirect3DSurface9_Release(render
->depth_stencil
);
708 render
->depth_stencil
= NULL
;
711 IDirect3DSurface9_Release(render
->dst_cube_texture
);
712 render
->dst_cube_texture
= NULL
;
714 render
->state
= INITIAL
;
718 static HRESULT WINAPI
D3DXRenderToEnvMap_OnLostDevice(ID3DXRenderToEnvMap
*iface
)
720 FIXME("(%p)->(): stub\n", iface
);
724 static HRESULT WINAPI
D3DXRenderToEnvMap_OnResetDevice(ID3DXRenderToEnvMap
*iface
)
726 FIXME("(%p)->(): stub\n", iface
);
730 static const ID3DXRenderToEnvMapVtbl render_to_envmap_vtbl
=
732 /* IUnknown methods */
733 D3DXRenderToEnvMap_QueryInterface
,
734 D3DXRenderToEnvMap_AddRef
,
735 D3DXRenderToEnvMap_Release
,
736 /* ID3DXRenderToEnvMap methods */
737 D3DXRenderToEnvMap_GetDevice
,
738 D3DXRenderToEnvMap_GetDesc
,
739 D3DXRenderToEnvMap_BeginCube
,
740 D3DXRenderToEnvMap_BeginSphere
,
741 D3DXRenderToEnvMap_BeginHemisphere
,
742 D3DXRenderToEnvMap_BeginParabolic
,
743 D3DXRenderToEnvMap_Face
,
744 D3DXRenderToEnvMap_End
,
745 D3DXRenderToEnvMap_OnLostDevice
,
746 D3DXRenderToEnvMap_OnResetDevice
749 HRESULT WINAPI
D3DXCreateRenderToEnvMap(IDirect3DDevice9
*device
,
754 D3DFORMAT depth_stencil_format
,
755 ID3DXRenderToEnvMap
**out
)
758 struct render_to_envmap
*render
;
760 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device
, size
, mip_levels
,
761 format
, depth_stencil
, depth_stencil_format
, out
);
763 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
765 hr
= D3DXCheckTextureRequirements(device
, &size
, &size
, &mip_levels
,
766 D3DUSAGE_RENDERTARGET
, &format
, D3DPOOL_DEFAULT
);
767 if (FAILED(hr
)) return hr
;
769 render
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_envmap
));
770 if (!render
) return E_OUTOFMEMORY
;
772 render
->ID3DXRenderToEnvMap_iface
.lpVtbl
= &render_to_envmap_vtbl
;
775 render
->desc
.Size
= size
;
776 render
->desc
.MipLevels
= mip_levels
;
777 render
->desc
.Format
= format
;
778 render
->desc
.DepthStencil
= depth_stencil
;
779 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
781 render
->state
= INITIAL
;
782 render
->render_target
= NULL
;
783 render
->depth_stencil
= NULL
;
784 render
->dst_cube_texture
= NULL
;
786 hr
= device_state_init(device
, &render
->previous_device_state
);
789 HeapFree(GetProcessHeap(), 0, render
);
793 IDirect3DDevice9_AddRef(device
);
794 render
->device
= device
;
796 *out
= &render
->ID3DXRenderToEnvMap_iface
;