diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index db4324d309f..f0db9cf6964 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -287,7 +287,8 @@ struct shader_arb_priv const struct arb_ps_compiled_shader *compiled_fprog; const struct arb_vs_compiled_shader *compiled_vprog; GLuint depth_blt_vprogram_id; - GLuint depth_blt_fprogram_id[tex_type_count]; + GLuint depth_blt_fprogram_id_full[tex_type_count]; + GLuint depth_blt_fprogram_id_masked[tex_type_count]; BOOL use_arbfp_fixed_func; struct wine_rb_tree fragment_shaders; BOOL last_ps_const_clamped; @@ -3103,12 +3104,14 @@ static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_inf } /* GL locking is done by the caller */ -static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, enum tex_types tex_type) +static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, + enum tex_types tex_type, BOOL masked) { GLuint program_id = 0; + const char *fprogram; GLint pos; - static const char * const blt_fprograms[tex_type_count] = + static const char * const blt_fprograms_full[tex_type_count] = { /* tex_1d */ NULL, @@ -3134,7 +3137,46 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i "END\n", }; - if (!blt_fprograms[tex_type]) + static const char * const blt_fprograms_masked[tex_type_count] = + { + /* tex_1d */ + NULL, + /* tex_2d */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + /* tex_3d */ + NULL, + /* tex_cube */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + /* tex_rect */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + }; + + fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type]; + if (!fprogram) { FIXME("tex_type %#x not supported\n", tex_type); tex_type = tex_2d; @@ -3142,8 +3184,7 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i GL_EXTCALL(glGenProgramsARB(1, &program_id)); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id)); - GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(blt_fprograms[tex_type]), blt_fprograms[tex_type])); + GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fprogram), fprogram)); checkGLcall("glProgramStringARB()"); glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos); @@ -3151,7 +3192,7 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i { FIXME("Fragment program error at position %d: %s\n\n", pos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB))); - shader_arb_dump_program_source(blt_fprograms[tex_type]); + shader_arb_dump_program_source(fprogram); } else { @@ -4444,18 +4485,23 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, } /* GL locking is done by the caller */ -static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { +static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size) +{ + const float mask[] = {0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy}; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + BOOL masked = ds_mask_size->cx && ds_mask_size->cy; struct shader_arb_priv *priv = This->shader_priv; - GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type]; const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + GLuint *blt_fprogram; if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info); GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id)); glEnable(GL_VERTEX_PROGRAM_ARB); - if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type); + blt_fprogram = masked ? &priv->depth_blt_fprogram_id_masked[tex_type] : &priv->depth_blt_fprogram_id_full[tex_type]; + if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type, masked); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *blt_fprogram)); + if (masked) GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, mask)); glEnable(GL_FRAGMENT_PROGRAM_ARB); } @@ -4595,9 +4641,15 @@ static void shader_arb_free(IWineD3DDevice *iface) { if(priv->depth_blt_vprogram_id) { GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id)); } - for (i = 0; i < tex_type_count; ++i) { - if (priv->depth_blt_fprogram_id[i]) { - GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id[i])); + for (i = 0; i < tex_type_count; ++i) + { + if (priv->depth_blt_fprogram_id_full[i]) + { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_full[i])); + } + if (priv->depth_blt_fprogram_id_masked[i]) + { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_masked[i])); } } LEAVE_GL(); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index f28505313d4..20c509d6dc5 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -563,7 +563,7 @@ void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *c device->contexts = new_array; } -static void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) +void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) { IWineD3DStateBlockImpl *stateblock = device->stateBlock; WINED3DVIEWPORT *vp = &stateblock->viewport; @@ -582,7 +582,9 @@ void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, if (device->onscreen_depth_stencil) { surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_DS_OFFSCREEN); - surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_DS_OFFSCREEN); + surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_DS_OFFSCREEN, + device->onscreen_depth_stencil->ds_current_size.cx, + device->onscreen_depth_stencil->ds_current_size.cy); IWineD3DSurface_Release((IWineD3DSurface *)device->onscreen_depth_stencil); } device->onscreen_depth_stencil = depth_stencil; @@ -4371,6 +4373,61 @@ static BOOL is_full_clear(IWineD3DSurfaceImpl *target, const RECT *draw_rect, co return TRUE; } +static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *context, + DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect) +{ + RECT current_rect, r; + + if (ds->Flags & location) + SetRect(¤t_rect, 0, 0, + ds->ds_current_size.cx, + ds->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); + + IntersectRect(&r, draw_rect, ¤t_rect); + if (EqualRect(&r, draw_rect)) + { + /* current_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); + return; + } + + if (EqualRect(&r, ¤t_rect)) + { + /* draw_rect ⊇ current_rect, test if we're doing a full clear. */ + + if (!clear_rect) + { + /* Full clear, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + + if (rect_count > 1) + { + /* Multiple clear rects, full load. Strictly speaking this can + * also be a full draw_rect clear, but it's probably rare enough + * that we don't care. */ + surface_load_ds_location(ds, context, location); + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); + return; + } + + IntersectRect(&r, draw_rect, clear_rect); + if (EqualRect(&r, draw_rect)) + { + /* clear_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + } + + /* Full load. */ + surface_load_ds_location(ds, context, location); + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); +} + /* Not called from the VTable (internal subroutine) */ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) @@ -4456,10 +4513,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac if (location == SFLAG_DS_ONSCREEN && depth_stencil != This->onscreen_depth_stencil) device_switch_onscreen_ds(This, context, depth_stencil); - - if (!(depth_stencil->Flags & location) && !is_full_clear(depth_stencil, &draw_rect, clear_rect)) - surface_load_ds_location(depth_stencil, context, location); - surface_modify_ds_location(depth_stencil, location); + prepare_ds_clear(depth_stencil, context, location, &draw_rect, Count, clear_rect); glDepthMask(GL_TRUE); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); @@ -5941,7 +5995,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice * if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL || This->depth_stencil->Flags & SFLAG_DISCARD) { - surface_modify_ds_location(This->depth_stencil, SFLAG_DS_DISCARDED); + surface_modify_ds_location(This->depth_stencil, SFLAG_DS_DISCARDED, + This->depth_stencil->currentDesc.Width, + This->depth_stencil->currentDesc.Height); if (This->depth_stencil == This->onscreen_depth_stencil) { IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil); diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 146d73a8f24..5f88f4ebbe6 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -613,12 +613,29 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE] || This->stateBlock->renderState[WINED3DRS_ZENABLE]) { + RECT current_rect, draw_rect, r; + if (location == SFLAG_DS_ONSCREEN && This->depth_stencil != This->onscreen_depth_stencil) device_switch_onscreen_ds(This, context, This->depth_stencil); - surface_load_ds_location(This->depth_stencil, context, location); + + if (This->depth_stencil->Flags & location) + SetRect(¤t_rect, 0, 0, + This->depth_stencil->ds_current_size.cx, + This->depth_stencil->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); + + device_get_draw_rect(This, &draw_rect); + + IntersectRect(&r, &draw_rect, ¤t_rect); + if (!EqualRect(&r, &draw_rect)) + surface_load_ds_location(This->depth_stencil, context, location); + + if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]) + surface_modify_ds_location(This->depth_stencil, location, + This->depth_stencil->ds_current_size.cx, + This->depth_stencil->ds_current_size.cy); } - if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]) - surface_modify_ds_location(This->depth_stencil, location); } /* Ok, we will be updating the screen from here onwards so grab the lock */ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 7648d153f7c..aca9d0e27a5 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -89,7 +89,8 @@ struct shader_glsl_priv { struct constant_heap vconst_heap; struct constant_heap pconst_heap; unsigned char *stack; - GLhandleARB depth_blt_program[tex_type_count]; + GLhandleARB depth_blt_program_full[tex_type_count]; + GLhandleARB depth_blt_program_masked[tex_type_count]; UINT next_constant_version; }; @@ -4463,10 +4464,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, } /* GL locking is done by the caller */ -static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type) +static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked) { GLhandleARB program_id; GLhandleARB vshader_id, pshader_id; + const char *blt_pshader; + static const char *blt_vshader[] = { "#version 120\n" @@ -4478,7 +4481,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, "}\n" }; - static const char *blt_pshaders[tex_type_count] = + static const char *blt_pshaders_full[tex_type_count] = { /* tex_1d */ NULL, @@ -4508,7 +4511,44 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, "}\n", }; - if (!blt_pshaders[tex_type]) + static const char *blt_pshaders_masked[tex_type_count] = + { + /* tex_1d */ + NULL, + /* tex_2d */ + "#version 120\n" + "uniform sampler2D sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n" + "}\n", + /* tex_3d */ + NULL, + /* tex_cube */ + "#version 120\n" + "uniform samplerCube sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n" + "}\n", + /* tex_rect */ + "#version 120\n" + "#extension GL_ARB_texture_rectangle : enable\n" + "uniform sampler2DRect sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n" + "}\n", + }; + + blt_pshader = masked ? blt_pshaders_masked[tex_type] : blt_pshaders_full[tex_type]; + if (!blt_pshader) { FIXME("tex_type %#x not supported\n", tex_type); tex_type = tex_2d; @@ -4519,7 +4559,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, GL_EXTCALL(glCompileShaderARB(vshader_id)); pshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); - GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshaders[tex_type], NULL)); + GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshader, NULL)); GL_EXTCALL(glCompileShaderARB(pshader_id)); program_id = GL_EXTCALL(glCreateProgramObjectARB()); @@ -4581,21 +4621,34 @@ static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS } /* GL locking is done by the caller */ -static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { +static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, + enum tex_types tex_type, const SIZE *ds_mask_size) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + BOOL masked = ds_mask_size->cx && ds_mask_size->cy; struct shader_glsl_priv *priv = This->shader_priv; - GLhandleARB *blt_program = &priv->depth_blt_program[tex_type]; + GLhandleARB *blt_program; + GLint loc; - if (!*blt_program) { - GLint loc; - *blt_program = create_glsl_blt_shader(gl_info, tex_type); + blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type]; + if (!*blt_program) + { + *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked); loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "sampler")); GL_EXTCALL(glUseProgramObjectARB(*blt_program)); GL_EXTCALL(glUniform1iARB(loc, 0)); - } else { + } + else + { GL_EXTCALL(glUseProgramObjectARB(*blt_program)); } + + if (masked) + { + loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "mask")); + GL_EXTCALL(glUniform4fARB(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy)); + } } /* GL locking is done by the caller */ @@ -4831,9 +4884,13 @@ static void shader_glsl_free(IWineD3DDevice *iface) { ENTER_GL(); for (i = 0; i < tex_type_count; ++i) { - if (priv->depth_blt_program[i]) + if (priv->depth_blt_program_full[i]) { - GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program[i])); + GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_full[i])); + } + if (priv->depth_blt_program_masked[i]) + { + GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_masked[i])); } } LEAVE_GL(); diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 683653245da..b0151788fe9 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1403,7 +1403,7 @@ static void shader_cleanup(IWineD3DBaseShader *iface) static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {} static void shader_none_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {} -static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {} +static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size) {} static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {} static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {} static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {} diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 8a934a8209f..6ec3ed9f54a 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -4092,7 +4092,8 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, const struct wined3d_gl glGetIntegerv(info.binding, &old_binding); glBindTexture(info.bind_target, texture); - device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, info.tex_type); + device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, + info.tex_type, &This->ds_current_size); glBegin(GL_TRIANGLE_STRIP); glTexCoord3fv(info.coords[0]); @@ -4112,13 +4113,16 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, const struct wined3d_gl device->shader_backend->shader_deselect_depth_blt((IWineD3DDevice *)device); } -void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, DWORD location) +void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, + DWORD location, UINT w, UINT h) { - TRACE("surface %p, new location %#x.\n", surface, location); + TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); if (location & ~SFLAG_DS_LOCATIONS) FIXME("Invalid location (%#x) specified.\n", location); + surface->ds_current_size.cx = w; + surface->ds_current_size.cy = h; surface->Flags &= ~SFLAG_DS_LOCATIONS; surface->Flags |= location; } @@ -4134,7 +4138,14 @@ void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_conte /* TODO: Make this work for modes other than FBO */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; - if (surface->Flags & location) + if (!(surface->Flags & location)) + { + surface->ds_current_size.cx = 0; + surface->ds_current_size.cy = 0; + } + + if (surface->ds_current_size.cx == surface->currentDesc.Width + && surface->ds_current_size.cy == surface->currentDesc.Height) { TRACE("Location (%#x) is already up to date.\n", location); return; @@ -4250,6 +4261,8 @@ void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_conte } surface->Flags |= location; + surface->ds_current_size.cx = surface->currentDesc.Width; + surface->ds_current_size.cy = surface->currentDesc.Height; } static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) { diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index e1cb2ad74a2..a7b6a70ab4f 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -468,7 +468,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL || This->device->depth_stencil->Flags & SFLAG_DISCARD) { - surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED); + surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED, + This->device->depth_stencil->currentDesc.Width, + This->device->depth_stencil->currentDesc.Height); if (This->device->depth_stencil == This->device->onscreen_depth_stencil) { IWineD3DSurface_Release((IWineD3DSurface *)This->device->onscreen_depth_stencil); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3e54ad8a5cc..c2e17b1d9c7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -713,7 +713,7 @@ struct wined3d_context; typedef struct { void (*shader_handle_instruction)(const struct wined3d_shader_instruction *); void (*shader_select)(const struct wined3d_context *context, BOOL usePS, BOOL useVS); - void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type); + void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size); void (*shader_deselect_depth_blt)(IWineD3DDevice *iface); void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count); void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count); @@ -1725,6 +1725,7 @@ struct IWineD3DDeviceImpl BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; +void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN; HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, UINT adapter_idx, WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags, IUnknown *parent, IWineD3DDeviceParent *device_parent) DECLSPEC_HIDDEN; @@ -2090,6 +2091,7 @@ struct IWineD3DSurfaceImpl struct list renderbuffers; renderbuffer_entry_t *current_renderbuffer; + SIZE ds_current_size; /* DirectDraw clippers */ IWineD3DClipper *clipper; @@ -2677,7 +2679,7 @@ void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN; void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, DWORD location) DECLSPEC_HIDDEN; +void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned int width, unsigned int height) DECLSPEC_HIDDEN; void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;