Skip to content

Commit f9bc499

Browse files
Dynamic Buffer: fixed issues with sparse buffer size alignment
1 parent ff42779 commit f9bc499

2 files changed

Lines changed: 24 additions & 14 deletions

File tree

Graphics/GraphicsTools/interface/DynamicBuffer.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,14 @@ class DynamicBuffer
174174
}
175175

176176

177-
/// Returns the virtual size of the sparse buffer.
177+
/// Returns the logical virtual size of the sparse buffer.
178178
///
179-
/// \remarks If the internal buffer has not been initialized yet,
180-
/// the method returns zero.
179+
/// \note The actual size of the sparse buffer may be larger
180+
/// than the logical size due to alignment requirements.
181+
/// Use GetBuffer()->GetDesc().Size to get the actual size.
181182
Uint64 GetVirtualSize() const
182183
{
183-
return m_pBuffer ? m_VirtualSize : 0;
184+
return m_VirtualSize;
184185
}
185186

186187
private:
@@ -203,7 +204,8 @@ class DynamicBuffer
203204
RefCntAutoPtr<IDeviceMemory> m_pMemory;
204205

205206
Uint64 m_PendingSize = 0;
206-
Uint64 m_VirtualSize = 0;
207+
208+
const Uint64 m_VirtualSize;
207209

208210
Uint32 m_MemoryPageSize = 0;
209211

Graphics/GraphicsTools/src/DynamicBuffer.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,6 @@ DynamicBuffer::DynamicBuffer(IRenderDevice* pDevice,
6969
m_VirtualSize{CI.Desc.Usage == USAGE_SPARSE ? CI.VirtualSize : 0},
7070
m_MemoryPageSize{CI.MemoryPageSize}
7171
{
72-
if (m_Desc.BindFlags & (BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS))
73-
{
74-
VERIFY_EXPR(m_Desc.ElementByteStride != 0);
75-
m_VirtualSize = AlignDownNonPw2(m_VirtualSize, m_Desc.ElementByteStride);
76-
}
7772
m_Desc.Name = m_Name.c_str();
7873
m_PendingSize = m_Desc.Size;
7974
m_Desc.Size = 0; // Current buffer size
@@ -99,12 +94,22 @@ void DynamicBuffer::CreateSparseBuffer(IRenderDevice* pDevice)
9994
const auto& SparseResources = pDevice->GetAdapterInfo().SparseResources;
10095
const auto SparseMemBlockSize = SparseResources.StandardBlockSize;
10196

102-
m_MemoryPageSize = std::max(AlignUp(m_MemoryPageSize, SparseMemBlockSize), SparseMemBlockSize);
103-
m_VirtualSize = std::min(m_VirtualSize, AlignDown(SparseResources.ResourceSpaceSize, m_MemoryPageSize));
97+
m_MemoryPageSize = std::max(AlignUpNonPw2(m_MemoryPageSize, SparseMemBlockSize), SparseMemBlockSize);
10498

10599
{
106100
auto Desc = m_Desc;
107-
Desc.Size = m_VirtualSize;
101+
102+
Desc.Size = AlignUpNonPw2(m_VirtualSize, m_MemoryPageSize);
103+
auto MaxSize = AlignDownNonPw2(SparseResources.ResourceSpaceSize, m_MemoryPageSize);
104+
if (m_Desc.BindFlags & (BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS))
105+
{
106+
VERIFY_EXPR(m_Desc.ElementByteStride != 0);
107+
// Buffer size must be a multiple of the element stride
108+
Desc.Size = AlignUpNonPw2(Desc.Size, m_Desc.ElementByteStride);
109+
MaxSize = AlignDownNonPw2(MaxSize, m_Desc.ElementByteStride);
110+
}
111+
Desc.Size = std::min(Desc.Size, MaxSize);
112+
108113
pDevice->CreateBuffer(Desc, nullptr, &m_pBuffer);
109114
DEV_CHECK_ERR(m_pBuffer, "Failed to create sparse buffer");
110115
if (!m_pBuffer)
@@ -293,7 +298,10 @@ IBuffer* DynamicBuffer::Resize(IRenderDevice* pDevice,
293298
bool DiscardContent)
294299
{
295300
if (m_Desc.Usage == USAGE_SPARSE)
296-
NewSize = AlignUp(NewSize, m_MemoryPageSize);
301+
{
302+
DEV_CHECK_ERR(NewSize <= m_VirtualSize, "New size (", NewSize, ") exceeds the buffer virtual size (", m_VirtualSize, ").");
303+
NewSize = AlignUpNonPw2(NewSize, m_MemoryPageSize);
304+
}
297305

298306
if (m_Desc.Size != NewSize)
299307
{

0 commit comments

Comments
 (0)