2 * IDirect3DVertexShader8 implementation
4 * Copyright 2002-2003 Jason Edmeades
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
23 #include "d3d8_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d8
);
27 /* IDirect3DVertexShader8 IUnknown parts follow: */
28 static HRESULT WINAPI
IDirect3DVertexShader8Impl_QueryInterface(IDirect3DVertexShader8
*iface
, REFIID riid
, LPVOID
* ppobj
) {
29 IDirect3DVertexShader8Impl
*This
= (IDirect3DVertexShader8Impl
*)iface
;
31 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), ppobj
);
33 if (IsEqualGUID(riid
, &IID_IUnknown
)
34 || IsEqualGUID(riid
, &IID_IDirect3DVertexShader8
)) {
35 IUnknown_AddRef(iface
);
40 WARN("(%p)->(%s,%p),not found\n", This
, debugstr_guid(riid
), ppobj
);
45 static ULONG WINAPI
IDirect3DVertexShader8Impl_AddRef(IDirect3DVertexShader8
*iface
) {
46 IDirect3DVertexShader8Impl
*This
= (IDirect3DVertexShader8Impl
*)iface
;
47 ULONG ref
= InterlockedIncrement(&This
->ref
);
49 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
51 if (ref
== 1 && This
->wineD3DVertexShader
)
54 IWineD3DVertexShader_AddRef(This
->wineD3DVertexShader
);
55 wined3d_mutex_unlock();
61 static void STDMETHODCALLTYPE
d3d8_vertexshader_wined3d_object_destroyed(void *parent
)
63 IDirect3DVertexShader8Impl
*shader
= parent
;
64 IDirect3DVertexDeclaration8_Release(shader
->vertex_declaration
);
65 HeapFree(GetProcessHeap(), 0, shader
);
68 static ULONG WINAPI
IDirect3DVertexShader8Impl_Release(IDirect3DVertexShader8
*iface
) {
69 IDirect3DVertexShader8Impl
*This
= (IDirect3DVertexShader8Impl
*)iface
;
70 ULONG ref
= InterlockedDecrement(&This
->ref
);
72 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
75 if (This
->wineD3DVertexShader
)
78 IWineD3DVertexShader_Release(This
->wineD3DVertexShader
);
79 wined3d_mutex_unlock();
83 d3d8_vertexshader_wined3d_object_destroyed(This
);
89 static const IDirect3DVertexShader8Vtbl Direct3DVertexShader8_Vtbl
=
92 IDirect3DVertexShader8Impl_QueryInterface
,
93 IDirect3DVertexShader8Impl_AddRef
,
94 IDirect3DVertexShader8Impl_Release
,
97 static const struct wined3d_parent_ops d3d8_vertexshader_wined3d_parent_ops
=
99 d3d8_vertexshader_wined3d_object_destroyed
,
102 static HRESULT
vertexshader_create_vertexdeclaration(IDirect3DDevice8Impl
*device
,
103 const DWORD
*declaration
, DWORD shader_handle
, IDirect3DVertexDeclaration8
**decl_ptr
)
105 IDirect3DVertexDeclaration8Impl
*object
;
108 TRACE("device %p, declaration %p, shader_handle %#x, decl_ptr %p.\n",
109 device
, declaration
, shader_handle
, decl_ptr
);
111 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
113 ERR("Memory allocation failed\n");
115 return D3DERR_OUTOFVIDEOMEMORY
;
118 hr
= vertexdeclaration_init(object
, device
, declaration
, shader_handle
);
121 WARN("Failed to initialize vertex declaration, hr %#x.\n", hr
);
122 HeapFree(GetProcessHeap(), 0, object
);
126 TRACE("Created vertex declaration %p.\n", object
);
127 *decl_ptr
= (IDirect3DVertexDeclaration8
*)object
;
132 HRESULT
vertexshader_init(IDirect3DVertexShader8Impl
*shader
, IDirect3DDevice8Impl
*device
,
133 const DWORD
*declaration
, const DWORD
*byte_code
, DWORD shader_handle
, DWORD usage
)
135 const DWORD
*token
= declaration
;
138 /* Test if the vertex declaration is valid */
139 while (D3DVSD_END() != *token
)
141 D3DVSD_TOKENTYPE token_type
= ((*token
& D3DVSD_TOKENTYPEMASK
) >> D3DVSD_TOKENTYPESHIFT
);
143 if (token_type
== D3DVSD_TOKEN_STREAMDATA
&& !(token_type
& 0x10000000))
145 DWORD type
= ((*token
& D3DVSD_DATATYPEMASK
) >> D3DVSD_DATATYPESHIFT
);
146 DWORD reg
= ((*token
& D3DVSD_VERTEXREGMASK
) >> D3DVSD_VERTEXREGSHIFT
);
148 if (reg
== D3DVSDE_NORMAL
&& type
!= D3DVSDT_FLOAT3
&& !byte_code
)
150 WARN("Attempt to use a non-FLOAT3 normal with the fixed function function\n");
151 return D3DERR_INVALIDCALL
;
154 token
+= parse_token(token
);
158 shader
->lpVtbl
= &Direct3DVertexShader8_Vtbl
;
160 hr
= vertexshader_create_vertexdeclaration(device
, declaration
, shader_handle
, &shader
->vertex_declaration
);
163 WARN("Failed to create vertex declaration, hr %#x.\n", hr
);
169 if (usage
) FIXME("Usage %#x not implemented.\n", usage
);
171 wined3d_mutex_lock();
172 hr
= IWineD3DDevice_CreateVertexShader(device
->WineD3DDevice
, byte_code
,
173 NULL
/* output signature */, &shader
->wineD3DVertexShader
,
174 (IUnknown
*)shader
, &d3d8_vertexshader_wined3d_parent_ops
);
175 wined3d_mutex_unlock();
178 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr
);
179 IDirect3DVertexDeclaration8_Release(shader
->vertex_declaration
);
183 load_local_constants(declaration
, shader
->wineD3DVertexShader
);