[PATCH 2/6] wined3d: Keep track of FBOs through the GL names (v2).
Stefan Dösinger
stefan at codeweavers.com
Wed Oct 28 09:29:18 CDT 2015
Version 2: Don't use fbo_entry->d3d_* for logging, plan for it to go
away. The disadvantage is now that we don't know the d3d properties once
we find out that an FBO doesn't work and need a full TRACE log for this
information, but I think that's something we can live with.
If there is a prettier way to find the texture target of a GL texture
name please advise. I couldn't find any.
Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
---
dlls/wined3d/context.c | 393 +++++++++++++++++++++++++++--------------
dlls/wined3d/wined3d_private.h | 17 +-
2 files changed, 279 insertions(+), 131 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 978f7d7..2bd9eb0 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -120,57 +120,39 @@ static void context_attach_depth_stencil_rb(const struct wined3d_gl_info *gl_inf
/* Context activation is done by the caller. */
static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
- GLenum fbo_target, struct wined3d_surface *depth_stencil, DWORD location)
+ GLenum fbo_target, const struct wined3d_fbo_resource *resource, BOOL rb_namespace,
+ DWORD format_flags, GLuint rb_override)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- TRACE("Attach depth stencil %p\n", depth_stencil);
-
- if (depth_stencil)
+ if (resource->object)
{
- DWORD format_flags = depth_stencil->container->resource.format_flags;
+ TRACE("Attach depth stencil %u.\n", resource->object);
- if (depth_stencil->current_renderbuffer)
+ if (rb_override)
{
context_attach_depth_stencil_rb(gl_info, fbo_target,
- format_flags, depth_stencil->current_renderbuffer->id);
+ format_flags, rb_override);
+ }
+ else if (rb_namespace)
+ {
+ context_attach_depth_stencil_rb(gl_info, fbo_target,
+ format_flags, resource->object);
}
else
{
- switch (location)
+ if (format_flags & WINED3DFMT_FLAG_DEPTH)
{
- case WINED3D_LOCATION_TEXTURE_RGB:
- case WINED3D_LOCATION_TEXTURE_SRGB:
- if (format_flags & WINED3DFMT_FLAG_DEPTH)
- {
- gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
- depth_stencil->texture_target, depth_stencil->container->texture_rgb.name,
- depth_stencil->texture_level);
- checkGLcall("glFramebufferTexture2D()");
- }
-
- if (format_flags & WINED3DFMT_FLAG_STENCIL)
- {
- gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT,
- depth_stencil->texture_target, depth_stencil->container->texture_rgb.name,
- depth_stencil->texture_level);
- checkGLcall("glFramebufferTexture2D()");
- }
- break;
-
- case WINED3D_LOCATION_RB_MULTISAMPLE:
- context_attach_depth_stencil_rb(gl_info, fbo_target,
- format_flags, depth_stencil->rb_multisample);
- break;
-
- case WINED3D_LOCATION_RB_RESOLVED:
- context_attach_depth_stencil_rb(gl_info, fbo_target,
- format_flags, depth_stencil->rb_resolved);
- break;
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
+ resource->target, resource->object, resource->level);
+ checkGLcall("glFramebufferTexture2D()");
+ }
- default:
- ERR("Unsupported location %s (%#x).\n", wined3d_debug_location(location), location);
- break;
+ if (format_flags & WINED3DFMT_FLAG_STENCIL)
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT,
+ resource->target, resource->object, resource->level);
+ checkGLcall("glFramebufferTexture2D()");
}
}
@@ -188,6 +170,8 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
}
else
{
+ TRACE("Attach depth stencil 0.\n");
+
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
checkGLcall("glFramebufferTexture2D()");
@@ -198,42 +182,26 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
/* Context activation is done by the caller. */
static void context_attach_surface_fbo(struct wined3d_context *context,
- GLenum fbo_target, DWORD idx, struct wined3d_surface *surface, DWORD location)
+ GLenum fbo_target, DWORD idx, const struct wined3d_fbo_resource *resource, BOOL rb_namespace)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
- TRACE("Attach surface %p to %u\n", surface, idx);
+ TRACE("Attach GL object %u to %u.\n", resource->object, idx);
- if (surface && surface->resource.format->id != WINED3DFMT_NULL)
+ if (resource->object)
{
- BOOL srgb;
- switch (location)
+ if (rb_namespace)
{
- case WINED3D_LOCATION_TEXTURE_RGB:
- case WINED3D_LOCATION_TEXTURE_SRGB:
- srgb = location == WINED3D_LOCATION_TEXTURE_SRGB;
- gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
- surface->texture_target, surface_get_texture_name(surface, gl_info, srgb),
- surface->texture_level);
- checkGLcall("glFramebufferTexture2D()");
- break;
-
- case WINED3D_LOCATION_RB_MULTISAMPLE:
- gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
- GL_RENDERBUFFER, surface->rb_multisample);
- checkGLcall("glFramebufferRenderbuffer()");
- break;
-
- case WINED3D_LOCATION_RB_RESOLVED:
- gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
- GL_RENDERBUFFER, surface->rb_resolved);
- checkGLcall("glFramebufferRenderbuffer()");
- break;
-
- default:
- ERR("Unsupported location %s (%#x).\n", wined3d_debug_location(location), location);
- break;
+ gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
+ GL_RENDERBUFFER, resource->object);
+ checkGLcall("glFramebufferRenderbuffer()");
+ }
+ else
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
+ resource->target, resource->object, resource->level);
+ checkGLcall("glFramebufferTexture2D()");
}
}
else
@@ -243,6 +211,94 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
}
}
+static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, GLenum target,
+ GLenum attachment, const char *name_string)
+{
+ GLint type, name, samples, width, height, old_texture, level, face, fmt, tex_target;
+
+ gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);
+ gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
+
+ if (type == GL_RENDERBUFFER)
+ {
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, name);
+ gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
+ gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
+ if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
+ gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
+ else
+ samples = 1;
+ gl_info->fbo_ops.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &fmt);
+ FIXME("\t%s: renderbuffer %d, %dx%d, %d samples, format %x.\n",
+ name_string, name, width, height, samples, fmt);
+ }
+ else if (type == GL_TEXTURE)
+ {
+ const char *tex_type_str;
+
+ gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &level);
+ gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv(target, attachment,
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &face);
+
+ if (face)
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &old_texture);
+
+ glBindTexture(GL_TEXTURE_CUBE_MAP, name);
+ glGetTexLevelParameteriv(face, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
+ glGetTexLevelParameteriv(face, level, GL_TEXTURE_WIDTH, &width);
+ glGetTexLevelParameteriv(face, level, GL_TEXTURE_HEIGHT, &height);
+
+ tex_target = GL_TEXTURE_CUBE_MAP;
+ tex_type_str = "cube";
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_texture);
+ while (gl_info->gl_ops.gl.p_glGetError());
+
+ glBindTexture(GL_TEXTURE_2D, name);
+ if (!gl_info->gl_ops.gl.p_glGetError())
+ {
+ tex_target = GL_TEXTURE_2D;
+ tex_type_str = "2d";
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, old_texture);
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_texture);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, name);
+ if (gl_info->gl_ops.gl.p_glGetError())
+ {
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, old_texture);
+ FIXME("Cannot find type of texture %d.\n", name);
+ return;
+ }
+ tex_target = GL_TEXTURE_RECTANGLE_ARB;
+ tex_type_str = "rectangle";
+ }
+
+ glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
+ glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_WIDTH, &width);
+ glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_HEIGHT, &height);
+ }
+
+ FIXME("\t%s: %s texture %d, %dx%d, format %x.\n", name_string, tex_type_str, name, width, height, fmt);
+
+ glBindTexture(tex_target, old_texture);
+ }
+ else if (type == GL_NONE)
+ {
+ FIXME("\t%s: NONE.\n", name_string);
+ }
+ else
+ ERR("\t%s: Unknown attachment %x.\n", name_string, type);
+}
+
/* Context activation is done by the caller. */
void context_check_fbo_status(const struct wined3d_context *context, GLenum target)
{
@@ -258,7 +314,6 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ
}
else
{
- const struct wined3d_surface *attachment;
unsigned int i;
FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
@@ -269,29 +324,16 @@ void context_check_fbo_status(const struct wined3d_context *context, GLenum targ
return;
}
- FIXME("\tColor Location %s (%#x).\n", wined3d_debug_location(context->current_fbo->color_location),
- context->current_fbo->color_location);
- FIXME("\tDepth Stencil Location %s (%#x).\n", wined3d_debug_location(context->current_fbo->ds_location),
- context->current_fbo->ds_location);
+ context_dump_fbo_attachment(gl_info, target, GL_DEPTH_ATTACHMENT, "Depth attachment");
+ context_dump_fbo_attachment(gl_info, target, GL_STENCIL_ATTACHMENT, "Stencil attachment");
- /* Dump the FBO attachments */
for (i = 0; i < gl_info->limits.buffers; ++i)
{
- attachment = context->current_fbo->render_targets[i];
- if (attachment)
- {
- FIXME("\tColor attachment %d: (%p) %s %ux%u %u samples.\n",
- i, attachment, debug_d3dformat(attachment->resource.format->id),
- attachment->pow2Width, attachment->pow2Height, attachment->resource.multisample_type);
- }
- }
- attachment = context->current_fbo->depth_stencil;
- if (attachment)
- {
- FIXME("\tDepth attachment: (%p) %s %ux%u %u samples.\n",
- attachment, debug_d3dformat(attachment->resource.format->id),
- attachment->pow2Width, attachment->pow2Height, attachment->resource.multisample_type);
+ char name[32];
+ sprintf(name, "Color attachment %u", i);
+ context_dump_fbo_attachment(gl_info, target, GL_COLOR_ATTACHMENT0 + i, name);
}
+ checkGLcall("Dump FBO attachments");
}
}
@@ -306,19 +348,74 @@ static inline DWORD context_generate_rt_mask_from_surface(const struct wined3d_s
return (1u << 31) | surface_get_gl_buffer(target);
}
+static inline void context_set_fbo_key_for_surface(struct wined3d_fbo_entry_key *key, UINT idx,
+ struct wined3d_surface *surface, DWORD location)
+{
+ if (!surface)
+ {
+ key->objects[idx].object = 0;
+ key->objects[idx].level = key->objects[idx].target = 0;
+ }
+ else
+ {
+ switch (location)
+ {
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ key->objects[idx].object = surface->container->texture_rgb.name;
+ key->objects[idx].level = surface->texture_level;
+ key->objects[idx].target = surface->texture_target;
+ break;
+
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ key->objects[idx].object = surface->container->texture_srgb.name;
+ key->objects[idx].level = surface->texture_level;
+ key->objects[idx].target = surface->texture_target;
+ break;
+
+ case WINED3D_LOCATION_RB_MULTISAMPLE:
+ key->objects[idx].object = surface->rb_multisample;
+ key->objects[idx].level = key->objects[idx].target = 0;
+ key->rb_namespace |= 1 << idx;
+ break;
+
+ case WINED3D_LOCATION_RB_RESOLVED:
+ key->objects[idx].object = surface->rb_resolved;
+ key->objects[idx].level = key->objects[idx].target = 0;
+ key->rb_namespace |= 1 << idx;
+ break;
+ }
+ }
+}
+
+static inline void context_create_fbo_key(struct wined3d_fbo_entry_key *key,
+ struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil,
+ DWORD color_location, DWORD ds_location, UINT color_buffers)
+{
+ UINT i;
+
+ key->rb_namespace = 0;
+ context_set_fbo_key_for_surface(key, 0, depth_stencil, ds_location);
+
+ for (i = 0; i < color_buffers; ++i)
+ context_set_fbo_key_for_surface(key, i + 1, render_targets[i], color_location);
+}
+
static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil,
DWORD color_location, DWORD ds_location)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct fbo_entry *entry;
-
- entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
- entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets));
- memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
- entry->depth_stencil = depth_stencil;
- entry->color_location = color_location;
- entry->ds_location = ds_location;
+ UINT object_count = gl_info->limits.buffers + 1;
+
+ entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ FIELD_OFFSET(struct fbo_entry, key.objects[object_count]));
+ entry->d3d_render_targets = HeapAlloc(GetProcessHeap(), 0,
+ gl_info->limits.buffers * sizeof(*entry->d3d_render_targets));
+ context_create_fbo_key(&entry->key, render_targets, depth_stencil, color_location, ds_location,
+ gl_info->limits.buffers);
+ memcpy(entry->d3d_render_targets, render_targets, sizeof(*entry->d3d_render_targets) * gl_info->limits.buffers);
+ entry->d3d_depth_stencil = depth_stencil;
entry->rt_mask = context_generate_rt_mask(GL_COLOR_ATTACHMENT0);
entry->attached = FALSE;
gl_info->fbo_ops.glGenFramebuffers(1, &entry->id);
@@ -338,10 +435,10 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum targ
context_bind_fbo(context, target, entry->id);
context_clean_fbo_attachments(gl_info, target);
- memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
- entry->depth_stencil = depth_stencil;
- entry->color_location = color_location;
- entry->ds_location = ds_location;
+ context_create_fbo_key(&entry->key, render_targets, depth_stencil, color_location, ds_location,
+ gl_info->limits.buffers);
+ memcpy(entry->d3d_render_targets, render_targets, sizeof(*entry->d3d_render_targets) * gl_info->limits.buffers);
+ entry->d3d_depth_stencil = depth_stencil;
entry->attached = FALSE;
}
@@ -355,7 +452,7 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb
}
--context->fbo_entry_count;
list_remove(&entry->entry);
- HeapFree(GetProcessHeap(), 0, entry->render_targets);
+ HeapFree(GetProcessHeap(), 0, entry->d3d_render_targets);
HeapFree(GetProcessHeap(), 0, entry);
}
@@ -366,6 +463,8 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct fbo_entry *entry;
+ UINT object_count = gl_info->limits.buffers + 1;
+ unsigned int i;
if (depth_stencil && render_targets && render_targets[0])
{
@@ -377,19 +476,44 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
}
}
- LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
+ context_create_fbo_key(context->fbo_key, render_targets, depth_stencil, color_location,
+ ds_location, gl_info->limits.buffers);
+
+ if (TRACE_ON(d3d))
{
- if (!memcmp(entry->render_targets,
- render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets))
- && entry->depth_stencil == depth_stencil && entry->color_location == color_location
- && entry->ds_location == ds_location)
+ TRACE("Dumping FBO attachments:\n");
+ for (i = 0; i < gl_info->limits.buffers; ++i)
{
- list_remove(&entry->entry);
- list_add_head(&context->fbo_list, &entry->entry);
- return entry;
+ if (render_targets[i])
+ {
+ TRACE("\tColor attachment %u: (%p) %s gl obj %u(%s) %ux%u %u samples.\n",
+ i, render_targets[i], debug_d3dformat(render_targets[i]->resource.format->id),
+ context->fbo_key->objects[i + 1].object,
+ context->fbo_key->rb_namespace & (1 << (i + 1)) ? "rb" : "texure",
+ render_targets[i]->pow2Width, render_targets[i]->pow2Height,
+ render_targets[i]->resource.multisample_type);
+ }
+ }
+ if (depth_stencil)
+ {
+ TRACE("\tDepth attachment: (%p) %s gl obj %u(%s) %ux%u %u samples.\n",
+ depth_stencil, debug_d3dformat(depth_stencil->resource.format->id),
+ context->fbo_key->objects[0].object,
+ context->fbo_key->rb_namespace & (1 << 0) ? "rb" : "texure",
+ depth_stencil->pow2Width, depth_stencil->pow2Height, depth_stencil->resource.multisample_type);
}
}
+ LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
+ {
+ if (memcmp(context->fbo_key, &entry->key, FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[object_count])))
+ continue;
+
+ list_remove(&entry->entry);
+ list_add_head(&context->fbo_list, &entry->entry);
+ return entry;
+ }
+
if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES)
{
entry = context_create_fbo_entry(context, render_targets, depth_stencil, color_location, ds_location);
@@ -413,7 +537,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int i;
GLuint read_binding, draw_binding;
- struct wined3d_surface *depth_stencil = entry->depth_stencil;
+ struct wined3d_surface *depth_stencil = entry->d3d_depth_stencil;
if (entry->attached)
{
@@ -428,25 +552,36 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
/* Apply render targets */
for (i = 0; i < gl_info->limits.buffers; ++i)
{
- context_attach_surface_fbo(context, target, i, entry->render_targets[i], entry->color_location);
+ context_attach_surface_fbo(context, target, i, &entry->key.objects[i + 1],
+ entry->key.rb_namespace & (1 << (i + 1)));
}
- if (depth_stencil && entry->render_targets[0]
+ if (depth_stencil && entry->d3d_render_targets[0]
&& (depth_stencil->resource.multisample_type
- != entry->render_targets[0]->resource.multisample_type
+ != entry->d3d_render_targets[0]->resource.multisample_type
|| depth_stencil->resource.multisample_quality
- != entry->render_targets[0]->resource.multisample_quality))
+ != entry->d3d_render_targets[0]->resource.multisample_quality))
{
WARN("Color multisample type %u and quality %u, depth stencil has %u and %u, disabling ds buffer.\n",
- entry->render_targets[0]->resource.multisample_quality,
- entry->render_targets[0]->resource.multisample_type,
+ entry->d3d_render_targets[0]->resource.multisample_quality,
+ entry->d3d_render_targets[0]->resource.multisample_type,
depth_stencil->resource.multisample_quality, depth_stencil->resource.multisample_type);
depth_stencil = NULL;
}
if (depth_stencil)
- surface_set_compatible_renderbuffer(depth_stencil, entry->render_targets[0]);
- context_attach_depth_stencil_fbo(context, target, depth_stencil, entry->ds_location);
+ {
+ DWORD format_flags = depth_stencil->container->resource.format_flags;
+ surface_set_compatible_renderbuffer(depth_stencil, entry->d3d_render_targets[0]);
+ context_attach_depth_stencil_fbo(context, target, &entry->key.objects[0],
+ entry->key.rb_namespace & 0x1, format_flags,
+ depth_stencil->current_renderbuffer ? depth_stencil->current_renderbuffer->id : 0);
+ }
+ else
+ {
+ struct wined3d_fbo_resource resource = {0};
+ context_attach_depth_stencil_fbo(context, target, &resource, FALSE, 0, 0);
+ }
/* Set valid read and draw buffer bindings to satisfy pedantic pre-ES2_compatibility
* GL contexts requirements. */
@@ -695,7 +830,7 @@ static void context_enum_surface_fbo_entries(const struct wined3d_device *device
{
UINT j;
- if (entry->depth_stencil == surface)
+ if (entry->d3d_depth_stencil == surface)
{
callback(context, entry);
continue;
@@ -703,7 +838,7 @@ static void context_enum_surface_fbo_entries(const struct wined3d_device *device
for (j = 0; j < gl_info->limits.buffers; ++j)
{
- if (entry->render_targets[j] == surface)
+ if (entry->d3d_render_targets[j] == surface)
{
callback(context, entry);
break;
@@ -764,21 +899,16 @@ void context_surface_update(struct wined3d_context *context, const struct wined3
if (!entry || context->rebind_fbo) return;
- for (i = 0; i < gl_info->limits.buffers; ++i)
+ for (i = 0; i < gl_info->limits.buffers + 1; ++i)
{
- if (surface == entry->render_targets[i])
+ if (surface->container->texture_rgb.name == entry->key.objects[i].object ||
+ surface->container->texture_srgb.name == entry->key.objects[i].object)
{
- TRACE("Updated surface %p is bound as color attachment %u to the current FBO.\n", surface, i);
+ TRACE("Updated surface %p is bound as attachment %u to the current FBO.\n", surface, i);
context->rebind_fbo = TRUE;
return;
}
}
-
- if (surface == entry->depth_stencil)
- {
- TRACE("Updated surface %p is bound as depth attachment to the current FBO.\n", surface);
- context->rebind_fbo = TRUE;
- }
}
static BOOL context_restore_pixel_format(struct wined3d_context *ctx)
@@ -1480,6 +1610,11 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
if (!ret->draw_buffers)
goto out;
+ ret->fbo_key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[gl_info->limits.buffers + 1]));
+ if (!ret->fbo_key)
+ goto out;
+
ret->free_timestamp_query_size = 4;
ret->free_timestamp_queries = HeapAlloc(GetProcessHeap(), 0,
ret->free_timestamp_query_size * sizeof(*ret->free_timestamp_queries));
@@ -1832,6 +1967,7 @@ out:
HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries);
+ HeapFree(GetProcessHeap(), 0, ret->fbo_key);
HeapFree(GetProcessHeap(), 0, ret->draw_buffers);
HeapFree(GetProcessHeap(), 0, ret->blit_targets);
HeapFree(GetProcessHeap(), 0, ret);
@@ -1863,6 +1999,7 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont
device->shader_backend->shader_free_context_data(context);
device->adapter->fragment_pipe->free_context_data(context);
+ HeapFree(GetProcessHeap(), 0, context->fbo_key);
HeapFree(GetProcessHeap(), 0, context->draw_buffers);
HeapFree(GetProcessHeap(), 0, context->blit_targets);
device_context_remove(device, context);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index fd7bbc8..50952db 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1229,6 +1229,7 @@ struct wined3d_context
GLuint fbo_read_binding;
GLuint fbo_draw_binding;
struct wined3d_surface **blit_targets;
+ struct wined3d_fbo_entry_key *fbo_key;
GLenum *draw_buffers;
DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */
@@ -2374,15 +2375,25 @@ struct wined3d_renderbuffer_entry
UINT height;
};
+struct wined3d_fbo_resource
+{
+ GLuint object;
+ GLuint level, target;
+};
+
struct fbo_entry
{
struct list entry;
- struct wined3d_surface **render_targets;
- struct wined3d_surface *depth_stencil;
- DWORD color_location, ds_location;
+ struct wined3d_surface **d3d_render_targets;
+ struct wined3d_surface *d3d_depth_stencil;
DWORD rt_mask;
BOOL attached;
GLuint id;
+ struct wined3d_fbo_entry_key
+ {
+ DWORD rb_namespace;
+ struct wined3d_fbo_resource objects[1];
+ } key;
};
struct wined3d_surface_ops
--
2.4.10
More information about the wine-patches
mailing list