Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/context.c | 122 ++++++++++++++++++++++++++++---------------------
1 file changed, 71 insertions(+), 51 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 4929b84..d552c8c 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -413,7 +413,7 @@ static inline DWORD context_generate_rt_mask_from_resource(struct wined3d_resour
}
static inline void context_set_fbo_key_for_render_target(const struct wined3d_context *context,
- struct wined3d_fbo_entry_key *key, unsigned int idx, struct wined3d_rendertarget_info *render_target,
+ struct wined3d_fbo_entry_key *key, unsigned int idx, const struct wined3d_rendertarget_info *render_target,
DWORD location)
{
unsigned int sub_resource_idx = render_target->sub_resource_idx;
@@ -487,28 +487,21 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co
}
static void context_generate_fbo_key(const struct wined3d_context *context,
- struct wined3d_fbo_entry_key *key, struct wined3d_rendertarget_info *render_targets,
- struct wined3d_surface *depth_stencil_surface, DWORD color_location,
+ struct wined3d_fbo_entry_key *key, const struct wined3d_rendertarget_info *render_targets,
+ const struct wined3d_rendertarget_info *depth_stencil, DWORD color_location,
DWORD ds_location)
{
- struct wined3d_rendertarget_info depth_stencil = {{0}};
unsigned int i;
key->rb_namespace = 0;
- if (depth_stencil_surface)
- {
- depth_stencil.resource = &depth_stencil_surface->container->resource;
- depth_stencil.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil_surface);
- depth_stencil.layer_count = 1;
- }
- context_set_fbo_key_for_render_target(context, key, 0, &depth_stencil, ds_location);
+ context_set_fbo_key_for_render_target(context, key, 0, depth_stencil, ds_location);
for (i = 0; i < context->gl_info->limits.buffers; ++i)
context_set_fbo_key_for_render_target(context, key, i + 1, &render_targets[i], color_location);
}
static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
- struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+ const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil,
DWORD color_location, DWORD ds_location)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -519,11 +512,11 @@ static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *
memset(&entry->key, 0, FIELD_OFFSET(struct wined3d_fbo_entry_key, objects[object_count]));
context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location);
entry->flags = 0;
- if (depth_stencil)
+ if (depth_stencil->resource)
{
- if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_DEPTH)
+ if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_DEPTH)
entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH;
- if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_STENCIL)
+ if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_STENCIL)
entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL;
}
entry->rt_mask = context_generate_rt_mask(GL_COLOR_ATTACHMENT0);
@@ -536,7 +529,7 @@ static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *
/* Context activation is done by the caller. */
static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
- struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+ const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil,
DWORD color_location, DWORD ds_location, struct fbo_entry *entry)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -546,11 +539,11 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum targ
context_generate_fbo_key(context, &entry->key, render_targets, depth_stencil, color_location, ds_location);
entry->flags = 0;
- if (depth_stencil)
+ if (depth_stencil->resource)
{
- if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_DEPTH)
+ if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_DEPTH)
entry->flags |= WINED3D_FBO_ENTRY_FLAG_DEPTH;
- if (depth_stencil->container->resource.format_flags & WINED3DFMT_FLAG_STENCIL)
+ if (depth_stencil->resource->format_flags & WINED3DFMT_FLAG_STENCIL)
entry->flags |= WINED3D_FBO_ENTRY_FLAG_STENCIL;
}
}
@@ -570,28 +563,31 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb
/* Context activation is done by the caller. */
static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
- struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
+ const struct wined3d_rendertarget_info *render_targets, const struct wined3d_rendertarget_info *depth_stencil,
DWORD color_location, DWORD ds_location)
{
+ static const struct wined3d_rendertarget_info ds_null = {{0}};
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int object_count = gl_info->limits.buffers + 1;
struct wined3d_texture *rt_texture, *ds_texture;
+ unsigned int i, ds_level, rt_level;
struct fbo_entry *entry;
- unsigned int i, level;
- if (depth_stencil && render_targets[0].resource && render_targets[0].resource->type != WINED3D_RTYPE_BUFFER)
+ if (depth_stencil->resource && depth_stencil->resource->type != WINED3D_RTYPE_BUFFER
+ && render_targets[0].resource && render_targets[0].resource->type != WINED3D_RTYPE_BUFFER)
{
rt_texture = wined3d_texture_from_resource(render_targets[0].resource);
- level = render_targets[0].sub_resource_idx % rt_texture->level_count;
- ds_texture = depth_stencil->container;
-
- if (wined3d_texture_get_level_width(ds_texture, depth_stencil->texture_level)
- < wined3d_texture_get_level_width(rt_texture, level)
- || wined3d_texture_get_level_height(ds_texture, depth_stencil->texture_level)
- < wined3d_texture_get_level_height(rt_texture, level))
+ rt_level = render_targets[0].sub_resource_idx % rt_texture->level_count;
+ ds_texture = wined3d_texture_from_resource(depth_stencil->resource);
+ ds_level = depth_stencil->sub_resource_idx % ds_texture->level_count;
+
+ if (wined3d_texture_get_level_width(ds_texture, ds_level)
+ < wined3d_texture_get_level_width(rt_texture, rt_level)
+ || wined3d_texture_get_level_height(ds_texture, ds_level)
+ < wined3d_texture_get_level_height(rt_texture, rt_level))
{
WARN("Depth stencil is smaller than the primary color buffer, disabling.\n");
- depth_stencil = NULL;
+ depth_stencil = &ds_null;
}
else if (ds_texture->resource.multisample_type != rt_texture->resource.multisample_type
|| ds_texture->resource.multisample_quality != rt_texture->resource.multisample_quality)
@@ -599,10 +595,15 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
WARN("Color multisample type %u and quality %u, depth stencil has %u and %u, disabling ds buffer.\n",
rt_texture->resource.multisample_type, rt_texture->resource.multisample_quality,
ds_texture->resource.multisample_type, ds_texture->resource.multisample_quality);
- depth_stencil = NULL;
+ depth_stencil = &ds_null;
+ }
+ else if (depth_stencil->resource->type == WINED3D_RTYPE_TEXTURE_2D)
+ {
+ struct wined3d_surface *surface;
+
+ surface = ds_texture->sub_resources[depth_stencil->sub_resource_idx].u.surface;
+ surface_set_compatible_renderbuffer(surface, &render_targets[0]);
}
- else
- surface_set_compatible_renderbuffer(depth_stencil, &render_targets[0]);
}
context_generate_fbo_key(context, context->fbo_key, render_targets, depth_stencil, color_location,
@@ -610,15 +611,15 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
if (TRACE_ON(d3d))
{
+ struct wined3d_resource *resource;
+ unsigned int width, height;
+ const char *resource_type;
+
TRACE("Dumping FBO attachments:\n");
for (i = 0; i < gl_info->limits.buffers; ++i)
{
- struct wined3d_resource *resource;
if ((resource = render_targets[i].resource))
{
- unsigned int width, height;
- const char *resource_type;
-
if (resource->type == WINED3D_RTYPE_BUFFER)
{
width = resource->size;
@@ -628,9 +629,9 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
else
{
rt_texture = wined3d_texture_from_resource(resource);
- level = render_targets[i].sub_resource_idx % rt_texture->level_count;
- width = wined3d_texture_get_level_pow2_width(rt_texture, level);
- height = wined3d_texture_get_level_pow2_height(rt_texture, level);
+ rt_level = render_targets[i].sub_resource_idx % rt_texture->level_count;
+ width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level);
+ height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level);
resource_type = "texture";
}
@@ -640,16 +641,27 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
context->fbo_key->objects[i + 1].object, width, height, resource->multisample_type);
}
}
- if (depth_stencil)
+ if ((resource = depth_stencil->resource))
{
- ds_texture = depth_stencil->container;
- TRACE(" Depth attachment: %p format %s, %s %u, %ux%u, %u samples.\n",
- depth_stencil, debug_d3dformat(ds_texture->resource.format->id),
- context->fbo_key->rb_namespace & (1 << 0) ? "renderbuffer" : "texture",
- context->fbo_key->objects[0].object,
- wined3d_texture_get_level_pow2_width(ds_texture, depth_stencil->texture_level),
- wined3d_texture_get_level_pow2_height(ds_texture, depth_stencil->texture_level),
- ds_texture->resource.multisample_type);
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ width = resource->size;
+ height = 1;
+ resource_type = "buffer";
+ }
+ else
+ {
+ ds_texture = wined3d_texture_from_resource(resource);
+ ds_level = depth_stencil->sub_resource_idx % ds_texture->level_count;
+ width = wined3d_texture_get_level_pow2_width(ds_texture, ds_level);
+ height = wined3d_texture_get_level_pow2_height(ds_texture, ds_level);
+ resource_type = "texture";
+ }
+
+ TRACE(" Depth attachment: %p, %u format %s, %s %u, %ux%u, %u samples.\n",
+ resource, depth_stencil->sub_resource_idx, debug_d3dformat(resource->format->id),
+ context->fbo_key->rb_namespace & (1 << 0) ? "renderbuffer" : resource_type,
+ context->fbo_key->objects[0].object, width, height, resource->multisample_type);
}
}
@@ -747,8 +759,16 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ
}
else
{
- context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil,
- color_location, ds_location);
+ struct wined3d_rendertarget_info ds = {{0}};
+
+ if (depth_stencil)
+ {
+ ds.resource = &depth_stencil->container->resource;
+ ds.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil);
+ ds.layer_count = 1;
+ }
+ context->current_fbo = context_find_fbo_entry(context, target,
+ render_targets, &ds, color_location, ds_location);
context_apply_fbo_entry(context, target, context->current_fbo);
}
}
--
2.1.4