wined3d: Record dirty regions for d3d9 textures.
Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4277112af5
commit
c90d34178d
|
@ -1369,6 +1369,8 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
|
||||||
}
|
}
|
||||||
if (!levels)
|
if (!levels)
|
||||||
levels = wined3d_log2i(max(width, height)) + 1;
|
levels = wined3d_log2i(max(width, height)) + 1;
|
||||||
|
if (pool == D3DPOOL_SYSTEMMEM)
|
||||||
|
flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
|
hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
|
||||||
|
@ -1449,6 +1451,8 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
|
||||||
}
|
}
|
||||||
if (!levels)
|
if (!levels)
|
||||||
levels = wined3d_log2i(edge_length) + 1;
|
levels = wined3d_log2i(edge_length) + 1;
|
||||||
|
if (pool == D3DPOOL_SYSTEMMEM)
|
||||||
|
flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
|
hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
|
||||||
|
@ -1470,6 +1474,7 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
|
||||||
UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
|
UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
|
||||||
{
|
{
|
||||||
struct wined3d_resource_desc desc;
|
struct wined3d_resource_desc desc;
|
||||||
|
DWORD flags = 0;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
|
if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
|
||||||
|
@ -1513,9 +1518,11 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
|
||||||
}
|
}
|
||||||
if (!levels)
|
if (!levels)
|
||||||
levels = wined3d_log2i(max(max(width, height), depth)) + 1;
|
levels = wined3d_log2i(max(max(width, height), depth)) + 1;
|
||||||
|
if (pool == D3DPOOL_SYSTEMMEM)
|
||||||
|
flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
|
hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
|
||||||
NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
|
NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
|
@ -4059,8 +4059,10 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
|
||||||
{
|
{
|
||||||
unsigned int src_size, dst_size, src_skip_levels = 0;
|
unsigned int src_size, dst_size, src_skip_levels = 0;
|
||||||
unsigned int src_level_count, dst_level_count;
|
unsigned int src_level_count, dst_level_count;
|
||||||
|
const struct wined3d_dirty_regions *regions;
|
||||||
unsigned int layer_count, level_count, i, j;
|
unsigned int layer_count, level_count, i, j;
|
||||||
enum wined3d_resource_type type;
|
enum wined3d_resource_type type;
|
||||||
|
BOOL entire_texture = TRUE;
|
||||||
struct wined3d_box box;
|
struct wined3d_box box;
|
||||||
|
|
||||||
TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture);
|
TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture);
|
||||||
|
@ -4127,6 +4129,21 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((regions = src_texture->dirty_regions))
|
||||||
|
{
|
||||||
|
for (i = 0; i < layer_count && entire_texture; ++i)
|
||||||
|
{
|
||||||
|
if (regions[i].box_count >= WINED3D_MAX_DIRTY_REGION_COUNT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
entire_texture = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entire_texture)
|
||||||
|
FIXME("Ignoring dirty regions.\n");
|
||||||
|
|
||||||
/* Update every surface level of the texture. */
|
/* Update every surface level of the texture. */
|
||||||
for (i = 0; i < level_count; ++i)
|
for (i = 0; i < level_count; ++i)
|
||||||
{
|
{
|
||||||
|
@ -4140,6 +4157,8 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wined3d_texture_clear_dirty_regions(src_texture);
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -340,6 +340,21 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture,
|
||||||
sub_resource_idx, texture);
|
sub_resource_idx, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wined3d_texture_clear_dirty_regions(struct wined3d_texture *texture)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
TRACE("texture %p\n", texture);
|
||||||
|
|
||||||
|
if (!texture->dirty_regions)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < texture->layer_count; ++i)
|
||||||
|
{
|
||||||
|
texture->dirty_regions[i].box_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture,
|
static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture,
|
||||||
unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
|
unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
|
||||||
{
|
{
|
||||||
|
@ -1114,6 +1129,15 @@ static void wined3d_texture_destroy_object(void *object)
|
||||||
heap_free(texture->overlay_info);
|
heap_free(texture->overlay_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (texture->dirty_regions)
|
||||||
|
{
|
||||||
|
for (i = 0; i < texture->layer_count; ++i)
|
||||||
|
{
|
||||||
|
heap_free(texture->dirty_regions[i].boxes);
|
||||||
|
}
|
||||||
|
heap_free(texture->dirty_regions);
|
||||||
|
}
|
||||||
|
|
||||||
resource->resource_ops->resource_unload(resource);
|
resource->resource_ops->resource_unload(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1770,6 +1794,37 @@ static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(str
|
||||||
return &texture->sub_resources[sub_resource_idx];
|
return &texture->sub_resources[sub_resource_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wined3d_texture_dirty_region_add(struct wined3d_texture *texture,
|
||||||
|
unsigned int layer, const struct wined3d_box *box)
|
||||||
|
{
|
||||||
|
struct wined3d_dirty_regions *regions;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
if (!texture->dirty_regions)
|
||||||
|
return;
|
||||||
|
|
||||||
|
regions = &texture->dirty_regions[layer];
|
||||||
|
count = regions->box_count + 1;
|
||||||
|
if (count >= WINED3D_MAX_DIRTY_REGION_COUNT || !box
|
||||||
|
|| (!box->left && !box->top && !box->front
|
||||||
|
&& box->right == texture->resource.width
|
||||||
|
&& box->bottom == texture->resource.height
|
||||||
|
&& box->back == texture->resource.depth))
|
||||||
|
{
|
||||||
|
regions->box_count = WINED3D_MAX_DIRTY_REGION_COUNT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wined3d_array_reserve((void **)®ions->boxes, ®ions->boxes_size, count, sizeof(*regions->boxes)))
|
||||||
|
{
|
||||||
|
WARN("Failed to grow boxes array, marking entire texture dirty.\n");
|
||||||
|
regions->box_count = WINED3D_MAX_DIRTY_REGION_COUNT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
regions->boxes[regions->box_count++] = *box;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
|
HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
|
||||||
UINT layer, const struct wined3d_box *dirty_region)
|
UINT layer, const struct wined3d_box *dirty_region)
|
||||||
{
|
{
|
||||||
|
@ -1781,16 +1836,13 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty_region)
|
if (dirty_region && FAILED(wined3d_texture_check_box_dimensions(texture, 0, dirty_region)))
|
||||||
{
|
|
||||||
if (FAILED(wined3d_texture_check_box_dimensions(texture, 0, dirty_region)))
|
|
||||||
{
|
{
|
||||||
WARN("Invalid dirty_region %s specified.\n", debug_box(dirty_region));
|
WARN("Invalid dirty_region %s specified.\n", debug_box(dirty_region));
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
FIXME("Ignoring dirty_region %s.\n", debug_box(dirty_region));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
wined3d_texture_dirty_region_add(texture, layer, dirty_region);
|
||||||
wined3d_cs_emit_add_dirty_texture_region(texture->resource.device->cs, texture, layer);
|
wined3d_cs_emit_add_dirty_texture_region(texture->resource.device->cs, texture, layer);
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
|
@ -3090,6 +3142,11 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We only record dirty regions for the top-most level. */
|
||||||
|
if (texture->dirty_regions && flags & WINED3D_MAP_WRITE
|
||||||
|
&& !(flags & WINED3D_MAP_NO_DIRTY_UPDATE) && !texture_level)
|
||||||
|
wined3d_texture_dirty_region_add(texture, sub_resource_idx / texture->level_count, box);
|
||||||
|
|
||||||
if (flags & WINED3D_MAP_WRITE
|
if (flags & WINED3D_MAP_WRITE
|
||||||
&& (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC)))
|
&& (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC)))
|
||||||
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
|
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
|
||||||
|
@ -3382,6 +3439,13 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
|
||||||
texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS;
|
texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS
|
||||||
|
&& !(texture->dirty_regions = heap_calloc(texture->layer_count, sizeof(*texture->dirty_regions))))
|
||||||
|
{
|
||||||
|
wined3d_texture_cleanup_sync(texture);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
/* Precalculated scaling for 'faked' non power of two texture coords. */
|
/* Precalculated scaling for 'faked' non power of two texture coords. */
|
||||||
if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT)
|
if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT)
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,8 @@
|
||||||
#define WINED3D_QUIRK_BROKEN_ARB_FOG 0x00000200
|
#define WINED3D_QUIRK_BROKEN_ARB_FOG 0x00000200
|
||||||
#define WINED3D_QUIRK_NO_INDEPENDENT_BIT_DEPTHS 0x00000400
|
#define WINED3D_QUIRK_NO_INDEPENDENT_BIT_DEPTHS 0x00000400
|
||||||
|
|
||||||
|
#define WINED3D_MAX_DIRTY_REGION_COUNT 7
|
||||||
|
|
||||||
struct wined3d_fragment_pipe_ops;
|
struct wined3d_fragment_pipe_ops;
|
||||||
struct wined3d_adapter;
|
struct wined3d_adapter;
|
||||||
struct wined3d_context;
|
struct wined3d_context;
|
||||||
|
@ -3538,6 +3540,13 @@ struct wined3d_texture
|
||||||
DWORD color_key_flags;
|
DWORD color_key_flags;
|
||||||
} async;
|
} async;
|
||||||
|
|
||||||
|
struct wined3d_dirty_regions
|
||||||
|
{
|
||||||
|
struct wined3d_box *boxes;
|
||||||
|
SIZE_T boxes_size;
|
||||||
|
unsigned int box_count;
|
||||||
|
} *dirty_regions;
|
||||||
|
|
||||||
struct wined3d_overlay_info
|
struct wined3d_overlay_info
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
@ -3666,6 +3675,7 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un
|
||||||
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN;
|
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN;
|
||||||
void wined3d_texture_validate_location(struct wined3d_texture *texture,
|
void wined3d_texture_validate_location(struct wined3d_texture *texture,
|
||||||
unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN;
|
unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN;
|
||||||
|
void wined3d_texture_clear_dirty_regions(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT wined3d_texture_no3d_init(struct wined3d_texture *texture_no3d, struct wined3d_device *device,
|
HRESULT wined3d_texture_no3d_init(struct wined3d_texture *texture_no3d, struct wined3d_device *device,
|
||||||
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
|
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
|
||||||
|
|
|
@ -1565,6 +1565,7 @@ enum wined3d_shader_type
|
||||||
#define WINED3D_TEXTURE_CREATE_GET_DC_LENIENT 0x00000004
|
#define WINED3D_TEXTURE_CREATE_GET_DC_LENIENT 0x00000004
|
||||||
#define WINED3D_TEXTURE_CREATE_GET_DC 0x00000008
|
#define WINED3D_TEXTURE_CREATE_GET_DC 0x00000008
|
||||||
#define WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS 0x00000010
|
#define WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS 0x00000010
|
||||||
|
#define WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS 0x00000020
|
||||||
|
|
||||||
#define WINED3D_STANDARD_MULTISAMPLE_PATTERN 0xffffffff
|
#define WINED3D_STANDARD_MULTISAMPLE_PATTERN 0xffffffff
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue