mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
wined3d: Replace memset/memcpy routines on stateblock (fixes dynamic shader constants regression).
This commit is contained in:
parent
75dce501ef
commit
75950b5bf8
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
/*****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user