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:
parent
8e117a51f7
commit
5e27e6b5d8
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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(¤t_rect, 0, 0,
|
||||
ds->ds_current_size.cx,
|
||||
ds->ds_current_size.cy);
|
||||
|
|
|
@ -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(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy);
|
||||
else
|
||||
SetRectEmpty(¤t_rect);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue