Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/context.c | 23 +++----
dlls/wined3d/surface.c | 84 ------------------------
dlls/wined3d/texture.c | 146 +++++++++++++++++++++++++++++++----------
dlls/wined3d/wined3d_private.h | 10 +--
4 files changed, 125 insertions(+), 138 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index c9efad0..60bf52b 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -445,19 +445,15 @@ static inline void context_set_fbo_key_for_render_target(const struct wined3d_co
}
texture = wined3d_texture_from_resource(resource);
- if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
+ if (texture->current_renderbuffer)
{
- struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
-
- if (surface->current_renderbuffer)
- {
- key->objects[idx].object = surface->current_renderbuffer->id;
- key->objects[idx].target = 0;
- key->objects[idx].level = key->objects[idx].layer = 0;
- key->rb_namespace |= 1 << idx;
- return;
- }
+ key->objects[idx].object = texture->current_renderbuffer->id;
+ key->objects[idx].target = 0;
+ key->objects[idx].level = key->objects[idx].layer = 0;
+ key->rb_namespace |= 1 << idx;
+ return;
}
+
key->objects[idx].target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
key->objects[idx].level = sub_resource_idx % texture->level_count;
key->objects[idx].layer = sub_resource_idx / texture->level_count;
@@ -604,10 +600,7 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
}
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]);
+ wined3d_texture_set_compatible_renderbuffer(ds_texture, ds_level, &render_targets[0]);
}
}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 8d6712b..5a2bf52 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -975,90 +975,6 @@ static HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface,
return WINED3D_OK;
}
-/* In D3D the depth stencil dimensions have to be greater than or equal to the
- * render target dimensions. With FBOs, the dimensions have to be an exact match. */
-/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
-/* Context activation is done by the caller. */
-void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt)
-{
- unsigned int sub_resource_idx, width, height, level;
- struct wined3d_renderbuffer_entry *entry;
- const struct wined3d_texture *texture;
- const struct wined3d_gl_info *gl_info;
- unsigned int src_width, src_height;
- GLuint renderbuffer = 0;
-
- texture = surface->container;
- gl_info = &texture->resource.device->adapter->gl_info;
- sub_resource_idx = surface_get_sub_resource_idx(surface);
- level = sub_resource_idx % texture->level_count;
-
- if (rt && rt->resource->format->id != WINED3DFMT_NULL)
- {
- struct wined3d_texture *rt_texture;
- unsigned int rt_level;
-
- if (rt->resource->type == WINED3D_RTYPE_BUFFER)
- {
- FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
- return;
- }
- rt_texture = wined3d_texture_from_resource(rt->resource);
- rt_level = rt->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);
- }
- else
- {
- width = wined3d_texture_get_level_pow2_width(texture, level);
- height = wined3d_texture_get_level_pow2_height(texture, level);
- }
-
- src_width = wined3d_texture_get_level_pow2_width(texture, level);
- src_height = wined3d_texture_get_level_pow2_height(texture, level);
-
- /* A depth stencil smaller than the render target is not valid */
- if (width > src_width || height > src_height) return;
-
- /* Remove any renderbuffer set if the sizes match */
- if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
- || (width == src_width && height == src_height))
- {
- surface->current_renderbuffer = NULL;
- return;
- }
-
- /* Look if we've already got a renderbuffer of the correct dimensions */
- LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- if (entry->width == width && entry->height == height)
- {
- renderbuffer = entry->id;
- surface->current_renderbuffer = entry;
- break;
- }
- }
-
- if (!renderbuffer)
- {
- gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
- gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
- gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
- texture->resource.format->glInternal, width, height);
-
- entry = heap_alloc(sizeof(*entry));
- entry->width = width;
- entry->height = height;
- entry->id = renderbuffer;
- list_add_head(&surface->renderbuffers, &entry->entry);
-
- surface->current_renderbuffer = entry;
- }
-
- checkGLcall("set_compatible_renderbuffer");
-}
-
/* See also float_16_to_32() in wined3d_private.h */
static inline unsigned short float_32_to_16(const float *in)
{
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 0c0e434..8c03331 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -418,6 +418,8 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS;
}
+ list_init(&texture->renderbuffers);
+
return WINED3D_OK;
}
@@ -654,8 +656,9 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
struct wined3d_device *device = texture->resource.device;
+ struct wined3d_renderbuffer_entry *entry, *entry2;
+ const struct wined3d_gl_info *gl_info = NULL;
struct wined3d_context *context = NULL;
- const struct wined3d_gl_info *gl_info;
GLuint buffer_object;
unsigned int i;
@@ -678,6 +681,21 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture)
GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
}
+
+ if (!context && !list_empty(&texture->renderbuffers))
+ {
+ context = context_acquire(device, NULL, 0);
+ gl_info = context->gl_info;
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ TRACE("Deleting renderbuffer %u.\n", entry->id);
+ context_gl_resource_released(device, entry->id, TRUE);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ heap_free(entry);
+ }
+
if (context)
context_release(context);
@@ -1233,6 +1251,89 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
return WINED3D_OK;
}
+/* In D3D the depth stencil dimensions have to be greater than or equal to the
+ * render target dimensions. With FBOs, the dimensions have to be an exact match. */
+/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
+/* Context activation is done by the caller. */
+void wined3d_texture_set_compatible_renderbuffer(struct wined3d_texture *texture,
+ unsigned int level, const struct wined3d_rendertarget_info *rt)
+{
+ struct wined3d_renderbuffer_entry *entry;
+ const struct wined3d_gl_info *gl_info;
+ unsigned int src_width, src_height;
+ unsigned int width, height;
+ GLuint renderbuffer = 0;
+
+ gl_info = &texture->resource.device->adapter->gl_info;
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
+ return;
+
+ if (rt && rt->resource->format->id != WINED3DFMT_NULL)
+ {
+ struct wined3d_texture *rt_texture;
+ unsigned int rt_level;
+
+ if (rt->resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
+ return;
+ }
+ rt_texture = wined3d_texture_from_resource(rt->resource);
+ rt_level = rt->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);
+ }
+ else
+ {
+ width = wined3d_texture_get_level_pow2_width(texture, level);
+ height = wined3d_texture_get_level_pow2_height(texture, level);
+ }
+
+ src_width = wined3d_texture_get_level_pow2_width(texture, level);
+ src_height = wined3d_texture_get_level_pow2_height(texture, level);
+
+ /* A depth stencil smaller than the render target is not valid */
+ if (width > src_width || height > src_height)
+ return;
+
+ /* Remove any renderbuffer set if the sizes match */
+ if (width == src_width && height == src_height)
+ {
+ texture->current_renderbuffer = NULL;
+ return;
+ }
+
+ /* Look if we've already got a renderbuffer of the correct dimensions */
+ LIST_FOR_EACH_ENTRY(entry, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ if (entry->width == width && entry->height == height)
+ {
+ renderbuffer = entry->id;
+ texture->current_renderbuffer = entry;
+ break;
+ }
+ }
+
+ if (!renderbuffer)
+ {
+ gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
+ texture->resource.format->glInternal, width, height);
+
+ entry = heap_alloc(sizeof(*entry));
+ entry->width = width;
+ entry->height = height;
+ entry->id = renderbuffer;
+ list_add_head(&texture->renderbuffers, &entry->entry);
+
+ texture->current_renderbuffer = entry;
+ }
+
+ checkGLcall("set_compatible_renderbuffer");
+}
+
static void texture2d_create_dc(void *object)
{
struct wined3d_surface *surface = object;
@@ -1738,10 +1839,7 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi
static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
- struct wined3d_device *device = texture->resource.device;
struct wined3d_texture_sub_resource *sub_resource;
- struct wined3d_renderbuffer_entry *entry, *entry2;
- const struct wined3d_gl_info *gl_info = NULL;
struct wined3d_context *context = NULL;
struct wined3d_surface *surface;
unsigned int i;
@@ -1754,20 +1852,6 @@ static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture)
TRACE("surface %p.\n", surface);
- if (!context && !list_empty(&surface->renderbuffers))
- {
- context = context_acquire(device, NULL, 0);
- gl_info = context->gl_info;
- }
-
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- TRACE("Deleting renderbuffer %u.\n", entry->id);
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- heap_free(entry);
- }
-
if (surface->dc)
texture2d_destroy_dc(surface);
}
@@ -1813,6 +1897,7 @@ static void wined3d_texture_unload(struct wined3d_resource *resource)
{
struct wined3d_texture *texture = texture_from_resource(resource);
UINT sub_count = texture->level_count * texture->layer_count;
+ struct wined3d_renderbuffer_entry *entry, *entry2;
struct wined3d_device *device = resource->device;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
@@ -1847,23 +1932,17 @@ static void wined3d_texture_unload(struct wined3d_resource *resource)
if (sub_resource->buffer_object)
wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
+ }
- if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
- {
- struct wined3d_surface *surface = sub_resource->u.surface;
- struct wined3d_renderbuffer_entry *entry, *entry2;
-
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- list_remove(&entry->entry);
- heap_free(entry);
- }
- list_init(&surface->renderbuffers);
- surface->current_renderbuffer = NULL;
- }
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ context_gl_resource_released(device, entry->id, TRUE);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ list_remove(&entry->entry);
+ heap_free(entry);
}
+ list_init(&texture->renderbuffers);
+ texture->current_renderbuffer = NULL;
context_release(context);
@@ -2247,7 +2326,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
surface->container = texture;
surface->texture_level = i;
surface->texture_layer = j;
- list_init(&surface->renderbuffers);
sub_resource = &texture->sub_resources[idx];
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a78055a..d92193d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3154,6 +3154,9 @@ struct wined3d_texture
RECT dst_rect;
} *overlay_info;
+ struct list renderbuffers;
+ const struct wined3d_renderbuffer_entry *current_renderbuffer;
+
struct wined3d_texture_sub_resource
{
void *parent;
@@ -3251,6 +3254,8 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_texture(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
+void wined3d_texture_set_compatible_renderbuffer(struct wined3d_texture *texture,
+ unsigned int level, const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) DECLSPEC_HIDDEN;
void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
@@ -3316,9 +3321,6 @@ struct wined3d_surface
/* For GetDC */
HBITMAP bitmap;
HDC dc;
-
- struct list renderbuffers;
- const struct wined3d_renderbuffer_entry *current_renderbuffer;
};
static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface)
@@ -3338,8 +3340,6 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
struct wined3d_context *context) DECLSPEC_HIDDEN;
BOOL surface_load_location(struct wined3d_surface *surface,
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
-void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
- const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
void wined3d_surface_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
const struct wined3d_gl_info *gl_info, const struct wined3d_format *format, const RECT *src_rect,
unsigned int src_pitch, const POINT *dst_point, BOOL srgb,
--
2.1.4