Mesa (master): st/nine: Reduce system memory allocated by D3DUSAGE_AUTOGENMIPMAP

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Mar 2 19:23:45 UTC 2021


Module: Mesa
Branch: master
Commit: 3dbc542f971661e2f848db3d55d6f1fe194f220c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3dbc542f971661e2f848db3d55d6f1fe194f220c

Author: Axel Davy <davyaxel0 at gmail.com>
Date:   Thu May 21 17:51:55 2020 +0200

st/nine: Reduce system memory allocated by D3DUSAGE_AUTOGENMIPMAP

For D3DUSAGE_AUTOGENMIPMAP basically, everything behaves
for the application as if the texture had one level.
However the pipe_resource has more levels, and those
get generated automatically.

Previously we did allocate all the Surfaces as if
the texture had all the levels, except of just one.
The app could still just access the first level.

This patch completly removes the useless unaccessible
Surfaces.
In addition removes redundant handling of D3DUSAGE_AUTOGENMIPMAP.

Signed-off-by: Axel Davy <davyaxel0 at gmail.com>
Acked-by: Timur Kristóf <timur.kristof at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9177>

---

 src/gallium/frontends/nine/basetexture9.c   | 30 ++++++++------------
 src/gallium/frontends/nine/basetexture9.h   |  2 ++
 src/gallium/frontends/nine/cubetexture9.c   | 36 ++++++++++--------------
 src/gallium/frontends/nine/device9.c        |  4 +--
 src/gallium/frontends/nine/texture9.c       | 43 +++++++++++------------------
 src/gallium/frontends/nine/volumetexture9.c | 19 +++++++------
 6 files changed, 57 insertions(+), 77 deletions(-)

diff --git a/src/gallium/frontends/nine/basetexture9.c b/src/gallium/frontends/nine/basetexture9.c
index c509a1f4621..7c29dbeff88 100644
--- a/src/gallium/frontends/nine/basetexture9.c
+++ b/src/gallium/frontends/nine/basetexture9.c
@@ -66,6 +66,9 @@ NineBaseTexture9_ctor( struct NineBaseTexture9 *This,
     This->format = format;
     This->mipfilter = (Usage & D3DUSAGE_AUTOGENMIPMAP) ?
         D3DTEXF_LINEAR : D3DTEXF_NONE;
+    /* In the case of D3DUSAGE_AUTOGENMIPMAP, only the first level is accessible,
+     * and thus needs a surface created. */
+    This->level_count = (Usage & D3DUSAGE_AUTOGENMIPMAP) ? 1 : (This->base.info.last_level+1);
     This->managed.lod = 0;
     This->managed.lod_resident = -1;
     /* Mark the texture as dirty to trigger first upload when we need the texture,
@@ -112,15 +115,12 @@ NineBaseTexture9_SetLOD( struct NineBaseTexture9 *This,
                          DWORD LODNew )
 {
     DWORD old = This->managed.lod;
-    DWORD max_level;
 
     DBG("This=%p LODNew=%d\n", This, LODNew);
 
     user_assert(This->base.pool == D3DPOOL_MANAGED, 0);
 
-    max_level = (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) ?
-                0 : This->base.info.last_level;
-    This->managed.lod = MIN2(LODNew, max_level);
+    This->managed.lod = MIN2(LODNew, This->level_count-1);
 
     if (This->managed.lod != old && This->bind_count && list_is_empty(&This->list))
        list_add(&This->list, &This->base.base.device->update_textures);
@@ -141,9 +141,7 @@ NineBaseTexture9_GetLevelCount( struct NineBaseTexture9 *This )
 {
     DBG("This=%p\n", This);
 
-    if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
-        return 1;
-    return This->base.info.last_level + 1;
+    return This->level_count;
 }
 
 HRESULT NINE_WINAPI
@@ -175,7 +173,6 @@ HRESULT
 NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
 {
     HRESULT hr;
-    unsigned last_level = This->base.info.last_level;
     unsigned l, min_level_dirty = This->managed.lod;
     BOOL update_lod;
 
@@ -184,9 +181,6 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
 
     assert(This->base.pool == D3DPOOL_MANAGED);
 
-    if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
-        last_level = 0;
-
     update_lod = This->managed.lod_resident != This->managed.lod;
     if (!update_lod && !This->managed.dirty)
         return D3D_OK;
@@ -210,7 +204,7 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
 
         if (This->managed.lod_resident == -1) {/* no levels were resident */
             This->managed.dirty = FALSE; /* We are going to upload everything. */
-            This->managed.lod_resident = This->base.info.last_level + 1;
+            This->managed.lod_resident = This->level_count;
         }
 
         if (This->base.type == D3DRTYPE_TEXTURE) {
@@ -223,14 +217,14 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
              * corresponds to This->managed.lod).
              * Note3: We don't care about the value passed for the surfaces
              * before This->managed.lod, negative with this implementation. */
-            for (l = 0; l <= This->base.info.last_level; ++l)
+            for (l = 0; l < This->level_count; ++l)
                 NineSurface9_SetResource(tex->surfaces[l], res, l - This->managed.lod);
         } else
         if (This->base.type == D3DRTYPE_CUBETEXTURE) {
             struct NineCubeTexture9 *tex = NineCubeTexture9(This);
             unsigned z;
 
-            for (l = 0; l <= This->base.info.last_level; ++l) {
+            for (l = 0; l < This->level_count; ++l) {
                 for (z = 0; z < 6; ++z)
                     NineSurface9_SetResource(tex->surfaces[l * 6 + z],
                                              res, l - This->managed.lod);
@@ -239,7 +233,7 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
         if (This->base.type == D3DRTYPE_VOLUMETEXTURE) {
             struct NineVolumeTexture9 *tex = NineVolumeTexture9(This);
 
-            for (l = 0; l <= This->base.info.last_level; ++l)
+            for (l = 0; l < This->level_count; ++l)
                 NineVolume9_SetResource(tex->volumes[l], res, l - This->managed.lod);
         } else {
             assert(!"invalid texture type");
@@ -266,7 +260,7 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
              * either non-existing (and thus will be entirely re-uploaded
              * if the lod changes) or going to have a full upload */
             if (tex->dirty_rect.width) {
-                for (l = min_level_dirty; l <= last_level; ++l) {
+                for (l = min_level_dirty; l < This->level_count; ++l) {
                     u_box_minify_2d(&box, &tex->dirty_rect, l);
                     NineSurface9_UploadSelf(tex->surfaces[l], &box);
                 }
@@ -287,7 +281,7 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
                     tex->dirty_rect[z].width, tex->dirty_rect[z].height);
 
                 if (tex->dirty_rect[z].width) {
-                    for (l = min_level_dirty; l <= last_level; ++l) {
+                    for (l = min_level_dirty; l < This->level_count; ++l) {
                         u_box_minify_2d(&box, &tex->dirty_rect[z], l);
                         NineSurface9_UploadSelf(tex->surfaces[l * 6 + z], &box);
                     }
@@ -305,7 +299,7 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
                 tex->dirty_box.width, tex->dirty_box.height, tex->dirty_box.depth);
 
             if (tex->dirty_box.width) {
-                for (l = min_level_dirty; l <= last_level; ++l) {
+                for (l = min_level_dirty; l < This->level_count; ++l) {
                     u_box_minify_3d(&box, &tex->dirty_box, l);
                     NineVolume9_UploadSelf(tex->volumes[l], &box);
                 }
diff --git a/src/gallium/frontends/nine/basetexture9.h b/src/gallium/frontends/nine/basetexture9.h
index 70e8b934f56..e3952cf12a2 100644
--- a/src/gallium/frontends/nine/basetexture9.h
+++ b/src/gallium/frontends/nine/basetexture9.h
@@ -47,6 +47,8 @@ struct NineBaseTexture9
     boolean dirty_mip;
     D3DTEXTUREFILTERTYPE mipfilter;
 
+    unsigned level_count;
+
     /* Specific to managed textures */
     struct {
         boolean dirty;
diff --git a/src/gallium/frontends/nine/cubetexture9.c b/src/gallium/frontends/nine/cubetexture9.c
index 89821682f8f..a4259dce61e 100644
--- a/src/gallium/frontends/nine/cubetexture9.c
+++ b/src/gallium/frontends/nine/cubetexture9.c
@@ -107,26 +107,26 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This,
         DBG("Application asked for Software Vertex Processing, "
             "but this is unimplemented\n");
 
+    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_CUBETEXTURE,
+                               Format, Pool, Usage);
+    if (FAILED(hr))
+        return hr;
+    This->base.pstype = 2;
+
     if (Pool != D3DPOOL_DEFAULT) {
-        level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
+        level_offsets = alloca(sizeof(unsigned) * This->base.level_count);
         face_size = nine_format_get_size_and_offsets(pf, level_offsets,
                                                      EdgeLength, EdgeLength,
-                                                     info->last_level);
+                                                     This->base.level_count-1);
         This->managed_buffer = align_calloc(6 * face_size, 32);
         if (!This->managed_buffer)
             return E_OUTOFMEMORY;
     }
 
-    This->surfaces = CALLOC(6 * (info->last_level + 1), sizeof(*This->surfaces));
+    This->surfaces = CALLOC(6 * This->base.level_count, sizeof(*This->surfaces));
     if (!This->surfaces)
         return E_OUTOFMEMORY;
 
-    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_CUBETEXTURE,
-                               Format, Pool, Usage);
-    if (FAILED(hr))
-        return hr;
-    This->base.pstype = 2;
-
     /* Create all the surfaces right away.
      * They manage backing storage, and transfers (LockRect) are deferred
      * to them.
@@ -143,7 +143,7 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This,
      */
     for (f = 0; f < 6; f++) {
         offset = f * face_size;
-        for (l = 0; l <= info->last_level; l++) {
+        for (l = 0; l < This->base.level_count; l++) {
             sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, l);
             p = This->managed_buffer ? This->managed_buffer + offset +
                     level_offsets[l] : NULL;
@@ -174,7 +174,7 @@ NineCubeTexture9_dtor( struct NineCubeTexture9 *This )
     DBG("This=%p\n", This);
 
     if (This->surfaces) {
-        for (i = 0; i < (This->base.base.info.last_level + 1) * 6; ++i)
+        for (i = 0; i < This->base.level_count * 6; ++i)
             NineUnknown_Destroy(&This->surfaces[i]->base.base);
         FREE(This->surfaces);
     }
@@ -192,9 +192,7 @@ NineCubeTexture9_GetLevelDesc( struct NineCubeTexture9 *This,
 {
     DBG("This=%p Level=%u pDesc=%p\n", This, Level, pDesc);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
-    user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP),
-                D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     *pDesc = This->surfaces[Level * 6]->desc;
 
@@ -212,9 +210,7 @@ NineCubeTexture9_GetCubeMapSurface( struct NineCubeTexture9 *This,
     DBG("This=%p FaceType=%d Level=%u ppCubeMapSurface=%p\n",
         This, FaceType, Level, ppCubeMapSurface);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
-    user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP),
-                D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
     user_assert(FaceType < 6, D3DERR_INVALIDCALL);
 
     NineUnknown_AddRef(NineUnknown(This->surfaces[s]));
@@ -236,9 +232,7 @@ NineCubeTexture9_LockRect( struct NineCubeTexture9 *This,
     DBG("This=%p FaceType=%d Level=%u pLockedRect=%p pRect=%p Flags=%d\n",
         This, FaceType, Level, pLockedRect, pRect, Flags);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
-    user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP),
-                D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
     user_assert(FaceType < 6, D3DERR_INVALIDCALL);
 
     return NineSurface9_LockRect(This->surfaces[s], pLockedRect, pRect, Flags);
@@ -253,7 +247,7 @@ NineCubeTexture9_UnlockRect( struct NineCubeTexture9 *This,
 
     DBG("This=%p FaceType=%d Level=%u\n", This, FaceType, Level);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
     user_assert(FaceType < 6, D3DERR_INVALIDCALL);
 
     return NineSurface9_UnlockRect(This->surfaces[s]);
diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c
index badf65258b5..c8685588f11 100644
--- a/src/gallium/frontends/nine/device9.c
+++ b/src/gallium/frontends/nine/device9.c
@@ -1484,8 +1484,8 @@ NineDevice9_UpdateTexture( struct NineDevice9 *This,
      * That should satisfy the constraints (and instead of crashing for some cases we return D3D_OK)
      */
 
-    last_src_level = (srcb->base.usage & D3DUSAGE_AUTOGENMIPMAP) ? 0 : srcb->base.info.last_level;
-    last_dst_level = (dstb->base.usage & D3DUSAGE_AUTOGENMIPMAP) ? 0 : dstb->base.info.last_level;
+    last_src_level = srcb->level_count-1;
+    last_dst_level = dstb->level_count-1;
 
     for (m = 0; m <= last_src_level; ++m) {
         unsigned w = u_minify(srcb->base.info.width0, m);
diff --git a/src/gallium/frontends/nine/texture9.c b/src/gallium/frontends/nine/texture9.c
index fca5e603230..ae779a0bb5b 100644
--- a/src/gallium/frontends/nine/texture9.c
+++ b/src/gallium/frontends/nine/texture9.c
@@ -149,37 +149,32 @@ NineTexture9_ctor( struct NineTexture9 *This,
         DBG("Application asked for Software Vertex Processing, "
             "but this is unimplemented\n");
 
+    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage);
+    if (FAILED(hr))
+        return hr;
+    This->base.pstype = (Height == 1) ? 1 : 0;
+
     if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */
         user_buffer = (void *)*pSharedHandle;
-        level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
+        level_offsets = alloca(sizeof(unsigned) * This->base.level_count);
         (void) nine_format_get_size_and_offsets(pf, level_offsets,
                                                 Width, Height,
-                                                info->last_level);
+                                                This->base.level_count-1);
     } 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) * This->base.level_count);
         user_buffer = align_calloc(
             nine_format_get_size_and_offsets(pf, level_offsets,
                                              Width, Height,
-                                             info->last_level), 32);
+                                             This->base.level_count-1), 32);
         This->managed_buffer = user_buffer;
         if (!This->managed_buffer)
             return E_OUTOFMEMORY;
     }
 
-    This->surfaces = CALLOC(info->last_level + 1, sizeof(*This->surfaces));
+    This->surfaces = CALLOC(This->base.level_count, sizeof(*This->surfaces));
     if (!This->surfaces)
         return E_OUTOFMEMORY;
 
-    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage);
-    if (FAILED(hr))
-        return hr;
-    This->base.pstype = (Height == 1) ? 1 : 0;
-
     /* Create all the surfaces right away.
      * They manage backing storage, and transfers (LockRect) are deferred
      * to them.
@@ -191,7 +186,7 @@ NineTexture9_ctor( struct NineTexture9 *This,
     sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE;
     sfdesc.MultiSampleQuality = 0;
 
-    for (l = 0; l <= info->last_level; ++l) {
+    for (l = 0; l < This->base.level_count; ++l) {
         sfdesc.Width = u_minify(Width, l);
         sfdesc.Height = u_minify(Height, l);
         /* Some apps expect the memory to be allocated in
@@ -228,7 +223,7 @@ NineTexture9_dtor( struct NineTexture9 *This )
 
     if (This->surfaces) {
         /* The surfaces should have 0 references and be unbound now. */
-        for (l = 0; l <= This->base.base.info.last_level; ++l)
+        for (l = 0; l < This->base.level_count; ++l)
             if (This->surfaces[l])
                 NineUnknown_Destroy(&This->surfaces[l]->base.base);
         FREE(This->surfaces);
@@ -247,9 +242,7 @@ NineTexture9_GetLevelDesc( struct NineTexture9 *This,
 {
     DBG("This=%p Level=%d pDesc=%p\n", This, Level, pDesc);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
-    user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP),
-                D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     *pDesc = This->surfaces[Level]->desc;
 
@@ -263,9 +256,7 @@ NineTexture9_GetSurfaceLevel( struct NineTexture9 *This,
 {
     DBG("This=%p Level=%d ppSurfaceLevel=%p\n", This, Level, ppSurfaceLevel);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
-    user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP),
-                D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     NineUnknown_AddRef(NineUnknown(This->surfaces[Level]));
     *ppSurfaceLevel = (IDirect3DSurface9 *)This->surfaces[Level];
@@ -283,9 +274,7 @@ NineTexture9_LockRect( struct NineTexture9 *This,
     DBG("This=%p Level=%u pLockedRect=%p pRect=%p Flags=%d\n",
         This, Level, pLockedRect, pRect, Flags);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
-    user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP),
-                D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     return NineSurface9_LockRect(This->surfaces[Level], pLockedRect,
                                  pRect, Flags);
@@ -297,7 +286,7 @@ NineTexture9_UnlockRect( struct NineTexture9 *This,
 {
     DBG("This=%p Level=%u\n", This, Level);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     return NineSurface9_UnlockRect(This->surfaces[Level]);
 }
diff --git a/src/gallium/frontends/nine/volumetexture9.c b/src/gallium/frontends/nine/volumetexture9.c
index c7191bce688..4d574994599 100644
--- a/src/gallium/frontends/nine/volumetexture9.c
+++ b/src/gallium/frontends/nine/volumetexture9.c
@@ -100,9 +100,6 @@ NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
         DBG("Application asked for Software Vertex Processing, "
             "but this is unimplemented\n");
 
-    This->volumes = CALLOC(info->last_level + 1, sizeof(*This->volumes));
-    if (!This->volumes)
-        return E_OUTOFMEMORY;
     This->base.pstype = 3;
 
     hr = NineBaseTexture9_ctor(&This->base, pParams, NULL,
@@ -110,11 +107,15 @@ NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
     if (FAILED(hr))
         return hr;
 
+    This->volumes = CALLOC(This->base.level_count, sizeof(*This->volumes));
+    if (!This->volumes)
+        return E_OUTOFMEMORY;
+
     voldesc.Format = Format;
     voldesc.Type = D3DRTYPE_VOLUME;
     voldesc.Usage = Usage;
     voldesc.Pool = Pool;
-    for (l = 0; l <= info->last_level; ++l) {
+    for (l = 0; l < This->base.level_count; ++l) {
         voldesc.Width = u_minify(Width, l);
         voldesc.Height = u_minify(Height, l);
         voldesc.Depth = u_minify(Depth, l);
@@ -140,7 +141,7 @@ NineVolumeTexture9_dtor( struct NineVolumeTexture9 *This )
     DBG("This=%p\n", This);
 
     if (This->volumes) {
-        for (l = 0; l <= This->base.base.info.last_level; ++l)
+        for (l = 0; l < This->base.level_count; ++l)
             if (This->volumes[l])
                 NineUnknown_Destroy(&This->volumes[l]->base);
         FREE(This->volumes);
@@ -154,7 +155,7 @@ NineVolumeTexture9_GetLevelDesc( struct NineVolumeTexture9 *This,
                                  UINT Level,
                                  D3DVOLUME_DESC *pDesc )
 {
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     *pDesc = This->volumes[Level]->desc;
 
@@ -166,7 +167,7 @@ NineVolumeTexture9_GetVolumeLevel( struct NineVolumeTexture9 *This,
                                    UINT Level,
                                    IDirect3DVolume9 **ppVolumeLevel )
 {
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     NineUnknown_AddRef(NineUnknown(This->volumes[Level]));
     *ppVolumeLevel = (IDirect3DVolume9 *)This->volumes[Level];
@@ -184,7 +185,7 @@ NineVolumeTexture9_LockBox( struct NineVolumeTexture9 *This,
     DBG("This=%p Level=%u pLockedVolume=%p pBox=%p Flags=%d\n",
         This, Level, pLockedVolume, pBox, Flags);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     return NineVolume9_LockBox(This->volumes[Level], pLockedVolume, pBox,
                                Flags);
@@ -196,7 +197,7 @@ NineVolumeTexture9_UnlockBox( struct NineVolumeTexture9 *This,
 {
     DBG("This=%p Level=%u\n", This, Level);
 
-    user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL);
+    user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
 
     return NineVolume9_UnlockBox(This->volumes[Level]);
 }



More information about the mesa-commit mailing list