diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 9bd248f43ff..18f3e75ccb6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2728,11 +2728,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetSamplerState(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_SetScissorRect(IWineD3DDevice *iface, CONST RECT* pRect) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - RECT windowRect; - UINT winHeight; This->updateStateBlock->set.scissorRect = TRUE; This->updateStateBlock->changed.scissorRect = TRUE; + if(memcmp(&This->updateStateBlock->scissorRect, pRect, sizeof(*pRect)) == 0) { + TRACE("App is setting the old scissor rectangle over, nothing to do\n"); + return WINED3D_OK; + } memcpy(&This->updateStateBlock->scissorRect, pRect, sizeof(*pRect)); if(This->isRecordingState) { @@ -2740,17 +2742,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetScissorRect(IWineD3DDevice *iface, C return WINED3D_OK; } - GetClientRect(((IWineD3DSwapChainImpl *)This->swapchains[0])->win_handle, &windowRect); - /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply - * Warning2: Even in windowed mode the coords are relative to the window, not the screen - */ - winHeight = windowRect.bottom - windowRect.top; - TRACE("(%p)Setting new Scissor Rect to %d:%d-%d:%d\n", This, pRect->left, pRect->bottom - winHeight, - pRect->right - pRect->left, pRect->bottom - pRect->top); - ENTER_GL(); - glScissor(pRect->left, winHeight - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top); - checkGLcall("glScissor"); - LEAVE_GL(); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SCISSORRECT); return WINED3D_OK; } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 257757f87d7..0b96e542e04 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3045,6 +3045,23 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex return; } +static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) stateblock->wineD3DDevice->swapchains[0]; + RECT *pRect = &stateblock->scissorRect; + RECT windowRect; + UINT winHeight; + + GetClientRect(swapchain->win_handle, &windowRect); + /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply + * Warning2: Even in windowed mode the coords are relative to the window, not the screen + */ + winHeight = windowRect.bottom - windowRect.top; + TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - winHeight, + pRect->right - pRect->left, pRect->bottom - pRect->top); + glScissor(pRect->left, winHeight - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top); + checkGLcall("glScissor"); +} + const struct StateEntry StateTable[] = { /* State name representative, apply function */ @@ -4074,4 +4091,6 @@ const struct StateEntry StateTable[] = { /* , STATE_ACTIVELIGHT(5) */ STATE_ACTIVELIGHT(5), light }, { /* , STATE_ACTIVELIGHT(6) */ STATE_ACTIVELIGHT(6), light }, { /* , STATE_ACTIVELIGHT(7) */ STATE_ACTIVELIGHT(7), light }, + + { /* Scissor rect */ STATE_SCISSORRECT, scissorrect } }; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7fea727be99..3bf0c8e46de 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -444,7 +444,10 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock, #define STATE_ACTIVELIGHT(a) (STATE_PIXELSHADERCONSTANT + (a) + 1) #define STATE_IS_ACTIVELIGHT(a) ((a) >= STATE_ACTIVELIGHT(0) && (a) < STATE_PIXELSHADERCONSTANT(MAX_ACTIVE_LIGHTS)) -#define STATE_HIGHEST (STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS - 1)) +#define STATE_SCISSORRECT (STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS - 1) + 1) +#define STATE_IS_SCISSORRECT(a) ((a) == STATE_SCISSORRECT) + +#define STATE_HIGHEST (STATE_SCISSORRECT) struct StateEntry {