diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 1ce2287a871..8c98962e7b5 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2669,7 +2669,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTransform(IWineD3DDevice *iface, W /* Handle recording of state blocks */ if (This->isRecordingState) { TRACE("Recording... not performing anything\n"); - This->updateStateBlock->changed.transform[d3dts] = TRUE; + This->updateStateBlock->changed.transform[d3dts >> 5] |= 1 << (d3dts & 0x1f); This->updateStateBlock->transforms[d3dts] = *lpmatrix; return WINED3D_OK; } @@ -4752,10 +4752,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IW object->num_contained_render_states++; } } - for(i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) { - if(object->changed.transform[i]) { - object->contained_transform_states[object->num_contained_transform_states] = i; - object->num_contained_transform_states++; + + for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i) + { + DWORD map = object->changed.transform[i]; + for (j = 0; map; map >>= 1, ++j) + { + if (!(map & 1)) continue; + + object->contained_transform_states[object->num_contained_transform_states++] = (i << 5) | j; } } for(i = 0; i < GL_LIMITS(vshader_constantsF); i++) { diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 1ffdabe1933..d5206c7349f 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -89,7 +89,7 @@ static void stateblock_savedstates_copy(IWineD3DStateBlock* iface, SAVEDSTATES * dest->streamSource = source->streamSource; dest->streamFreq = source->streamFreq; dest->textures = source->textures; - memcpy(dest->transform, source->transform, bsize * (HIGHEST_TRANSFORMSTATE + 1)); + memcpy(dest->transform, source->transform, sizeof(source->transform)); memcpy(dest->renderState, source->renderState, bsize * (WINEHIGHEST_RENDER_STATE + 1)); memcpy(dest->textureState, source->textureState, bsize * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)); memcpy(dest->samplerState, source->samplerState, bsize * MAX_COMBINED_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1)); @@ -104,6 +104,13 @@ static void stateblock_savedstates_copy(IWineD3DStateBlock* iface, SAVEDSTATES * memcpy(dest->vertexShaderConstantsF, source->vertexShaderConstantsF, bsize * GL_LIMITS(vshader_constantsF)); } +static inline void stateblock_set_bits(DWORD *map, UINT map_size) +{ + DWORD mask = (1 << (map_size & 0x1f)) - 1; + memset(map, 0xff, (map_size >> 5) * sizeof(*map)); + if (mask) map[map_size >> 5] = mask; +} + /** Set all members of a stateblock savedstate to the given value */ void stateblock_savedstates_set( IWineD3DStateBlock* iface, @@ -126,7 +133,8 @@ void stateblock_savedstates_set( states->streamSource = value ? 0xffff : 0; states->streamFreq = value ? 0xffff : 0; states->textures = value ? 0xfffff : 0; - memset(states->transform, value, bsize * (HIGHEST_TRANSFORMSTATE + 1)); + if (value) stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1); + else memset(states->transform, 0, sizeof(states->transform)); memset(states->renderState, value, bsize * (WINEHIGHEST_RENDER_STATE + 1)); memset(states->textureState, value, bsize * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)); memset(states->samplerState, value, bsize * MAX_COMBINED_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1)); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 90f8ee147a5..b9740776146 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1758,10 +1758,10 @@ extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl; /* Note: Very long winded but gl Lists are not flexible enough */ /* to resolve everything we need, so doing it manually for now */ typedef struct SAVEDSTATES { + DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; WORD streamSource; /* MAX_STREAMS, 16 */ WORD streamFreq; /* MAX_STREAMS, 16 */ DWORD textures; /* MAX_COMBINED_SAMPLERS, 20 */ - BOOL transform[HIGHEST_TRANSFORMSTATE + 1]; BOOL renderState[WINEHIGHEST_RENDER_STATE + 1]; BOOL textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; BOOL samplerState[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];