2 * state block implementation
4 * Copyright 2002 Raphael Junqueira
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wine/debug.h"
29 #include "d3d8_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
33 /* Used for CreateStateBlock */
34 #define NUM_SAVEDPIXELSTATES_R 38
35 #define NUM_SAVEDPIXELSTATES_T 27
36 #define NUM_SAVEDVERTEXSTATES_R 33
37 #define NUM_SAVEDVERTEXSTATES_T 2
42 extern DWORD SavedPixelStates_R
[NUM_SAVEDPIXELSTATES_R
];
43 extern DWORD SavedPixelStates_T
[NUM_SAVEDPIXELSTATES_T
];
44 extern DWORD SavedVertexStates_R
[NUM_SAVEDVERTEXSTATES_R
];
45 extern DWORD SavedVertexStates_T
[NUM_SAVEDVERTEXSTATES_T
];
46 static const float idmatrix
[16] = {
53 HRESULT WINAPI
IDirect3DDeviceImpl_InitStartupStateBlock(IDirect3DDevice8Impl
* This
) {
56 LPDIRECT3DDEVICE8 iface
= (LPDIRECT3DDEVICE8
) This
;
58 /* Note this may have a large overhead but it should only be executed
59 once, in order to initialize the complete state of the device and
60 all opengl equivalents */
61 TRACE("-----------------------> Setting up device defaults...\n");
62 This
->StateBlock
->blockType
= D3DSBT_ALL
;
64 /* FIXME: Set some of the defaults for lights, transforms etc */
65 memcpy(&This
->StateBlock
->transforms
[D3DTS_PROJECTION
], &idmatrix
, sizeof(idmatrix
));
66 memcpy(&This
->StateBlock
->transforms
[D3DTS_VIEW
], &idmatrix
, sizeof(idmatrix
));
67 for (i
= 0; i
< 256; ++i
) {
68 memcpy(&This
->StateBlock
->transforms
[D3DTS_WORLDMATRIX(i
)], &idmatrix
, sizeof(idmatrix
));
72 if (This
->PresentParms
.EnableAutoDepthStencil
) {
73 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZENABLE
, D3DZB_TRUE
);
75 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZENABLE
, D3DZB_FALSE
);
77 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FILLMODE
, D3DFILL_SOLID
);
78 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SHADEMODE
, D3DSHADE_GOURAUD
);
79 lp
.wRepeatFactor
= 0; lp
.wLinePattern
= 0; IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LINEPATTERN
, (DWORD
) &lp
);
80 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZWRITEENABLE
, TRUE
);
81 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHATESTENABLE
, FALSE
);
82 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LASTPIXEL
, TRUE
);
83 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SRCBLEND
, D3DBLEND_ONE
);
84 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DESTBLEND
, D3DBLEND_ZERO
);
85 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_CULLMODE
, D3DCULL_CCW
);
86 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
87 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHAFUNC
, D3DCMP_ALWAYS
);
88 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHAREF
, 0xff); /*??*/
89 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DITHERENABLE
, FALSE
);
90 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHABLENDENABLE
, FALSE
);
91 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGENABLE
, FALSE
);
92 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SPECULARENABLE
, FALSE
);
93 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZVISIBLE
, 0);
94 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGCOLOR
, 0);
95 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
96 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGSTART
, 0.0f
);
97 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGEND
, 1.0f
);
98 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGDENSITY
, 1.0f
);
99 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_EDGEANTIALIAS
, FALSE
);
100 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZBIAS
, 0);
101 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_RANGEFOGENABLE
, FALSE
);
102 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILENABLE
, FALSE
);
103 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILFAIL
, D3DSTENCILOP_KEEP
);
104 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILZFAIL
, D3DSTENCILOP_KEEP
);
105 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILPASS
, D3DSTENCILOP_KEEP
);
106 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILFUNC
, D3DCMP_ALWAYS
);
107 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILREF
, 0);
108 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILMASK
, 0xFFFFFFFF);
109 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILWRITEMASK
, 0xFFFFFFFF);
110 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_TEXTUREFACTOR
, 0xFFFFFFFF);
111 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP0
, 0);
112 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP1
, 0);
113 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP2
, 0);
114 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP3
, 0);
115 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP4
, 0);
116 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP5
, 0);
117 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP6
, 0);
118 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP7
, 0);
119 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_CLIPPING
, TRUE
);
120 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LIGHTING
, TRUE
);
121 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_AMBIENT
, 0);
122 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
123 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_COLORVERTEX
, TRUE
);
124 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LOCALVIEWER
, TRUE
);
125 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_NORMALIZENORMALS
, FALSE
);
126 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DIFFUSEMATERIALSOURCE
, D3DMCS_COLOR1
);
127 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SPECULARMATERIALSOURCE
, D3DMCS_COLOR2
);
128 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_AMBIENTMATERIALSOURCE
, D3DMCS_COLOR2
);
129 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_EMISSIVEMATERIALSOURCE
, D3DMCS_MATERIAL
);
130 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_VERTEXBLEND
, D3DVBF_DISABLE
);
131 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_CLIPPLANEENABLE
, 0);
132 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SOFTWAREVERTEXPROCESSING
, FALSE
);
133 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSIZE
, 1.0f
);
134 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSIZE_MIN
, 0.0f
);
135 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSPRITEENABLE
, FALSE
);
136 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALEENABLE
, FALSE
);
137 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALE_A
, TRUE
);
138 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALE_B
, TRUE
);
139 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALE_C
, TRUE
);
140 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_MULTISAMPLEANTIALIAS
, TRUE
);
141 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_MULTISAMPLEMASK
, 0xFFFFFFFF);
142 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_PATCHEDGESTYLE
, D3DPATCHEDGE_DISCRETE
);
143 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_PATCHSEGMENTS
, 1.0f
);
144 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DEBUGMONITORTOKEN
, D3DDMT_DISABLE
);
145 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSIZE_MAX
, (DWORD
) 64.0f
);
146 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_INDEXEDVERTEXBLENDENABLE
, FALSE
);
147 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_COLORWRITEENABLE
, 0x0000000F);
148 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_TWEENFACTOR
, (DWORD
) 0.0f
);
149 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_BLENDOP
, D3DBLENDOP_ADD
);
150 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POSITIONORDER
, D3DORDER_CUBIC
);
151 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_NORMALORDER
, D3DORDER_LINEAR
);
153 /* Texture Stage States - Put directly into state block, we will call function below */
154 for (i
=0; i
<This
->TextureUnits
;i
++) {
155 memcpy(&This
->StateBlock
->transforms
[D3DTS_TEXTURE0
+i
], &idmatrix
, sizeof(idmatrix
));
156 This
->StateBlock
->texture_state
[i
][D3DTSS_COLOROP
] = (i
==0)? D3DTOP_MODULATE
: D3DTOP_DISABLE
;
157 This
->StateBlock
->texture_state
[i
][D3DTSS_COLORARG1
] = D3DTA_TEXTURE
;
158 This
->StateBlock
->texture_state
[i
][D3DTSS_COLORARG2
] = D3DTA_CURRENT
;
159 This
->StateBlock
->texture_state
[i
][D3DTSS_ALPHAOP
] = (i
==0)? D3DTOP_SELECTARG1
: D3DTOP_DISABLE
;
160 This
->StateBlock
->texture_state
[i
][D3DTSS_ALPHAARG1
] = D3DTA_TEXTURE
;
161 This
->StateBlock
->texture_state
[i
][D3DTSS_ALPHAARG2
] = D3DTA_CURRENT
;
162 This
->StateBlock
->texture_state
[i
][D3DTSS_BUMPENVMAT00
] = (DWORD
) 0.0;
163 This
->StateBlock
->texture_state
[i
][D3DTSS_BUMPENVMAT01
] = (DWORD
) 0.0;
164 This
->StateBlock
->texture_state
[i
][D3DTSS_BUMPENVMAT10
] = (DWORD
) 0.0;
165 This
->StateBlock
->texture_state
[i
][D3DTSS_BUMPENVMAT11
] = (DWORD
) 0.0;
166 /* FIXME: This->StateBlock->texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
167 This
->StateBlock
->texture_state
[i
][D3DTSS_ADDRESSU
] = D3DTADDRESS_WRAP
;
168 This
->StateBlock
->texture_state
[i
][D3DTSS_ADDRESSV
] = D3DTADDRESS_WRAP
;
169 This
->StateBlock
->texture_state
[i
][D3DTSS_BORDERCOLOR
] = 0x00;
170 This
->StateBlock
->texture_state
[i
][D3DTSS_MAGFILTER
] = D3DTEXF_POINT
;
171 This
->StateBlock
->texture_state
[i
][D3DTSS_MINFILTER
] = D3DTEXF_POINT
;
172 This
->StateBlock
->texture_state
[i
][D3DTSS_MIPFILTER
] = D3DTEXF_NONE
;
173 This
->StateBlock
->texture_state
[i
][D3DTSS_MIPMAPLODBIAS
] = 0;
174 This
->StateBlock
->texture_state
[i
][D3DTSS_MAXMIPLEVEL
] = 0;
175 This
->StateBlock
->texture_state
[i
][D3DTSS_MAXANISOTROPY
] = 1;
176 This
->StateBlock
->texture_state
[i
][D3DTSS_BUMPENVLSCALE
] = (DWORD
) 0.0;
177 This
->StateBlock
->texture_state
[i
][D3DTSS_BUMPENVLOFFSET
] = (DWORD
) 0.0;
178 This
->StateBlock
->texture_state
[i
][D3DTSS_TEXTURETRANSFORMFLAGS
] = D3DTTFF_DISABLE
;
179 This
->StateBlock
->texture_state
[i
][D3DTSS_ADDRESSW
] = D3DTADDRESS_WRAP
;
180 This
->StateBlock
->texture_state
[i
][D3DTSS_COLORARG0
] = D3DTA_CURRENT
;
181 This
->StateBlock
->texture_state
[i
][D3DTSS_ALPHAARG0
] = D3DTA_CURRENT
;
182 This
->StateBlock
->texture_state
[i
][D3DTSS_RESULTARG
] = D3DTA_CURRENT
;
185 /* Under DirectX you can have texture stage operations even if no texture is
186 bound, whereas opengl will only do texture operations when a valid texture is
187 bound. We emulate this by creating dummy textures and binding them to each
188 texture stage, but disable all stages by default. Hence if a stage is enabled
189 then the default texture will kick in until replaced by a SetTexture call */
191 for (i
= 0; i
< This
->TextureUnits
; i
++) {
194 /* Note this avoids calling settexture, so pretend it has been called */
195 This
->StateBlock
->Set
.textures
[i
] = TRUE
;
196 This
->StateBlock
->Changed
.textures
[i
] = TRUE
;
197 This
->StateBlock
->textures
[i
] = NULL
;
199 /* Make appropriate texture active */
200 if (This
->isMultiTexture
) {
201 glActiveTextureARB(GL_TEXTURE0_ARB
+ i
);
202 checkGLcall("glActiveTextureARB");
204 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
207 /* Generate an opengl texture name */
208 glGenTextures(1, &This
->dummyTextureName
[i
]);
209 checkGLcall("glGenTextures");
210 TRACE("Dummy Texture %d given name %d\n", i
, This
->dummyTextureName
[i
]);
212 /* Generate a dummy 1d texture */
213 This
->StateBlock
->textureDimensions
[i
] = GL_TEXTURE_1D
;
214 glBindTexture(GL_TEXTURE_1D
, This
->dummyTextureName
[i
]);
215 checkGLcall("glBindTexture");
217 glTexImage1D(GL_TEXTURE_1D
, 0, GL_LUMINANCE
, 1, 0, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, &white
);
218 checkGLcall("glTexImage1D");
220 /* Reapply all the texture state information to this texture */
221 setupTextureStates(iface
, i
);
224 TRACE("-----------------------> Device defaults now set up...\n");
231 HRESULT WINAPI
IDirect3DDeviceImpl_CreateStateBlock(IDirect3DDevice8Impl
* This
, D3DSTATEBLOCKTYPE Type
, IDirect3DStateBlockImpl
** ppStateBlock
) {
232 IDirect3DStateBlockImpl
* object
;
235 TRACE("(%p) : Type(%d)\n", This
, Type
);
237 /* Allocate Storage */
238 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DStateBlockImpl
));
240 if (NULL
== This
->StateBlock
) { /** if it the main stateblock only do init and returns */
241 /*object->lpVtbl = &Direct3DStateBlock9_Vtbl;*/
242 object
->device
= This
; /* FIXME: AddRef(This) */
244 object
->blockType
= Type
;
245 This
->StateBlock
= object
;
246 /* don't forget to init it calling InitStartupStateBlock */
249 memcpy(object
, This
->StateBlock
, sizeof(IDirect3DStateBlockImpl
));
251 *ppStateBlock
= (IDirect3DStateBlockImpl
*) 0xFFFFFFFF;
252 return E_OUTOFMEMORY
;
254 /*object->lpVtbl = &Direct3DStateBlock9_Vtbl;*/
255 object
->device
= This
; /* FIXME: AddRef(This) */
257 object
->blockType
= Type
;
259 TRACE("Updating changed flags appropriate for type %d\n", Type
);
261 if (Type
== D3DSBT_ALL
) {
262 TRACE("ALL => Pretend everything has changed\n");
263 memset(&object
->Changed
, TRUE
, sizeof(This
->StateBlock
->Changed
));
265 } else if (Type
== D3DSBT_PIXELSTATE
) {
267 memset(&object
->Changed
, FALSE
, sizeof(This
->StateBlock
->Changed
));
269 /* TODO: Pixel Shader Constants */
270 object
->Changed
.pixelShader
= TRUE
;
271 for (i
= 0; i
< NUM_SAVEDPIXELSTATES_R
; i
++) {
272 object
->Changed
.renderstate
[SavedPixelStates_R
[i
]] = TRUE
;
274 for (j
= 0; j
< This
->TextureUnits
; i
++) {
275 for (i
= 0; i
< NUM_SAVEDPIXELSTATES_T
; i
++) {
276 object
->Changed
.texture_state
[j
][SavedPixelStates_T
[i
]] = TRUE
;
280 } else if (Type
== D3DSBT_VERTEXSTATE
) {
282 memset(&object
->Changed
, FALSE
, sizeof(This
->StateBlock
->Changed
));
284 /* TODO: Vertex Shader Constants */
285 object
->Changed
.vertexShader
= TRUE
;
286 for (i
= 0; i
< NUM_SAVEDVERTEXSTATES_R
; i
++) {
287 object
->Changed
.renderstate
[SavedVertexStates_R
[i
]] = TRUE
;
289 for (j
= 0; j
< This
->TextureUnits
; i
++) {
290 for (i
= 0; i
< NUM_SAVEDVERTEXSTATES_T
; i
++) {
291 object
->Changed
.texture_state
[j
][SavedVertexStates_T
[i
]] = TRUE
;
294 for (i
= 0; i
< This
->maxLights
; i
++) {
295 object
->Changed
.lightEnable
[i
] = TRUE
;
296 object
->Changed
.lights
[i
] = TRUE
;
300 FIXME("Unrecognized state block type %d\n", Type
);
302 TRACE("(%p) returning token (ptr to stateblock) of %p\n", This
, object
);
304 *ppStateBlock
= object
;
308 /** yakkk temporary waiting for Release */
309 HRESULT WINAPI
IDirect3DDeviceImpl_DeleteStateBlock(IDirect3DDevice8Impl
* This
, IDirect3DStateBlockImpl
* pSB
) {
310 TRACE("(%p) : freeing StateBlock %p\n", This
, pSB
);
311 HeapFree(GetProcessHeap(), 0, (void *)pSB
);
315 HRESULT WINAPI
IDirect3DDeviceImpl_BeginStateBlock(IDirect3DDevice8Impl
* This
) {
316 IDirect3DStateBlockImpl
* object
;
318 TRACE("(%p)\n", This
);
320 if (This
->isRecordingState
) {
321 TRACE("(%p) already recording! returning error\n", This
);
322 return D3DERR_INVALIDCALL
;
325 /* Allocate Storage */
326 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DStateBlockImpl
));
329 return E_OUTOFMEMORY
;
331 /*object->lpVtbl = &Direct3DVextexShaderDeclaration8_Vtbl;*/
332 object
->device
= This
; /* FIXME: AddRef(This) */
335 This
->isRecordingState
= TRUE
;
336 This
->UpdateStateBlock
= object
;
341 HRESULT WINAPI
IDirect3DDeviceImpl_EndStateBlock(IDirect3DDevice8Impl
* This
, IDirect3DStateBlockImpl
** ppStateBlock
) {
342 TRACE("(%p)\n", This
);
344 if (!This
->isRecordingState
) {
345 TRACE("(%p) not recording! returning error\n", This
);
346 *ppStateBlock
= NULL
;
347 return D3DERR_INVALIDCALL
;
350 This
->UpdateStateBlock
->blockType
= D3DSBT_RECORDED
;
351 *ppStateBlock
= This
->UpdateStateBlock
;
352 This
->isRecordingState
= FALSE
;
353 This
->UpdateStateBlock
= This
->StateBlock
;
355 TRACE("(%p) returning token (ptr to stateblock) of %p\n", This
, *ppStateBlock
);
359 HRESULT WINAPI
IDirect3DDeviceImpl_ApplyStateBlock(IDirect3DDevice8Impl
* This
, IDirect3DStateBlockImpl
* pSB
) {
362 LPDIRECT3DDEVICE8 iface
= (LPDIRECT3DDEVICE8
) This
;
364 TRACE("(%p) : Applying state block %p ------------------v\n", This
, pSB
);
366 /* FIXME: Only apply applicable states not all states */
368 if (pSB
->blockType
== D3DSBT_RECORDED
|| pSB
->blockType
== D3DSBT_ALL
|| pSB
->blockType
== D3DSBT_VERTEXSTATE
) {
370 for (i
=0; i
<This
->maxLights
; i
++) {
372 if (pSB
->Set
.lightEnable
[i
] && pSB
->Changed
.lightEnable
[i
])
373 IDirect3DDevice8Impl_LightEnable(iface
, i
, pSB
->lightEnable
[i
]);
374 if (pSB
->Set
.lights
[i
] && pSB
->Changed
.lights
[i
])
375 IDirect3DDevice8Impl_SetLight(iface
, i
, &pSB
->lights
[i
]);
378 if (pSB
->Set
.vertexShader
&& pSB
->Changed
.vertexShader
)
379 IDirect3DDevice8Impl_SetVertexShader(iface
, pSB
->VertexShader
);
381 /* TODO: Vertex Shader Constants */
384 if (pSB
->blockType
== D3DSBT_RECORDED
|| pSB
->blockType
== D3DSBT_ALL
|| pSB
->blockType
== D3DSBT_PIXELSTATE
) {
386 if (pSB
->Set
.pixelShader
&& pSB
->Changed
.pixelShader
)
387 IDirect3DDevice8Impl_SetPixelShader(iface
, pSB
->PixelShader
);
389 /* TODO: Pixel Shader Constants */
392 /* Others + Render & Texture */
393 if (pSB
->blockType
== D3DSBT_RECORDED
|| pSB
->blockType
== D3DSBT_ALL
) {
394 for (i
=0; i
<HIGHEST_TRANSFORMSTATE
; i
++) {
395 if (pSB
->Set
.transform
[i
] && pSB
->Changed
.transform
[i
])
396 IDirect3DDevice8Impl_SetTransform(iface
, i
, &pSB
->transforms
[i
]);
399 if (pSB
->Set
.Indices
&& pSB
->Changed
.Indices
)
400 IDirect3DDevice8Impl_SetIndices(iface
, pSB
->pIndexData
, pSB
->baseVertexIndex
);
402 if (pSB
->Set
.material
&& pSB
->Changed
.material
)
403 IDirect3DDevice8Impl_SetMaterial(iface
, &pSB
->material
);
405 if (pSB
->Set
.viewport
&& pSB
->Changed
.viewport
)
406 IDirect3DDevice8Impl_SetViewport(iface
, &pSB
->viewport
);
408 for (i
=0; i
<MAX_STREAMS
; i
++) {
409 if (pSB
->Set
.stream_source
[i
] && pSB
->Changed
.stream_source
[i
])
410 IDirect3DDevice8Impl_SetStreamSource(iface
, i
, pSB
->stream_source
[i
], pSB
->stream_stride
[i
]);
413 for (i
=0; i
<This
->clipPlanes
; i
++) {
414 if (pSB
->Set
.clipplane
[i
] && pSB
->Changed
.clipplane
[i
]) {
417 clip
[0] = pSB
->clipplane
[i
][0];
418 clip
[1] = pSB
->clipplane
[i
][1];
419 clip
[2] = pSB
->clipplane
[i
][2];
420 clip
[3] = pSB
->clipplane
[i
][3];
421 IDirect3DDevice8Impl_SetClipPlane(iface
, i
, clip
);
426 for (i
=0; i
<HIGHEST_RENDER_STATE
; i
++) {
428 if (pSB
->Set
.renderstate
[i
] && pSB
->Changed
.renderstate
[i
])
429 IDirect3DDevice8Impl_SetRenderState(iface
, i
, pSB
->renderstate
[i
]);
434 for (j
= 0; j
< This
->TextureUnits
; j
++) {
435 for (i
= 0; i
< HIGHEST_TEXTURE_STATE
; i
++) {
436 if (pSB
->Set
.texture_state
[j
][i
] && pSB
->Changed
.texture_state
[j
][i
]) {
437 IDirect3DDevice8Impl_SetTextureStageState(iface
, j
, i
, pSB
->texture_state
[j
][i
]);
440 if (pSB
->Set
.textures
[j
] && pSB
->Changed
.textures
[j
]) {
441 IDirect3DDevice8Impl_SetTexture(iface
, j
, pSB
->textures
[j
]);
446 } else if (pSB
->blockType
== D3DSBT_PIXELSTATE
) {
448 for (i
=0; i
<NUM_SAVEDPIXELSTATES_R
; i
++) {
449 if (pSB
->Set
.renderstate
[SavedPixelStates_R
[i
]] && pSB
->Changed
.renderstate
[SavedPixelStates_R
[i
]])
450 IDirect3DDevice8Impl_SetRenderState(iface
, SavedPixelStates_R
[i
], pSB
->renderstate
[SavedPixelStates_R
[i
]]);
454 for (j
=0; j
<This
->TextureUnits
; i
++) {
455 for (i
=0; i
<NUM_SAVEDPIXELSTATES_T
; i
++) {
457 if (pSB
->Set
.texture_state
[j
][SavedPixelStates_T
[i
]] &&
458 pSB
->Changed
.texture_state
[j
][SavedPixelStates_T
[i
]])
459 IDirect3DDevice8Impl_SetTextureStageState(iface
, j
, SavedPixelStates_T
[i
], pSB
->texture_state
[j
][SavedPixelStates_T
[i
]]);
463 } else if (pSB
->blockType
== D3DSBT_VERTEXSTATE
) {
465 for (i
=0; i
<NUM_SAVEDVERTEXSTATES_R
; i
++) {
466 if (pSB
->Set
.renderstate
[SavedVertexStates_R
[i
]] && pSB
->Changed
.renderstate
[SavedVertexStates_R
[i
]])
467 IDirect3DDevice8Impl_SetRenderState(iface
, SavedVertexStates_R
[i
], pSB
->renderstate
[SavedVertexStates_R
[i
]]);
471 for (j
=0; j
<This
->TextureUnits
; i
++) {
472 for (i
=0; i
<NUM_SAVEDVERTEXSTATES_T
; i
++) {
474 if (pSB
->Set
.texture_state
[j
][SavedVertexStates_T
[i
]] &&
475 pSB
->Changed
.texture_state
[j
][SavedVertexStates_T
[i
]])
476 IDirect3DDevice8Impl_SetTextureStageState(iface
, j
, SavedVertexStates_T
[i
], pSB
->texture_state
[j
][SavedVertexStates_T
[i
]]);
482 FIXME("Unrecognized state block type %d\n", pSB
->blockType
);
484 memcpy(&This
->StateBlock
->Changed
, &pSB
->Changed
, sizeof(This
->StateBlock
->Changed
));
485 TRACE("(%p) : Applied state block %p ------------------^\n", This
, pSB
);
490 HRESULT WINAPI
IDirect3DDeviceImpl_CaptureStateBlock(IDirect3DDevice8Impl
* This
, IDirect3DStateBlockImpl
* updateBlock
) {
491 LPDIRECT3DDEVICE8 iface
= (LPDIRECT3DDEVICE8
) This
;
493 TRACE("(%p) : Updating state block %p ------------------v \n", This
, updateBlock
);
495 /* If not recorded, then update can just recapture */
496 if (updateBlock
->blockType
!= D3DSBT_RECORDED
) {
497 IDirect3DStateBlockImpl
* tmpBlock
;
498 IDirect3DDeviceImpl_CreateStateBlock(This
, updateBlock
->blockType
, &tmpBlock
);
499 memcpy(updateBlock
, tmpBlock
, sizeof(IDirect3DStateBlockImpl
));
500 IDirect3DDeviceImpl_DeleteStateBlock(This
, tmpBlock
);
502 /* FIXME: This will record states of new lights! May need to have and save set_lights
503 across this action */
508 /* Recorded => Only update 'changed' values */
509 if (updateBlock
->Set
.vertexShader
&& updateBlock
->VertexShader
!= This
->StateBlock
->VertexShader
) {
510 updateBlock
->VertexShader
= This
->StateBlock
->VertexShader
;
511 TRACE("Updating vertex shader to %ld\n", This
->StateBlock
->VertexShader
);
514 /* TODO: Vertex Shader Constants */
516 for (i
=0; i
<This
->maxLights
; i
++) {
517 if (updateBlock
->Set
.lightEnable
[i
] && This
->StateBlock
->lightEnable
[i
] != updateBlock
->lightEnable
[i
]) {
518 TRACE("Updating light enable for light %d to %d\n", i
, This
->StateBlock
->lightEnable
[i
]);
519 updateBlock
->lightEnable
[i
] = This
->StateBlock
->lightEnable
[i
];
522 if (updateBlock
->Set
.lights
[i
] && memcmp(&This
->StateBlock
->lights
[i
],
523 &updateBlock
->lights
[i
],
524 sizeof(D3DLIGHT8
)) != 0) {
525 TRACE("Updating lights for light %d\n", i
);
526 memcpy(&updateBlock
->lights
[i
], &This
->StateBlock
->lights
[i
], sizeof(D3DLIGHT8
));
530 if (updateBlock
->Set
.pixelShader
&& updateBlock
->PixelShader
!= This
->StateBlock
->PixelShader
) {
531 TRACE("Updating pixel shader to %ld\n", This
->StateBlock
->PixelShader
);
532 updateBlock
->lights
[i
] = This
->StateBlock
->lights
[i
];
533 IDirect3DDevice8Impl_SetVertexShader(iface
, updateBlock
->PixelShader
);
536 /* TODO: Pixel Shader Constants */
538 /* Others + Render & Texture */
539 for (i
=0; i
<HIGHEST_TRANSFORMSTATE
; i
++) {
540 if (updateBlock
->Set
.transform
[i
] && memcmp(&This
->StateBlock
->transforms
[i
],
541 &updateBlock
->transforms
[i
],
542 sizeof(D3DMATRIX
)) != 0) {
543 TRACE("Updating transform %d\n", i
);
544 memcpy(&updateBlock
->transforms
[i
], &This
->StateBlock
->transforms
[i
], sizeof(D3DMATRIX
));
548 if (updateBlock
->Set
.Indices
&& ((updateBlock
->pIndexData
!= This
->StateBlock
->pIndexData
)
549 || (updateBlock
->baseVertexIndex
!= This
->StateBlock
->baseVertexIndex
))) {
550 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
551 This
->StateBlock
->pIndexData
, This
->StateBlock
->baseVertexIndex
);
552 updateBlock
->pIndexData
= This
->StateBlock
->pIndexData
;
553 updateBlock
->baseVertexIndex
= This
->StateBlock
->baseVertexIndex
;
556 if (updateBlock
->Set
.material
&& memcmp(&This
->StateBlock
->material
,
557 &updateBlock
->material
,
558 sizeof(D3DMATERIAL8
)) != 0) {
559 TRACE("Updating material\n");
560 memcpy(&updateBlock
->material
, &This
->StateBlock
->material
, sizeof(D3DMATERIAL8
));
563 if (updateBlock
->Set
.viewport
&& memcmp(&This
->StateBlock
->viewport
,
564 &updateBlock
->viewport
,
565 sizeof(D3DVIEWPORT8
)) != 0) {
566 TRACE("Updating viewport\n");
567 memcpy(&updateBlock
->viewport
, &This
->StateBlock
->viewport
, sizeof(D3DVIEWPORT8
));
570 for (i
=0; i
<MAX_STREAMS
; i
++) {
571 if (updateBlock
->Set
.stream_source
[i
] &&
572 ((updateBlock
->stream_stride
[i
] != This
->StateBlock
->stream_stride
[i
]) ||
573 (updateBlock
->stream_source
[i
] != This
->StateBlock
->stream_source
[i
]))) {
574 TRACE("Updating stream source %d to %p, stride to %d\n", i
, This
->StateBlock
->stream_source
[i
],
575 This
->StateBlock
->stream_stride
[i
]);
576 updateBlock
->stream_stride
[i
] = This
->StateBlock
->stream_stride
[i
];
577 updateBlock
->stream_source
[i
] = This
->StateBlock
->stream_source
[i
];
581 for (i
=0; i
<This
->clipPlanes
; i
++) {
582 if (updateBlock
->Set
.clipplane
[i
] && memcmp(&This
->StateBlock
->clipplane
[i
],
583 &updateBlock
->clipplane
[i
],
584 sizeof(updateBlock
->clipplane
)) != 0) {
586 TRACE("Updating clipplane %d\n", i
);
587 memcpy(&updateBlock
->clipplane
[i
], &This
->StateBlock
->clipplane
[i
],
588 sizeof(updateBlock
->clipplane
));
593 for (i
=0; i
<HIGHEST_RENDER_STATE
; i
++) {
595 if (updateBlock
->Set
.renderstate
[i
] && (updateBlock
->renderstate
[i
] !=
596 This
->StateBlock
->renderstate
[i
])) {
597 TRACE("Updating renderstate %d to %ld\n", i
, This
->StateBlock
->renderstate
[i
]);
598 updateBlock
->renderstate
[i
] = This
->StateBlock
->renderstate
[i
];
603 for (j
=0; j
<This
->TextureUnits
; j
++) {
604 for (i
=0; i
<HIGHEST_TEXTURE_STATE
; i
++) {
606 if (updateBlock
->Set
.texture_state
[j
][i
] && (updateBlock
->texture_state
[j
][i
] !=
607 This
->StateBlock
->texture_state
[j
][i
])) {
608 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j
,i
, This
->StateBlock
->texture_state
[j
][i
],
609 updateBlock
->texture_state
[j
][i
]);
610 updateBlock
->texture_state
[j
][i
] = This
->StateBlock
->texture_state
[j
][i
];
613 if (updateBlock
->Set
.textures
[j
] && (updateBlock
->textures
[j
] != This
->StateBlock
->textures
[j
])) {
614 TRACE("Updating texture %d to %p (was %p)\n", j
, This
->StateBlock
->textures
[j
], updateBlock
->textures
[j
]);
615 updateBlock
->textures
[j
] = This
->StateBlock
->textures
[j
];
622 TRACE("(%p) : Updated state block %p ------------------^\n", This
, updateBlock
);
627 DWORD SavedPixelStates_R
[NUM_SAVEDPIXELSTATES_R
] = {
628 D3DRS_ALPHABLENDENABLE
,
631 D3DRS_ALPHATESTENABLE
,
633 D3DRS_COLORWRITEENABLE
,
636 D3DRS_EDGEANTIALIAS
,
645 D3DRS_STENCILENABLE
,
651 D3DRS_STENCILWRITEMASK
,
653 D3DRS_TEXTUREFACTOR
,
668 DWORD SavedPixelStates_T
[NUM_SAVEDPIXELSTATES_T
] = {
677 D3DTSS_BUMPENVLOFFSET
,
678 D3DTSS_BUMPENVLSCALE
,
679 D3DTSS_BUMPENVMAT00
,
680 D3DTSS_BUMPENVMAT01
,
681 D3DTSS_BUMPENVMAT10
,
682 D3DTSS_BUMPENVMAT11
,
688 D3DTSS_MAXANISOTROPY
,
692 D3DTSS_MIPMAPLODBIAS
,
694 D3DTSS_TEXCOORDINDEX
,
695 D3DTSS_TEXTURETRANSFORMFLAGS
698 DWORD SavedVertexStates_R
[NUM_SAVEDVERTEXSTATES_R
] = {
700 D3DRS_AMBIENTMATERIALSOURCE
,
702 D3DRS_CLIPPLANEENABLE
,
704 D3DRS_DIFFUSEMATERIALSOURCE
,
705 D3DRS_EMISSIVEMATERIALSOURCE
,
710 D3DRS_FOGVERTEXMODE
,
711 D3DRS_INDEXEDVERTEXBLENDENABLE
,
714 D3DRS_MULTISAMPLEANTIALIAS
,
715 D3DRS_MULTISAMPLEMASK
,
716 D3DRS_NORMALIZENORMALS
,
717 D3DRS_PATCHEDGESTYLE
,
718 D3DRS_PATCHSEGMENTS
,
722 D3DRS_POINTSCALEENABLE
,
724 D3DRS_POINTSIZE_MAX
,
725 D3DRS_POINTSIZE_MIN
,
726 D3DRS_POINTSPRITEENABLE
,
727 D3DRS_RANGEFOGENABLE
,
728 D3DRS_SOFTWAREVERTEXPROCESSING
,
729 D3DRS_SPECULARMATERIALSOURCE
,
734 DWORD SavedVertexStates_T
[NUM_SAVEDVERTEXSTATES_T
] = {
735 D3DTSS_TEXCOORDINDEX
,
736 D3DTSS_TEXTURETRANSFORMFLAGS