Commit 3d21ea08 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Store the EXT_fbo "renderbuffers" list in the texture instead of the surface.

parent 6fd5bce0
......@@ -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]);
}
}
......
......@@ -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)
{
......
......@@ -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;
......
......@@ -3155,6 +3155,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;
......@@ -3252,6 +3255,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;
......@@ -3317,9 +3322,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)
......@@ -3339,8 +3341,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,
......
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