Commit 16ff4e7c authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Track the map binding per-texture.

parent feb86895
......@@ -363,7 +363,7 @@ void wined3d_surface_destroy_dc(struct wined3d_surface *surface)
gl_info = context->gl_info;
}
wined3d_texture_get_memory(texture, sub_resource_idx, &data, surface->resource.map_binding);
wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
wined3d_texture_unmap_bo_address(&data, gl_info, GL_PIXEL_UNPACK_BUFFER);
if (context)
......@@ -399,7 +399,7 @@ HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface)
gl_info = context->gl_info;
}
wined3d_texture_get_memory(texture, sub_resource_idx, &data, surface->resource.map_binding);
wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
desc.pMemory = wined3d_texture_map_bo_address(&data, surface->resource.size,
gl_info, GL_PIXEL_UNPACK_BUFFER, 0);
......@@ -867,8 +867,8 @@ static void surface_unload(struct wined3d_resource *resource)
}
else
{
surface_load_location(surface, context, surface->resource.map_binding);
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~surface->resource.map_binding);
surface_load_location(surface, context, texture->resource.map_binding);
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
}
/* Destroy fbo render buffers. This is needed for implicit render targets, for
......@@ -2936,9 +2936,9 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
const struct wined3d_color_key_conversion *conversion;
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_bo_address data;
BYTE *src_mem, *dst_mem = NULL;
struct wined3d_format format;
POINT dst_point = {0, 0};
BYTE *mem = NULL;
RECT src_rect;
sub_resource = surface_get_sub_resource(surface);
......@@ -2991,22 +2991,22 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
if (srgb)
{
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding))
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | texture->resource.map_binding))
== WINED3D_LOCATION_TEXTURE_RGB)
{
/* Performance warning... */
FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface);
surface_load_location(surface, context, surface->resource.map_binding);
surface_load_location(surface, context, texture->resource.map_binding);
}
}
else
{
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->resource.map_binding))
if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | texture->resource.map_binding))
== WINED3D_LOCATION_TEXTURE_SRGB)
{
/* Performance warning... */
FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface);
surface_load_location(surface, context, surface->resource.map_binding);
surface_load_location(surface, context, texture->resource.map_binding);
}
}
......@@ -3032,9 +3032,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
{
TRACE("Removing the pbo attached to surface %p.\n", surface);
surface->resource.map_binding = WINED3D_LOCATION_SYSMEM;
surface_load_location(surface, context, surface->resource.map_binding);
wined3d_texture_remove_buffer_object(texture, sub_resource_idx, gl_info);
surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM);
wined3d_texture_set_map_binding(texture, WINED3D_LOCATION_SYSMEM);
}
wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations);
......@@ -3044,16 +3043,21 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
format.byte_count = format.conv_byte_count;
wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch);
if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
src_mem = wined3d_texture_map_bo_address(&data, src_slice_pitch,
gl_info, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READONLY);
if (!(dst_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
{
ERR("Out of memory (%u).\n", dst_slice_pitch);
context_release(context);
return E_OUTOFMEMORY;
}
format.convert(data.addr, mem, src_row_pitch, src_slice_pitch,
format.convert(src_mem, dst_mem, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, width, height, 1);
src_row_pitch = dst_row_pitch;
data.addr = mem;
wined3d_texture_unmap_bo_address(&data, gl_info, GL_PIXEL_UNPACK_BUFFER);
data.buffer_object = 0;
data.addr = dst_mem;
}
else if (conversion)
{
......@@ -3063,7 +3067,9 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
wined3d_format_calculate_pitch(&format, device->surface_alignment,
width, height, &dst_row_pitch, &dst_slice_pitch);
if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
src_mem = wined3d_texture_map_bo_address(&data, src_slice_pitch,
gl_info, GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READONLY);
if (!(dst_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
{
ERR("Out of memory (%u).\n", dst_slice_pitch);
context_release(context);
......@@ -3071,16 +3077,19 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
}
if (texture->swapchain && texture->swapchain->palette)
palette = texture->swapchain->palette;
conversion->convert(data.addr, src_row_pitch, mem, dst_row_pitch,
conversion->convert(src_mem, src_row_pitch, dst_mem, dst_row_pitch,
width, height, palette, &texture->async.gl_color_key);
src_row_pitch = dst_row_pitch;
data.addr = mem;
wined3d_texture_unmap_bo_address(&data, gl_info, GL_PIXEL_UNPACK_BUFFER);
data.buffer_object = 0;
data.addr = dst_mem;
}
wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
HeapFree(GetProcessHeap(), 0, mem);
HeapFree(GetProcessHeap(), 0, dst_mem);
return WINED3D_OK;
}
......@@ -4249,8 +4258,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
/* 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_sub_resource->locations & dst_surface->resource.map_binding)
&& (!src_texture || (src_sub_resource->locations & src_surface->resource.map_binding)))
if ((dst_sub_resource->locations & dst_texture->resource.map_binding)
&& (!src_texture || (src_sub_resource->locations & src_texture->resource.map_binding)))
{
if (scale)
TRACE("Not doing sysmem blit because of scaling.\n");
......@@ -4422,9 +4431,6 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
if (container->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
container->sub_resources[sub_resource_idx].locations = WINED3D_LOCATION_DISCARDED;
if (wined3d_texture_use_pbo(container, gl_info))
surface->resource.map_binding = WINED3D_LOCATION_BUFFER;
return hr;
}
......
......@@ -28,7 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
{
return texture->resource.pool == WINED3D_POOL_DEFAULT
&& texture->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU
......@@ -230,7 +230,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
}
/* Context activation is done by the caller. */
void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
{
GLuint *buffer_object;
......@@ -245,6 +245,40 @@ void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
*buffer_object, texture, sub_resource_idx);
}
static void wined3d_texture_update_map_binding(struct wined3d_texture *texture)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
const struct wined3d_device *device = texture->resource.device;
DWORD map_binding = texture->update_map_binding;
struct wined3d_context *context = NULL;
unsigned int i;
if (device->d3d_initialized)
context = context_acquire(device, NULL);
for (i = 0; i < sub_count; ++i)
{
if (texture->sub_resources[i].locations == texture->resource.map_binding
&& !texture->texture_ops->texture_load_location(texture, i, context, map_binding))
ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER)
wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
}
if (context)
context_release(context);
texture->resource.map_binding = map_binding;
texture->update_map_binding = 0;
}
void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding)
{
texture->update_map_binding = map_binding;
if (!texture->resource.map_count)
wined3d_texture_update_map_binding(texture);
}
/* A GL context is provided by the caller */
static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info,
struct gl_texture *tex)
......@@ -692,12 +726,10 @@ void wined3d_texture_load(struct wined3d_texture *texture,
TRACE("Reloading because of color key value change.\n");
for (i = 0; i < sub_count; i++)
{
struct wined3d_resource *sub_resource = texture->sub_resources[i].resource;
if (!texture->texture_ops->texture_load_location(texture, i, context, sub_resource->map_binding))
ERR("Failed to load location %s.\n", wined3d_debug_location(sub_resource->map_binding));
if (!texture->texture_ops->texture_load_location(texture, i, context, texture->resource.map_binding))
ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding));
else
wined3d_texture_invalidate_location(texture, i, ~sub_resource->map_binding);
wined3d_texture_invalidate_location(texture, i, ~texture->resource.map_binding);
}
texture->async.gl_color_key = texture->async.src_blt_color_key;
......@@ -962,7 +994,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
if ((texture->user_memory = mem))
{
sub_resource->resource->map_binding = WINED3D_LOCATION_USER_MEMORY;
texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
valid_location = WINED3D_LOCATION_USER_MEMORY;
}
else
......@@ -975,8 +1007,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 (sub_resource->resource->map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info))
sub_resource->resource->map_binding = WINED3D_LOCATION_SYSMEM;
if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info))
texture->resource.map_binding = WINED3D_LOCATION_SYSMEM;
wined3d_texture_validate_location(texture, 0, valid_location);
......@@ -1131,31 +1163,30 @@ struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct win
HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
UINT layer, const struct wined3d_box *dirty_region)
{
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_context *context;
unsigned int sub_resource_idx;
TRACE("texture %p, layer %u, dirty_region %s.\n", texture, layer, debug_box(dirty_region));
sub_resource_idx = layer * texture->level_count;
if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
if (layer >= texture->layer_count)
{
WARN("Failed to get sub-resource.\n");
WARN("Invalid layer %u specified.\n", layer);
return WINED3DERR_INVALIDCALL;
}
sub_resource_idx = layer * texture->level_count;
if (dirty_region)
FIXME("Ignoring dirty_region %s.\n", debug_box(dirty_region));
context = context_acquire(texture->resource.device, NULL);
if (!texture->texture_ops->texture_load_location(texture, sub_resource_idx,
context, sub_resource->resource->map_binding))
context, texture->resource.map_binding))
{
ERR("Failed to load location %s.\n", wined3d_debug_location(sub_resource->resource->map_binding));
ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding));
context_release(context);
return E_OUTOFMEMORY;
}
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~sub_resource->resource->map_binding);
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
context_release(context);
return WINED3D_OK;
......@@ -1421,17 +1452,17 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
if (flags & WINED3D_MAP_DISCARD)
{
TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n",
wined3d_debug_location(sub_resource->resource->map_binding));
wined3d_debug_location(texture->resource.map_binding));
if ((ret = texture->texture_ops->texture_prepare_location(texture,
sub_resource_idx, context, sub_resource->resource->map_binding)))
wined3d_texture_validate_location(texture, sub_resource_idx, sub_resource->resource->map_binding);
sub_resource_idx, context, texture->resource.map_binding)))
wined3d_texture_validate_location(texture, sub_resource_idx, texture->resource.map_binding);
}
else
{
if (resource->usage & WINED3DUSAGE_DYNAMIC)
WARN_(d3d_perf)("Mapping a dynamic texture without WINED3D_MAP_DISCARD.\n");
ret = texture->texture_ops->texture_load_location(texture,
sub_resource_idx, context, sub_resource->resource->map_binding);
sub_resource_idx, context, texture->resource.map_binding);
}
if (!ret)
......@@ -1442,9 +1473,9 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
}
if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~sub_resource->resource->map_binding);
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->resource->map_binding);
wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
base_memory = wined3d_texture_map_bo_address(&data, sub_resource->resource->size,
gl_info, GL_PIXEL_UNPACK_BUFFER, flags);
TRACE("Base memory pointer %p.\n", base_memory);
......@@ -1535,7 +1566,7 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso
gl_info = context->gl_info;
}
wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->resource->map_binding);
wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
wined3d_texture_unmap_bo_address(&data, gl_info, GL_PIXEL_UNPACK_BUFFER);
if (context)
......@@ -1552,7 +1583,8 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso
}
--sub_resource->map_count;
--resource->map_count;
if (!--resource->map_count && texture->update_map_binding)
wined3d_texture_update_map_binding(texture);
return WINED3D_OK;
}
......@@ -1713,6 +1745,9 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
texture->pow2_matrix[15] = 1.0f;
TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
if (wined3d_texture_use_pbo(texture, gl_info))
texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
if (!(surfaces = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*surfaces) * level_count * layer_count)))
{
wined3d_texture_cleanup(texture);
......@@ -1977,6 +2012,9 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
texture->pow2_matrix[15] = 1.0f;
texture->target = GL_TEXTURE_3D;
if (wined3d_texture_use_pbo(texture, gl_info))
texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
if (!(volumes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*volumes) * levels)))
{
wined3d_texture_cleanup(texture);
......@@ -2346,8 +2384,8 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
if (device->d3d_initialized)
context = context_acquire(device, NULL);
surface_load_location(surface, context, surface->resource.map_binding);
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~surface->resource.map_binding);
surface_load_location(surface, context, texture->resource.map_binding);
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
if (!surface->dc)
hr = wined3d_surface_create_dc(surface);
......@@ -2399,7 +2437,8 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign
wined3d_surface_destroy_dc(surface);
--sub_resource->map_count;
--texture->resource.map_count;
if (!--texture->resource.map_count && texture->update_map_binding)
wined3d_texture_update_map_binding(texture);
if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
texture->flags &= ~WINED3D_TEXTURE_DC_IN_USE;
......
......@@ -451,15 +451,12 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur
return hr;
}
if (container->resource.map_binding == WINED3D_LOCATION_BUFFER)
wined3d_resource_free_sysmem(&volume->resource);
volume->texture_level = level;
container->sub_resources[level].locations = WINED3D_LOCATION_DISCARDED;
if (wined3d_texture_use_pbo(container, gl_info))
{
wined3d_resource_free_sysmem(&volume->resource);
volume->resource.map_binding = WINED3D_LOCATION_BUFFER;
}
volume->container = container;
return WINED3D_OK;
......
......@@ -2469,6 +2469,7 @@ struct wined3d_texture
DWORD sampler;
DWORD flags;
GLenum target;
DWORD update_map_binding;
GLuint rb_multisample;
GLuint rb_resolved;
......@@ -2572,15 +2573,12 @@ 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,
unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) DECLSPEC_HIDDEN;
void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void wined3d_texture_unmap_bo_address(const struct wined3d_bo_address *data,
const struct wined3d_gl_info *gl_info, GLenum binding) DECLSPEC_HIDDEN;
BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_validate_location(struct wined3d_texture *texture,
unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN;
......
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