Commit 0d446053 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Don't create more than WINED3D_MAX_FBO_ENTRIES FBO entries.

This essentially turns the FBO entry list into an LRU cache.
parent cad271f1
......@@ -53,12 +53,10 @@ void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo)
checkGLcall("glBindFramebuffer()");
}
static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
static void context_clean_fbo_attachments(IWineD3DDeviceImpl *This)
{
unsigned int i;
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
checkGLcall("glBindFramebuffer()");
for (i = 0; i < GL_LIMITS(buffers); ++i)
{
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
......@@ -66,6 +64,15 @@ static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
}
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
checkGLcall("glFramebufferTexture2D()");
}
static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
{
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
checkGLcall("glBindFramebuffer()");
context_clean_fbo_attachments(This);
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
checkGLcall("glBindFramebuffer()");
GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
......@@ -230,6 +237,19 @@ static struct fbo_entry *context_create_fbo_entry(IWineD3DDevice *iface)
return entry;
}
static void context_reuse_fbo_entry(IWineD3DDevice *iface, struct fbo_entry *entry)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, entry->id));
checkGLcall("glBindFramebuffer()");
context_clean_fbo_attachments(This);
memcpy(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
entry->depth_stencil = This->stencilBufferTarget;
entry->attached = FALSE;
}
static void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, struct fbo_entry *entry)
{
if (entry->id)
......@@ -253,12 +273,26 @@ static struct fbo_entry *context_find_fbo_entry(IWineD3DDevice *iface, WineD3DCo
if (!memcmp(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets))
&& entry->depth_stencil == This->stencilBufferTarget)
{
list_remove(&entry->entry);
list_add_head(&context->fbo_list, &entry->entry);
return entry;
}
}
entry = context_create_fbo_entry(iface);
list_add_head(&context->fbo_list, &entry->entry);
if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES)
{
entry = context_create_fbo_entry(iface);
list_add_head(&context->fbo_list, &entry->entry);
++context->fbo_entry_count;
}
else
{
entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry);
context_reuse_fbo_entry(iface, entry);
list_remove(&entry->entry);
list_add_head(&context->fbo_list, &entry->entry);
}
return entry;
}
......
......@@ -1167,6 +1167,8 @@ enum fogsource {
FOGSOURCE_COORD,
};
#define WINED3D_MAX_FBO_ENTRIES 64
/* The new context manager that should deal with onscreen and offscreen rendering */
struct WineD3DContext {
/* State dirtification
......@@ -1214,6 +1216,7 @@ struct WineD3DContext {
GLint aux_buffers;
/* FBOs */
UINT fbo_entry_count;
struct list fbo_list;
struct fbo_entry *current_fbo;
GLuint src_fbo;
......
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