1 /*
2 * IDirect3DVertexShader8 implementation
3 *
4 * Copyright 2002-2003 Jason Edmeades
5 * Raphael Junqueira
6 *
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.
11 *
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.
16 *
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
20 */
21
22 #include "config.h"
23 #include "d3d8_private.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
26
27 /* IDirect3DVertexShader8 IUnknown parts follow: */
28 static HRESULT WINAPI IDirect3DVertexShader8Impl_QueryInterface(IDirect3DVertexShader8 *iface, REFIID riid, LPVOID* ppobj) {
29 IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
30
31 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
32
33 if (IsEqualGUID(riid, &IID_IUnknown)
34 || IsEqualGUID(riid, &IID_IDirect3DVertexShader8)) {
35 IUnknown_AddRef(iface);
36 *ppobj = This;
37 return S_OK;
38 }
39
40 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
41 *ppobj = NULL;
42 return E_NOINTERFACE;
43 }
44
45 static ULONG WINAPI IDirect3DVertexShader8Impl_AddRef(IDirect3DVertexShader8 *iface) {
46 IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
47 ULONG ref = InterlockedIncrement(&This->ref);
48
49 TRACE("%p increasing refcount to %u.\n", iface, ref);
50
51 if (ref == 1 && This->wineD3DVertexShader)
52 {
53 wined3d_mutex_lock();
54 IWineD3DVertexShader_AddRef(This->wineD3DVertexShader);
55 wined3d_mutex_unlock();
56 }
57
58 return ref;
59 }
60
61 static void STDMETHODCALLTYPE d3d8_vertexshader_wined3d_object_destroyed(void *parent)
62 {
63 IDirect3DVertexShader8Impl *shader = parent;
64 IDirect3DVertexDeclaration8_Release(shader->vertex_declaration);
65 HeapFree(GetProcessHeap(), 0, shader);
66 }
67
68 static ULONG WINAPI IDirect3DVertexShader8Impl_Release(IDirect3DVertexShader8 *iface) {
69 IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
70 ULONG ref = InterlockedDecrement(&This->ref);
71
72 TRACE("%p decreasing refcount to %u.\n", iface, ref);
73
74 if (ref == 0) {
75 if (This->wineD3DVertexShader)
76 {
77 wined3d_mutex_lock();
78 IWineD3DVertexShader_Release(This->wineD3DVertexShader);
79 wined3d_mutex_unlock();
80 }
81 else
82 {
83 d3d8_vertexshader_wined3d_object_destroyed(This);
84 }
85 }
86 return ref;
87 }
88
89 static const IDirect3DVertexShader8Vtbl Direct3DVertexShader8_Vtbl =
90 {
91 /* IUnknown */
92 IDirect3DVertexShader8Impl_QueryInterface,
93 IDirect3DVertexShader8Impl_AddRef,
94 IDirect3DVertexShader8Impl_Release,
95 };
96
97 static const struct wined3d_parent_ops d3d8_vertexshader_wined3d_parent_ops =
98 {
99 d3d8_vertexshader_wined3d_object_destroyed,
100 };
101
102 static HRESULT vertexshader_create_vertexdeclaration(IDirect3DDevice8Impl *device,
103 const DWORD *declaration, DWORD shader_handle, IDirect3DVertexDeclaration8 **decl_ptr)
104 {
105 IDirect3DVertexDeclaration8Impl *object;
106 HRESULT hr;
107
108 TRACE("device %p, declaration %p, shader_handle %#x, decl_ptr %p.\n",
109 device, declaration, shader_handle, decl_ptr);
110
111 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
112 if (!object) {
113 ERR("Memory allocation failed\n");
114 *decl_ptr = NULL;
115 return D3DERR_OUTOFVIDEOMEMORY;
116 }
117
118 hr = vertexdeclaration_init(object, device, declaration, shader_handle);
119 if (FAILED(hr))
120 {
121 WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
122 HeapFree(GetProcessHeap(), 0, object);
123 return hr;
124 }
125
126 TRACE("Created vertex declaration %p.\n", object);
127 *decl_ptr = (IDirect3DVertexDeclaration8 *)object;
128
129 return D3D_OK;
130 }
131
132 HRESULT vertexshader_init(IDirect3DVertexShader8Impl *shader, IDirect3DDevice8Impl *device,
133 const DWORD *declaration, const DWORD *byte_code, DWORD shader_handle, DWORD usage)
134 {
135 const DWORD *token = declaration;
136 HRESULT hr;
137
138 /* Test if the vertex declaration is valid */
139 while (D3DVSD_END() != *token)
140 {
141 D3DVSD_TOKENTYPE token_type = ((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
142
143 if (token_type == D3DVSD_TOKEN_STREAMDATA && !(token_type & 0x10000000))
144 {
145 DWORD type = ((*token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
146 DWORD reg = ((*token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
147
148 if (reg == D3DVSDE_NORMAL && type != D3DVSDT_FLOAT3 && !byte_code)
149 {
150 WARN("Attempt to use a non-FLOAT3 normal with the fixed function function\n");
151 return D3DERR_INVALIDCALL;
152 }
153 }
154 token += parse_token(token);
155 }
156
157 shader->ref = 1;
158 shader->lpVtbl = &Direct3DVertexShader8_Vtbl;
159
160 hr = vertexshader_create_vertexdeclaration(device, declaration, shader_handle, &shader->vertex_declaration);
161 if (FAILED(hr))
162 {
163 WARN("Failed to create vertex declaration, hr %#x.\n", hr);
164 return hr;
165 }
166
167 if (byte_code)
168 {
169 if (usage) FIXME("Usage %#x not implemented.\n", usage);
170
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();
176 if (FAILED(hr))
177 {
178 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
179 IDirect3DVertexDeclaration8_Release(shader->vertex_declaration);
180 return hr;
181 }
182
183 load_local_constants(declaration, shader->wineD3DVertexShader);
184 }
185
186 return D3D_OK;
187 }
188
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.