Commit 5e27e6b5 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

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

parent 8e117a51
......@@ -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(&current_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(&current_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy);
else
SetRectEmpty(&current_rect);
......
......@@ -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)
{
struct wined3d_const_bo_address data =
else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
{
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))
{
struct wined3d_bo_address data =
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
{
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)
{
......
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