st/nine: Enforce LOD 0 for D3DUSAGE_AUTOGENMIPMAP
For D3DUSAGE_AUTOGENMIPMAP textures, applications can only lock/copy from/get surface descriptor for/etc the first level. Thus it makes sense to restrict the LOD to 0, and use only the first level to generate the sublevels. Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
parent
6f57e01436
commit
58d295d41e
|
@ -104,12 +104,15 @@ NineBaseTexture9_SetLOD( struct NineBaseTexture9 *This,
|
||||||
DWORD LODNew )
|
DWORD LODNew )
|
||||||
{
|
{
|
||||||
DWORD old = This->managed.lod;
|
DWORD old = This->managed.lod;
|
||||||
|
DWORD max_level;
|
||||||
|
|
||||||
DBG("This=%p LODNew=%d\n", This, LODNew);
|
DBG("This=%p LODNew=%d\n", This, LODNew);
|
||||||
|
|
||||||
user_assert(This->base.pool == D3DPOOL_MANAGED, 0);
|
user_assert(This->base.pool == D3DPOOL_MANAGED, 0);
|
||||||
|
|
||||||
This->managed.lod = MIN2(LODNew, This->base.info.last_level);
|
max_level = (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) ?
|
||||||
|
0 : This->base.info.last_level;
|
||||||
|
This->managed.lod = MIN2(LODNew, max_level);
|
||||||
|
|
||||||
if (This->managed.lod != old && This->bind_count && LIST_IS_EMPTY(&This->list))
|
if (This->managed.lod != old && This->bind_count && LIST_IS_EMPTY(&This->list))
|
||||||
list_add(&This->list, &This->base.base.device->update_textures);
|
list_add(&This->list, &This->base.base.device->update_textures);
|
||||||
|
@ -172,7 +175,7 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
|
||||||
assert(This->base.pool == D3DPOOL_MANAGED);
|
assert(This->base.pool == D3DPOOL_MANAGED);
|
||||||
|
|
||||||
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
|
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
|
||||||
last_level = 0; /* TODO: What if level 0 is not resident ? */
|
last_level = 0;
|
||||||
|
|
||||||
update_lod = This->managed.lod_resident != This->managed.lod;
|
update_lod = This->managed.lod_resident != This->managed.lod;
|
||||||
if (!update_lod && !This->managed.dirty)
|
if (!update_lod && !This->managed.dirty)
|
||||||
|
@ -366,7 +369,6 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
|
||||||
|
|
||||||
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
|
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
|
||||||
This->dirty_mip = TRUE;
|
This->dirty_mip = TRUE;
|
||||||
/* TODO: if dirty only because of lod change, only generate added levels */
|
|
||||||
|
|
||||||
DBG("DONE, generate mip maps = %i\n", This->dirty_mip);
|
DBG("DONE, generate mip maps = %i\n", This->dirty_mip);
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
|
@ -146,6 +146,11 @@ NineTexture9_ctor( struct NineTexture9 *This,
|
||||||
Width, Height,
|
Width, Height,
|
||||||
info->last_level);
|
info->last_level);
|
||||||
} else if (Pool != D3DPOOL_DEFAULT) {
|
} else if (Pool != D3DPOOL_DEFAULT) {
|
||||||
|
/* TODO: For D3DUSAGE_AUTOGENMIPMAP, it is likely we only have to
|
||||||
|
* allocate only for the first level, since it is the only lockable
|
||||||
|
* level. Check apps don't crash if we allocate smaller buffer (some
|
||||||
|
* apps access sublevels of texture even if they locked only first
|
||||||
|
* level) */
|
||||||
level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
|
level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
|
||||||
user_buffer = MALLOC(
|
user_buffer = MALLOC(
|
||||||
nine_format_get_size_and_offsets(pf, level_offsets,
|
nine_format_get_size_and_offsets(pf, level_offsets,
|
||||||
|
|
Loading…
Reference in New Issue