Hi, I can't compile wine with this patch. Here is error log:
device.c: In function ‘stretch_rect_fbo’:
device.c:5311: error: ‘WineD3D_GL_Info’ has no member named
‘glBlitFramebufferEXT’
device.c:5314: error: ‘WineD3D_GL_Info’ has no member named
‘glBlitFramebufferEXT’
make[2]: *** [device.o] Error 1
make[2]: Leaving directory
`/root/.WineCVS/sources/cvswine/wine/dlls/wined3d'
make[1]: *** [wined3d] Error 2
make[1]: *** Waiting for unfinished jobs....
Mirek
H. Verbeet napsal(a):
> Although this patch is somewhat similar to Fabian's, it's not actually
> based on it.
>
> Changelog:
> - Use the framebuffer blit extension to implement StretchRect
>
>
> ------------------------------------------------------------------------
>
> ---
>
> dlls/wined3d/device.c | 77 ++++++++++++++++++++++++++++++++++++++++
> dlls/wined3d/surface.c | 12 ++++--
> dlls/wined3d/wined3d_private.h | 5 +++
> 3 files changed, 90 insertions(+), 4 deletions(-)
>
> diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
> index 506b61c..580fcd0 100644
> --- a/dlls/wined3d/device.c
> +++ b/dlls/wined3d/device.c
> @@ -181,6 +181,12 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
> if (This->fbo) {
> GL_EXTCALL(glDeleteFramebuffersEXT(1, &This->fbo));
> }
> + if (This->src_fbo) {
> + GL_EXTCALL(glDeleteFramebuffersEXT(1, &This->src_fbo));
> + }
> + if (This->dst_fbo) {
> + GL_EXTCALL(glDeleteFramebuffersEXT(1, &This->dst_fbo));
> + }
>
> HeapFree(GetProcessHeap(), 0, This->render_targets);
> HeapFree(GetProcessHeap(), 0, This->fbo_color_attachments);
> @@ -5242,6 +5248,77 @@ void apply_fbo_state(IWineD3DDevice *iface) {
> check_fbo_status(iface);
> }
>
> +static BOOL is_onscreen(IWineD3DSurface *target) {
> + HRESULT hr;
> + void *tmp;
> +
> + hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, &tmp);
> + if (SUCCEEDED(hr)) {
> + IWineD3DSwapChain_Release((IUnknown *)tmp);
> + return TRUE;
> + }
> +
> + return FALSE;
> +}
> +
> +void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const WINED3DRECT *src_rect,
> + IWineD3DSurface *dst_surface, const WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
> + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
> + GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
> + GLenum gl_filter;
> +
> + TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x)\n",
> + This, src_surface, src_rect, dst_surface, dst_rect, debug_d3dtexturefiltertype(filter), filter);
> +
> + switch (filter) {
> + case WINED3DTEXF_LINEAR:
> + gl_filter = GL_LINEAR;
> + break;
> +
> + default:
> + FIXME("Unsupported filter mode %s (0x%08x)\n", debug_d3dtexturefiltertype(filter), filter);
> + case WINED3DTEXF_NONE:
> + case WINED3DTEXF_POINT:
> + gl_filter = GL_NEAREST;
> + break;
> + }
> +
> + /* Attach src surface to src fbo */
> + if (is_onscreen(src_surface)) {
> + GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));
> + flip = !flip;
> + } else {
> + IWineD3DSurface_PreLoad(src_surface);
> + bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->src_fbo);
> + attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
> + }
> +
> + /* Attach dst surface to dst fbo */
> + if (is_onscreen(dst_surface)) {
> + GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
> + flip = !flip;
> + } else {
> + IWineD3DSurface_PreLoad(dst_surface);
> + bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->dst_fbo);
> + attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
> + }
> +
> + if (flip) {
> + GL_EXTCALL(glBlitFramebufferEXT(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
> + dst_rect->x1, dst_rect->y2, dst_rect->x2, dst_rect->y1, mask, gl_filter));
> + } else {
> + GL_EXTCALL(glBlitFramebufferEXT(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
> + dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2, mask, gl_filter));
> + }
> +
> + if (This->render_offscreen) {
> + bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->fbo);
> + } else {
> + GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
> + checkGLcall("glBindFramebuffer()");
> + }
> +}
> +
> static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget) {
> IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
> WINED3DVIEWPORT viewport;
> diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
> index 8b7b47d..5db1aa0 100644
> --- a/dlls/wined3d/surface.c
> +++ b/dlls/wined3d/surface.c
> @@ -2752,8 +2752,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
> }
>
> /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot
> - * flip the image nor scale it. If GL_EXT_framebuffer_blit is available it can be used(hopefully,
> - * not implemented by now). Otherwise:
> + * flip the image nor scale it.
> *
> * -> If the app asks for a unscaled, upside down copy, just perform one glCopyTexSubImage2D call
> * -> If the app wants a image width an unscaled width, copy it line per line
> @@ -2762,9 +2761,14 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
> * back buffer. This is slower than reading line per line, thus not used for flipping
> * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied
> * pixel by pixel
> + *
> + * If EXT_framebuffer_blit is supported that can be used instead. Note that EXT_framebuffer_blit implies
> + * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering
> + * backends.
> */
> - if(FALSE /* GL_SUPPORT(EXT_FRAMEBUFFER_BLIT) */) {
> - TRACE("Using GL_EXT_framebuffer_blit for copying\n");
> + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT)) {
> + stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect,
> + (IWineD3DSurface *)This, &rect, Filter, upsideDown);
> } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width ||
> rect.y2 - rect.y1 > Src->currentDesc.Height) {
> TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n");
> diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
> index 65cd345..d0da532 100644
> --- a/dlls/wined3d/wined3d_private.h
> +++ b/dlls/wined3d/wined3d_private.h
> @@ -674,6 +674,8 @@ struct IWineD3DDeviceImpl
> BOOL render_offscreen;
> WINED3D_DEPTHCOPYSTATE depth_copy_state;
> GLuint fbo;
> + GLuint src_fbo;
> + GLuint dst_fbo;
> GLenum *draw_buffers;
>
> /* Cursor management */
> @@ -1969,4 +1971,7 @@ static inline BOOL use_ps(IWineD3DDeviceImpl *device) {
> && ((IWineD3DPixelShaderImpl *)device->stateBlock->pixelShader)->baseShader.function);
> }
>
> +void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const WINED3DRECT *src_rect,
> + IWineD3DSurface *dst_surface, const WINED3DRECT *dst_rect, WINED3DTEXTUREFILTERTYPE filter, BOOL flip);
> +
> #endif
>
>
> ------------------------------------------------------------------------
>
>