wined3d: Merge wined3d_surface_map() and wined3d_volume_map().

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Stefan Dösinger 2016-03-11 16:01:43 +01:00 committed by Alexandre Julliard
parent a9506bf952
commit aeefbdffba
6 changed files with 245 additions and 349 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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;
if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), sub_resource_idx)))
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);
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;

View File

@ -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);

View File

@ -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;