From aeefbdffba9ea77310759956007f1348920b4477 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Fri, 11 Mar 2016 16:01:43 +0100 Subject: [PATCH] wined3d: Merge wined3d_surface_map() and wined3d_volume_map(). Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3d8/volume.c | 5 +- dlls/d3d9/volume.c | 5 +- dlls/wined3d/surface.c | 153 ------------------------ dlls/wined3d/texture.c | 256 ++++++++++++++++++++++++++++++++++++----- dlls/wined3d/volume.c | 163 +------------------------- dlls/wined3d/wined3d_private.h | 12 +- 6 files changed, 245 insertions(+), 349 deletions(-) diff --git a/dlls/d3d8/volume.c b/dlls/d3d8/volume.c index dd75fff26d0..fb3afb3edfa 100644 --- a/dlls/d3d8/volume.c +++ b/dlls/d3d8/volume.c @@ -146,8 +146,9 @@ static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface, iface, locked_box, box, flags); wined3d_mutex_lock(); - hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, - &map_desc, (const struct wined3d_box *)box, flags); + if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), + volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, flags))) + map_desc.data = NULL; wined3d_mutex_unlock(); locked_box->RowPitch = map_desc.row_pitch; diff --git a/dlls/d3d9/volume.c b/dlls/d3d9/volume.c index c032a013e1b..0346f98ebaf 100644 --- a/dlls/d3d9/volume.c +++ b/dlls/d3d9/volume.c @@ -146,8 +146,9 @@ static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface, iface, locked_box, box, flags); wined3d_mutex_lock(); - hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, - &map_desc, (const struct wined3d_box *)box, flags); + if (FAILED(hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), + volume->sub_resource_idx, &map_desc, (const struct wined3d_box *)box, flags))) + map_desc.data = NULL; wined3d_mutex_unlock(); locked_box->RowPitch = map_desc.row_pitch; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 1169c0092cc..574069b4135 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2078,159 +2078,6 @@ do { \ return WINED3D_OK; } -HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, - const struct wined3d_box *box, DWORD flags) -{ - struct wined3d_texture *texture = surface->container; - const struct wined3d_format *format = texture->resource.format; - struct wined3d_device *device = texture->resource.device; - unsigned int fmt_flags = texture->resource.format_flags; - const struct wined3d_gl_info *gl_info = NULL; - struct wined3d_context *context = NULL; - BYTE *base_memory; - - TRACE("surface %p, map_desc %p, box %s, flags %#x.\n", - surface, map_desc, debug_box(box), flags); - - if (surface->resource.map_count) - { - WARN("Surface is already mapped.\n"); - return WINED3DERR_INVALIDCALL; - } - - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box - && !wined3d_texture_check_block_align(texture, surface->texture_level, box)) - { - WARN("Map box %s is misaligned for %ux%u blocks.\n", - debug_box(box), format->block_width, format->block_height); - - if (surface->resource.pool == WINED3D_POOL_DEFAULT) - return WINED3DERR_INVALIDCALL; - } - - ++surface->resource.map_count; - - if (!(surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) - WARN("Trying to lock unlockable surface.\n"); - - flags = wined3d_resource_sanitize_map_flags(&texture->resource, flags); - - if (device->d3d_initialized) - { - context = context_acquire(device, NULL); - gl_info = context->gl_info; - } - - if (flags & WINED3D_MAP_DISCARD) - { - TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", - wined3d_debug_location(surface->resource.map_binding)); - wined3d_surface_prepare(surface, context, surface->resource.map_binding); - surface_validate_location(surface, surface->resource.map_binding); - } - else - { - if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) - WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); - - surface_load_location(surface, context, surface->resource.map_binding); - } - - if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) - surface_invalidate_location(surface, ~surface->resource.map_binding); - - switch (surface->resource.map_binding) - { - case WINED3D_LOCATION_SYSMEM: - base_memory = surface->resource.heap_memory; - break; - - case WINED3D_LOCATION_USER_MEMORY: - base_memory = texture->user_memory; - break; - - case WINED3D_LOCATION_DIB: - base_memory = surface->dib.bitmap_data; - break; - - case WINED3D_LOCATION_BUFFER: - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, - texture->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GLbitfield map_flags = wined3d_resource_gl_map_flags(flags); - map_flags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; - base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, - 0, surface->resource.size, map_flags)); - } - else - { - GLenum access = wined3d_resource_gl_legacy_map_flags(flags); - base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); - } - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("map PBO"); - break; - - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); - base_memory = NULL; - } - - if (context) - context_release(context); - - if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) - { - map_desc->row_pitch = surface->resource.width * format->byte_count; - map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch; - } - else - { - wined3d_texture_get_pitch(texture, surface->texture_level, - &map_desc->row_pitch, &map_desc->slice_pitch); - } - - if (!box) - { - map_desc->data = base_memory; - } - else - { - if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) - { - /* Compressed textures are block based, so calculate the offset of - * the block that contains the top-left pixel of the locked rectangle. */ - map_desc->data = base_memory - + ((box->top / format->block_height) * map_desc->row_pitch) - + ((box->left / format->block_width) * format->block_byte_count); - } - else - { - map_desc->data = base_memory - + (map_desc->row_pitch * box->top) - + (box->left * format->byte_count); - } - } - - if (texture->swapchain && texture->swapchain->front_buffer == texture) - { - RECT *r = &texture->swapchain->front_buffer_update; - - if (!box) - SetRect(r, 0, 0, texture->resource.width, texture->resource.height); - else - SetRect(r, box->left, box->top, box->right, box->bottom); - TRACE("Mapped front buffer %s.\n", wine_dbgstr_rect(r)); - } - - TRACE("Returning memory %p, pitch %u.\n", map_desc->data, map_desc->row_pitch); - - return WINED3D_OK; -} - static void read_from_framebuffer(struct wined3d_surface *surface, struct wined3d_context *old_ctx, DWORD dst_location) { diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 9963c75c4ec..e0b5510e2e1 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -25,6 +25,7 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture); +WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(winediag); static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops, @@ -528,6 +529,22 @@ void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) return texture->resource.parent; } +static BOOL wined3d_texture_check_box_dimensions(const struct wined3d_texture *texture, + unsigned int level, const struct wined3d_box *box) +{ + if (box->left >= box->right + || box->top >= box->bottom + || box->front >= box->back) + return FALSE; + + if (box->right > wined3d_texture_get_level_width(texture, level) + || box->bottom > wined3d_texture_get_level_height(texture, level) + || box->back > wined3d_texture_get_level_depth(texture, level)) + return FALSE; + + return TRUE; +} + void CDECL wined3d_texture_get_pitch(const struct wined3d_texture *texture, unsigned int level, unsigned int *row_pitch, unsigned int *slice_pitch) { @@ -889,6 +906,19 @@ static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_reso &src_rect, data->row_pitch, &dst_point, FALSE, &addr); } +static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) +{ + return SUCCEEDED(surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location)); +} + +static BOOL texture2d_prepare_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) +{ + wined3d_surface_prepare(texture->sub_resources[sub_resource_idx].u.surface, context, location); + return TRUE; +} + /* Context activation is done by the caller. */ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { @@ -974,6 +1004,8 @@ static const struct wined3d_texture_ops texture2d_ops = texture2d_sub_resource_invalidate_location, texture2d_sub_resource_validate_location, texture2d_sub_resource_upload_data, + texture2d_load_location, + texture2d_prepare_location, texture2d_prepare_texture, texture2d_cleanup_sub_resources, }; @@ -1017,15 +1049,191 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) wined3d_texture_unload_gl_texture(texture); } -static HRESULT texture2d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, +static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) { + const struct wined3d_format *format = resource->format; + struct wined3d_device *device = resource->device; + unsigned int fmt_flags = resource->format_flags; + const struct wined3d_gl_info *gl_info = NULL; + struct wined3d_context *context = NULL; struct wined3d_resource *sub_resource; + struct wined3d_texture *texture; + unsigned int texture_level; + BYTE *base_memory; + BOOL ret; + + TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n", + resource, sub_resource_idx, map_desc, debug_box(box), flags); - if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx))) + texture = wined3d_texture_from_resource(resource); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) return E_INVALIDARG; - return wined3d_surface_map(surface_from_resource(sub_resource), map_desc, box, flags); + texture_level = sub_resource_idx % texture->level_count; + if (box && !wined3d_texture_check_box_dimensions(texture, texture_level, box)) + { + WARN("Map box is invalid.\n"); + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) + return WINED3DERR_INVALIDCALL; + } + + if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box + && !wined3d_texture_check_block_align(texture, texture_level, box)) + { + WARN("Map box %s is misaligned for %ux%u blocks.\n", + debug_box(box), format->block_width, format->block_height); + if (resource->type != WINED3D_RTYPE_TEXTURE_2D || resource->pool == WINED3D_POOL_DEFAULT) + return WINED3DERR_INVALIDCALL; + } + + if (!(resource->access_flags & WINED3D_RESOURCE_ACCESS_CPU)) + { + WARN("Trying to map unmappable texture.\n"); + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) + return WINED3DERR_INVALIDCALL; + } + + if (sub_resource->map_count) + { + WARN("Sub-resource is already mapped.\n"); + return WINED3DERR_INVALIDCALL; + } + + flags = wined3d_resource_sanitize_map_flags(resource, flags); + + if (device->d3d_initialized) + { + context = context_acquire(device, NULL); + gl_info = context->gl_info; + } + + if (flags & WINED3D_MAP_DISCARD) + { + TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", + wined3d_debug_location(sub_resource->map_binding)); + if ((ret = texture->texture_ops->texture_prepare_location(texture, + sub_resource_idx, context, sub_resource->map_binding))) + texture->texture_ops->texture_sub_resource_validate_location(sub_resource, sub_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->map_binding); + } + + if (!ret) + { + ERR("Failed to prepare location.\n"); + context_release(context); + return E_OUTOFMEMORY; + } + + if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) + texture->texture_ops->texture_sub_resource_invalidate_location(sub_resource, ~sub_resource->map_binding); + + switch (sub_resource->map_binding) + { + case WINED3D_LOCATION_SYSMEM: + base_memory = sub_resource->heap_memory; + break; + + case WINED3D_LOCATION_USER_MEMORY: + base_memory = texture->user_memory; + break; + + case WINED3D_LOCATION_DIB: + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) + ERR("Invalid map binding %#x for resource type %#x.\n", + sub_resource->map_binding, resource->type); + base_memory = texture->sub_resources[sub_resource_idx].u.surface->dib.bitmap_data; + break; + + case WINED3D_LOCATION_BUFFER: + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, + texture->sub_resources[sub_resource_idx].buffer_object)); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield map_flags = wined3d_resource_gl_map_flags(flags); + map_flags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; + base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, + 0, sub_resource->size, map_flags)); + } + else + { + GLenum access = wined3d_resource_gl_legacy_map_flags(flags); + base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); + } + + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("Map PBO"); + break; + + default: + ERR("Unexpected map binding %s.\n", wined3d_debug_location(sub_resource->map_binding)); + base_memory = NULL; + break; + } + + if (context) + context_release(context); + + TRACE("Base memory pointer %p.\n", base_memory); + + if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) + { + map_desc->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count; + map_desc->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * map_desc->row_pitch; + } + else + { + wined3d_texture_get_pitch(texture, texture_level, &map_desc->row_pitch, &map_desc->slice_pitch); + } + + if (!box) + { + map_desc->data = base_memory; + } + else + { + if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) + { + /* Compressed textures are block based, so calculate the offset of + * the block that contains the top-left pixel of the mapped box. */ + map_desc->data = base_memory + + (box->front * map_desc->slice_pitch) + + ((box->top / format->block_height) * map_desc->row_pitch) + + ((box->left / format->block_width) * format->block_byte_count); + } + else + { + map_desc->data = base_memory + + (box->front * map_desc->slice_pitch) + + (box->top * map_desc->row_pitch) + + (box->left * format->byte_count); + } + } + + if (texture->swapchain && texture->swapchain->front_buffer == texture) + { + RECT *r = &texture->swapchain->front_buffer_update; + + if (!box) + SetRect(r, 0, 0, resource->width, resource->height); + else + SetRect(r, box->left, box->top, box->right, box->bottom); + TRACE("Mapped front buffer %s.\n", wine_dbgstr_rect(r)); + } + + ++sub_resource->map_count; + + TRACE("Returning memory %p, row pitch %u, slice pitch %u.\n", + map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); + + return WINED3D_OK; } static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) @@ -1088,12 +1296,12 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso return WINED3D_OK; } -static const struct wined3d_resource_ops texture2d_resource_ops = +static const struct wined3d_resource_ops texture_resource_ops = { texture_resource_incref, texture_resource_decref, wined3d_texture_unload, - texture2d_resource_sub_resource_map, + texture_resource_sub_resource_map, texture_resource_sub_resource_unmap, }; @@ -1167,7 +1375,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 } if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, - flags, device, parent, parent_ops, &texture2d_resource_ops))) + flags, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); return hr; @@ -1317,6 +1525,18 @@ static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_reso wined3d_volume_upload_data(volume, context, &addr); } +static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) +{ + return wined3d_volume_load_location(texture->sub_resources[sub_resource_idx].u.volume, context, location); +} + +static BOOL texture3d_prepare_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location) +{ + return wined3d_volume_prepare_location(texture->sub_resources[sub_resource_idx].u.volume, context, location); +} + static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { unsigned int sub_count = texture->level_count * texture->layer_count; @@ -1364,6 +1584,8 @@ static const struct wined3d_texture_ops texture3d_ops = texture3d_sub_resource_invalidate_location, texture3d_sub_resource_validate_location, texture3d_sub_resource_upload_data, + texture3d_load_location, + texture3d_prepare_location, texture3d_prepare_texture, texture3d_cleanup_sub_resources, }; @@ -1397,26 +1619,6 @@ BOOL wined3d_texture_check_block_align(const struct wined3d_texture *texture, return TRUE; } -static HRESULT texture3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - struct wined3d_resource *sub_resource; - - if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx))) - return E_INVALIDARG; - - return wined3d_volume_map(volume_from_resource(sub_resource), map_desc, box, flags); -} - -static const struct wined3d_resource_ops texture3d_resource_ops = -{ - texture_resource_incref, - texture_resource_decref, - wined3d_texture_unload, - texture3d_resource_sub_resource_map, - texture_resource_sub_resource_unmap, -}; - static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, UINT levels, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops) { @@ -1486,7 +1688,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct } if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels, desc, - 0, device, parent, parent_ops, &texture3d_resource_ops))) + 0, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); return hr; diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index 7bde0247e69..e1749ac654f 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -42,7 +42,7 @@ static BOOL volume_prepare_system_memory(struct wined3d_volume *volume) /* Context activation is done by the caller. Context may be NULL in * WINED3D_NO3D mode. */ -static BOOL wined3d_volume_prepare_location(struct wined3d_volume *volume, +BOOL wined3d_volume_prepare_location(struct wined3d_volume *volume, struct wined3d_context *context, DWORD location) { struct wined3d_texture *texture = volume->container; @@ -247,7 +247,7 @@ static BOOL wined3d_volume_can_evict(const struct wined3d_volume *volume) } /* Context activation is done by the caller. */ -static BOOL wined3d_volume_load_location(struct wined3d_volume *volume, +BOOL wined3d_volume_load_location(struct wined3d_volume *volume, struct wined3d_context *context, DWORD location) { DWORD required_access = volume_access_from_location(location); @@ -420,165 +420,6 @@ static void volume_unload(struct wined3d_resource *resource) resource_unload(resource); } -static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *volume, - const struct wined3d_box *box) -{ - if (!box) - return TRUE; - - if (box->left >= box->right) - return FALSE; - if (box->top >= box->bottom) - return FALSE; - if (box->front >= box->back) - return FALSE; - if (box->right > volume->resource.width) - return FALSE; - if (box->bottom > volume->resource.height) - return FALSE; - if (box->back > volume->resource.depth) - return FALSE; - - return TRUE; -} - -HRESULT wined3d_volume_map(struct wined3d_volume *volume, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -{ - struct wined3d_device *device = volume->resource.device; - struct wined3d_texture *texture = volume->container; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - BYTE *base_memory; - const struct wined3d_format *format = volume->resource.format; - const unsigned int fmt_flags = texture->resource.format_flags; - BOOL ret; - - TRACE("volume %p, map_desc %p, box %s, flags %#x.\n", - volume, map_desc, debug_box(box), flags); - - map_desc->data = NULL; - if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) - { - WARN("Volume %p is not CPU accessible.\n", volume); - return WINED3DERR_INVALIDCALL; - } - if (volume->resource.map_count) - { - WARN("Volume is already mapped.\n"); - return WINED3DERR_INVALIDCALL; - } - if (!wined3d_volume_check_box_dimensions(volume, box)) - { - WARN("Map box is invalid.\n"); - return WINED3DERR_INVALIDCALL; - } - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box - && !wined3d_texture_check_block_align(texture, volume->texture_level, box)) - { - WARN("Map box %s is misaligned for %ux%u blocks.\n", - debug_box(box), format->block_width, format->block_height); - return WINED3DERR_INVALIDCALL; - } - - flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); - - context = context_acquire(device, NULL); - gl_info = context->gl_info; - - if (flags & WINED3D_MAP_DISCARD) - { - wined3d_volume_validate_location(volume, volume->resource.map_binding); - ret = wined3d_volume_prepare_location(volume, context, volume->resource.map_binding); - } - else - { - ret = wined3d_volume_load_location(volume, context, volume->resource.map_binding); - } - - if (!ret) - { - ERR("Failed to prepare location.\n"); - context_release(context); - map_desc->data = NULL; - return E_OUTOFMEMORY; - } - - if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) - { - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->sub_resources[volume->texture_level].buffer_object)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { - GLbitfield mapflags = wined3d_resource_gl_map_flags(flags); - mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; - base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, - 0, volume->resource.size, mapflags)); - } - else - { - GLenum access = wined3d_resource_gl_legacy_map_flags(flags); - base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); - } - - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Map PBO"); - } - else - { - base_memory = volume->resource.heap_memory; - } - - context_release(context); - - TRACE("Base memory pointer %p.\n", base_memory); - - if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) - { - map_desc->row_pitch = volume->resource.width * format->byte_count; - map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height; - } - else - { - wined3d_texture_get_pitch(texture, volume->texture_level, - &map_desc->row_pitch, &map_desc->slice_pitch); - } - - if (!box) - { - map_desc->data = base_memory; - } - else - { - if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) - { - /* Compressed textures are block based, so calculate the offset of - * the block that contains the top-left pixel of the locked rectangle. */ - map_desc->data = base_memory - + (box->front * map_desc->slice_pitch) - + ((box->top / format->block_height) * map_desc->row_pitch) - + ((box->left / format->block_width) * format->block_byte_count); - } - else - { - map_desc->data = base_memory - + (map_desc->slice_pitch * box->front) - + (map_desc->row_pitch * box->top) - + (box->left * volume->resource.format->byte_count); - } - } - - if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) - wined3d_volume_invalidate_location(volume, ~volume->resource.map_binding); - - volume->resource.map_count++; - - TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", - map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); - - return WINED3D_OK; -} - static ULONG volume_resource_incref(struct wined3d_resource *resource) { struct wined3d_volume *volume = volume_from_resource(resource); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8d64854c6d2..83a9d046428 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2337,6 +2337,10 @@ struct wined3d_texture_ops void (*texture_sub_resource_validate_location)(struct wined3d_resource *sub_resource, DWORD location); void (*texture_sub_resource_upload_data)(struct wined3d_resource *sub_resource, const struct wined3d_context *context, const struct wined3d_sub_resource_data *data); + BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location); + BOOL (*texture_prepare_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, DWORD location); void (*texture_prepare_texture)(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb); void (*texture_cleanup_sub_resources)(struct wined3d_texture *texture); @@ -2488,8 +2492,10 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) DECLSPEC_HIDDEN; -HRESULT wined3d_volume_map(struct wined3d_volume *volume, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; +BOOL wined3d_volume_load_location(struct wined3d_volume *volume, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +BOOL wined3d_volume_prepare_location(struct wined3d_volume *volume, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; @@ -2607,8 +2613,6 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN; HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, - const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -- 2.11.4.GIT