Commit ec97383f authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Add support for ARB_framebuffer_object.

parent c4c86215
......@@ -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;
......
......@@ -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;
......
......@@ -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. */
......
......@@ -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 {
......
......@@ -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);
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment