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

wined3d: Merge wined3d_surface_map() and wined3d_volume_map().

parent a9506bf9
......@@ -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;
......
......@@ -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;
......
......@@ -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)
{
......
......@@ -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);
......
......@@ -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;
......
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