2 * Copyright 2002-2003 Jason Edmeades
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "d3d8_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d8
);
25 static HRESULT WINAPI
d3d8_vertexshader_QueryInterface(IDirect3DVertexShader8
*iface
, REFIID riid
, void **object
)
27 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
29 if (IsEqualGUID(riid
, &IID_IDirect3DVertexShader8
)
30 || IsEqualGUID(riid
, &IID_IUnknown
))
32 IUnknown_AddRef(iface
);
37 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
43 static ULONG WINAPI
d3d8_vertexshader_AddRef(IDirect3DVertexShader8
*iface
)
45 IDirect3DVertexShader8Impl
*shader
= (IDirect3DVertexShader8Impl
*)iface
;
46 ULONG refcount
= InterlockedIncrement(&shader
->ref
);
48 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
50 if (refcount
== 1 && shader
->wineD3DVertexShader
)
53 IWineD3DVertexShader_AddRef(shader
->wineD3DVertexShader
);
54 wined3d_mutex_unlock();
60 static void STDMETHODCALLTYPE
d3d8_vertexshader_wined3d_object_destroyed(void *parent
)
62 IDirect3DVertexShader8Impl
*shader
= parent
;
63 IDirect3DVertexDeclaration8_Release(shader
->vertex_declaration
);
64 HeapFree(GetProcessHeap(), 0, shader
);
67 static ULONG WINAPI
d3d8_vertexshader_Release(IDirect3DVertexShader8
*iface
)
69 IDirect3DVertexShader8Impl
*shader
= (IDirect3DVertexShader8Impl
*)iface
;
70 ULONG refcount
= InterlockedDecrement(&shader
->ref
);
72 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
76 if (shader
->wineD3DVertexShader
)
79 IWineD3DVertexShader_Release(shader
->wineD3DVertexShader
);
80 wined3d_mutex_unlock();
84 d3d8_vertexshader_wined3d_object_destroyed(shader
);
91 static const IDirect3DVertexShader8Vtbl d3d8_vertexshader_vtbl
=
94 d3d8_vertexshader_QueryInterface
,
95 d3d8_vertexshader_AddRef
,
96 d3d8_vertexshader_Release
,
99 static const struct wined3d_parent_ops d3d8_vertexshader_wined3d_parent_ops
=
101 d3d8_vertexshader_wined3d_object_destroyed
,
104 static HRESULT
d3d8_vertexshader_create_vertexdeclaration(IDirect3DDevice8Impl
*device
,
105 const DWORD
*declaration
, DWORD shader_handle
, IDirect3DVertexDeclaration8
**decl_ptr
)
107 IDirect3DVertexDeclaration8Impl
*object
;
110 TRACE("device %p, declaration %p, shader_handle %#x, decl_ptr %p.\n",
111 device
, declaration
, shader_handle
, decl_ptr
);
113 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
116 ERR("Memory allocation failed.\n");
117 return E_OUTOFMEMORY
;
120 hr
= vertexdeclaration_init(object
, device
, declaration
, shader_handle
);
123 WARN("Failed to initialize vertex declaration, hr %#x.\n", hr
);
124 HeapFree(GetProcessHeap(), 0, object
);
128 TRACE("Created vertex declaration %p.\n", object
);
129 *decl_ptr
= (IDirect3DVertexDeclaration8
*)object
;
134 HRESULT
vertexshader_init(IDirect3DVertexShader8Impl
*shader
, IDirect3DDevice8Impl
*device
,
135 const DWORD
*declaration
, const DWORD
*byte_code
, DWORD shader_handle
, DWORD usage
)
137 const DWORD
*token
= declaration
;
140 /* Test if the vertex declaration is valid. */
141 while (D3DVSD_END() != *token
)
143 D3DVSD_TOKENTYPE token_type
= ((*token
& D3DVSD_TOKENTYPEMASK
) >> D3DVSD_TOKENTYPESHIFT
);
145 if (token_type
== D3DVSD_TOKEN_STREAMDATA
&& !(token_type
& 0x10000000))
147 DWORD type
= ((*token
& D3DVSD_DATATYPEMASK
) >> D3DVSD_DATATYPESHIFT
);
148 DWORD reg
= ((*token
& D3DVSD_VERTEXREGMASK
) >> D3DVSD_VERTEXREGSHIFT
);
150 if (reg
== D3DVSDE_NORMAL
&& type
!= D3DVSDT_FLOAT3
&& !byte_code
)
152 WARN("Attempt to use a non-FLOAT3 normal with the fixed function function\n");
153 return D3DERR_INVALIDCALL
;
156 token
+= parse_token(token
);
160 shader
->lpVtbl
= &d3d8_vertexshader_vtbl
;
162 hr
= d3d8_vertexshader_create_vertexdeclaration(device
, declaration
, shader_handle
, &shader
->vertex_declaration
);
165 WARN("Failed to create vertex declaration, hr %#x.\n", hr
);
171 if (usage
) FIXME("Usage %#x not implemented.\n", usage
);
173 wined3d_mutex_lock();
174 hr
= IWineD3DDevice_CreateVertexShader(device
->WineD3DDevice
, byte_code
, NULL
/* output signature */,
175 shader
, &d3d8_vertexshader_wined3d_parent_ops
, &shader
->wineD3DVertexShader
);
176 wined3d_mutex_unlock();
179 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr
);
180 IDirect3DVertexDeclaration8_Release(shader
->vertex_declaration
);
184 load_local_constants(declaration
, shader
->wineD3DVertexShader
);
190 static HRESULT WINAPI
d3d8_pixelshader_QueryInterface(IDirect3DPixelShader8
*iface
, REFIID riid
, void **object
)
192 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
194 if (IsEqualGUID(riid
, &IID_IDirect3DPixelShader8
)
195 || IsEqualGUID(riid
, &IID_IUnknown
))
197 IUnknown_AddRef(iface
);
202 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
205 return E_NOINTERFACE
;
208 static ULONG WINAPI
d3d8_pixelshader_AddRef(IDirect3DPixelShader8
*iface
)
210 IDirect3DPixelShader8Impl
*shader
= (IDirect3DPixelShader8Impl
*)iface
;
211 ULONG refcount
= InterlockedIncrement(&shader
->ref
);
213 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
217 wined3d_mutex_lock();
218 IWineD3DPixelShader_AddRef(shader
->wineD3DPixelShader
);
219 wined3d_mutex_unlock();
225 static ULONG WINAPI
d3d8_pixelshader_Release(IDirect3DPixelShader8
*iface
)
227 IDirect3DPixelShader8Impl
*shader
= (IDirect3DPixelShader8Impl
*)iface
;
228 ULONG refcount
= InterlockedDecrement(&shader
->ref
);
230 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
234 wined3d_mutex_lock();
235 IWineD3DPixelShader_Release(shader
->wineD3DPixelShader
);
236 wined3d_mutex_unlock();
242 static const IDirect3DPixelShader8Vtbl d3d8_pixelshader_vtbl
=
245 d3d8_pixelshader_QueryInterface
,
246 d3d8_pixelshader_AddRef
,
247 d3d8_pixelshader_Release
,
250 static void STDMETHODCALLTYPE
d3d8_pixelshader_wined3d_object_destroyed(void *parent
)
252 HeapFree(GetProcessHeap(), 0, parent
);
255 static const struct wined3d_parent_ops d3d8_pixelshader_wined3d_parent_ops
=
257 d3d8_pixelshader_wined3d_object_destroyed
,
260 HRESULT
pixelshader_init(IDirect3DPixelShader8Impl
*shader
, IDirect3DDevice8Impl
*device
,
261 const DWORD
*byte_code
, DWORD shader_handle
)
266 shader
->lpVtbl
= &d3d8_pixelshader_vtbl
;
267 shader
->handle
= shader_handle
;
269 wined3d_mutex_lock();
270 hr
= IWineD3DDevice_CreatePixelShader(device
->WineD3DDevice
, byte_code
, NULL
, shader
,
271 &d3d8_pixelshader_wined3d_parent_ops
, &shader
->wineD3DPixelShader
);
272 wined3d_mutex_unlock();
275 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr
);