Commit 1ef4f075 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Introduce a separate structure for stateblock states.

We'd like to not pass an entire stateblock to things like state handlers and the shader backend, because those then use the stateblock to get to the device and through there to all the rest of wined3d. This would also be required for serialization of wined3d draw and state change commands into a single GL context. Resource updates would be explicitly excluded from serialization.
parent 689c45b9
......@@ -4405,15 +4405,12 @@ static inline void find_arb_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWi
* is quite expensive because it forces the driver to disable early Z discards. It is cheaper to
* duplicate the shader than have a no-op KIL instruction in every shader
*/
if((!((IWineD3DDeviceImpl *) shader->baseShader.device)->vs_clipping) && use_vs(stateblock) &&
stateblock->renderState[WINED3DRS_CLIPPING] && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE])
{
if ((!((IWineD3DDeviceImpl *)shader->baseShader.device)->vs_clipping) && use_vs(stateblock)
&& stateblock->state.render_states[WINED3DRS_CLIPPING]
&& stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
args->clip = 1;
}
else
{
args->clip = 0;
}
/* Skip if unused or local, or supported natively */
int_skip = ~shader->baseShader.reg_maps.integer_constants | shader->baseShader.reg_maps.local_int_consts;
......@@ -4468,12 +4465,10 @@ static inline void find_arb_vs_compile_args(IWineD3DVertexShaderImpl *shader, IW
/* Otherwise: Setting boolclip_compare set clip_texcoord to 0 */
}
if(args->clip.boolclip.clip_texcoord)
if (args->clip.boolclip.clip_texcoord)
{
if(stateblock->renderState[WINED3DRS_CLIPPING])
{
args->clip.boolclip.clipplane_mask = (unsigned char) stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
}
if (stateblock->state.render_states[WINED3DRS_CLIPPING])
args->clip.boolclip.clipplane_mask = (unsigned char)stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE];
/* clipplane_mask was set to 0 by setting boolclip_compare to 0 */
}
......@@ -5543,7 +5538,7 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1);
}
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_TEXTUREFACTOR], col);
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, col));
checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, col)");
......@@ -5565,7 +5560,8 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1);
}
if(stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
if (stateblock->state.render_states[WINED3DRS_SPECULARENABLE])
{
/* The specular color has no alpha */
col[0] = 1.0f; col[1] = 1.0f;
col[2] = 1.0f; col[3] = 0.0f;
......@@ -6248,17 +6244,19 @@ static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, str
fragment_prog_arbfp(state, stateblock, context);
}
if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
if (!stateblock->state.render_states[WINED3DRS_FOGENABLE]) return;
if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
{
if(use_vs(stateblock)) {
new_source = FOGSOURCE_VS;
} else {
if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
}
else
{
if (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw)
new_source = FOGSOURCE_COORD;
} else {
else
new_source = FOGSOURCE_FFP;
}
}
} else {
new_source = FOGSOURCE_FFP;
......
......@@ -849,7 +849,7 @@ static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *statebloc
{
const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_TEXTUREFACTOR], col);
GL_EXTCALL(glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col));
checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col)");
......@@ -914,7 +914,7 @@ static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *statebl
static void atifs_srgbwriteenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
if (stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE])
WARN("sRGB writes are not supported by this fragment pipe.\n");
}
......
......@@ -565,7 +565,7 @@ void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect)
SetRect(rect, vp->X, vp->Y, vp->X + vp->Width, vp->Y + vp->Height);
if (stateblock->renderState[WINED3DRS_SCISSORTESTENABLE])
if (stateblock->state.render_states[WINED3DRS_SCISSORTESTENABLE])
{
IntersectRect(rect, rect, &stateblock->scissorRect);
}
......@@ -3021,19 +3021,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetViewport(IWineD3DDevice *iface, WINE
return WINED3D_OK;
}
/*****
* Get / Set Render States
* TODO: Verify against dx9 definitions
*****/
static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, WINED3DRENDERSTATETYPE State, DWORD Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
DWORD oldValue = This->stateBlock->renderState[State];
static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface,
WINED3DRENDERSTATETYPE State, DWORD Value)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
DWORD oldValue = This->stateBlock->state.render_states[State];
TRACE("iface %p, state %s (%#x), value %#x.\n", iface, debug_d3drenderstate(State), State, Value);
This->updateStateBlock->changed.renderState[State >> 5] |= 1 << (State & 0x1f);
This->updateStateBlock->renderState[State] = Value;
This->updateStateBlock->state.render_states[State] = Value;
/* Handle recording of state blocks */
if (This->isRecordingState) {
......@@ -3051,12 +3048,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, W
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderState(IWineD3DDevice *iface, WINED3DRENDERSTATETYPE State, DWORD *pValue) {
static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderState(IWineD3DDevice *iface,
WINED3DRENDERSTATETYPE State, DWORD *pValue)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
TRACE("iface %p, state %s (%#x), value %p.\n", iface, debug_d3drenderstate(State), State, pValue);
*pValue = This->stateBlock->renderState[State];
*pValue = This->stateBlock->state.render_states[State];
return WINED3D_OK;
}
......@@ -3836,11 +3835,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
dest_conv = dest_conv_addr;
}
/* Should I clip?
* a) WINED3DRS_CLIPPING is enabled
* b) WINED3DVOP_CLIP is passed
*/
if(This->stateBlock->renderState[WINED3DRS_CLIPPING]) {
if (This->stateBlock->state.render_states[WINED3DRS_CLIPPING])
{
static BOOL warned = FALSE;
/*
* The clipping code is not quite correct. Some things need
......
......@@ -139,10 +139,10 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
specular = element->data + streams[element->stream_idx].offset;
/* special case where the fog density is stored in the specular alpha channel */
if (This->stateBlock->renderState[WINED3DRS_FOGENABLE]
&& (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE
if (This->stateBlock->state.render_states[WINED3DRS_FOGENABLE]
&& (This->stateBlock->state.render_states[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE
|| si->elements[WINED3D_FFP_POSITION].format->id == WINED3DFMT_R32G32B32A32_FLOAT)
&& This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
&& This->stateBlock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
{
if (gl_info->supported[EXT_FOG_COORD])
{
......@@ -580,7 +580,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
if (!index_count) return;
if (This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE])
if (This->stateBlock->state.render_states[WINED3DRS_COLORWRITEENABLE])
{
/* Invalidate the back buffer memory so LockRect will read it the next time */
for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i)
......@@ -615,8 +615,8 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
* depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
* that we never copy the stencil data.*/
DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]
|| This->stateBlock->renderState[WINED3DRS_ZENABLE])
if (This->stateBlock->state.render_states[WINED3DRS_ZWRITEENABLE]
|| This->stateBlock->state.render_states[WINED3DRS_ZENABLE])
{
RECT current_rect, draw_rect, r;
......@@ -636,7 +636,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
if (!EqualRect(&r, &draw_rect))
surface_load_ds_location(This->depth_stencil, context, location);
if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE])
if (This->stateBlock->state.render_states[WINED3DRS_ZWRITEENABLE])
{
surface_modify_ds_location(This->depth_stencil, location,
This->depth_stencil->ds_current_size.cx,
......@@ -649,7 +649,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
if ((!context->gl_info->supported[WINED3D_GL_VERSION_2_0]
|| (!glPointParameteri && !context->gl_info->supported[NV_POINT_SPRITE]))
&& context->render_offscreen
&& This->stateBlock->renderState[WINED3DRS_POINTSPRITEENABLE]
&& This->stateBlock->state.render_states[WINED3DRS_POINTSPRITEENABLE]
&& This->stateBlock->gl_primitive_type == GL_POINTS)
{
FIXME("Point sprite coordinate origin switching not supported.\n");
......@@ -666,7 +666,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
if (!use_vs(This->stateBlock))
{
if (!This->strided_streams.position_transformed && context->num_untracked_materials
&& This->stateBlock->renderState[WINED3DRS_LIGHTING])
&& This->stateBlock->state.render_states[WINED3DRS_LIGHTING])
{
static BOOL warned;
if (!warned) {
......@@ -677,7 +677,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
}
emulation = TRUE;
}
else if (context->fog_coord && This->stateBlock->renderState[WINED3DRS_FOGENABLE])
else if (context->fog_coord && This->stateBlock->state.render_states[WINED3DRS_FOGENABLE])
{
/* Either write a pipeline replacement shader or convert the specular alpha from unsigned byte
* to a float in the vertex buffer
......
......@@ -606,7 +606,7 @@ static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
{
const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_TEXTUREFACTOR], col);
GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
}
......
......@@ -1709,9 +1709,10 @@ static const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
void find_vs_compile_args(IWineD3DVertexShaderImpl *shader,
IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args)
{
args->fog_src = stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
args->clip_enabled = stateblock->renderState[WINED3DRS_CLIPPING]
&& stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
args->fog_src = stateblock->state.render_states[WINED3DRS_FOGTABLEMODE]
== WINED3DFOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
args->clip_enabled = stateblock->state.render_states[WINED3DRS_CLIPPING]
&& stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE];
args->swizzle_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.swizzle_map;
}
......@@ -2074,7 +2075,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader,
UINT i;
memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */
if (stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE])
{
IWineD3DSurfaceImpl *rt = device->render_targets[0];
if(rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE) args->srgb_correction = 1;
......@@ -2121,9 +2122,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader,
else
{
args->vp_mode = vertexshader;
if (stateblock->renderState[WINED3DRS_FOGENABLE])
if (stateblock->state.render_states[WINED3DRS_FOGENABLE])
{
switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE])
switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
{
case WINED3DFOG_NONE:
if (device->strided_streams.position_transformed || use_vs(stateblock))
......@@ -2132,7 +2133,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader,
break;
}
switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE])
switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
{
case WINED3DFOG_NONE: /* Fall through. */
case WINED3DFOG_LINEAR: args->fog = FOG_LINEAR; break;
......
......@@ -816,9 +816,9 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
{
WINED3DRENDERSTATETYPE rs = This->contained_render_states[i];
TRACE("Updating renderState %#x to %u.\n", rs, targetStateBlock->renderState[rs]);
TRACE("Updating render state %#x to %u.\n", rs, targetStateBlock->state.render_states[rs]);
This->renderState[rs] = targetStateBlock->renderState[rs];
This->state.render_states[rs] = targetStateBlock->state.render_states[rs];
}
/* Texture states */
......@@ -942,7 +942,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface)
for (i = 0; i < This->num_contained_render_states; ++i)
{
IWineD3DDevice_SetRenderState(device, This->contained_render_states[i],
This->renderState[This->contained_render_states[i]]);
This->state.render_states[This->contained_render_states[i]]);
}
/* Texture states */
......
......@@ -2800,7 +2800,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
}
if (!i && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
if (!i && stateblock->textures[0] && stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
{
UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
......@@ -2818,7 +2818,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
}
else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
{
if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
{
aarg2 = WINED3DTA_TEXTURE;
aop = WINED3DTOP_MODULATE;
......@@ -2827,7 +2827,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
}
else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
{
if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
{
aarg1 = WINED3DTA_TEXTURE;
aop = WINED3DTOP_MODULATE;
......@@ -2880,14 +2880,20 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
}
if (!stateblock->renderState[WINED3DRS_FOGENABLE])
if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
{
settings->fog = FOG_OFF;
} else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
}
else if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
{
if (use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *)stateblock->vertexDecl)->position_transformed)
{
settings->fog = FOG_LINEAR;
} else {
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
}
else
{
switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
{
case WINED3DFOG_NONE:
case WINED3DFOG_LINEAR:
settings->fog = FOG_LINEAR;
......@@ -2900,8 +2906,11 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
break;
}
}
} else {
switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
}
else
{
switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
{
case WINED3DFOG_LINEAR:
settings->fog = FOG_LINEAR;
break;
......@@ -2913,15 +2922,16 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
break;
}
}
if (stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]
if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE]
&& rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE)
{
settings->sRGB_write = 1;
} else {
settings->sRGB_write = 0;
}
if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] ||
!stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
if (device->vs_clipping || !use_vs(stateblock) || !stateblock->state.render_states[WINED3DRS_CLIPPING]
|| !stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
{
/* No need to emulate clipplanes if GL supports native vertex shader clipping or if
* the fixed function vertex pipeline is used(which always supports clipplanes), or
* if no clipplane is enabled
......
......@@ -2347,6 +2347,11 @@ struct wined3d_stream_state
UINT flags;
};
struct wined3d_state
{
DWORD render_states[WINEHIGHEST_RENDER_STATE + 1];
};
struct IWineD3DStateBlockImpl
{
/* IUnknown fields */
......@@ -2359,6 +2364,7 @@ struct IWineD3DStateBlockImpl
/* Array indicating whether things have been set or changed */
SAVEDSTATES changed;
struct wined3d_state state;
/* Vertex Shader Declaration */
IWineD3DVertexDeclaration *vertexDecl;
......@@ -2410,9 +2416,6 @@ struct IWineD3DStateBlockImpl
INT pixelShaderConstantI[MAX_CONST_I * 4];
float *pixelShaderConstantF;
/* RenderState */
DWORD renderState[WINEHIGHEST_RENDER_STATE + 1];
/* Texture */
IWineD3DBaseTexture *textures[MAX_COMBINED_SAMPLERS];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment