wined3d: Store sub-resource locations in the sub-resource structure.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Stefan Dösinger 2016-03-28 18:58:01 +02:00 committed by Alexandre Julliard
parent 8e117a51f7
commit 5e27e6b5d8
8 changed files with 138 additions and 108 deletions

View File

@ -7884,7 +7884,8 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_
/* Now load the surface */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
&& (src_surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE))
&& (surface_get_sub_resource(src_surface)->locations
& (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE))
== WINED3D_LOCATION_DRAWABLE
&& !wined3d_resource_is_offscreen(&src_texture->resource))
{

View File

@ -234,9 +234,10 @@ static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw
static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context *context,
DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect, RECT *out_rect)
{
struct wined3d_texture_sub_resource *sub_resource = surface_get_sub_resource(ds);
RECT current_rect, r;
if (ds->locations & WINED3D_LOCATION_DISCARDED)
if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
{
/* Depth buffer was discarded, make it entirely current in its new location since
* there is no other place where we would get data anyway. */
@ -244,7 +245,7 @@ static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context
return;
}
if (ds->locations & location)
if (sub_resource->locations & location)
SetRect(&current_rect, 0, 0,
ds->ds_current_size.cx,
ds->ds_current_size.cy);

View File

@ -652,7 +652,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
if (!context->render_offscreen && ds != device->onscreen_depth_stencil)
device_switch_onscreen_ds(device, context, ds);
if (ds->locations & location)
if (surface_get_sub_resource(ds)->locations & location)
SetRect(&current_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy);
else
SetRectEmpty(&current_rect);

View File

@ -40,11 +40,6 @@ static const DWORD surface_simple_locations =
WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY
| WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER;
static unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface)
{
return surface->texture_layer * surface->container->level_count + surface->texture_level;
}
void wined3d_surface_cleanup(struct wined3d_surface *surface)
{
struct wined3d_surface *overlay, *cur;
@ -502,7 +497,7 @@ static void surface_prepare_system_memory(struct wined3d_surface *surface)
if (!wined3d_resource_allocate_sysmem(&surface->resource))
ERR("Failed to allocate system memory.\n");
if (surface->locations & WINED3D_LOCATION_SYSMEM)
if (surface_get_sub_resource(surface)->locations & WINED3D_LOCATION_SYSMEM)
ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n");
}
@ -1363,7 +1358,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
surface_get_memory(src_surface, &data, src_surface->locations);
surface_get_memory(src_surface, &data, surface_get_sub_resource(src_surface)->locations);
wined3d_texture_get_pitch(src_texture, src_surface->texture_level, &src_row_pitch, &src_slice_pitch);
wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect,
@ -1454,7 +1449,7 @@ void surface_load(struct wined3d_surface *surface, struct wined3d_context *conte
if (surface->container->resource.pool == WINED3D_POOL_SCRATCH)
ERR("Not supported on scratch surfaces.\n");
if (surface->locations & location)
if (surface_get_sub_resource(surface)->locations & location)
{
TRACE("surface is already in texture\n");
return;
@ -2238,7 +2233,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
checkGLcall("glEnable(texture_target)");
/* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */
src_surface->locations &= ~WINED3D_LOCATION_TEXTURE_RGB;
surface_get_sub_resource(src_surface)->locations &= ~WINED3D_LOCATION_TEXTURE_RGB;
}
/* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
@ -2784,15 +2779,19 @@ static void surface_depth_blt(const struct wined3d_surface *surface, struct wine
void surface_modify_ds_location(struct wined3d_surface *surface,
DWORD location, UINT w, UINT h)
{
struct wined3d_texture_sub_resource *sub_resource;
TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h);
if (((surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB))
|| (!(surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && (location & WINED3D_LOCATION_TEXTURE_RGB)))
sub_resource = surface_get_sub_resource(surface);
if (((sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB))
|| (!(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
&& (location & WINED3D_LOCATION_TEXTURE_RGB)))
wined3d_texture_set_dirty(surface->container);
surface->ds_current_size.cx = w;
surface->ds_current_size.cy = h;
surface->locations = location;
sub_resource->locations = location;
}
/* Context activation is done by the caller. */
@ -2808,7 +2807,7 @@ static void surface_load_ds_location(struct wined3d_surface *surface, struct win
/* TODO: Make this work for modes other than FBO */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return;
if (!(surface->locations & location))
if (!(surface_get_sub_resource(surface)->locations & location))
{
w = surface->ds_current_size.cx;
h = surface->ds_current_size.cy;
@ -2916,18 +2915,21 @@ void surface_validate_location(struct wined3d_surface *surface, DWORD location)
{
TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location));
surface->locations |= location;
surface_get_sub_resource(surface)->locations |= location;
}
void surface_invalidate_location(struct wined3d_surface *surface, DWORD location)
{
struct wined3d_texture_sub_resource *sub_resource;
TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location));
sub_resource = surface_get_sub_resource(surface);
if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
wined3d_texture_set_dirty(surface->container);
surface->locations &= ~location;
sub_resource->locations &= ~location;
if (!surface->locations)
if (!sub_resource->locations)
ERR("Surface %p does not have any up to date location.\n", surface);
}
@ -2963,7 +2965,7 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD
UINT size = surface->resource.size;
surface_get_memory(surface, &dst, location);
surface_get_memory(surface, &src, surface->locations);
surface_get_memory(surface, &src, surface_get_sub_resource(surface)->locations);
if (dst.buffer_object)
{
@ -2995,39 +2997,41 @@ static void surface_load_sysmem(struct wined3d_surface *surface,
struct wined3d_context *context, DWORD dst_location)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_texture_sub_resource *sub_resource;
wined3d_surface_prepare(surface, context, dst_location);
if (surface->locations & surface_simple_locations)
sub_resource = surface_get_sub_resource(surface);
if (sub_resource->locations & surface_simple_locations)
{
surface_copy_simple_location(surface, dst_location);
return;
}
if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
/* Download the surface to system memory. */
if (surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
struct wined3d_texture *texture = surface->container;
wined3d_texture_bind_and_dirtify(texture, context,
!(surface->locations & WINED3D_LOCATION_TEXTURE_RGB));
!(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
surface_download_data(surface, gl_info, dst_location);
++texture->download_count;
return;
}
if (surface->locations & WINED3D_LOCATION_DRAWABLE)
if (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)
{
read_from_framebuffer(surface, context, dst_location);
return;
}
FIXME("Can't load surface %p with location flags %s into sysmem.\n",
surface, wined3d_debug_location(surface->locations));
surface, wined3d_debug_location(sub_resource->locations));
}
/* Context activation is done by the caller. */
@ -3061,21 +3065,23 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
struct wined3d_texture *texture = surface->container;
struct wined3d_device *device = texture->resource.device;
const struct wined3d_color_key_conversion *conversion;
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_bo_address data;
struct wined3d_format format;
POINT dst_point = {0, 0};
BYTE *mem = NULL;
sub_resource = surface_get_sub_resource(surface);
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
&& wined3d_resource_is_offscreen(&texture->resource)
&& (surface->locations & WINED3D_LOCATION_DRAWABLE))
&& (sub_resource->locations & WINED3D_LOCATION_DRAWABLE))
{
surface_load_fb_texture(surface, srgb, context);
return WINED3D_OK;
}
if (surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
&& (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
&& fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
NULL, texture->resource.usage, texture->resource.pool, texture->resource.format,
@ -3091,13 +3097,13 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
return WINED3D_OK;
}
if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)
if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)
&& (!srgb || (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))
&& fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
NULL, texture->resource.usage, texture->resource.pool, texture->resource.format,
NULL, texture->resource.usage, texture->resource.pool, texture->resource.format))
{
DWORD src_location = surface->locations & WINED3D_LOCATION_RB_RESOLVED ?
DWORD src_location = sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED ?
WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE;
DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
RECT rect = {0, 0, surface->resource.width, surface->resource.height};
@ -3112,7 +3118,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
if (srgb)
{
if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding))
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding))
== WINED3D_LOCATION_TEXTURE_RGB)
{
/* Performance warning... */
@ -3122,7 +3128,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
}
else
{
if ((surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->resource.map_binding))
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->resource.map_binding))
== WINED3D_LOCATION_TEXTURE_SRGB)
{
/* Performance warning... */
@ -3131,7 +3137,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
}
}
if (!(surface->locations & surface_simple_locations))
if (!(sub_resource->locations & surface_simple_locations))
{
WARN("Trying to load a texture from sysmem, but no simple location is valid.\n");
/* Lets hope we get it from somewhere... */
@ -3165,7 +3171,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
wined3d_texture_remove_buffer_object(texture, surface_get_sub_resource_idx(surface), gl_info);
}
surface_get_memory(surface, &data, surface->locations);
surface_get_memory(surface, &data, sub_resource->locations);
if (format.convert)
{
/* This code is entered for texture formats which need a fixup. */
@ -3221,13 +3227,14 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi
DWORD dst_location)
{
const RECT rect = {0, 0, surface->resource.width, surface->resource.height};
DWORD locations = surface_get_sub_resource(surface)->locations;
DWORD src_location;
if (surface->locations & WINED3D_LOCATION_RB_MULTISAMPLE)
if (locations & WINED3D_LOCATION_RB_MULTISAMPLE)
src_location = WINED3D_LOCATION_RB_MULTISAMPLE;
else if (surface->locations & WINED3D_LOCATION_RB_RESOLVED)
else if (locations & WINED3D_LOCATION_RB_RESOLVED)
src_location = WINED3D_LOCATION_RB_RESOLVED;
else if (surface->locations & WINED3D_LOCATION_TEXTURE_SRGB)
else if (locations & WINED3D_LOCATION_TEXTURE_SRGB)
src_location = WINED3D_LOCATION_TEXTURE_SRGB;
else /* surface_blt_fbo will load the source location if necessary. */
src_location = WINED3D_LOCATION_TEXTURE_RGB;
@ -3239,12 +3246,13 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi
/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */
HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location)
{
struct wined3d_texture_sub_resource *sub_resource = surface_get_sub_resource(surface);
struct wined3d_texture *texture = surface->container;
HRESULT hr;
TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location));
if (surface->locations & location && (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
if (sub_resource->locations & location && (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
|| (surface->ds_current_size.cx == surface->resource.width
&& surface->ds_current_size.cy == surface->resource.height)))
{
@ -3260,7 +3268,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co
required_access, texture->resource.access_flags);
}
if (surface->locations & WINED3D_LOCATION_DISCARDED)
if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
{
TRACE("Surface previously discarded, nothing to do.\n");
wined3d_surface_prepare(surface, context, location);
@ -3269,7 +3277,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co
goto done;
}
if (!surface->locations)
if (!sub_resource->locations)
{
ERR("Surface %p does not have any up to date location.\n", surface);
surface_validate_location(surface, WINED3D_LOCATION_DISCARDED);
@ -3278,15 +3286,15 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co
if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
{
if ((location == WINED3D_LOCATION_TEXTURE_RGB && surface->locations & WINED3D_LOCATION_DRAWABLE)
|| (location == WINED3D_LOCATION_DRAWABLE && surface->locations & WINED3D_LOCATION_TEXTURE_RGB))
if ((location == WINED3D_LOCATION_TEXTURE_RGB && sub_resource->locations & WINED3D_LOCATION_DRAWABLE)
|| (location == WINED3D_LOCATION_DRAWABLE && sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB))
{
surface_load_ds_location(surface, context, location);
goto done;
}
FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n",
wined3d_debug_location(surface->locations), wined3d_debug_location(location));
wined3d_debug_location(sub_resource->locations), wined3d_debug_location(location));
return WINED3DERR_INVALIDCALL;
}
@ -3330,7 +3338,7 @@ done:
surface->ds_current_size.cy = surface->resource.height;
}
if (location != WINED3D_LOCATION_SYSMEM && (surface->locations & WINED3D_LOCATION_SYSMEM))
if (location != WINED3D_LOCATION_SYSMEM && (sub_resource->locations & WINED3D_LOCATION_SYSMEM))
surface_evict_sysmem(surface);
return WINED3D_OK;
@ -4349,12 +4357,16 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
}
else
{
struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource;
const struct blit_shader *blitter;
dst_sub_resource = surface_get_sub_resource(dst_surface);
src_sub_resource = src_surface ? surface_get_sub_resource(src_surface) : NULL;
/* In principle this would apply to depth blits as well, but we don't
* implement those in the CPU blitter at the moment. */
if ((dst_surface->locations & dst_surface->resource.map_binding)
&& (!src_surface || (src_surface->locations & src_surface->resource.map_binding)))
if ((dst_sub_resource->locations & dst_surface->resource.map_binding)
&& (!src_surface || (src_sub_resource->locations & src_surface->resource.map_binding)))
{
if (scale)
TRACE("Not doing sysmem blit because of scaling.\n");
@ -4398,8 +4410,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
{
blit_op = WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST;
}
else if ((src_surface->locations & WINED3D_LOCATION_SYSMEM)
&& !(dst_surface->locations & WINED3D_LOCATION_SYSMEM))
else if ((src_sub_resource->locations & WINED3D_LOCATION_SYSMEM)
&& !(dst_sub_resource->locations & WINED3D_LOCATION_SYSMEM))
{
/* Upload */
if (scale)
@ -4560,7 +4572,10 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
}
surface->container = container;
surface_validate_location(surface, WINED3D_LOCATION_SYSMEM);
surface->texture_target = target;
surface->texture_level = level;
surface->texture_layer = layer;
list_init(&surface->renderbuffers);
list_init(&surface->overlays);
@ -4570,12 +4585,9 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
if (lockable || desc->format == WINED3DFMT_D16_LOCKABLE)
surface->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU;
surface->texture_target = target;
surface->texture_level = level;
surface->texture_layer = layer;
surface_validate_location(surface, WINED3D_LOCATION_SYSMEM);
if (container->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
surface->locations = WINED3D_LOCATION_DISCARDED;
surface_get_sub_resource(surface)->locations = WINED3D_LOCATION_DISCARDED;
if (wined3d_texture_use_pbo(container, gl_info))
surface->resource.map_binding = WINED3D_LOCATION_BUFFER;

View File

@ -429,6 +429,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
/* Context activation is done by the caller. */
static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct wined3d_context *context)
{
struct wined3d_texture_sub_resource *sub_resource;
struct gl_texture tex0;
GLuint rb0;
DWORD locations0;
@ -439,25 +440,26 @@ static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct
if (swapchain->desc.backbuffer_count < 2 || !swapchain->render_to_fbo)
return;
surface_prev = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0));
surface_prev = swapchain->back_buffers[0]->sub_resources[0].u.surface;
/* Back buffer 0 is already in the draw binding. */
tex0 = swapchain->back_buffers[0]->texture_rgb;
rb0 = surface_prev->rb_multisample;
locations0 = surface_prev->locations;
locations0 = surface_get_sub_resource(surface_prev)->locations;
for (i = 1; i < swapchain->desc.backbuffer_count; ++i)
{
surface = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[i], 0));
sub_resource = &swapchain->back_buffers[i]->sub_resources[0];
surface = sub_resource->u.surface;
if (!(surface->locations & supported_locations))
if (!(sub_resource->locations & supported_locations))
surface_load_location(surface, context, swapchain->back_buffers[i]->resource.draw_binding);
swapchain->back_buffers[i - 1]->texture_rgb = swapchain->back_buffers[i]->texture_rgb;
surface_prev->rb_multisample = surface->rb_multisample;
surface_validate_location(surface_prev, surface->locations & supported_locations);
surface_invalidate_location(surface_prev, ~(surface->locations & supported_locations));
surface_validate_location(surface_prev, sub_resource->locations & supported_locations);
surface_invalidate_location(surface_prev, ~(sub_resource->locations & supported_locations));
surface_prev = surface;
}

View File

@ -735,6 +735,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_surface *surface;
DWORD valid_location = 0;
BOOL create_dib = FALSE;
@ -771,8 +772,9 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
return WINED3DERR_INVALIDCALL;
}
surface = texture->sub_resources[0].u.surface;
if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE))
sub_resource = &texture->sub_resources[0];
surface = sub_resource->u.surface;
if (sub_resource->resource->map_count || (surface->flags & SFLAG_DCINUSE))
{
WARN("Surface is mapped or the DC is in use.\n");
return WINED3DERR_INVALIDCALL;
@ -792,7 +794,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
create_dib = TRUE;
}
wined3d_resource_free_sysmem(&surface->resource);
wined3d_resource_free_sysmem(sub_resource->resource);
if ((texture->row_pitch = pitch))
texture->slice_pitch = height * pitch;
@ -807,12 +809,12 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
texture->resource.width = width;
texture->resource.height = height;
surface->resource.format = format;
surface->resource.multisample_type = multisample_type;
surface->resource.multisample_quality = multisample_quality;
surface->resource.width = width;
surface->resource.height = height;
surface->resource.size = texture->slice_pitch;
sub_resource->resource->format = format;
sub_resource->resource->multisample_type = multisample_type;
sub_resource->resource->multisample_quality = multisample_quality;
sub_resource->resource->width = width;
sub_resource->resource->height = height;
sub_resource->resource->size = texture->slice_pitch;
if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
&& !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
@ -831,11 +833,11 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
surface->pow2Height = height;
}
surface->locations = 0;
sub_resource->locations = 0;
if ((texture->user_memory = mem))
{
surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
sub_resource->resource->map_binding = WINED3D_LOCATION_USER_MEMORY;
valid_location = WINED3D_LOCATION_USER_MEMORY;
}
else if (create_dib && SUCCEEDED(surface_create_dib_section(surface)))
@ -852,8 +854,8 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
* If the surface didn't use PBOs previously but could now, don't
* change it - whatever made us not use PBOs might come back, e.g.
* color keys. */
if (surface->resource.map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info))
surface->resource.map_binding = surface->dib.DIBsection ? WINED3D_LOCATION_DIB : WINED3D_LOCATION_SYSMEM;
if (sub_resource->resource->map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info))
sub_resource->resource->map_binding = surface->dib.DIBsection ? WINED3D_LOCATION_DIB : WINED3D_LOCATION_SYSMEM;
surface_validate_location(surface, valid_location);
@ -1420,7 +1422,8 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso
{
struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
if (!(surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)))
if (!(surface_get_sub_resource(surface)->locations
& (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)))
texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(texture->swapchain);
}
else if (resource->format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))

View File

@ -132,20 +132,28 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location)
{
struct wined3d_texture_sub_resource *sub_resource;
TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location));
volume->locations |= location;
TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations));
sub_resource = &volume->container->sub_resources[volume->texture_level];
sub_resource->locations |= location;
TRACE("new location flags are %s.\n", wined3d_debug_location(sub_resource->locations));
}
void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location)
{
struct wined3d_texture_sub_resource *sub_resource;
TRACE("Volume %p, clearing %s.\n", volume, wined3d_debug_location(location));
sub_resource = &volume->container->sub_resources[volume->texture_level];
if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
wined3d_texture_set_dirty(volume->container);
volume->locations &= ~location;
sub_resource->locations &= ~location;
TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations));
TRACE("new location flags are %s.\n", wined3d_debug_location(sub_resource->locations));
}
/* Context activation is done by the caller. */
@ -253,11 +261,13 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
{
DWORD required_access = volume_access_from_location(location);
struct wined3d_texture *texture = volume->container;
struct wined3d_texture_sub_resource *sub_resource;
sub_resource = &texture->sub_resources[volume->texture_level];
TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location),
wined3d_debug_location(volume->locations));
wined3d_debug_location(sub_resource->locations));
if ((volume->locations & location) == location)
if ((sub_resource->locations & location) == location)
{
TRACE("Location(s) already up to date.\n");
return TRUE;
@ -273,7 +283,7 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
if (!wined3d_volume_prepare_location(volume, context, location))
return FALSE;
if (volume->locations & WINED3D_LOCATION_DISCARDED)
if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
{
TRACE("Volume previously discarded, nothing to do.\n");
wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED);
@ -284,45 +294,41 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
{
case WINED3D_LOCATION_TEXTURE_RGB:
case WINED3D_LOCATION_TEXTURE_SRGB:
if (volume->locations & WINED3D_LOCATION_SYSMEM)
if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
{
struct wined3d_const_bo_address data = {0, volume->resource.heap_memory};
wined3d_texture_bind_and_dirtify(texture, context,
location == WINED3D_LOCATION_TEXTURE_SRGB);
wined3d_volume_upload_data(volume, context, &data);
}
else if (volume->locations & WINED3D_LOCATION_BUFFER)
else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
{
struct wined3d_const_bo_address data =
{
texture->sub_resources[volume->texture_level].buffer_object,
NULL
};
struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
wined3d_texture_bind_and_dirtify(texture, context,
location == WINED3D_LOCATION_TEXTURE_SRGB);
wined3d_volume_upload_data(volume, context, &data);
}
else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
{
wined3d_volume_srgb_transfer(volume, context, TRUE);
}
else if (volume->locations & WINED3D_LOCATION_TEXTURE_SRGB)
else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
{
wined3d_volume_srgb_transfer(volume, context, FALSE);
}
else
{
FIXME("Implement texture loading from %s.\n", wined3d_debug_location(volume->locations));
FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
return FALSE;
}
break;
case WINED3D_LOCATION_SYSMEM:
if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
struct wined3d_bo_address data = {0, volume->resource.heap_memory};
if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
else
wined3d_texture_bind_and_dirtify(texture, context, TRUE);
@ -333,21 +339,17 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
else
{
FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
wined3d_debug_location(volume->locations));
wined3d_debug_location(sub_resource->locations));
return FALSE;
}
break;
case WINED3D_LOCATION_BUFFER:
if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
struct wined3d_bo_address data =
{
texture->sub_resources[volume->texture_level].buffer_object,
NULL
};
struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
else
wined3d_texture_bind_and_dirtify(texture, context, TRUE);
@ -357,14 +359,14 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
else
{
FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
wined3d_debug_location(volume->locations));
wined3d_debug_location(sub_resource->locations));
return FALSE;
}
break;
default:
FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
wined3d_debug_location(volume->locations));
wined3d_debug_location(sub_resource->locations));
return FALSE;
}
@ -488,7 +490,7 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur
}
volume->texture_level = level;
volume->locations = WINED3D_LOCATION_DISCARDED;
container->sub_resources[level].locations = WINED3D_LOCATION_DISCARDED;
if (wined3d_texture_use_pbo(container, gl_info))
{

View File

@ -2417,7 +2417,7 @@ struct wined3d_texture
DWORD color_key_flags;
} async;
struct
struct wined3d_texture_sub_resource
{
struct wined3d_resource *resource;
union
@ -2426,6 +2426,7 @@ struct wined3d_texture
struct wined3d_volume *volume;
} u;
DWORD locations;
GLuint buffer_object;
} sub_resources[1];
};
@ -2502,7 +2503,6 @@ struct wined3d_volume
struct wined3d_resource resource;
struct wined3d_texture *container;
DWORD locations;
GLint texture_level;
};
@ -2567,7 +2567,6 @@ struct wined3d_surface
{
struct wined3d_resource resource;
struct wined3d_texture *container;
DWORD locations;
DWORD flags;
@ -2606,6 +2605,16 @@ static inline BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *
&& context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL;
}
static inline unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface)
{
return surface->texture_layer * surface->container->level_count + surface->texture_level;
}
static inline struct wined3d_texture_sub_resource *surface_get_sub_resource(struct wined3d_surface *surface)
{
return &surface->container->sub_resources[surface_get_sub_resource_idx(surface)];
}
static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface,
const struct wined3d_context *context, BOOL srgb)
{