wined3d: Restructure Stateblock::apply a bit.
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 8a91781..a66a74f 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -604,6 +604,24 @@
return WINED3D_OK;
}
+static inline void apply_lights(IWineD3DDevice *pDevice, IWineD3DStateBlockImpl *This) {
+ UINT i;
+ for(i = 0; i < LIGHTMAP_SIZE; i++) {
+ struct list *e;
+
+ LIST_FOR_EACH(e, &This->lightMap[i]) {
+ PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
+
+ if(light->changed) {
+ IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms);
+ }
+ if(light->enabledChanged) {
+ IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1);
+ }
+ }
+ }
+}
+
static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface){
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
IWineD3DDevice* pDevice = (IWineD3DDevice*)This->wineD3DDevice;
@@ -611,88 +629,73 @@
/*Copy thing over to updateBlock is isRecording otherwise StateBlock,
should really perform a delta so that only the changes get updated*/
-
UINT i;
UINT j;
TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);
TRACE("Blocktype: %d\n", This->blockType);
- /* FIXME: Only apply applicable states not all states */
- if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */This->blockType == WINED3DSBT_INIT || This->blockType == WINED3DSBT_ALL || This->blockType == WINED3DSBT_VERTEXSTATE) {
-
- for(i = 0; i < LIGHTMAP_SIZE; i++) {
- struct list *e;
-
- LIST_FOR_EACH(e, &This->lightMap[i]) {
- PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
-
- if(light->changed) {
- IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms);
- }
- if(light->enabledChanged) {
- IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1);
- }
- }
- }
-
- /* Vertex Shader */
+ if(This->blockType == WINED3DSBT_RECORDED) {
if (This->changed.vertexShader) {
IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
}
-
/* Vertex Shader Constants */
for (i = 0; i < This->num_contained_vs_consts_f; i++) {
IWineD3DDevice_SetVertexShaderConstantF(pDevice, This->contained_vs_consts_f[i],
This->vertexShaderConstantF + This->contained_vs_consts_f[i] * 4, 1);
}
-
for (i = 0; i < This->num_contained_vs_consts_i; i++) {
IWineD3DDevice_SetVertexShaderConstantI(pDevice, This->contained_vs_consts_i[i],
This->vertexShaderConstantI + This->contained_vs_consts_i[i] * 4, 1);
}
-
for (i = 0; i < This->num_contained_vs_consts_b; i++) {
IWineD3DDevice_SetVertexShaderConstantB(pDevice, This->contained_vs_consts_b[i],
This->vertexShaderConstantB + This->contained_vs_consts_b[i], 1);
}
- }
- if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */ This->blockType == WINED3DSBT_ALL || This->blockType == WINED3DSBT_PIXELSTATE) {
+ apply_lights(pDevice, This);
- /* Pixel Shader */
if (This->changed.pixelShader) {
IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
}
-
/* Pixel Shader Constants */
for (i = 0; i < This->num_contained_ps_consts_f; i++) {
IWineD3DDevice_SetPixelShaderConstantF(pDevice, This->contained_ps_consts_f[i],
This->pixelShaderConstantF + This->contained_ps_consts_f[i] * 4, 1);
}
-
for (i = 0; i < This->num_contained_ps_consts_i; i++) {
IWineD3DDevice_SetPixelShaderConstantI(pDevice, This->contained_ps_consts_i[i],
This->pixelShaderConstantI + This->contained_ps_consts_i[i] * 4, 1);
}
-
for (i = 0; i < This->num_contained_ps_consts_b; i++) {
IWineD3DDevice_SetPixelShaderConstantB(pDevice, This->contained_ps_consts_b[i],
This->pixelShaderConstantB + This->contained_ps_consts_b[i], 1);
}
- }
- if (This->changed.fvf) {
- IWineD3DDevice_SetFVF(pDevice, This->fvf);
- }
+ /* Render */
+ for (i = 0; i <= This->num_contained_render_states; i++) {
+ IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i],
+ This->renderState[This->contained_render_states[i]]);
+ }
+ /* Texture states */
+ for (i = 0; i < This->num_contained_tss_states; i++) {
+ DWORD stage = This->contained_tss_states[i].stage;
+ DWORD state = This->contained_tss_states[i].state;
+ ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[stage][state] = This->textureState[stage][state];
+ ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[stage][state] = TRUE;
+ /* TODO: Record a display list to apply all gl states. For now apply by brute force */
+ IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(stage, state));
+ }
+ /* Sampler states */
+ for (i = 0; i < This->num_contained_sampler_states; i++) {
+ DWORD stage = This->contained_sampler_states[i].stage;
+ DWORD state = This->contained_sampler_states[i].state;
+ ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[stage][state] = This->samplerState[stage][state];
+ ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[stage][state] = TRUE;
+ IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_SAMPLER(stage));
+ }
- if (This->changed.vertexDecl) {
- IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
- }
-
- /* Others + Render & Texture */
- if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */ This->blockType == WINED3DSBT_ALL || This->blockType == WINED3DSBT_INIT) {
for (i = 0; i < This->num_contained_transform_states; i++) {
IWineD3DDevice_SetTransform(pDevice, This->contained_transform_states[i],
&This->transforms[This->contained_transform_states[i]]);
@@ -703,14 +706,25 @@
IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
}
- if (This->changed.material )
+ if (This->changed.fvf) {
+ IWineD3DDevice_SetFVF(pDevice, This->fvf);
+ }
+
+ if (This->changed.vertexDecl) {
+ IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
+ }
+
+ if (This->changed.material ) {
IWineD3DDevice_SetMaterial(pDevice, &This->material);
+ }
- if (This->changed.viewport)
+ if (This->changed.viewport) {
IWineD3DDevice_SetViewport(pDevice, &This->viewport);
+ }
- if (This->changed.scissorRect)
+ if (This->changed.scissorRect) {
IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect);
+ }
/* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
for (i=0; i<MAX_STREAMS; i++) {
@@ -720,6 +734,15 @@
if (This->changed.streamFreq[i])
IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
}
+ for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
+ if (This->changed.textures[j]) {
+ if (j < MAX_FRAGMENT_SAMPLERS) {
+ IWineD3DDevice_SetTexture(pDevice, j, This->textures[j]);
+ } else {
+ IWineD3DDevice_SetTexture(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS, This->textures[j]);
+ }
+ }
+ }
for (i = 0; i < GL_LIMITS(clipplanes); i++) {
if (This->changed.clipplane[i]) {
@@ -733,47 +756,160 @@
}
}
- /* Samplers */
- /* TODO: move over to memcpy */
- for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
- if (This->changed.textures[j]) {
- if (j < MAX_FRAGMENT_SAMPLERS) {
- IWineD3DDevice_SetTexture(pDevice, j, This->textures[j]);
- } else {
- IWineD3DDevice_SetTexture(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS, This->textures[j]);
- }
+ } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
+ IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
+ for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
+ IWineD3DDevice_SetVertexShaderConstantF(pDevice, i,
+ This->vertexShaderConstantF + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_I; i++) {
+ IWineD3DDevice_SetVertexShaderConstantI(pDevice, i,
+ This->vertexShaderConstantI + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_B; i++) {
+ IWineD3DDevice_SetVertexShaderConstantB(pDevice, i,
+ This->vertexShaderConstantB + i, 1);
+ }
+
+ apply_lights(pDevice, This);
+
+ for(i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
+ IWineD3DDevice_SetRenderState(pDevice, SavedVertexStates_R[i], This->renderState[SavedVertexStates_R[i]]);
+ }
+ for(j = 0; j < MAX_TEXTURES; j++) {
+ for(i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
+ IWineD3DDevice_SetTextureStageState(pDevice, j, SavedVertexStates_T[i],
+ This->textureState[j][SavedVertexStates_T[i]]);
}
}
- } else if (This->blockType == WINED3DSBT_PIXELSTATE) {
+ for(j = 0; j < MAX_FRAGMENT_SAMPLERS; j++) {
+ for(i = 0; i < NUM_SAVEDVERTEXSTATES_S; i++) {
+ IWineD3DDevice_SetSamplerState(pDevice, j, SavedVertexStates_S[i],
+ This->samplerState[j][SavedVertexStates_S[i]]);
+ }
+ }
+ for(j = MAX_FRAGMENT_SAMPLERS; j < MAX_COMBINED_SAMPLERS; j++) {
+ for(i = 0; i < NUM_SAVEDVERTEXSTATES_S; i++) {
+ IWineD3DDevice_SetSamplerState(pDevice,
+ WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS,
+ SavedVertexStates_S[i],
+ This->samplerState[j][SavedVertexStates_S[i]]);
+ }
+ }
+ } else if(This->blockType == WINED3DSBT_PIXELSTATE) {
+ IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
+ for (i = 0; i < GL_LIMITS(pshader_constantsF); i++) {
+ IWineD3DDevice_SetPixelShaderConstantF(pDevice, i,
+ This->pixelShaderConstantF + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_I; i++) {
+ IWineD3DDevice_SetPixelShaderConstantI(pDevice, i,
+ This->pixelShaderConstantI + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_B; i++) {
+ IWineD3DDevice_SetPixelShaderConstantB(pDevice, i,
+ This->pixelShaderConstantB + i, 1);
+ }
- } else if (This->blockType == WINED3DSBT_VERTEXSTATE) {
+ for(i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
+ IWineD3DDevice_SetRenderState(pDevice, SavedPixelStates_R[i], This->renderState[SavedPixelStates_R[i]]);
+ }
+ for(j = 0; j < MAX_TEXTURES; j++) {
+ for(i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
+ IWineD3DDevice_SetTextureStageState(pDevice, j, SavedPixelStates_T[i],
+ This->textureState[j][SavedPixelStates_T[i]]);
+ }
+ }
- } else {
- FIXME("Unrecognized state block type %d\n", This->blockType);
- }
+ for(j = 0; j < MAX_FRAGMENT_SAMPLERS; j++) {
+ for(i = 0; i < NUM_SAVEDPIXELSTATES_S; i++) {
+ IWineD3DDevice_SetSamplerState(pDevice, j, SavedPixelStates_S[i],
+ This->samplerState[j][SavedPixelStates_S[i]]);
+ }
+ }
+ for(j = MAX_FRAGMENT_SAMPLERS; j < MAX_COMBINED_SAMPLERS; j++) {
+ for(i = 0; i < NUM_SAVEDPIXELSTATES_S; i++) {
+ IWineD3DDevice_SetSamplerState(pDevice,
+ WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS,
+ SavedPixelStates_S[i],
+ This->samplerState[j][SavedPixelStates_S[i]]);
+ }
+ }
+ } else if(This->blockType == WINED3DSBT_ALL) {
+ IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
+ for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
+ IWineD3DDevice_SetVertexShaderConstantF(pDevice, i,
+ This->vertexShaderConstantF + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_I; i++) {
+ IWineD3DDevice_SetVertexShaderConstantI(pDevice, i,
+ This->vertexShaderConstantI + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_B; i++) {
+ IWineD3DDevice_SetVertexShaderConstantB(pDevice, i,
+ This->vertexShaderConstantB + i, 1);
+ }
- /* Render */
- for (i = 0; i <= This->num_contained_render_states; i++) {
- IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i],
- This->renderState[This->contained_render_states[i]]);
- }
- /* Texture states */
- for (i = 0; i < This->num_contained_tss_states; i++) {
- DWORD stage = This->contained_tss_states[i].stage;
- DWORD state = This->contained_tss_states[i].state;
- ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[stage][state] = This->textureState[stage][state];
- ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[stage][state] = TRUE;
- /* TODO: Record a display list to apply all gl states. For now apply by brute force */
- IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(stage, state));
- }
- /* Sampler states */
- for (i = 0; i < This->num_contained_sampler_states; i++) {
- DWORD stage = This->contained_sampler_states[i].stage;
- DWORD state = This->contained_sampler_states[i].state;
- ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[stage][state] = This->samplerState[stage][state];
- ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[stage][state] = TRUE;
- IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_SAMPLER(stage));
+ IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
+ for (i = 0; i < GL_LIMITS(pshader_constantsF); i++) {
+ IWineD3DDevice_SetPixelShaderConstantF(pDevice, i,
+ This->pixelShaderConstantF + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_I; i++) {
+ IWineD3DDevice_SetPixelShaderConstantI(pDevice, i,
+ This->pixelShaderConstantI + i * 4, 1);
+ }
+ for (i = 0; i < MAX_CONST_B; i++) {
+ IWineD3DDevice_SetPixelShaderConstantB(pDevice, i,
+ This->pixelShaderConstantB + i, 1);
+ }
+
+ apply_lights(pDevice, This);
+
+ for(i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
+ IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
+ }
+ for(j = 0; j < MAX_TEXTURES; j++) {
+ for(i = 1; i <= WINED3D_HIGHEST_TEXTURE_STATE; i++) {
+ IWineD3DDevice_SetTextureStageState(pDevice, j, i, This->textureState[j][i]);
+ }
+ }
+
+ /* Skip unused values between TEXTURE8 and WORLD0 ? */
+ for(i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
+ IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]);
+ }
+ IWineD3DDevice_SetIndices(pDevice, This->pIndexData);
+ IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
+ IWineD3DDevice_SetFVF(pDevice, This->fvf);
+ IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
+ IWineD3DDevice_SetMaterial(pDevice, &This->material);
+ IWineD3DDevice_SetViewport(pDevice, &This->viewport);
+ IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect);
+
+ /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
+ for (i=0; i<MAX_STREAMS; i++) {
+ IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
+ IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
+ }
+ for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
+ UINT sampler = j < MAX_FRAGMENT_SAMPLERS ? j : WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS;
+
+ IWineD3DDevice_SetTexture(pDevice, sampler, This->textures[j]);
+ for(i = 1; i < WINED3D_HIGHEST_SAMPLER_STATE; i++) {
+ IWineD3DDevice_SetSamplerState(pDevice, sampler, i, This->samplerState[j][i]);
+ }
+ }
+ for (i = 0; i < GL_LIMITS(clipplanes); i++) {
+ float clip[4];
+
+ clip[0] = This->clipplane[i][0];
+ clip[1] = This->clipplane[i][1];
+ clip[2] = This->clipplane[i][2];
+ clip[3] = This->clipplane[i][3];
+ IWineD3DDevice_SetClipPlane(pDevice, i, clip);
+ }
}
((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1;