Commit feb86895 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Store renderbuffer IDs in struct wined3d_texture.

parent 599b19a8
......@@ -378,13 +378,13 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context
break;
case WINED3D_LOCATION_RB_MULTISAMPLE:
key->objects[idx].object = surface->rb_multisample;
key->objects[idx].object = surface->container->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].object = surface->container->rb_resolved;
key->objects[idx].level = key->objects[idx].target = 0;
key->rb_namespace |= 1 << idx;
break;
......
......@@ -44,7 +44,7 @@ void wined3d_surface_cleanup(struct wined3d_surface *surface)
TRACE("surface %p.\n", surface);
if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers))
if (!list_empty(&surface->renderbuffers))
{
struct wined3d_device *device = surface->container->resource.device;
struct wined3d_renderbuffer_entry *entry, *entry2;
......@@ -54,20 +54,6 @@ void wined3d_surface_cleanup(struct wined3d_surface *surface)
context = context_acquire(device, NULL);
gl_info = context->gl_info;
if (surface->rb_multisample)
{
TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample);
context_gl_resource_released(device, surface->rb_multisample, TRUE);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample);
}
if (surface->rb_resolved)
{
TRACE("Deleting resolved renderbuffer %u.\n", surface->rb_resolved);
context_gl_resource_released(device, surface->rb_resolved, TRUE);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved);
}
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
{
TRACE("Deleting renderbuffer %u.\n", entry->id);
......@@ -899,19 +885,6 @@ static void surface_unload(struct wined3d_resource *resource)
list_init(&surface->renderbuffers);
surface->current_renderbuffer = NULL;
if (surface->rb_multisample)
{
context_gl_resource_released(device, surface->rb_multisample, TRUE);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample);
surface->rb_multisample = 0;
}
if (surface->rb_resolved)
{
context_gl_resource_released(device, surface->rb_resolved, TRUE);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved);
surface->rb_resolved = 0;
}
context_release(context);
resource_unload(resource);
......@@ -1959,67 +1932,6 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct
context_restore(context, restore_rt);
}
static void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample)
{
struct wined3d_texture *texture = surface->container;
const struct wined3d_format *format = texture->resource.format;
if (multisample)
{
DWORD samples;
if (surface->rb_multisample)
return;
/* TODO: Nvidia exposes their Coverage Sample Anti-Aliasing (CSAA) feature
* through type == MULTISAMPLE_XX and quality != 0. This could be mapped
* to GL_NV_framebuffer_multisample_coverage.
*
* AMD has a similar feature called Enhanced Quality Anti-Aliasing (EQAA),
* but it does not have an equivalent OpenGL extension. */
/* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality levels
* as the count of advertised multisample types for the surface format. */
if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
{
unsigned int i, count = 0;
for (i = 0; i < sizeof(format->multisample_types) * 8; ++i)
{
if (format->multisample_types & 1u << i)
{
if (texture->resource.multisample_quality == count++)
break;
}
}
samples = i + 1;
}
else
{
samples = texture->resource.multisample_type;
}
gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_multisample);
gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_multisample);
gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
format->glInternal, surface->pow2Width, surface->pow2Height);
checkGLcall("glRenderbufferStorageMultisample()");
TRACE("Created multisample rb %u.\n", surface->rb_multisample);
}
else
{
if (surface->rb_resolved)
return;
gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_resolved);
gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_resolved);
gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format->glInternal,
surface->pow2Width, surface->pow2Height);
checkGLcall("glRenderbufferStorage()");
TRACE("Created resolved rb %u.\n", surface->rb_resolved);
}
}
/* Does a direct frame buffer -> texture copy. Stretching is done with single
* pixel copy calls. */
static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
......@@ -4547,11 +4459,11 @@ void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_con
break;
case WINED3D_LOCATION_RB_MULTISAMPLE:
surface_prepare_rb(surface, context->gl_info, TRUE);
wined3d_texture_prepare_rb(texture, context->gl_info, TRUE);
break;
case WINED3D_LOCATION_RB_RESOLVED:
surface_prepare_rb(surface, context->gl_info, FALSE);
wined3d_texture_prepare_rb(texture, context->gl_info, FALSE);
break;
}
}
......@@ -434,7 +434,6 @@ static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct
struct gl_texture tex0;
GLuint rb0;
DWORD locations0;
struct wined3d_surface *surface, *surface_prev;
unsigned int i;
static const DWORD supported_locations = WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_RB_MULTISAMPLE;
......@@ -442,34 +441,31 @@ static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct
return;
texture_prev = swapchain->back_buffers[0];
surface_prev = texture_prev->sub_resources[0].u.surface;
/* Back buffer 0 is already in the draw binding. */
tex0 = texture_prev->texture_rgb;
rb0 = surface_prev->rb_multisample;
rb0 = texture_prev->rb_multisample;
locations0 = texture_prev->sub_resources[0].locations;
for (i = 1; i < swapchain->desc.backbuffer_count; ++i)
{
texture = swapchain->back_buffers[i];
sub_resource = &texture->sub_resources[0];
surface = sub_resource->u.surface;
if (!(sub_resource->locations & supported_locations))
surface_load_location(surface, context, texture->resource.draw_binding);
surface_load_location(sub_resource->u.surface, context, texture->resource.draw_binding);
texture_prev->texture_rgb = texture->texture_rgb;
surface_prev->rb_multisample = surface->rb_multisample;
texture_prev->rb_multisample = texture->rb_multisample;
wined3d_texture_validate_location(texture_prev, 0, sub_resource->locations & supported_locations);
wined3d_texture_invalidate_location(texture_prev, 0, ~(sub_resource->locations & supported_locations));
texture_prev = texture;
surface_prev = surface;
}
texture_prev->texture_rgb = tex0;
surface_prev->rb_multisample = rb0;
texture_prev->rb_multisample = rb0;
wined3d_texture_validate_location(texture_prev, 0, locations0 & supported_locations);
wined3d_texture_invalidate_location(texture_prev, 0, ~(locations0 & supported_locations));
......
......@@ -257,11 +257,14 @@ static void gltexture_delete(struct wined3d_device *device, const struct wined3d
static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture)
{
struct wined3d_device *device = texture->resource.device;
const struct wined3d_gl_info *gl_info = NULL;
struct wined3d_context *context = NULL;
if (texture->texture_rgb.name || texture->texture_srgb.name)
if (texture->texture_rgb.name || texture->texture_srgb.name
|| texture->rb_multisample || texture->rb_resolved)
{
context = context_acquire(device, NULL);
gl_info = context->gl_info;
}
if (texture->texture_rgb.name)
......@@ -270,6 +273,20 @@ static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture)
if (texture->texture_srgb.name)
gltexture_delete(device, context->gl_info, &texture->texture_srgb);
if (texture->rb_multisample)
{
TRACE("Deleting multisample renderbuffer %u.\n", texture->rb_multisample);
context_gl_resource_released(device, texture->rb_multisample, TRUE);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_multisample);
}
if (texture->rb_resolved)
{
TRACE("Deleting resolved renderbuffer %u.\n", texture->rb_resolved);
context_gl_resource_released(device, texture->rb_resolved, TRUE);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_resolved);
}
if (context) context_release(context);
wined3d_texture_set_dirty(texture);
......@@ -1027,6 +1044,68 @@ void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct win
texture->flags |= alloc_flag;
}
void wined3d_texture_prepare_rb(struct wined3d_texture *texture,
const struct wined3d_gl_info *gl_info, BOOL multisample)
{
const struct wined3d_format *format = texture->resource.format;
if (multisample)
{
DWORD samples;
if (texture->rb_multisample)
return;
/* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA)
* feature through type == MULTISAMPLE_XX and quality != 0. This could
* be mapped to GL_NV_framebuffer_multisample_coverage.
*
* AMD have a similar feature called Enhanced Quality Anti-Aliasing
* (EQAA), but it does not have an equivalent OpenGL extension. */
/* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality
* levels as the count of advertised multisample types for the texture
* format. */
if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
{
unsigned int i, count = 0;
for (i = 0; i < sizeof(format->multisample_types) * 8; ++i)
{
if (format->multisample_types & 1u << i)
{
if (texture->resource.multisample_quality == count++)
break;
}
}
samples = i + 1;
}
else
{
samples = texture->resource.multisample_type;
}
gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_multisample);
gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_multisample);
gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
format->glInternal, texture->resource.width, texture->resource.height);
checkGLcall("glRenderbufferStorageMultisample()");
TRACE("Created multisample rb %u.\n", texture->rb_multisample);
}
else
{
if (texture->rb_resolved)
return;
gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_resolved);
gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_resolved);
gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format->glInternal,
texture->resource.width, texture->resource.height);
checkGLcall("glRenderbufferStorage()");
TRACE("Created resolved rb %u.\n", texture->rb_resolved);
}
}
void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture)
{
/* TODO: Implement filters using GL_SGI_generate_mipmaps. */
......
......@@ -2470,6 +2470,9 @@ struct wined3d_texture
DWORD flags;
GLenum target;
GLuint rb_multisample;
GLuint rb_resolved;
void *user_memory;
unsigned int row_pitch;
unsigned int slice_pitch;
......@@ -2565,6 +2568,8 @@ void *wined3d_texture_map_bo_address(const struct wined3d_bo_address *data, size
const struct wined3d_gl_info *gl_info, GLenum binding, DWORD flags) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_rb(struct wined3d_texture *texture,
const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_texture(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
......@@ -2652,8 +2657,6 @@ struct wined3d_surface
UINT pow2Width;
UINT pow2Height;
GLuint rb_multisample;
GLuint rb_resolved;
GLenum texture_target;
unsigned int texture_level;
unsigned int texture_layer;
......
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