wpcap: Handle different layout of the native packet header structure on 32-bit.
[wine.git] / dlls / d3dx9_36 / render.c
blob6bef9430f80a628e56fc0b56454ee5b4c126152f
1 /*
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 "d3dx9_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
25 struct device_state
27 DWORD num_render_targets;
28 IDirect3DSurface9 **render_targets;
29 IDirect3DSurface9 *depth_stencil;
30 D3DVIEWPORT9 viewport;
33 static HRESULT device_state_init(IDirect3DDevice9 *device, struct device_state *state)
35 HRESULT hr;
36 D3DCAPS9 caps;
37 unsigned int i;
39 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
40 if (FAILED(hr)) return hr;
42 state->num_render_targets = caps.NumSimultaneousRTs;
43 state->render_targets = malloc(state->num_render_targets * sizeof(IDirect3DSurface9 *));
44 if (!state->render_targets)
45 return E_OUTOFMEMORY;
47 for (i = 0; i < state->num_render_targets; i++)
48 state->render_targets[i] = NULL;
49 state->depth_stencil = NULL;
50 return D3D_OK;
53 static void device_state_capture(IDirect3DDevice9 *device, struct device_state *state)
55 HRESULT hr;
56 unsigned int i;
58 IDirect3DDevice9_GetViewport(device, &state->viewport);
60 for (i = 0; i < state->num_render_targets; i++)
62 hr = IDirect3DDevice9_GetRenderTarget(device, i, &state->render_targets[i]);
63 if (FAILED(hr)) state->render_targets[i] = NULL;
66 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &state->depth_stencil);
67 if (FAILED(hr)) state->depth_stencil = NULL;
70 static void device_state_restore(IDirect3DDevice9 *device, struct device_state *state)
72 unsigned int i;
74 for (i = 0; i < state->num_render_targets; i++)
76 IDirect3DDevice9_SetRenderTarget(device, i, state->render_targets[i]);
77 if (state->render_targets[i])
78 IDirect3DSurface9_Release(state->render_targets[i]);
79 state->render_targets[i] = NULL;
82 IDirect3DDevice9_SetDepthStencilSurface(device, state->depth_stencil);
83 if (state->depth_stencil)
85 IDirect3DSurface9_Release(state->depth_stencil);
86 state->depth_stencil = NULL;
89 IDirect3DDevice9_SetViewport(device, &state->viewport);
92 static void device_state_release(struct device_state *state)
94 unsigned int i;
96 for (i = 0; i < state->num_render_targets; i++)
98 if (state->render_targets[i])
99 IDirect3DSurface9_Release(state->render_targets[i]);
102 free(state->render_targets);
104 if (state->depth_stencil) IDirect3DSurface9_Release(state->depth_stencil);
107 struct render_to_surface
109 ID3DXRenderToSurface ID3DXRenderToSurface_iface;
110 LONG ref;
112 IDirect3DDevice9 *device;
113 D3DXRTS_DESC desc;
115 IDirect3DSurface9 *dst_surface;
117 IDirect3DSurface9 *render_target;
118 IDirect3DSurface9 *depth_stencil;
120 struct device_state previous_state;
123 static inline struct render_to_surface *impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface *iface)
125 return CONTAINING_RECORD(iface, struct render_to_surface, ID3DXRenderToSurface_iface);
128 static HRESULT WINAPI D3DXRenderToSurface_QueryInterface(ID3DXRenderToSurface *iface,
129 REFIID riid,
130 void **out)
132 TRACE("iface %p, riid %s, out %p\n", iface, debugstr_guid(riid), out);
134 if (IsEqualGUID(riid, &IID_ID3DXRenderToSurface)
135 || IsEqualGUID(riid, &IID_IUnknown))
137 IUnknown_AddRef(iface);
138 *out = iface;
139 return S_OK;
142 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
144 *out = NULL;
145 return E_NOINTERFACE;
148 static ULONG WINAPI D3DXRenderToSurface_AddRef(ID3DXRenderToSurface *iface)
150 struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
151 ULONG ref = InterlockedIncrement(&render->ref);
153 TRACE("%p increasing refcount to %lu.\n", iface, ref);
155 return ref;
158 static ULONG WINAPI D3DXRenderToSurface_Release(ID3DXRenderToSurface *iface)
160 struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
161 ULONG ref = InterlockedDecrement(&render->ref);
163 TRACE("%p decreasing refcount to %lu.\n", iface, ref);
165 if (!ref)
167 if (render->dst_surface) IDirect3DSurface9_Release(render->dst_surface);
169 if (render->render_target) IDirect3DSurface9_Release(render->render_target);
170 if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
172 device_state_release(&render->previous_state);
174 IDirect3DDevice9_Release(render->device);
176 free(render);
179 return ref;
182 static HRESULT WINAPI D3DXRenderToSurface_GetDevice(ID3DXRenderToSurface *iface,
183 IDirect3DDevice9 **device)
185 struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
187 TRACE("iface %p, device %p.\n", iface, device);
189 if (!device) return D3DERR_INVALIDCALL;
191 IDirect3DDevice9_AddRef(render->device);
192 *device = render->device;
193 return D3D_OK;
196 static HRESULT WINAPI D3DXRenderToSurface_GetDesc(ID3DXRenderToSurface *iface,
197 D3DXRTS_DESC *desc)
199 struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
201 TRACE("iface %p, desc %p.\n", iface, desc);
203 if (!desc) return D3DERR_INVALIDCALL;
205 *desc = render->desc;
206 return D3D_OK;
209 static HRESULT WINAPI D3DXRenderToSurface_BeginScene(ID3DXRenderToSurface *iface,
210 IDirect3DSurface9 *surface,
211 const D3DVIEWPORT9 *viewport)
213 struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
214 unsigned int i;
215 IDirect3DDevice9 *device;
216 D3DSURFACE_DESC surface_desc;
217 HRESULT hr = D3DERR_INVALIDCALL;
218 D3DMULTISAMPLE_TYPE multi_sample_type = D3DMULTISAMPLE_NONE;
219 DWORD multi_sample_quality = 0;
221 TRACE("iface %p, surface %p, viewport %p.\n", iface, surface, viewport);
223 if (!surface || render->dst_surface) return D3DERR_INVALIDCALL;
225 IDirect3DSurface9_GetDesc(surface, &surface_desc);
226 if (surface_desc.Format != render->desc.Format
227 || surface_desc.Width != render->desc.Width
228 || surface_desc.Height != render->desc.Height)
229 return D3DERR_INVALIDCALL;
231 if (viewport)
233 if (viewport->X > render->desc.Width || viewport->Y > render->desc.Height
234 || viewport->X + viewport->Width > render->desc.Width
235 || viewport->Y + viewport->Height > render->desc.Height)
236 return D3DERR_INVALIDCALL;
238 if (!(surface_desc.Usage & D3DUSAGE_RENDERTARGET)
239 && (viewport->X != 0 || viewport->Y != 0
240 || viewport->Width != render->desc.Width
241 || viewport->Height != render->desc.Height))
242 return D3DERR_INVALIDCALL;
245 device = render->device;
247 device_state_capture(device, &render->previous_state);
249 /* prepare for rendering to surface */
250 for (i = 1; i < render->previous_state.num_render_targets; i++)
251 IDirect3DDevice9_SetRenderTarget(device, i, NULL);
253 if (surface_desc.Usage & D3DUSAGE_RENDERTARGET)
255 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
256 multi_sample_type = surface_desc.MultiSampleType;
257 multi_sample_quality = surface_desc.MultiSampleQuality;
259 else
261 hr = IDirect3DDevice9_CreateRenderTarget(device, render->desc.Width, render->desc.Height,
262 render->desc.Format, multi_sample_type, multi_sample_quality, FALSE,
263 &render->render_target, NULL);
264 if (FAILED(hr)) goto cleanup;
265 hr = IDirect3DDevice9_SetRenderTarget(device, 0, render->render_target);
268 if (FAILED(hr)) goto cleanup;
270 if (render->desc.DepthStencil)
272 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, render->desc.Width, render->desc.Height,
273 render->desc.DepthStencilFormat, multi_sample_type, multi_sample_quality, TRUE,
274 &render->depth_stencil, NULL);
276 else render->depth_stencil = NULL;
278 if (FAILED(hr)) goto cleanup;
280 hr = IDirect3DDevice9_SetDepthStencilSurface(device, render->depth_stencil);
281 if (FAILED(hr)) goto cleanup;
283 if (viewport) IDirect3DDevice9_SetViewport(device, viewport);
285 IDirect3DSurface9_AddRef(surface);
286 render->dst_surface = surface;
287 return IDirect3DDevice9_BeginScene(device);
289 cleanup:
290 device_state_restore(device, &render->previous_state);
292 if (render->dst_surface) IDirect3DSurface9_Release(render->dst_surface);
293 render->dst_surface = NULL;
295 if (render->render_target) IDirect3DSurface9_Release(render->render_target);
296 render->render_target = NULL;
297 if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
298 render->depth_stencil = NULL;
300 return hr;
303 static HRESULT WINAPI D3DXRenderToSurface_EndScene(ID3DXRenderToSurface *iface,
304 DWORD filter)
306 struct render_to_surface *render = impl_from_ID3DXRenderToSurface(iface);
307 HRESULT hr;
309 TRACE("iface %p, filter %#lx.\n", iface, filter);
311 if (!render->dst_surface) return D3DERR_INVALIDCALL;
313 hr = IDirect3DDevice9_EndScene(render->device);
315 /* copy render target data to destination surface, if needed */
316 if (render->render_target)
318 hr = D3DXLoadSurfaceFromSurface(render->dst_surface, NULL, NULL,
319 render->render_target, NULL, NULL, filter, 0);
320 if (FAILED(hr))
321 ERR("Copying render target data to surface failed, hr %#lx.\n", hr);
324 device_state_restore(render->device, &render->previous_state);
326 /* release resources */
327 if (render->render_target)
329 IDirect3DSurface9_Release(render->render_target);
330 render->render_target = NULL;
333 if (render->depth_stencil)
335 IDirect3DSurface9_Release(render->depth_stencil);
336 render->depth_stencil = NULL;
339 IDirect3DSurface9_Release(render->dst_surface);
340 render->dst_surface = NULL;
342 return hr;
345 static HRESULT WINAPI D3DXRenderToSurface_OnLostDevice(ID3DXRenderToSurface *iface)
347 FIXME("iface %p stub!\n", iface);
348 return D3D_OK;
351 static HRESULT WINAPI D3DXRenderToSurface_OnResetDevice(ID3DXRenderToSurface *iface)
353 FIXME("iface %p stub!\n", iface);
354 return D3D_OK;
357 static const ID3DXRenderToSurfaceVtbl render_to_surface_vtbl =
359 /* IUnknown methods */
360 D3DXRenderToSurface_QueryInterface,
361 D3DXRenderToSurface_AddRef,
362 D3DXRenderToSurface_Release,
363 /* ID3DXRenderToSurface methods */
364 D3DXRenderToSurface_GetDevice,
365 D3DXRenderToSurface_GetDesc,
366 D3DXRenderToSurface_BeginScene,
367 D3DXRenderToSurface_EndScene,
368 D3DXRenderToSurface_OnLostDevice,
369 D3DXRenderToSurface_OnResetDevice
372 HRESULT WINAPI D3DXCreateRenderToSurface(IDirect3DDevice9 *device,
373 UINT width,
374 UINT height,
375 D3DFORMAT format,
376 BOOL depth_stencil,
377 D3DFORMAT depth_stencil_format,
378 ID3DXRenderToSurface **out)
380 HRESULT hr;
381 struct render_to_surface *render;
383 TRACE("device %p, width %u, height %u, format %#x, depth_stencil %#x, depth_stencil_format %#x, out %p.\n",
384 device, width, height, format, depth_stencil, depth_stencil_format, out);
386 if (!device || !out) return D3DERR_INVALIDCALL;
388 render = malloc(sizeof(struct render_to_surface));
389 if (!render) return E_OUTOFMEMORY;
391 render->ID3DXRenderToSurface_iface.lpVtbl = &render_to_surface_vtbl;
392 render->ref = 1;
394 render->desc.Width = width;
395 render->desc.Height = height;
396 render->desc.Format = format;
397 render->desc.DepthStencil = depth_stencil;
398 render->desc.DepthStencilFormat = depth_stencil_format;
400 render->dst_surface = NULL;
401 render->render_target = NULL;
402 render->depth_stencil = NULL;
404 hr = device_state_init(device, &render->previous_state);
405 if (FAILED(hr))
407 free(render);
408 return hr;
411 IDirect3DDevice9_AddRef(device);
412 render->device = device;
414 *out = &render->ID3DXRenderToSurface_iface;
415 return D3D_OK;
419 enum render_state
421 INITIAL,
423 CUBE_BEGIN,
424 CUBE_FACE
427 struct render_to_envmap
429 ID3DXRenderToEnvMap ID3DXRenderToEnvMap_iface;
430 LONG ref;
432 IDirect3DDevice9 *device;
433 D3DXRTE_DESC desc;
435 enum render_state state;
436 struct device_state previous_device_state;
438 D3DCUBEMAP_FACES face;
439 DWORD filter;
441 IDirect3DSurface9 *render_target;
442 IDirect3DSurface9 *depth_stencil;
444 IDirect3DCubeTexture9 *dst_cube_texture;
447 static void copy_render_target_to_cube_texture_face(IDirect3DCubeTexture9 *cube_texture,
448 D3DCUBEMAP_FACES face, IDirect3DSurface9 *render_target, DWORD filter)
450 HRESULT hr;
451 IDirect3DSurface9 *cube_surface;
453 IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, face, 0, &cube_surface);
455 hr = D3DXLoadSurfaceFromSurface(cube_surface, NULL, NULL, render_target, NULL, NULL, filter, 0);
456 if (FAILED(hr))
457 ERR("Copying render target data to surface failed, hr %#lx.\n", hr);
459 IDirect3DSurface9_Release(cube_surface);
462 static inline struct render_to_envmap *impl_from_ID3DXRenderToEnvMap(ID3DXRenderToEnvMap *iface)
464 return CONTAINING_RECORD(iface, struct render_to_envmap, ID3DXRenderToEnvMap_iface);
467 static HRESULT WINAPI D3DXRenderToEnvMap_QueryInterface(ID3DXRenderToEnvMap *iface,
468 REFIID riid,
469 void **out)
471 TRACE("iface %p, riid %s, out %p\n", iface, debugstr_guid(riid), out);
473 if (IsEqualGUID(riid, &IID_ID3DXRenderToEnvMap)
474 || IsEqualGUID(riid, &IID_IUnknown))
476 IUnknown_AddRef(iface);
477 *out = iface;
478 return S_OK;
481 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
483 *out = NULL;
484 return E_NOINTERFACE;
487 static ULONG WINAPI D3DXRenderToEnvMap_AddRef(ID3DXRenderToEnvMap *iface)
489 struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
490 ULONG ref = InterlockedIncrement(&render->ref);
492 TRACE("%p increasing refcount to %lu.\n", iface, ref);
494 return ref;
497 static ULONG WINAPI D3DXRenderToEnvMap_Release(ID3DXRenderToEnvMap *iface)
499 struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
500 ULONG ref = InterlockedDecrement(&render->ref);
502 TRACE("%p decreasing refcount to %lu.\n", iface, ref);
504 if (!ref)
506 if (render->dst_cube_texture) IDirect3DSurface9_Release(render->dst_cube_texture);
508 if (render->render_target) IDirect3DSurface9_Release(render->render_target);
509 if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
511 device_state_release(&render->previous_device_state);
513 IDirect3DDevice9_Release(render->device);
515 free(render);
518 return ref;
521 static HRESULT WINAPI D3DXRenderToEnvMap_GetDevice(ID3DXRenderToEnvMap *iface,
522 IDirect3DDevice9 **device)
524 struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
526 TRACE("iface %p, device %p.\n", iface, device);
528 if (!device) return D3DERR_INVALIDCALL;
530 IDirect3DDevice9_AddRef(render->device);
531 *device = render->device;
532 return D3D_OK;
535 static HRESULT WINAPI D3DXRenderToEnvMap_GetDesc(ID3DXRenderToEnvMap *iface,
536 D3DXRTE_DESC *desc)
538 struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
540 TRACE("iface %p, desc %p.\n", iface, desc);
542 if (!desc) return D3DERR_INVALIDCALL;
544 *desc = render->desc;
545 return D3D_OK;
548 static HRESULT WINAPI D3DXRenderToEnvMap_BeginCube(ID3DXRenderToEnvMap *iface,
549 IDirect3DCubeTexture9 *texture)
551 struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
552 HRESULT hr;
553 D3DSURFACE_DESC level_desc;
555 TRACE("iface %p, texture %p.\n", iface, texture);
557 if (!texture) return D3DERR_INVALIDCALL;
559 if (render->state != INITIAL) return D3DERR_INVALIDCALL;
561 IDirect3DCubeTexture9_GetLevelDesc(texture, 0, &level_desc);
562 if (level_desc.Format != render->desc.Format || level_desc.Width != render->desc.Size)
563 return D3DERR_INVALIDCALL;
565 if (!(level_desc.Usage & D3DUSAGE_RENDERTARGET))
567 hr = IDirect3DDevice9_CreateRenderTarget(render->device, level_desc.Width, level_desc.Height,
568 level_desc.Format, level_desc.MultiSampleType, level_desc.MultiSampleQuality,
569 TRUE, &render->render_target, NULL);
570 if (FAILED(hr)) goto cleanup;
571 IDirect3DCubeTexture9_GetLevelDesc(texture, 0, &level_desc);
574 if (render->desc.DepthStencil)
576 hr = IDirect3DDevice9_CreateDepthStencilSurface(render->device, level_desc.Width, level_desc.Height,
577 render->desc.DepthStencilFormat, level_desc.MultiSampleType, level_desc.MultiSampleQuality,
578 TRUE, &render->depth_stencil, NULL);
579 if (FAILED(hr)) goto cleanup;
582 IDirect3DCubeTexture9_AddRef(texture);
583 render->dst_cube_texture = texture;
584 render->state = CUBE_BEGIN;
585 return D3D_OK;
587 cleanup:
588 if (render->dst_cube_texture) IDirect3DSurface9_Release(render->dst_cube_texture);
589 render->dst_cube_texture = NULL;
591 if (render->render_target) IDirect3DSurface9_Release(render->render_target);
592 render->render_target = NULL;
593 if (render->depth_stencil) IDirect3DSurface9_Release(render->depth_stencil);
594 render->depth_stencil = NULL;
596 return hr;
599 static HRESULT WINAPI D3DXRenderToEnvMap_BeginSphere(ID3DXRenderToEnvMap *iface,
600 IDirect3DTexture9 *texture)
602 FIXME("iface %p, texture %p stub!\n", iface, texture);
603 return E_NOTIMPL;
606 static HRESULT WINAPI D3DXRenderToEnvMap_BeginHemisphere(ID3DXRenderToEnvMap *iface,
607 IDirect3DTexture9 *pos_z_texture,
608 IDirect3DTexture9 *neg_z_texture)
610 FIXME("iface %p, pos_z_texture %p, neg_z_texture %p stub!\n", iface, pos_z_texture, neg_z_texture);
611 return E_NOTIMPL;
614 static HRESULT WINAPI D3DXRenderToEnvMap_BeginParabolic(ID3DXRenderToEnvMap *iface,
615 IDirect3DTexture9 *pos_z_texture,
616 IDirect3DTexture9 *neg_z_texture)
618 FIXME("iface %p, pos_z_texture %p, neg_z_texture %p stub!\n", iface, pos_z_texture, neg_z_texture);
619 return E_NOTIMPL;
622 static HRESULT WINAPI D3DXRenderToEnvMap_Face(ID3DXRenderToEnvMap *iface,
623 D3DCUBEMAP_FACES face,
624 DWORD filter)
626 struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
627 HRESULT hr;
628 unsigned int i;
630 TRACE("iface %p, face %u, filter %#lx.\n", iface, face, filter);
632 if (render->state == CUBE_FACE)
634 IDirect3DDevice9_EndScene(render->device);
635 if (render->render_target)
636 copy_render_target_to_cube_texture_face(render->dst_cube_texture, render->face,
637 render->render_target, render->filter);
639 device_state_restore(render->device, &render->previous_device_state);
641 render->state = CUBE_BEGIN;
643 else if (render->state != CUBE_BEGIN)
644 return D3DERR_INVALIDCALL;
646 device_state_capture(render->device, &render->previous_device_state);
648 for (i = 1; i < render->previous_device_state.num_render_targets; i++)
649 IDirect3DDevice9_SetRenderTarget(render->device, i, NULL);
651 if (!render->render_target)
653 IDirect3DSurface9 *render_target;
654 IDirect3DCubeTexture9_GetCubeMapSurface(render->dst_cube_texture, face, 0, &render_target);
655 hr = IDirect3DDevice9_SetRenderTarget(render->device, 0, render_target);
656 IDirect3DSurface9_Release(render_target);
658 else hr = IDirect3DDevice9_SetRenderTarget(render->device, 0, render->render_target);
660 if (FAILED(hr)) goto cleanup;
662 hr = IDirect3DDevice9_SetDepthStencilSurface(render->device, render->depth_stencil);
663 if (FAILED(hr)) goto cleanup;
665 render->state = CUBE_FACE;
666 render->face = face;
667 render->filter = filter;
668 return IDirect3DDevice9_BeginScene(render->device);
670 cleanup:
671 device_state_restore(render->device, &render->previous_device_state);
672 return hr;
675 static HRESULT WINAPI D3DXRenderToEnvMap_End(ID3DXRenderToEnvMap *iface,
676 DWORD filter)
678 struct render_to_envmap *render = impl_from_ID3DXRenderToEnvMap(iface);
680 TRACE("iface %p, filter %#lx.\n", iface, filter);
682 if (render->state == INITIAL) return D3DERR_INVALIDCALL;
684 if (render->state == CUBE_FACE)
686 IDirect3DDevice9_EndScene(render->device);
687 if (render->render_target)
688 copy_render_target_to_cube_texture_face(render->dst_cube_texture, render->face,
689 render->render_target, render->filter);
691 device_state_restore(render->device, &render->previous_device_state);
694 D3DXFilterTexture((IDirect3DBaseTexture9 *)render->dst_cube_texture, NULL, 0, filter);
696 if (render->render_target)
698 IDirect3DSurface9_Release(render->render_target);
699 render->render_target = NULL;
702 if (render->depth_stencil)
704 IDirect3DSurface9_Release(render->depth_stencil);
705 render->depth_stencil = NULL;
708 IDirect3DSurface9_Release(render->dst_cube_texture);
709 render->dst_cube_texture = NULL;
711 render->state = INITIAL;
712 return D3D_OK;
715 static HRESULT WINAPI D3DXRenderToEnvMap_OnLostDevice(ID3DXRenderToEnvMap *iface)
717 FIXME("iface %p stub!\n", iface);
718 return D3D_OK;
721 static HRESULT WINAPI D3DXRenderToEnvMap_OnResetDevice(ID3DXRenderToEnvMap *iface)
723 FIXME("iface %p stub!\n", iface);
724 return D3D_OK;
727 static const ID3DXRenderToEnvMapVtbl render_to_envmap_vtbl =
729 /* IUnknown methods */
730 D3DXRenderToEnvMap_QueryInterface,
731 D3DXRenderToEnvMap_AddRef,
732 D3DXRenderToEnvMap_Release,
733 /* ID3DXRenderToEnvMap methods */
734 D3DXRenderToEnvMap_GetDevice,
735 D3DXRenderToEnvMap_GetDesc,
736 D3DXRenderToEnvMap_BeginCube,
737 D3DXRenderToEnvMap_BeginSphere,
738 D3DXRenderToEnvMap_BeginHemisphere,
739 D3DXRenderToEnvMap_BeginParabolic,
740 D3DXRenderToEnvMap_Face,
741 D3DXRenderToEnvMap_End,
742 D3DXRenderToEnvMap_OnLostDevice,
743 D3DXRenderToEnvMap_OnResetDevice
746 HRESULT WINAPI D3DXCreateRenderToEnvMap(IDirect3DDevice9 *device,
747 UINT size,
748 UINT mip_levels,
749 D3DFORMAT format,
750 BOOL depth_stencil,
751 D3DFORMAT depth_stencil_format,
752 ID3DXRenderToEnvMap **out)
754 HRESULT hr;
755 struct render_to_envmap *render;
757 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device, size, mip_levels,
758 format, depth_stencil, depth_stencil_format, out);
760 if (!device || !out) return D3DERR_INVALIDCALL;
762 hr = D3DXCheckTextureRequirements(device, &size, &size, &mip_levels,
763 D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
764 if (FAILED(hr)) return hr;
766 render = malloc(sizeof(*render));
767 if (!render) return E_OUTOFMEMORY;
769 render->ID3DXRenderToEnvMap_iface.lpVtbl = &render_to_envmap_vtbl;
770 render->ref = 1;
772 render->desc.Size = size;
773 render->desc.MipLevels = mip_levels;
774 render->desc.Format = format;
775 render->desc.DepthStencil = depth_stencil;
776 render->desc.DepthStencilFormat = depth_stencil_format;
778 render->state = INITIAL;
779 render->render_target = NULL;
780 render->depth_stencil = NULL;
781 render->dst_cube_texture = NULL;
783 hr = device_state_init(device, &render->previous_device_state);
784 if (FAILED(hr))
786 free(render);
787 return hr;
790 IDirect3DDevice9_AddRef(device);
791 render->device = device;
793 *out = &render->ID3DXRenderToEnvMap_iface;
794 return D3D_OK;