From ec97383f6fb1a14c19dfcb85dd5239a8938c9e3c Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 23 Sep 2009 10:05:55 +0200 Subject: [PATCH] wined3d: Add support for ARB_framebuffer_object. --- dlls/wined3d/context.c | 104 +++++++++++++++++++------------------- dlls/wined3d/device.c | 53 +++++++++++-------- dlls/wined3d/directx.c | 61 ++++++++++++++++++++-- dlls/wined3d/surface.c | 55 ++++++++++++-------- dlls/wined3d/utils.c | 93 +++++++++++++++++++--------------- dlls/wined3d/wined3d_gl.h | 24 +++++++++ 6 files changed, 250 insertions(+), 140 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 28cd4a090cb..878e5bf8969 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -48,8 +48,8 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb { if (!*fbo) { - GL_EXTCALL(glGenFramebuffersEXT(1, fbo)); - checkGLcall("glGenFramebuffersEXT()"); + gl_info->fbo_ops.glGenFramebuffers(1, fbo); + checkGLcall("glGenFramebuffers()"); TRACE("Created FBO %u.\n", *fbo); } f = *fbo; @@ -57,17 +57,17 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb switch (target) { - case GL_READ_FRAMEBUFFER_EXT: + case GL_READ_FRAMEBUFFER: if (context->fbo_read_binding == f) return; context->fbo_read_binding = f; break; - case GL_DRAW_FRAMEBUFFER_EXT: + case GL_DRAW_FRAMEBUFFER: if (context->fbo_draw_binding == f) return; context->fbo_draw_binding = f; break; - case GL_FRAMEBUFFER_EXT: + case GL_FRAMEBUFFER: if (context->fbo_read_binding == f && context->fbo_draw_binding == f) return; context->fbo_read_binding = f; @@ -79,7 +79,7 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb break; } - GL_EXTCALL(glBindFramebufferEXT(target, f)); + gl_info->fbo_ops.glBindFramebuffer(target, f); checkGLcall("glBindFramebuffer()"); } @@ -90,13 +90,13 @@ static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info) for (i = 0; i < GL_LIMITS(buffers); ++i) { - GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0)); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); } - GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); - GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); } @@ -105,11 +105,11 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo) { const struct wined3d_gl_info *gl_info = context->gl_info; - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, fbo); + context_bind_fbo(context, GL_FRAMEBUFFER, fbo); context_clean_fbo_attachments(gl_info); - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo)); + gl_info->fbo_ops.glDeleteFramebuffers(1, fbo); checkGLcall("glDeleteFramebuffers()"); } @@ -194,16 +194,16 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context, { if (format_flags & WINED3DFMT_FLAG_DEPTH) { - GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id)); - checkGLcall("glFramebufferRenderbufferEXT()"); + gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id); + checkGLcall("glFramebufferRenderbuffer()"); } if (format_flags & WINED3DFMT_FLAG_STENCIL) { - GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id)); - checkGLcall("glFramebufferRenderbufferEXT()"); + gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id); + checkGLcall("glFramebufferRenderbuffer()"); } } else @@ -212,40 +212,40 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context, if (format_flags & WINED3DFMT_FLAG_DEPTH) { - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, depth_stencil_impl->texture_target, depth_stencil_impl->texture_name, - depth_stencil_impl->texture_level)); - checkGLcall("glFramebufferTexture2DEXT()"); + depth_stencil_impl->texture_level); + checkGLcall("glFramebufferTexture2D()"); } if (format_flags & WINED3DFMT_FLAG_STENCIL) { - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, depth_stencil_impl->texture_target, depth_stencil_impl->texture_name, - depth_stencil_impl->texture_level)); - checkGLcall("glFramebufferTexture2DEXT()"); + depth_stencil_impl->texture_level); + checkGLcall("glFramebufferTexture2D()"); } } if (!(format_flags & WINED3DFMT_FLAG_DEPTH)) { - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); - checkGLcall("glFramebufferTexture2DEXT()"); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + checkGLcall("glFramebufferTexture2D()"); } if (!(format_flags & WINED3DFMT_FLAG_STENCIL)) { - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); - checkGLcall("glFramebufferTexture2DEXT()"); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + checkGLcall("glFramebufferTexture2D()"); } } else { - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); - checkGLcall("glFramebufferTexture2DEXT()"); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + checkGLcall("glFramebufferTexture2D()"); - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); - checkGLcall("glFramebufferTexture2DEXT()"); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + checkGLcall("glFramebufferTexture2D()"); } } @@ -262,12 +262,14 @@ void context_attach_surface_fbo(const struct wined3d_context *context, { context_apply_attachment_filter_states(surface, TRUE); - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, surface_impl->texture_target, - surface_impl->texture_name, surface_impl->texture_level)); - checkGLcall("glFramebufferTexture2DEXT()"); - } else { - GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0)); - checkGLcall("glFramebufferTexture2DEXT()"); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface_impl->texture_target, + surface_impl->texture_name, surface_impl->texture_level); + checkGLcall("glFramebufferTexture2D()"); + } + else + { + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_TEXTURE_2D, 0, 0); + checkGLcall("glFramebufferTexture2D()"); } } @@ -277,8 +279,8 @@ static void context_check_fbo_status(struct wined3d_context *context) const struct wined3d_gl_info *gl_info = context->gl_info; GLenum status; - status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); - if (status == GL_FRAMEBUFFER_COMPLETE_EXT) + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("FBO complete\n"); } else { @@ -329,7 +331,7 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_ IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; const struct wined3d_gl_info *gl_info = context->gl_info; - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &entry->id); + context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id); context_clean_fbo_attachments(gl_info); memcpy(entry->render_targets, device->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets)); @@ -394,7 +396,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &entry->id); + context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id); if (!entry->attached) { @@ -402,7 +404,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ for (i = 0; i < GL_LIMITS(buffers); ++i) { IWineD3DSurface *render_target = device->render_targets[i]; - context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, i, render_target); + context_attach_surface_fbo(context, GL_FRAMEBUFFER, i, render_target); } /* Apply depth targets */ @@ -413,7 +415,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ surface_set_compatible_renderbuffer(device->stencilBufferTarget, w, h); } - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, device->stencilBufferTarget, TRUE); + context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, device->stencilBufferTarget, TRUE); entry->attached = TRUE; } else { @@ -429,7 +431,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ for (i = 0; i < GL_LIMITS(buffers); ++i) { if (device->render_targets[i]) - device->draw_buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i; + device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; else device->draw_buffers[i] = GL_NONE; } @@ -444,7 +446,7 @@ static void context_apply_fbo_state(struct wined3d_context *context) context_apply_fbo_entry(context, context->current_fbo); } else { context->current_fbo = NULL; - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); } context_check_fbo_status(context); @@ -1958,7 +1960,7 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit checkGLcall("glDrawBuffer()"); } } else { - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glDrawBuffer(GL_COLOR_ATTACHMENT0); checkGLcall("glDrawBuffer()"); } } @@ -2040,13 +2042,13 @@ struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurfac { FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n"); ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, 0, target); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, NULL, FALSE); + context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); + context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, target); + context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); LEAVE_GL(); } else { ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); LEAVE_GL(); } context->draw_buffer_dirty = TRUE; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 17f51a8e55b..30912f1668f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2210,6 +2210,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + const struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; int sampler; UINT i; TRACE("(%p)\n", This); @@ -2219,7 +2221,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, /* I don't think that the interface guarantees that the device is destroyed from the same thread * it was created. Thus make sure a context is active for the glDelete* calls */ - ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD); + context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD); + gl_info = context->gl_info; if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface); @@ -2273,7 +2276,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, } if (This->depth_blt_rb) { ENTER_GL(); - GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb)); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &This->depth_blt_rb); LEAVE_GL(); This->depth_blt_rb = 0; This->depth_blt_rb_w = 0; @@ -5952,7 +5955,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, context = ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD); ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); buffer = surface_get_gl_buffer(surface, swapchain); glDrawBuffer(buffer); checkGLcall("glDrawBuffer()"); @@ -5961,9 +5964,9 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD); ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, 0, surface); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, NULL, FALSE); + context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); + context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, surface); + context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); } if (rect) { @@ -6320,6 +6323,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */ IWineD3DSwapChain *src_swapchain, *dst_swapchain; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; GLenum gl_filter; POINT offset = {0, 0}; @@ -6350,6 +6354,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED else if (dst_swapchain) context = ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD); else context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD); + gl_info = context->gl_info; + if (src_swapchain) { GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain); @@ -6373,17 +6379,17 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED } ENTER_GL(); - context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_READ_FRAMEBUFFER, NULL); glReadBuffer(buffer); checkGLcall("glReadBuffer()"); } else { TRACE("Source surface %p is offscreen\n", src_surface); ENTER_GL(); - context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, &context->src_fbo); - context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER_EXT, 0, src_surface); - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo); + context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, src_surface); + glReadBuffer(GL_COLOR_ATTACHMENT0); checkGLcall("glReadBuffer()"); - context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL, FALSE); + context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE); } LEAVE_GL(); @@ -6412,29 +6418,29 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED } ENTER_GL(); - context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL); glDrawBuffer(buffer); checkGLcall("glDrawBuffer()"); } else { TRACE("Destination surface %p is offscreen\n", dst_surface); ENTER_GL(); - context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, &context->dst_fbo); - context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, &context->dst_fbo); + context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER, 0, dst_surface); + glDrawBuffer(GL_COLOR_ATTACHMENT0); checkGLcall("glDrawBuffer()"); - context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL, FALSE); + context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER, NULL, FALSE); } glDisable(GL_SCISSOR_TEST); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); 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)); + gl_info->fbo_ops.glBlitFramebuffer(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); checkGLcall("glBlitFramebuffer()"); } 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)); + gl_info->fbo_ops.glBlitFramebuffer(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); checkGLcall("glBlitFramebuffer()"); } @@ -6878,10 +6884,13 @@ static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, const WINED3DPRE void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface; + const struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; UINT i; IWineD3DBaseShaderImpl *shader; - ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD); + context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD); + gl_info = context->gl_info; IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL); LIST_FOR_EACH_ENTRY(shader, &This->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry) { @@ -6894,7 +6903,7 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_ This->depth_blt_texture = 0; } if (This->depth_blt_rb) { - GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb)); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &This->depth_blt_rb); This->depth_blt_rb = 0; This->depth_blt_rb_w = 0; This->depth_blt_rb_h = 0; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 5c946814a4a..2f4cdae9e5f 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1872,10 +1872,63 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_gl_info *gl_info) * shaders), but 8 texture stages (register combiners). */ gl_info->max_sampler_stages = max(gl_info->max_fragment_samplers, gl_info->max_texture_stages); - /* We can only use ORM_FBO when the hardware supports it. */ - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) { - WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to backbuffer offscreen rendering mode.\n"); - wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) + { + gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbuffer; + gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbuffer; + gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffers; + gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffers; + gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorage; + gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisample; + gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameteriv; + gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebuffer; + gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebuffer; + gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffers; + gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffers; + gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatus; + gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1D; + gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2D; + gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3D; + gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbuffer; + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameteriv; + gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebuffer; + gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmap; + } + else + { + if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) + { + gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbufferEXT; + gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbufferEXT; + gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffersEXT; + gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffersEXT; + gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorageEXT; + gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameterivEXT; + gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebufferEXT; + gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebufferEXT; + gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffersEXT; + gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffersEXT; + gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatusEXT; + gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1DEXT; + gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2DEXT; + gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3DEXT; + gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbufferEXT; + gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameterivEXT; + gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmapEXT; + } + else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + WARN_(d3d_caps)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n"); + wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; + } + if (gl_info->supported[EXT_FRAMEBUFFER_BLIT]) + { + gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebufferEXT; + } + if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE]) + { + gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisampleEXT; + } } /* MRTs are currently only supported when FBOs are used. */ diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 6a5e66d8dd3..564f6b38a6f 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -70,7 +70,7 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This) LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry) { - GL_EXTCALL(glDeleteRenderbuffersEXT(1, &entry->id)); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); HeapFree(GetProcessHeap(), 0, entry); } @@ -610,6 +610,7 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, /* GL locking is done by the caller */ void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info; renderbuffer_entry_t *entry; GLuint renderbuffer = 0; unsigned int src_width, src_height; @@ -636,10 +637,10 @@ void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int wi } if (!renderbuffer) { - GL_EXTCALL(glGenRenderbuffersEXT(1, &renderbuffer)); - GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer)); - GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - This->resource.format_desc->glInternal, width, height)); + gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, + This->resource.format_desc->glInternal, width, height); entry = HeapAlloc(GetProcessHeap(), 0, sizeof(renderbuffer_entry_t)); entry->width = width; @@ -814,6 +815,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { IWineD3DBaseTexture *texture = NULL; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + const struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; renderbuffer_entry_t *entry, *entry2; TRACE("(%p)\n", iface); @@ -844,7 +847,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE); This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); - ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD); + context = ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD); + gl_info = context->gl_info; /* Destroy PBOs, but load them into real sysmem before */ if(This->Flags & SFLAG_PBO) { @@ -857,7 +861,7 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { */ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry) { ENTER_GL(); - GL_EXTCALL(glDeleteRenderbuffersEXT(1, &entry->id)); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id); LEAVE_GL(); list_remove(&entry->entry); HeapFree(GetProcessHeap(), 0, entry); @@ -1885,7 +1889,8 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ break; case WINED3DFMT_D15S1: - if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) + if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT) + || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) { *convert = CONVERT_D15S1; *target_bpp = 4; @@ -1893,7 +1898,8 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ break; case WINED3DFMT_D24X4S4: - if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) + if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT) + || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) { *convert = CONVERT_D24X4S4; } @@ -3581,7 +3587,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering * backends. */ - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer && surface_can_stretch_rect(Src, This)) { stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect, @@ -3645,7 +3652,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const Src->palette = This->palette; } - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer && !(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) && surface_can_stretch_rect(Src, This)) { @@ -4342,6 +4350,7 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("(%p) New location %#x\n", This, location); @@ -4373,7 +4382,7 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co /* Note that we use depth_blt here as well, rather than glCopyTexImage2D * directly on the FBO texture. That's because we need to flip. */ - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) { glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); @@ -4395,30 +4404,32 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co /* Setup the destination */ if (!device->depth_blt_rb) { - GL_EXTCALL(glGenRenderbuffersEXT(1, &device->depth_blt_rb)); + gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb); checkGLcall("glGenRenderbuffersEXT"); } if (device->depth_blt_rb_w != This->currentDesc.Width || device->depth_blt_rb_h != This->currentDesc.Height) { - GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, device->depth_blt_rb)); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb); checkGLcall("glBindRenderbufferEXT"); - GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, This->currentDesc.Width, This->currentDesc.Height)); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, + This->currentDesc.Width, This->currentDesc.Height); checkGLcall("glRenderbufferStorageEXT"); device->depth_blt_rb_w = This->currentDesc.Width; device->depth_blt_rb_h = This->currentDesc.Height; } - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo); - GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, device->depth_blt_rb)); + context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb); checkGLcall("glFramebufferRenderbufferEXT"); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, iface, FALSE); + context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, iface, FALSE); /* Do the actual blit */ surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target); checkGLcall("depth_blt"); - if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id); - else context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL); + if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); + else context_bind_fbo(context, GL_FRAMEBUFFER, NULL); LEAVE_GL(); } else { @@ -4430,12 +4441,12 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); surface_depth_blt(This, This->texture_name, This->currentDesc.Width, This->currentDesc.Height, This->texture_target); checkGLcall("depth_blt"); - if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id); + if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); LEAVE_GL(); } else { diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 2d7a6b9b2d2..16755ef5ae1 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -443,6 +443,10 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = { GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, EXT_PACKED_DEPTH_STENCIL}, + {WINED3DFMT_D15S1, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, + ARB_FRAMEBUFFER_OBJECT}, {WINED3DFMT_D24S8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, @@ -451,6 +455,10 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = { GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, EXT_PACKED_DEPTH_STENCIL}, + {WINED3DFMT_D24S8, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, + ARB_FRAMEBUFFER_OBJECT}, {WINED3DFMT_D24X8, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, @@ -463,6 +471,10 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = { GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, EXT_PACKED_DEPTH_STENCIL}, + {WINED3DFMT_D24X4S4, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, + ARB_FRAMEBUFFER_OBJECT}, {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, @@ -476,7 +488,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = { WINED3DFMT_FLAG_DEPTH, ARB_DEPTH_BUFFER_FLOAT}, {WINED3DFMT_D24FS8, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, - GL_DEPTH_STENCIL_EXT, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, + GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, ARB_DEPTH_BUFFER_FLOAT}, /* Vendor-specific formats */ @@ -587,12 +599,12 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPix glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0)); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); - status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); checkGLcall("Framebuffer format check"); - if (status == GL_FRAMEBUFFER_COMPLETE_EXT) + if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format)); format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE; @@ -621,19 +633,19 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPix while(glGetError()); - GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0)); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0, format_desc->glFormat, format_desc->glType, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0)); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); - status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); checkGLcall("Framebuffer format check"); - if (status == GL_FRAMEBUFFER_COMPLETE_EXT) + if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("Format %s rtInternal format is supported as FBO color attachment\n", debug_d3dformat(format_desc->format)); @@ -647,38 +659,36 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPix } } - if (status == GL_FRAMEBUFFER_COMPLETE_EXT && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) + if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) { GLuint rb; - if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) + if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT) + || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) { - GL_EXTCALL(glGenRenderbuffersEXT(1, &rb)); - GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb)); - GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 16, 16)); - GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, rb)); - GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, rb)); + gl_info->fbo_ops.glGenRenderbuffers(1, &rb); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb); checkGLcall("RB attachment"); } glEnable(GL_BLEND); glClear(GL_COLOR_BUFFER_BIT); - if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION_EXT) + if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION) { while(glGetError()); TRACE("Format doesn't support post-pixelshader blending.\n"); format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING; } - if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) + if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT) + || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL)) { - GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, 0)); - GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, 0)); - GL_EXTCALL(glDeleteRenderbuffersEXT(1, &rb)); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb); checkGLcall("RB cleanup"); } } @@ -698,8 +708,8 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info) { ENTER_GL(); - GL_EXTCALL(glGenFramebuffersEXT(1, &fbo)); - GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)); + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); LEAVE_GL(); } @@ -739,7 +749,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info) { ENTER_GL(); - GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo)); + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); LEAVE_GL(); } @@ -830,10 +840,10 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glEnable(GL_TEXTURE_2D); - GL_EXTCALL(glGenFramebuffersEXT(1, &fbo)); - GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)); - GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, buffer, 0)); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0); + glDrawBuffer(GL_COLOR_ATTACHMENT0); glViewport(0, 0, 16, 1); glDisable(GL_LIGHTING); @@ -873,8 +883,8 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) ret = TRUE; } - GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)); - GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo)); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); glDeleteTextures(1, &tex); glDeleteTextures(1, &buffer); @@ -1762,15 +1772,16 @@ const char* debug_d3dpool(WINED3DPOOL Pool) { const char *debug_fbostatus(GLenum status) { switch(status) { #define FBOSTATUS_TO_STR(u) case u: return #u - FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT); - FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT); - FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT); FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT); - FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT); - FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT); - FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT); - FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED); + FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED); #undef FBOSTATUS_TO_STR default: FIXME("Unrecognied FBO status 0x%08x\n", status); @@ -1788,7 +1799,7 @@ const char *debug_glerror(GLenum error) { GLERROR_TO_STR(GL_STACK_OVERFLOW); GLERROR_TO_STR(GL_STACK_UNDERFLOW); GLERROR_TO_STR(GL_OUT_OF_MEMORY); - GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT); + GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION); #undef GLERROR_TO_STR default: FIXME("Unrecognied GL error 0x%08x\n", error); diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 03893ba8b9f..7c08f384cb3 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -4097,6 +4097,29 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLSETPIXELFORMATWINE) (HDC hdc, int iPixelFor * Structures ****************************************************/ +struct wined3d_fbo_ops +{ + PGLFNGLISRENDERBUFFERPROC glIsRenderbuffer; + PGLFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; + PGLFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; + PGLFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; + PGLFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; + PGLFNRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; + PGLFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; + PGLFNGLISFRAMEBUFFERPROC glIsFramebuffer; + PGLFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; + PGLFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; + PGLFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; + PGLFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; + PGLFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; + PGLFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; + PGLFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; + PGLFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; + PGLFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; + PGLFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; + PGLFNGLGENERATEMIPMAPPROC glGenerateMipmap; +}; + #define USE_GL_FUNC(type, pfn, ext, replace) type pfn; struct wined3d_gl_info @@ -4145,6 +4168,7 @@ struct wined3d_gl_info BOOL supported[WINED3D_GL_EXT_COUNT]; + struct wined3d_fbo_ops fbo_ops; /* GL function pointers */ GL_EXT_FUNCS_GEN /* WGL function pointers */