wined3d: Replace memset/memcpy routines on stateblock (fixes dynamic shader constants regression).

This commit is contained in:
Jason Green 2006-07-23 15:08:27 -04:00 committed by Alexandre Julliard
parent 75dce501ef
commit 75950b5bf8
4 changed files with 196 additions and 20 deletions

View File

@ -799,11 +799,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
return temp_result;
/* Otherwise, might as well set the whole state block to the appropriate values */
if ( This->stateBlock != NULL) {
memcpy(object, This->stateBlock, sizeof(IWineD3DStateBlockImpl));
} else {
memset(object->streamFreq, 1, sizeof(object->streamFreq));
}
if (This->stateBlock != NULL)
stateblock_copy((IWineD3DStateBlock*) object, (IWineD3DStateBlock*) This->stateBlock);
else
memset(object->streamFreq, 1, sizeof(object->streamFreq));
/* Reset the ref and type after kludging it */
object->wineD3DDevice = This;
@ -815,11 +814,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
if (Type == WINED3DSBT_ALL) {
TRACE("ALL => Pretend everything has changed\n");
memset(&object->changed, TRUE, sizeof(This->stateBlock->changed));
stateblock_savedstates_set((IWineD3DStateBlock*) object, &object->changed, TRUE);
} else if (Type == WINED3DSBT_PIXELSTATE) {
TRACE("PIXELSTATE => Pretend all pixel shates have changed\n");
memset(&object->changed, FALSE, sizeof(This->stateBlock->changed));
stateblock_savedstates_set((IWineD3DStateBlock*) object, &object->changed, FALSE);
object->changed.pixelShader = TRUE;
@ -849,7 +849,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
} else if (Type == WINED3DSBT_VERTEXSTATE) {
TRACE("VERTEXSTATE => Pretend all vertex shates have changed\n");
memset(&object->changed, FALSE, sizeof(This->stateBlock->changed));
stateblock_savedstates_set((IWineD3DStateBlock*) object, &object->changed, FALSE);
object->changed.vertexShader = TRUE;

View File

@ -208,10 +208,6 @@ static void select_shader_mode(
int* ps_selected,
int* vs_selected) {
/* Default # of constants to 0 */
gl_info->max_vshader_constantsF = 0;
gl_info->max_pshader_constantsF = 0;
/* Give priority to user disable/emulation request.
* Then respect REF device for software.
* Then check capabilities for hardware, and fallback to software */
@ -222,12 +218,8 @@ static void select_shader_mode(
*vs_selected = SHADER_SW;
} else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested) {
*vs_selected = SHADER_GLSL;
/* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
} else if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
*vs_selected = SHADER_ARB;
/* ARB shaders seem to have an implicit PARAM when fog is used, so we need to subtract 1 from the total available */
gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 1;
} else {
*vs_selected = SHADER_SW;
}
@ -239,16 +231,50 @@ static void select_shader_mode(
*ps_selected = SHADER_NONE;
} else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested) {
*ps_selected = SHADER_GLSL;
/* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
} else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
*ps_selected = SHADER_ARB;
gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF;
} else {
*ps_selected = SHADER_NONE;
}
}
/** Select the number of report maximum shader constants based on the selected shader modes */
void select_shader_max_constants(WineD3D_GL_Info *gl_info) {
switch (wined3d_settings.vs_selected_mode) {
case SHADER_GLSL:
/* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
break;
case SHADER_ARB:
/* ARB shaders seem to have an implicit PARAM when fog is used, so we need to subtract 1 from the total available */
gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 1;
break;
case SHADER_SW:
gl_info->max_vshader_constantsF = 96; /* TODO: Fixup software shaders */
break;
default:
gl_info->max_vshader_constantsF = 0;
break;
}
switch (wined3d_settings.ps_selected_mode) {
case SHADER_GLSL:
/* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
break;
case SHADER_ARB:
gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF;
break;
case SHADER_SW:
gl_info->max_pshader_constantsF = 96; /* TODO: Fixup software shaders */
break;
default:
gl_info->max_pshader_constantsF = 0;
break;
}
}
/**********************************************************
* IWineD3D parts follows
**********************************************************/
@ -1609,6 +1635,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
}
select_shader_mode(&This->gl_info, DeviceType,
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
select_shader_max_constants(&This->gl_info);
/* ------------------------------------------------
The following fields apply to both d3d8 and d3d9
@ -1995,6 +2022,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
LEAVE_GL();
select_shader_mode(&This->gl_info, DeviceType,
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
select_shader_max_constants(&This->gl_info);
temp_result = allocate_shader_constants(object->updateStateBlock);
if (WINED3D_OK != temp_result)

View File

@ -58,6 +58,140 @@ HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object) {
return WINED3D_OK;
}
/** Copy all members of one stateblock to another */
void stateblock_savedstates_copy(
IWineD3DStateBlock* iface,
SAVEDSTATES* dest,
SAVEDSTATES* source) {
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
unsigned bsize = sizeof(BOOL);
/* Single values */
dest->indices = source->indices;
dest->material = source->material;
dest->fvf = source->fvf;
dest->viewport = source->viewport;
dest->vertexDecl = source->vertexDecl;
dest->pixelShader = source->pixelShader;
dest->vertexShader = source->vertexShader;
/* Fixed size arrays */
memcpy(dest->streamSource, source->streamSource, bsize * MAX_STREAMS);
memcpy(dest->streamFreq, source->streamFreq, bsize * MAX_STREAMS);
memcpy(dest->textures, source->textures, bsize * MAX_SAMPLERS);
memcpy(dest->transform, source->transform, bsize * (HIGHEST_TRANSFORMSTATE + 1));
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_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1));
memcpy(dest->clipplane, source->clipplane, bsize * MAX_CLIPPLANES);
memcpy(dest->pixelShaderConstantsB, source->pixelShaderConstantsB, bsize * MAX_CONST_B);
memcpy(dest->pixelShaderConstantsI, source->pixelShaderConstantsI, bsize * MAX_CONST_I);
memcpy(dest->vertexShaderConstantsB, source->vertexShaderConstantsB, bsize * MAX_CONST_B);
memcpy(dest->vertexShaderConstantsI, source->vertexShaderConstantsI, bsize * MAX_CONST_I);
/* Dynamically sized arrays */
memcpy(dest->pixelShaderConstantsF, source->pixelShaderConstantsF, bsize * GL_LIMITS(pshader_constantsF));
memcpy(dest->vertexShaderConstantsF, source->vertexShaderConstantsF, bsize * GL_LIMITS(vshader_constantsF));
}
/** Set all members of a stateblock savedstate to the given value */
void stateblock_savedstates_set(
IWineD3DStateBlock* iface,
SAVEDSTATES* states,
BOOL value) {
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
unsigned bsize = sizeof(BOOL);
/* Single values */
states->indices = value;
states->material = value;
states->fvf = value;
states->viewport = value;
states->vertexDecl = value;
states->pixelShader = value;
states->vertexShader = value;
/* Fixed size arrays */
memset(states->streamSource, value, bsize * MAX_STREAMS);
memset(states->streamFreq, value, bsize * MAX_STREAMS);
memset(states->textures, value, bsize * MAX_SAMPLERS);
memset(states->transform, value, bsize * (HIGHEST_TRANSFORMSTATE + 1));
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_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1));
memset(states->clipplane, value, bsize * MAX_CLIPPLANES);
memset(states->pixelShaderConstantsB, value, bsize * MAX_CONST_B);
memset(states->pixelShaderConstantsI, value, bsize * MAX_CONST_I);
memset(states->vertexShaderConstantsB, value, bsize * MAX_CONST_B);
memset(states->vertexShaderConstantsI, value, bsize * MAX_CONST_I);
/* Dynamically sized arrays */
memset(states->pixelShaderConstantsF, value, bsize * GL_LIMITS(pshader_constantsF));
memset(states->vertexShaderConstantsF, value, bsize * GL_LIMITS(vshader_constantsF));
}
void stateblock_copy(
IWineD3DStateBlock* destination,
IWineD3DStateBlock* source) {
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)source;
IWineD3DStateBlockImpl *Dest = (IWineD3DStateBlockImpl *)destination;
/* IUnknown fields */
Dest->lpVtbl = This->lpVtbl;
Dest->ref = This->ref;
/* IWineD3DStateBlock information */
Dest->parent = This->parent;
Dest->wineD3DDevice = This->wineD3DDevice;
Dest->blockType = This->blockType;
/* Saved states */
stateblock_savedstates_copy(source, &Dest->set, &This->set);
stateblock_savedstates_copy(source, &Dest->changed, &This->changed);
/* Single items */
Dest->fvf = This->fvf;
Dest->vertexDecl = This->vertexDecl;
Dest->vertexShader = This->vertexShader;
Dest->streamIsUP = This->streamIsUP;
Dest->pIndexData = This->pIndexData;
Dest->baseVertexIndex = This->baseVertexIndex;
Dest->lights = This->lights;
Dest->clip_status = This->clip_status;
Dest->viewport = This->viewport;
Dest->material = This->material;
Dest->pixelShader = This->pixelShader;
Dest->vertex_blend = This->vertex_blend;
Dest->tween_factor = This->tween_factor;
Dest->shaderPrgId = This->shaderPrgId;
/* Fixed size arrays */
memcpy(Dest->vertexShaderConstantB, This->vertexShaderConstantB, sizeof(BOOL) * MAX_CONST_B);
memcpy(Dest->vertexShaderConstantI, This->vertexShaderConstantI, sizeof(INT) * MAX_CONST_I * 4);
memcpy(Dest->pixelShaderConstantB, This->pixelShaderConstantB, sizeof(BOOL) * MAX_CONST_B);
memcpy(Dest->pixelShaderConstantI, This->pixelShaderConstantI, sizeof(INT) * MAX_CONST_I * 4);
memcpy(Dest->streamStride, This->streamStride, sizeof(UINT) * MAX_STREAMS);
memcpy(Dest->streamOffset, This->streamOffset, sizeof(UINT) * MAX_STREAMS);
memcpy(Dest->streamSource, This->streamSource, sizeof(IWineD3DVertexBuffer*) * MAX_STREAMS);
memcpy(Dest->streamFreq, This->streamFreq, sizeof(UINT) * MAX_STREAMS);
memcpy(Dest->streamFlags, This->streamFlags, sizeof(UINT) * MAX_STREAMS);
memcpy(Dest->transforms, This->transforms, sizeof(D3DMATRIX) * (HIGHEST_TRANSFORMSTATE + 1));
memcpy(Dest->clipplane, This->clipplane, sizeof(double) * MAX_CLIPPLANES * 4);
memcpy(Dest->renderState, This->renderState, sizeof(DWORD) * (WINEHIGHEST_RENDER_STATE + 1));
memcpy(Dest->textures, This->textures, sizeof(IWineD3DBaseTexture*) * MAX_SAMPLERS);
memcpy(Dest->textureDimensions, This->textureDimensions, sizeof(int) * MAX_SAMPLERS);
memcpy(Dest->textureState, This->textureState, sizeof(DWORD) * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1));
memcpy(Dest->samplerState, This->samplerState, sizeof(DWORD) * MAX_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1));
/* Dynamically sized arrays */
memcpy(Dest->vertexShaderConstantF, This->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
memcpy(Dest->pixelShaderConstantF, This->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
}
/**********************************************************
* IWineD3DStateBlockImpl IUnknown parts follows
**********************************************************/
@ -654,7 +788,7 @@ should really perform a delta so that only the changes get updated*/
} else {
FIXME("Unrecognized state block type %d\n", This->blockType);
}
memcpy(&((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed, &This->changed, sizeof(((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed));
stateblock_savedstates_copy(iface, &((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed, &This->changed);
TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice);
return WINED3D_OK;

View File

@ -1113,6 +1113,20 @@ struct IWineD3DStateBlockImpl
GLhandleARB shaderPrgId;
};
extern void stateblock_savedstates_set(
IWineD3DStateBlock* iface,
SAVEDSTATES* states,
BOOL value);
extern void stateblock_savedstates_copy(
IWineD3DStateBlock* iface,
SAVEDSTATES* dest,
SAVEDSTATES* source);
extern void stateblock_copy(
IWineD3DStateBlock* destination,
IWineD3DStateBlock* source);
extern const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl;
/*****************************************************************************