@@ -324,11 +324,24 @@ ITextureView* DynamicTextureArray::GetTextureSRV(TEXTURE_FORMAT ViewFormat) cons
324324
325325bool DynamicTextureArray::ResizeSparseTexture (IDeviceContext* pContext)
326326{
327- const Uint32 CurrArraySize = GetArraySize ();
328- VERIFY_EXPR (m_PendingSize != CurrArraySize );
327+ const Uint32 CurrResidentSize = GetArraySize ();
328+ VERIFY_EXPR (m_PendingSize != CurrResidentSize );
329329 VERIFY_EXPR (m_pTexture && m_pMemory);
330330
331- m_PendingSize = AlignUp (m_PendingSize, m_NumSlicesInPage);
331+ const Uint64 ResidentSize = AlignUp (Uint64{m_PendingSize}, Uint64{m_NumSlicesInPage});
332+ if (ResidentSize > m_pTexture->GetDesc ().ArraySize )
333+ {
334+ LOG_ERROR_MESSAGE (" Requested sparse dynamic texture array size exceeds the texture capacity after page alignment" );
335+ return false ;
336+ }
337+
338+ m_PendingSize = StaticCast<Uint32>(ResidentSize);
339+ if (m_PendingSize == CurrResidentSize)
340+ {
341+ // The logical request fits in the currently resident page range. There
342+ // are no memory ranges to bind or unbind.
343+ return true ;
344+ }
332345
333346 const Uint64 RequiredMemSize = (m_PendingSize / m_NumSlicesInPage) * m_MemoryPageSize;
334347 if (RequiredMemSize > m_pMemory->GetCapacity ())
@@ -347,11 +360,11 @@ bool DynamicTextureArray::ResizeSparseTexture(IDeviceContext* pContext)
347360 }
348361 }
349362
350- const Uint32 NumSlicesToBind = m_PendingSize > CurrArraySize ?
351- m_PendingSize - CurrArraySize :
352- CurrArraySize - m_PendingSize;
363+ const Uint32 NumSlicesToBind = m_PendingSize > CurrResidentSize ?
364+ m_PendingSize - CurrResidentSize :
365+ CurrResidentSize - m_PendingSize;
353366
354- Uint64 CurrMemOffset = Uint64{(m_PendingSize > CurrArraySize ? CurrArraySize : m_PendingSize) / m_NumSlicesInPage} * m_MemoryPageSize;
367+ Uint64 CurrMemOffset = Uint64{(m_PendingSize > CurrResidentSize ? CurrResidentSize : m_PendingSize) / m_NumSlicesInPage} * m_MemoryPageSize;
355368
356369 const SparseTextureProperties& TexSparseProps = m_pTexture->GetSparseProperties ();
357370 const Uint32 NumNormalMips = std::min (m_Desc.MipLevels , TexSparseProps.FirstMipInTail );
@@ -362,8 +375,8 @@ bool DynamicTextureArray::ResizeSparseTexture(IDeviceContext* pContext)
362375 std::vector<SparseTextureMemoryBindRange> MipRanges (size_t {NumSlicesToBind} * (size_t {NumNormalMips} + (HasMipTail ? 1 : 0 )));
363376
364377 auto range_it = MipRanges.begin ();
365- Uint32 StartSlice = std::min (CurrArraySize , m_PendingSize);
366- Uint32 EndSlice = std::max (CurrArraySize , m_PendingSize);
378+ Uint32 StartSlice = std::min (CurrResidentSize , m_PendingSize);
379+ Uint32 EndSlice = std::max (CurrResidentSize , m_PendingSize);
367380 for (Uint32 Slice = StartSlice; Slice != EndSlice; ++Slice)
368381 {
369382 // Bind normal mip levels
@@ -380,7 +393,7 @@ bool DynamicTextureArray::ResizeSparseTexture(IDeviceContext* pContext)
380393 range_it->MipLevel = Mip;
381394 range_it->Region = Box{0 , MipProps.StorageWidth , 0 , MipProps.StorageHeight , 0 , MipProps.Depth };
382395
383- if (Slice >= CurrArraySize )
396+ if (Slice >= CurrResidentSize )
384397 {
385398 const uint3 NumTilesInMip = GetNumSparseTilesInBox (range_it->Region , TexSparseProps.TileSize );
386399 range_it->pMemory = m_pMemory;
@@ -410,7 +423,7 @@ bool DynamicTextureArray::ResizeSparseTexture(IDeviceContext* pContext)
410423 range_it->MipLevel = TexSparseProps.FirstMipInTail ;
411424 range_it->MemorySize = TexSparseProps.MipTailSize ;
412425
413- if (Slice >= CurrArraySize )
426+ if (Slice >= CurrResidentSize )
414427 {
415428 range_it->pMemory = m_pMemory;
416429 range_it->MemoryOffset = CurrMemOffset;
@@ -551,7 +564,7 @@ void DynamicTextureArray::CommitResize(IRenderDevice* pDevice,
551564 ResizeCommitted = true ;
552565 }
553566
554- if (ResizeCommitted)
567+ if (ResizeCommitted && m_PendingSize != CurrArraySize )
555568 {
556569 StoreArraySize (m_PendingSize);
557570
0 commit comments