From 2b926db50d04d4cfb0c8c7cfed0536a24074bf7e Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 30 Dec 2008 14:56:49 +0100 Subject: [PATCH] wined3d: Make use_vs() and use_ps() work on a stateblock instead of a device. Most callers work on a stateblock rather than a device, and the main fields we check (vertexShader and pixelShader) are part of the stateblock as well. --- dlls/wined3d/arb_program_shader.c | 14 ++++++---- dlls/wined3d/ati_fragment_shader.c | 2 +- dlls/wined3d/device.c | 4 +-- dlls/wined3d/drawprim.c | 8 ++++-- dlls/wined3d/glsl_shader.c | 3 +- dlls/wined3d/nvidia_texture_shader.c | 2 +- dlls/wined3d/pixelshader.c | 9 ++++-- dlls/wined3d/state.c | 41 ++++++++++++++-------------- dlls/wined3d/vertexbuffer.c | 3 +- dlls/wined3d/wined3d_private.h | 16 ++++++----- 10 files changed, 57 insertions(+), 45 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index d4d8ec4698..3e2155b07b 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -2379,7 +2379,7 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc * application provided constants */ if(device->shader_backend == &arb_program_shader_backend) { - if(use_ps(device)) return; + if (use_ps(stateblock)) return; device = stateblock->wineD3DDevice; device->activeContext->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1; @@ -2400,7 +2400,7 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb * application provided constants */ if(device->shader_backend == &arb_program_shader_backend) { - if(use_ps(device)) return; + if (use_ps(stateblock)) return; device = stateblock->wineD3DDevice; device->activeContext->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1; @@ -2424,7 +2424,8 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, W IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; float mat[2][2]; - if(use_ps(device)) { + if (use_ps(stateblock)) + { if(stage != 0 && ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) { /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled @@ -2458,7 +2459,8 @@ static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; float param[4]; - if(use_ps(device)) { + if (use_ps(stateblock)) + { if(stage != 0 && ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) { /* The pixel shader has to know the luminance offset. Do a constants update if it @@ -2961,8 +2963,8 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; struct shader_arb_priv *priv = (struct shader_arb_priv *) device->fragment_priv; - BOOL use_pshader = use_ps(device); - BOOL use_vshader = use_vs(device); + BOOL use_pshader = use_ps(stateblock); + BOOL use_vshader = use_vs(stateblock); struct ffp_frag_settings settings; const struct arbfp_ffp_desc *desc; unsigned int i; diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index b4c53343e9..aaecafff99 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -883,7 +883,7 @@ static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3 static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; - BOOL use_vshader = use_vs(device); + BOOL use_vshader = use_vs(stateblock); /* The ATIFS code does not support pixel shaders currently, but we have to provide a state handler * to call shader_select to select a vertex shader if one is applied because the vertex shader state diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 1aa3c56a30..b905936094 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3789,8 +3789,8 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) { } void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) { - BOOL vs = use_vs(This); - BOOL ps = use_ps(This); + BOOL vs = use_vs(This->stateBlock); + BOOL ps = use_ps(This->stateBlock); /* * Rules are: * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 89ab706e1f..fd06d777ce 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -296,7 +296,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const UINT *streamOffset = This->stateBlock->streamOffset; long SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex; - BOOL pixelShader = use_ps(This); + BOOL pixelShader = use_ps(This->stateBlock); BOOL specular_fog = FALSE; UINT texture_stages = GL_LIMITS(texture_stages); const BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; @@ -863,7 +863,8 @@ void drawPrimitive(IWineD3DDevice *iface, if (numberOfVertices == 0 ) numberOfVertices = calculatedNumberOfindices; - if(!use_vs(This)) { + if (!use_vs(This->stateBlock)) + { if(!This->strided_streams.u.s.position_transformed && This->activeContext->num_untracked_materials && This->stateBlock->renderState[WINED3DRS_LIGHTING]) { static BOOL warned; @@ -898,7 +899,8 @@ void drawPrimitive(IWineD3DDevice *iface, if (This->useDrawStridedSlow || emulation) { /* Immediate mode drawing */ - if(use_vs(This)) { + if (use_vs(This->stateBlock)) + { static BOOL warned; if (!warned) { FIXME("Using immediate mode with vertex shaders for half float emulation\n"); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 2aceb9068b..ff14fa3c72 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -797,7 +797,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s */ if (pshader && shader_version >= WINED3DPS_VERSION(3, 0)) { - if(use_vs(device)) { + if (use_vs(device->stateBlock)) + { shader_addline(buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4); } else { /* TODO: Write a replacement shader for the fixed function vertex pipeline, so this isn't needed. diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index a7f96c730f..2c58459d50 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -458,7 +458,7 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3 TRACE("Setting color op for stage %d\n", stage); /* Using a pixel shader? Don't care for anything here, the shader applying does it */ - if (use_ps(stateblock->wineD3DDevice)) return; + if (use_ps(stateblock)) return; if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage); diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index be1b1d1470..1a337ca990 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -479,7 +479,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp { if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed) { args->vp_mode = pretransformed; - } else if(use_vs((IWineD3DDeviceImpl *) shader->baseShader.device)) { + } + else if (use_vs(stateblock)) + { args->vp_mode = vertexshader; } else { args->vp_mode = fixedfunction; @@ -490,8 +492,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp if(stateblock->renderState[WINED3DRS_FOGENABLE]) { switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) { case WINED3DFOG_NONE: - if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed || - use_vs((IWineD3DDeviceImpl *) shader->baseShader.device)) { + if (((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.u.s.position_transformed + || use_vs(stateblock)) + { args->fog = FOG_LINEAR; break; } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index e4c819d259..c141fbd01a 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -532,7 +532,8 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine DWORD enable = 0xFFFFFFFF; DWORD disable = 0x00000000; - if (use_vs(stateblock->wineD3DDevice)) { + if (use_vs(stateblock)) + { /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't, * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some * conditions I got sick of tracking down. The shader state handler disables all clip planes because @@ -898,8 +899,7 @@ static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE]; IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *)stateblock->pixelShader; - BOOL is_ps3 = use_ps(stateblock->wineD3DDevice) - && ps_impl->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0); + BOOL is_ps3 = use_ps(stateblock) && ps_impl->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0); float fogstart, fogend; union { @@ -956,14 +956,14 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo */ if( is_ps3 ) { - if( !use_vs(stateblock->wineD3DDevice) - && stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ) { + if (!use_vs(stateblock) && stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) + { FIXME("Implement vertex fog for pixel shader >= 3.0 and fixed function pipeline\n"); } } - if (use_vs(stateblock->wineD3DDevice) - && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) { + if (use_vs(stateblock) && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) + { if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) { if(!is_ps3) FIXME("Implement table fog for foggy vertex shader\n"); /* Disable fog */ @@ -983,7 +983,8 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo } context->last_was_foggy_shader = TRUE; } - else if( use_ps(stateblock->wineD3DDevice) ) { + else if (use_ps(stateblock)) + { /* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but * -1/(e-s) and e/(e-s) respectively to simplify fog computation in the shader. */ @@ -2887,7 +2888,7 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D TRACE("Setting color op for stage %d\n", stage); /* Using a pixel shader? Don't care for anything here, the shader applying does it */ - if (use_ps(stateblock->wineD3DDevice)) return; + if (use_ps(stateblock)) return; if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage); @@ -3041,8 +3042,8 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W int coordIdx; /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */ - if(use_vs(stateblock->wineD3DDevice) || - isStateDirty(context, STATE_VDECL)) { + if (use_vs(stateblock) || isStateDirty(context, STATE_VDECL)) + { TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n"); return; } @@ -3309,7 +3310,7 @@ static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine return; } - device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device)); + device->shader_backend->shader_load_constants((IWineD3DDevice *)device, use_ps(stateblock), use_vs(stateblock)); } static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { @@ -3401,7 +3402,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)"); } - if(!use_ps(stateblock->wineD3DDevice) && sampler < stateblock->lowest_disabled_stage) { + if (!use_ps(stateblock) && sampler < stateblock->lowest_disabled_stage) + { if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) { /* If color keying is enabled update the alpha test, it depends on the existence * of a color key in stage 0 @@ -3425,9 +3427,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont } static void apply_pshader_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; - - if (use_ps(device)) { + if (use_ps(stateblock)) + { if(!context->last_was_pshader) { state_fog(state, stateblock, context); } @@ -3442,8 +3443,8 @@ static void apply_pshader_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, W void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; - BOOL use_pshader = use_ps(device); - BOOL use_vshader = use_vs(device); + BOOL use_pshader = use_ps(stateblock); + BOOL use_vshader = use_vs(stateblock); int i; if (use_pshader) { @@ -4383,8 +4384,8 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { BOOL updateFog = FALSE; - BOOL useVertexShaderFunction = use_vs(stateblock->wineD3DDevice); - BOOL usePixelShaderFunction = use_ps(stateblock->wineD3DDevice); + BOOL useVertexShaderFunction = use_vs(stateblock); + BOOL usePixelShaderFunction = use_ps(stateblock); BOOL transformed; /* Some stuff is in the device until we have per context tracking */ IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c index 014ced6ef2..b0a6296b73 100644 --- a/dlls/wined3d/vertexbuffer.c +++ b/dlls/wined3d/vertexbuffer.c @@ -327,7 +327,8 @@ static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T * done, or if the DIFFUSE is replaced with a D3DCOLOR BLENDWEIGHT we can happily dismiss the change. Some conversion types * depend on the semantic as well, for example a FLOAT4 texcoord needs no conversion while a FLOAT4 positiont needs one */ - if(use_vs(device)) { + if (use_vs(device->stateBlock)) + { TRACE("vshader\n"); /* If the current vertex declaration is marked for no half float conversion don't bother to * analyse the strided streams in depth, just set them up for no conversion. Return decl changed diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b0aa000b62..dd79c84963 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2462,15 +2462,17 @@ typedef struct { const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info, const struct GlPixelFormatDesc **glDesc); -static inline BOOL use_vs(IWineD3DDeviceImpl *device) { - return (device->vs_selected_mode != SHADER_NONE - && device->stateBlock->vertexShader - && !device->strided_streams.u.s.position_transformed); +static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock) +{ + return (stateblock->vertexShader + && !stateblock->wineD3DDevice->strided_streams.u.s.position_transformed + && stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE); } -static inline BOOL use_ps(IWineD3DDeviceImpl *device) { - return (device->ps_selected_mode != SHADER_NONE - && device->stateBlock->pixelShader); +static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock) +{ + return (stateblock->pixelShader + && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE); } void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,