mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
wined3d: Add support for ARB_framebuffer_object.
This commit is contained in:
parent
c4c86215ed
commit
ec97383f6f
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user